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);
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);
75
static void run_var_new_enum(run_t *run, tdata_enum_t *tenum,
75
78
/** Initialize runner instance.
363
367
static void run_if(run_t *run, stree_if_t *if_s)
365
369
rdata_item_t *rcond;
370
list_node_t *ifc_node;
371
stree_if_clause_t *ifc;
367
374
#ifdef DEBUG_RUN_TRACE
368
375
printf("Executing if statement.\n");
370
run_expr(run, if_s->cond, &rcond);
374
if (run_item_boolean_value(run, rcond) == b_true) {
375
#ifdef DEBUG_RUN_TRACE
376
printf("Taking true path.\n");
378
run_block(run, if_s->if_block);
380
#ifdef DEBUG_RUN_TRACE
381
printf("Taking false path.\n");
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);
380
/* Walk through all if/elif clauses and see if they fire. */
382
while (ifc_node != NULL) {
383
/* Get if/elif clause */
384
ifc = list_node_data(ifc_node, stree_if_clause_t *);
386
run_expr(run, ifc->cond, &rcond);
390
if (run_item_boolean_value(run, rcond) == b_true) {
391
#ifdef DEBUG_RUN_TRACE
392
printf("Taking non-default path.\n");
394
run_block(run, ifc->block);
395
clause_fired = b_true;
399
ifc_node = list_next(&if_s->if_clauses, ifc_node);
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");
407
run_block(run, if_s->else_block);
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))
414
if (run->thread_ar->bo_mode != bm_none)
438
if (run->thread_ar->bo_mode == bm_stat) {
439
/* Bailout due to break statement */
440
run->thread_ar->bo_mode = bm_none;
418
443
#ifdef DEBUG_RUN_TRACE
419
444
printf("While statement terminated.\n");
440
465
run_cvt_value_item(run, rexpr, &rexpr_vi);
467
/* Store expression cspan in thread AR. */
468
run->thread_ar->exc_cspan = raise_s->expr->cspan;
442
470
/* Store expression result in thread AR. */
443
471
run->thread_ar->exc_payload = rexpr_vi->u.value;
446
474
run->thread_ar->bo_mode = bm_exc;
477
/** Run @c break statement.
479
* Forces control to return from the active breakable statement by setting
480
* bailout mode to @c bm_stat.
482
* @param run Runner object
483
* @param break_s Break statement to run
485
static void run_break(run_t *run, stree_break_t *break_s)
487
#ifdef DEBUG_RUN_TRACE
488
printf("Executing 'break' statement.\n");
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;
449
497
/** Run @c return statement.
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.
454
502
* @param run Runner object
455
* @param raise_s Return statement to run
503
* @param return_s Return statement to run
457
505
static void run_return(run_t *run, stree_return_t *return_s)
463
511
#ifdef DEBUG_RUN_TRACE
464
512
printf("Executing return statement.\n");
466
run_expr(run, return_s->expr, &rexpr);
470
run_cvt_value_item(run, rexpr, &rexpr_vi);
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);
519
run_cvt_value_item(run, rexpr, &rexpr_vi);
521
/* Store expression result in procedure AR. */
522
proc_ar = run_get_current_proc_ar(run);
523
proc_ar->retval = rexpr_vi;
476
526
/* Force control to ascend and leave the procedure. */
477
527
if (run->thread_ar->bo_mode == bm_none)
632
682
exc_csi = run_exc_payload_get_csi(run);
684
if (run->thread_ar->exc_cspan != NULL) {
685
cspan_print(run->thread_ar->exc_cspan);
634
689
printf("Error: Unhandled exception '");
635
690
symbol_print_fqn(csi_to_symbol(exc_csi));
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;
840
*var = rdata_var_new(vc_enum);
841
enum_v = rdata_enum_new();
843
(*var)->u.enum_v = enum_v;
844
enum_v->value = item->u.value->var->u.enum_v->value;
784
847
*var = rdata_var_new(vc_int);
785
848
int_v = rdata_int_new();
877
941
assert(proc_ar->proc != NULL);
878
942
outer_symbol = proc_ar->proc->outer_symbol;
944
/* Make compiler happy. */
881
949
* The procedure being activated should belong to a member function or
882
950
* property getter/setter.
884
952
switch (outer_symbol->sc) {
954
ctor = symbol_to_ctor(outer_symbol);
955
args = &ctor->sig->args;
956
varg = ctor->sig->varg;
886
959
fun = symbol_to_fun(outer_symbol);
887
960
args = &fun->sig->args;
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.
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)
1383
1462
rdata_item_t *ref_val;
1384
1463
rdata_item_t *item;
1403
1482
printf("Error: Accessing null reference.\n");
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,
1407
1487
*ritem = run_recovery_item(run);
1422
1502
* @param run Runner object
1423
1503
* @param csi Exception class
1504
* @param cspan Cspan of code that caused exception (for debugging)
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)
1427
1508
rdata_item_t *exc_vi;
1510
/* Store exception cspan in thread AR. */
1511
run->thread_ar->exc_cspan = cspan;
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);
1473
1557
case tic_tdeleg:
1558
run_var_new_deleg(run, rvar);
1562
* One cannot declare variable of ebase type. It is just
1563
* type of expressions referring to enum types.
1567
run_var_new_enum(run, ti->u.tenum, rvar);
1475
1570
run_var_new_deleg(run, rvar);
1675
/** Construct a new variable containing default value of an enum type.
1677
* @param run Runner object
1678
* @param rvar Place to store pointer to new variable
1680
static void run_var_new_enum(run_t *run, tdata_enum_t *tenum,
1684
list_node_t *embr_n;
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);
1693
embr = list_node_data(embr_n, stree_embr_t *);
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;
1580
1703
/** Construct a new thread activation record.
1582
1705
* @param run Runner object