~jsvoboda/helenos/sysel

« back to all changes in this revision

Viewing changes to uspace/app/sbi/src/run.c

  • Committer: Jiri Svoboda
  • Date: 2010-05-08 08:10:44 UTC
  • Revision ID: jiri@wiwaxia-20100508081044-5hvcjwu15rsfvgnv
Update SBI to rev. 244.

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
#include <assert.h>
34
34
#include "bigint.h"
35
35
#include "builtin.h"
 
36
#include "cspan.h"
36
37
#include "debug.h"
37
38
#include "intmap.h"
38
39
#include "list.h"
53
54
static void run_if(run_t *run, stree_if_t *if_s);
54
55
static void run_while(run_t *run, stree_while_t *while_s);
55
56
static void run_raise(run_t *run, stree_raise_t *raise_s);
 
57
static void run_break(run_t *run, stree_break_t *break_s);
56
58
static void run_return(run_t *run, stree_return_t *return_s);
57
59
static void run_wef(run_t *run, stree_wef_t *wef_s);
58
60
 
70
72
    rdata_var_t **rvar);
71
73
static void run_var_new_null_ref(run_t *run, rdata_var_t **rvar);
72
74
static void run_var_new_deleg(run_t *run, rdata_var_t **rvar);
73
 
 
 
75
static void run_var_new_enum(run_t *run, tdata_enum_t *tenum,
 
76
    rdata_var_t **rvar);
74
77
 
75
78
/** Initialize runner instance.
76
79
 *
176
179
        /* Handle bailout. */
177
180
        switch (run->thread_ar->bo_mode) {
178
181
        case bm_stat:
179
 
                printf("Error: Misplaced 'break' statement.\n");
180
 
                exit(1);
 
182
                /* Break bailout was not caught. */
 
183
                assert(b_false);
181
184
        case bm_proc:
182
185
                run->thread_ar->bo_mode = bm_none;
183
186
                break;
282
285
        case st_raise:
283
286
                run_raise(run, stat->u.raise_s);
284
287
                break;
 
288
        case st_break:
 
289
                run_break(run, stat->u.break_s);
 
290
                break;
285
291
        case st_return:
286
292
                run_return(run, stat->u.return_s);
287
293
                break;
291
297
        case st_for:
292
298
                printf("Ignoring unimplemented statement type %d.\n", stat->sc);
293
299
                break;
294
 
        default:
295
 
                assert(b_false);
296
300
        }
297
301
}
298
302
 
363
367
static void run_if(run_t *run, stree_if_t *if_s)
364
368
{
365
369
        rdata_item_t *rcond;
 
370
        list_node_t *ifc_node;
 
371
        stree_if_clause_t *ifc;
 
372
        bool_t clause_fired;
366
373
 
367
374
#ifdef DEBUG_RUN_TRACE
368
375
        printf("Executing if statement.\n");
369
376
#endif
370
 
        run_expr(run, if_s->cond, &rcond);
371
 
        if (run_is_bo(run))
372
 
                return;
373
 
 
374
 
        if (run_item_boolean_value(run, rcond) == b_true) {
375
 
#ifdef DEBUG_RUN_TRACE
376
 
                printf("Taking true path.\n");
377
 
#endif
378
 
                run_block(run, if_s->if_block);
379
 
        } else {
380
 
#ifdef DEBUG_RUN_TRACE
381
 
                printf("Taking false path.\n");
382
 
#endif
383
 
                if (if_s->else_block != NULL)
384
 
                        run_block(run, if_s->else_block);
 
377
        clause_fired = b_false;
 
378
        ifc_node = list_first(&if_s->if_clauses);
 
379
 
 
380
        /* Walk through all if/elif clauses and see if they fire. */
 
381
 
 
382
        while (ifc_node != NULL) {
 
383
                /* Get if/elif clause */
 
384
                ifc = list_node_data(ifc_node, stree_if_clause_t *);
 
385
 
 
386
                run_expr(run, ifc->cond, &rcond);
 
387
                if (run_is_bo(run))
 
388
                        return;
 
389
 
 
390
                if (run_item_boolean_value(run, rcond) == b_true) {
 
391
#ifdef DEBUG_RUN_TRACE
 
392
                        printf("Taking non-default path.\n");
 
393
#endif
 
394
                        run_block(run, ifc->block);
 
395
                        clause_fired = b_true;
 
396
                        break;
 
397
                }
 
398
 
 
399
                ifc_node = list_next(&if_s->if_clauses, ifc_node);
 
400
        }
 
401
 
 
402
        /* If no if/elif clause fired, invoke the else clause. */
 
403
        if (clause_fired == b_false && if_s->else_block != NULL) {
 
404
#ifdef DEBUG_RUN_TRACE
 
405
                printf("Taking default path.\n");
 
406
#endif
 
407
                run_block(run, if_s->else_block);
385
408
        }
386
409
 
387
410
#ifdef DEBUG_RUN_TRACE
409
432
                run_block(run, while_s->body);
410
433
                run_expr(run, while_s->cond, &rcond);
411
434
                if (run_is_bo(run))
412
 
                        return;
413
 
 
414
 
                if (run->thread_ar->bo_mode != bm_none)
415
435
                        break;
416
436
        }
417
437
 
 
438
        if (run->thread_ar->bo_mode == bm_stat) {
 
439
                /* Bailout due to break statement */
 
440
                run->thread_ar->bo_mode = bm_none;
 
441
        }
 
442
 
418
443
#ifdef DEBUG_RUN_TRACE
419
444
        printf("While statement terminated.\n");
420
445
#endif
439
464
 
440
465
        run_cvt_value_item(run, rexpr, &rexpr_vi);
441
466
 
 
467
        /* Store expression cspan in thread AR. */
 
468
        run->thread_ar->exc_cspan = raise_s->expr->cspan;
 
469
 
442
470
        /* Store expression result in thread AR. */
443
471
        run->thread_ar->exc_payload = rexpr_vi->u.value;
444
472
 
446
474
        run->thread_ar->bo_mode = bm_exc;
447
475
}
448
476
 
 
477
/** Run @c break statement.
 
478
 *
 
479
 * Forces control to return from the active breakable statement by setting
 
480
 * bailout mode to @c bm_stat.
 
481
 *
 
482
 * @param run           Runner object
 
483
 * @param break_s       Break statement to run
 
484
 */
 
485
static void run_break(run_t *run, stree_break_t *break_s)
 
486
{
 
487
#ifdef DEBUG_RUN_TRACE
 
488
        printf("Executing 'break' statement.\n");
 
489
#endif
 
490
        (void) break_s;
 
491
 
 
492
        /* Force control to ascend and leave the procedure. */
 
493
        if (run->thread_ar->bo_mode == bm_none)
 
494
                run->thread_ar->bo_mode = bm_stat;
 
495
}
 
496
 
449
497
/** Run @c return statement.
450
498
 *
451
499
 * Sets the return value in procedure AR and forces control to return
452
500
 * from the function by setting bailout mode to @c bm_proc.
453
501
 *
454
502
 * @param run           Runner object
455
 
 * @param raise_s       Return statement to run
 
503
 * @param return_s      Return statement to run
456
504
 */
457
505
static void run_return(run_t *run, stree_return_t *return_s)
458
506
{
463
511
#ifdef DEBUG_RUN_TRACE
464
512
        printf("Executing return statement.\n");
465
513
#endif
466
 
        run_expr(run, return_s->expr, &rexpr);
467
 
        if (run_is_bo(run))
468
 
                return;
469
 
 
470
 
        run_cvt_value_item(run, rexpr, &rexpr_vi);
471
 
 
472
 
        /* Store expression result in procedure AR. */
473
 
        proc_ar = run_get_current_proc_ar(run);
474
 
        proc_ar->retval = rexpr_vi;
 
514
        if (return_s->expr != NULL) {
 
515
                run_expr(run, return_s->expr, &rexpr);
 
516
                if (run_is_bo(run))
 
517
                        return;
 
518
 
 
519
                run_cvt_value_item(run, rexpr, &rexpr_vi);
 
520
 
 
521
                /* Store expression result in procedure AR. */
 
522
                proc_ar = run_get_current_proc_ar(run);
 
523
                proc_ar->retval = rexpr_vi;
 
524
        }
475
525
 
476
526
        /* Force control to ascend and leave the procedure. */
477
527
        if (run->thread_ar->bo_mode == bm_none)
631
681
 
632
682
                exc_csi = run_exc_payload_get_csi(run);
633
683
 
 
684
                if (run->thread_ar->exc_cspan != NULL) {
 
685
                        cspan_print(run->thread_ar->exc_cspan);
 
686
                        putchar(' ');
 
687
                }
 
688
 
634
689
                printf("Error: Unhandled exception '");
635
690
                symbol_print_fqn(csi_to_symbol(exc_csi));
636
691
                printf("'.\n");
748
803
        rdata_bool_t *bool_v;
749
804
        rdata_char_t *char_v;
750
805
        rdata_deleg_t *deleg_v;
 
806
        rdata_enum_t *enum_v;
751
807
        rdata_int_t *int_v;
752
808
        rdata_string_t *string_v;
753
809
        rdata_ref_t *ref_v;
780
836
                deleg_v->obj = item->u.value->var->u.deleg_v->obj;
781
837
                deleg_v->sym = item->u.value->var->u.deleg_v->sym;
782
838
                break;
 
839
        case vc_enum:
 
840
                *var = rdata_var_new(vc_enum);
 
841
                enum_v = rdata_enum_new();
 
842
 
 
843
                (*var)->u.enum_v = enum_v;
 
844
                enum_v->value = item->u.value->var->u.enum_v->value;
 
845
                break;
783
846
        case vc_int:
784
847
                *var = rdata_var_new(vc_int);
785
848
                int_v = rdata_int_new();
853
916
 */
854
917
void run_proc_ar_set_args(run_t *run, run_proc_ar_t *proc_ar, list_t *arg_vals)
855
918
{
 
919
        stree_ctor_t *ctor;
856
920
        stree_fun_t *fun;
857
921
        stree_prop_t *prop;
858
922
        list_t *args;
877
941
        assert(proc_ar->proc != NULL);
878
942
        outer_symbol = proc_ar->proc->outer_symbol;
879
943
 
 
944
        /* Make compiler happy. */
 
945
        args = NULL;
 
946
        varg = NULL;
 
947
 
880
948
        /*
881
949
         * The procedure being activated should belong to a member function or
882
950
         * property getter/setter.
883
951
         */
884
952
        switch (outer_symbol->sc) {
 
953
        case sc_ctor:
 
954
                ctor = symbol_to_ctor(outer_symbol);
 
955
                args = &ctor->sig->args;
 
956
                varg = ctor->sig->varg;
 
957
                break;
885
958
        case sc_fun:
886
959
                fun = symbol_to_fun(outer_symbol);
887
960
                args = &fun->sig->args;
892
965
                args = &prop->args;
893
966
                varg = prop->varg;
894
967
                break;
895
 
        default:
 
968
        case sc_csi:
 
969
        case sc_deleg:
 
970
        case sc_enum:
 
971
        case sc_var:
896
972
                assert(b_false);
897
973
        }
898
974
 
1376
1452
 *
1377
1453
 * @param run           Runner object
1378
1454
 * @param ref           Reference
 
1455
 * @param cspan         Cspan to put into exception if reference is nil
 
1456
 *                      or @c NULL if no cspan is provided.
1379
1457
 * @param rtitem        Place to store pointer to the resulting address.
1380
1458
 */
1381
 
void run_dereference(run_t *run, rdata_item_t *ref, rdata_item_t **ritem)
 
1459
void run_dereference(run_t *run, rdata_item_t *ref, cspan_t *cspan,
 
1460
    rdata_item_t **ritem)
1382
1461
{
1383
1462
        rdata_item_t *ref_val;
1384
1463
        rdata_item_t *item;
1403
1482
                printf("Error: Accessing null reference.\n");
1404
1483
#endif
1405
1484
                /* Raise Error.NilReference */
1406
 
                run_raise_exc(run, run->program->builtin->error_nilreference);
 
1485
                run_raise_exc(run, run->program->builtin->error_nilreference,
 
1486
                    cspan);
1407
1487
                *ritem = run_recovery_item(run);
1408
1488
                return;
1409
1489
        }
1421
1501
 *
1422
1502
 * @param run           Runner object
1423
1503
 * @param csi           Exception class
 
1504
 * @param cspan         Cspan of code that caused exception (for debugging)
1424
1505
 */
1425
 
void run_raise_exc(run_t *run, stree_csi_t *csi)
 
1506
void run_raise_exc(run_t *run, stree_csi_t *csi, cspan_t *cspan)
1426
1507
{
1427
1508
        rdata_item_t *exc_vi;
1428
1509
 
 
1510
        /* Store exception cspan in thread AR. */
 
1511
        run->thread_ar->exc_cspan = cspan;
 
1512
 
1429
1513
        /* Create exception object. */
1430
1514
        run_new_csi_inst(run, csi, &exc_vi);
1431
1515
        assert(exc_vi->ic == ic_value);
1471
1555
                run_var_new_null_ref(run, rvar);
1472
1556
                break;
1473
1557
        case tic_tdeleg:
 
1558
                run_var_new_deleg(run, rvar);
 
1559
                break;
 
1560
        case tic_tebase:
 
1561
                /*
 
1562
                 * One cannot declare variable of ebase type. It is just
 
1563
                 * type of expressions referring to enum types.
 
1564
                 */
 
1565
                assert(b_false);
 
1566
        case tic_tenum:
 
1567
                run_var_new_enum(run, ti->u.tenum, rvar);
 
1568
                break;
1474
1569
        case tic_tfun:
1475
1570
                run_var_new_deleg(run, rvar);
1476
1571
                break;
1577
1672
        *rvar = var;
1578
1673
}
1579
1674
 
 
1675
/** Construct a new variable containing default value of an enum type.
 
1676
 *
 
1677
 * @param run           Runner object
 
1678
 * @param rvar          Place to store pointer to new variable
 
1679
 */
 
1680
static void run_var_new_enum(run_t *run, tdata_enum_t *tenum,
 
1681
    rdata_var_t **rvar)
 
1682
{
 
1683
        rdata_var_t *var;
 
1684
        list_node_t *embr_n;
 
1685
        stree_embr_t *embr;
 
1686
 
 
1687
        (void) run;
 
1688
 
 
1689
        /* Get first member of enum which will serve as default value. */
 
1690
        embr_n = list_first(&tenum->enum_d->members);
 
1691
        assert(embr_n != NULL);
 
1692
 
 
1693
        embr = list_node_data(embr_n, stree_embr_t *);
 
1694
 
 
1695
        /* Return null reference. */
 
1696
        var = rdata_var_new(vc_enum);
 
1697
        var->u.enum_v = rdata_enum_new();
 
1698
        var->u.enum_v->value = embr;
 
1699
 
 
1700
        *rvar = var;
 
1701
}
 
1702
 
1580
1703
/** Construct a new thread activation record.
1581
1704
 *
1582
1705
 * @param run   Runner object