Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/sbi/src/run.c

    rc5cb943d r051b3db8  
    11/*
    2  * Copyright (c) 2010 Jiri Svoboda
     2 * Copyright (c) 2011 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    5353static void run_vdecl(run_t *run, stree_vdecl_t *vdecl);
    5454static void run_if(run_t *run, stree_if_t *if_s);
     55static void run_switch(run_t *run, stree_switch_t *switch_s);
    5556static void run_while(run_t *run, stree_while_t *while_s);
    5657static void run_raise(run_t *run, stree_raise_t *raise_s);
     
    142143        run_proc_ar_set_args(run, proc_ar, &main_args);
    143144        run_proc(run, proc_ar, &res);
     145        run_proc_ar_destroy(run, proc_ar);
    144146
    145147        run_exc_check_unhandled(run);
     
    272274        assert(list_node_data(node, run_block_ar_t *) == block_ar);
    273275        list_remove(&proc_ar->block_ar, node);
     276
     277        /* Deallocate block activation record. */
     278        run_block_ar_destroy(run, block_ar);
    274279}
    275280
     
    303308                run_if(run, stat->u.if_s);
    304309                break;
     310        case st_switch:
     311                run_switch(run, stat->u.switch_s);
     312                break;
    305313        case st_while:
    306314                run_while(run, stat->u.while_s);
     
    342350        run_expr(run, exps->expr, &rexpr);
    343351
     352        /*
     353         * If the expression has a value, the caller should have asked for it.
     354         */
     355        assert(res != NULL || rexpr == NULL);
     356
    344357        if (res != NULL)
    345358                *res = rexpr;
     
    355368        run_block_ar_t *block_ar;
    356369        rdata_var_t *var, *old_var;
    357         tdata_item_t *var_ti;
    358370
    359371#ifdef DEBUG_RUN_TRACE
    360372        printf("Executing variable declaration statement.\n");
    361373#endif
    362         /* Compute variable type. XXX Memoize. */
    363         run_texpr(run->program, run_get_current_csi(run), vdecl->type,
    364             &var_ti);
    365 
    366374        /* Create variable and initialize with default value. */
    367         run_var_new(run, var_ti, &var);
     375        run_var_new(run, vdecl->titem, &var);
    368376
    369377        block_ar = run_get_current_block_ar(run);
     
    393401        list_node_t *ifc_node;
    394402        stree_if_clause_t *ifc;
    395         bool_t clause_fired;
     403        bool_t rcond_b, clause_fired;
    396404
    397405#ifdef DEBUG_RUN_TRACE
     
    411419                        return;
    412420
    413                 if (run_item_boolean_value(run, rcond) == b_true) {
     421                rcond_b = run_item_boolean_value(run, rcond);
     422                rdata_item_destroy(rcond);
     423
     424                if (rcond_b == b_true) {
    414425#ifdef DEBUG_RUN_TRACE
    415426                        printf("Taking non-default path.\n");
     
    436447}
    437448
     449/** Run @c switch statement.
     450 *
     451 * @param run           Runner object
     452 * @param switch_s      Switch statement to run
     453 */
     454static void run_switch(run_t *run, stree_switch_t *switch_s)
     455{
     456        rdata_item_t *rsexpr, *rsexpr_vi;
     457        rdata_item_t *rwexpr, *rwexpr_vi;
     458        list_node_t *whenc_node;
     459        stree_when_t *whenc;
     460        list_node_t *expr_node;
     461        stree_expr_t *expr;
     462        bool_t clause_fired;
     463        bool_t equal;
     464
     465#ifdef DEBUG_RUN_TRACE
     466        printf("Executing switch statement.\n");
     467#endif
     468        rsexpr_vi = NULL;
     469
     470        /* Evaluate switch expression */
     471        run_expr(run, switch_s->expr, &rsexpr);
     472        if (run_is_bo(run))
     473                goto cleanup;
     474
     475        /* Convert to value item */
     476        run_cvt_value_item(run, rsexpr, &rsexpr_vi);
     477        rdata_item_destroy(rsexpr);
     478        if (run_is_bo(run))
     479                goto cleanup;
     480
     481        clause_fired = b_false;
     482        whenc_node = list_first(&switch_s->when_clauses);
     483
     484        /* Walk through all when clauses and see if they fire. */
     485
     486        while (whenc_node != NULL) {
     487                /* Get when clause */
     488                whenc = list_node_data(whenc_node, stree_when_t *);
     489
     490                expr_node = list_first(&whenc->exprs);
     491
     492                /* Walk through all expressions in the when clause */
     493                while (expr_node != NULL) {
     494                        /* Get expression */
     495                        expr = list_node_data(expr_node, stree_expr_t *);
     496
     497                        /* Evaluate expression */
     498                        run_expr(run, expr, &rwexpr);
     499                        if (run_is_bo(run))
     500                                goto cleanup;
     501
     502                        /* Convert to value item */
     503                        run_cvt_value_item(run, rwexpr, &rwexpr_vi);
     504                        rdata_item_destroy(rwexpr);
     505                        if (run_is_bo(run)) {
     506                                rdata_item_destroy(rwexpr_vi);
     507                                goto cleanup;
     508                        }
     509
     510                        /* Check if values are equal ('==') */
     511                        run_equal(run, rsexpr_vi->u.value,
     512                            rwexpr_vi->u.value, &equal);
     513                        rdata_item_destroy(rwexpr_vi);
     514                        if (run_is_bo(run))
     515                                goto cleanup;
     516
     517                        if (equal) {
     518#ifdef DEBUG_RUN_TRACE
     519                                printf("Taking non-default path.\n");
     520#endif
     521                                run_block(run, whenc->block);
     522                                clause_fired = b_true;
     523                                break;
     524                        }
     525
     526                        expr_node = list_next(&whenc->exprs, expr_node);
     527                }
     528
     529                if (clause_fired)
     530                        break;
     531
     532                whenc_node = list_next(&switch_s->when_clauses, whenc_node);
     533        }
     534
     535        /* If no when clause fired, invoke the else clause. */
     536        if (clause_fired == b_false && switch_s->else_block != NULL) {
     537#ifdef DEBUG_RUN_TRACE
     538                printf("Taking default path.\n");
     539#endif
     540                run_block(run, switch_s->else_block);
     541        }
     542cleanup:
     543        if (rsexpr_vi != NULL)
     544                rdata_item_destroy(rsexpr_vi);
     545
     546#ifdef DEBUG_RUN_TRACE
     547        printf("Switch statement terminated.\n");
     548#endif
     549}
     550
    438551/** Run @c while statement.
    439552 *
     
    453566
    454567        while (run_item_boolean_value(run, rcond) == b_true) {
     568                rdata_item_destroy(rcond);
    455569                run_block(run, while_s->body);
    456570                run_expr(run, while_s->cond, &rcond);
     
    459573        }
    460574
     575        if (rcond != NULL)
     576                rdata_item_destroy(rcond);
     577
    461578        if (run->thread_ar->bo_mode == bm_stat) {
    462579                /* Bailout due to break statement */
     
    487604
    488605        run_cvt_value_item(run, rexpr, &rexpr_vi);
     606        rdata_item_destroy(rexpr);
     607        if (run_is_bo(run))
     608                return;
    489609
    490610        /* Store expression cspan in thread AR. */
     
    492612
    493613        /* Store expression result in thread AR. */
     614        /* XXX rexpr_vi is leaked here, we only return ->u.value */
    494615        run->thread_ar->exc_payload = rexpr_vi->u.value;
    495616
     
    541662
    542663                run_cvt_value_item(run, rexpr, &rexpr_vi);
     664                rdata_item_destroy(rexpr);
     665                if (run_is_bo(run))
     666                        return;
    543667
    544668                /* Store expression result in procedure AR. */
     
    632756{
    633757        stree_csi_t *exc_csi;
    634         tdata_item_t *etype;
    635758
    636759        /* Get CSI of active exception. */
    637760        exc_csi = run_exc_payload_get_csi(run);
    638761
    639         /* Evaluate type expression in except clause. */
    640         run_texpr(run->program, run_get_current_csi(run), except_c->etype,
    641             &etype);
    642 
    643762        /* Determine if active exc. is derived from type in exc. clause. */
    644763        /* XXX This is wrong, it does not work with generics. */
    645         return tdata_is_csi_derived_from_ti(exc_csi, etype);
     764        return tdata_is_csi_derived_from_ti(exc_csi, except_c->titem);
    646765}
    647766
     
    10091128        (void) run;
    10101129
    1011         /* Create function activation record. */
     1130        /* Create procedure activation record. */
    10121131        proc_ar = run_proc_ar_new();
    10131132        proc_ar->obj = obj;
     
    10241143        *rproc_ar = proc_ar;
    10251144}
     1145
     1146/** Destroy a procedure AR.
     1147 *
     1148 * @param run           Runner object
     1149 * @param proc_ar       Pointer to procedure activation record
     1150 */
     1151void run_proc_ar_destroy(run_t *run, run_proc_ar_t *proc_ar)
     1152{
     1153        list_node_t *ar_node;
     1154        run_block_ar_t *block_ar;
     1155
     1156        (void) run;
     1157
     1158        /* Destroy special block activation record. */
     1159        ar_node = list_first(&proc_ar->block_ar);
     1160        block_ar = list_node_data(ar_node, run_block_ar_t *);
     1161        list_remove(&proc_ar->block_ar, ar_node);
     1162        run_block_ar_destroy(run, block_ar);
     1163
     1164        /* Destroy procedure activation record. */
     1165        proc_ar->obj = NULL;
     1166        proc_ar->proc = NULL;
     1167        list_fini(&proc_ar->block_ar);
     1168        proc_ar->retval = NULL;
     1169        run_proc_ar_delete(proc_ar);
     1170}
     1171
    10261172
    10271173/** Fill arguments in a procedure AR.
     
    10551201        rdata_ref_t *ref;
    10561202        rdata_array_t *array;
     1203        rdata_var_t *elem_var;
    10571204        int n_vargs, idx;
    10581205
     
    11471294                        assert(rarg->ic == ic_value);
    11481295
    1149                         rdata_var_write(array->element[idx], rarg->u.value);
     1296                        run_value_item_to_var(rarg, &elem_var);
     1297                        array->element[idx] = elem_var;
    11501298
    11511299                        rarg_n = list_next(arg_vals, rarg_n);
     
    12411389}
    12421390
     1391/** Destroy a block AR.
     1392 *
     1393 * @param run           Runner object
     1394 * @param proc_ar       Pointer to block activation record
     1395 */
     1396void run_block_ar_destroy(run_t *run, run_block_ar_t *block_ar)
     1397{
     1398        map_elem_t *elem;
     1399        rdata_var_t *var;
     1400        int key;
     1401
     1402        (void) run;
     1403
     1404        elem = intmap_first(&block_ar->vars);
     1405        while (elem != NULL) {
     1406                /* Destroy the variable */
     1407                var = intmap_elem_get_value(elem);
     1408                rdata_var_destroy(var);
     1409
     1410                /* Remove the map element */
     1411                key = intmap_elem_get_key(elem);
     1412                intmap_set(&block_ar->vars, key, NULL);
     1413
     1414                elem = intmap_first(&block_ar->vars);
     1415        }
     1416
     1417        intmap_fini(&block_ar->vars);
     1418        run_block_ar_delete(block_ar);
     1419}
     1420
    12431421/** Convert item to value item.
    12441422 *
     
    12691447        }
    12701448
    1271         /* It already is a value, we can share the @c var. */
     1449        /* Make a copy of the var node within. */
    12721450        value = rdata_value_new();
    1273         value->var = item->u.value->var;
     1451        rdata_var_copy(item->u.value->var, &value->var);
    12741452        *ritem = rdata_item_new(ic_value);
    12751453        (*ritem)->u.value = value;
     
    13581536{
    13591537        (void) run;
     1538        assert(ritem != NULL);
    13601539
    13611540        switch (address->ac) {
     
    13681547        }
    13691548
    1370         assert((*ritem)->ic == ic_value);
     1549        assert(*ritem == NULL || (*ritem)->ic == ic_value);
    13711550}
    13721551
     
    14571636        run_proc(run, proc_ar, ritem);
    14581637
     1638        /* Destroy procedure activation record. */
     1639        run_proc_ar_destroy(run, proc_ar);
     1640
    14591641#ifdef DEBUG_RUN_TRACE
    14601642        printf("Getter returns ");
     
    15291711        /* Setter should not return a value. */
    15301712        assert(ritem == NULL);
     1713
     1714        /* Destroy procedure activation record. */
     1715        run_proc_ar_destroy(run, proc_ar);
    15311716
    15321717#ifdef DEBUG_RUN_TRACE
     
    15901775#endif
    15911776        run_cvt_value_item(run, ref, &ref_val);
     1777        if (run_is_bo(run)) {
     1778                *ritem = run_recovery_item(run);
     1779                return;
     1780        }
     1781
    15921782        assert(ref_val->u.value->var->vc == vc_ref);
    15931783
     
    15981788        address->u.var_a = addr_var;
    15991789        addr_var->vref = ref_val->u.value->var->u.ref_v->vref;
     1790
     1791        rdata_item_destroy(ref_val);
    16001792
    16011793        if (addr_var->vref == NULL) {
     
    18402032}
    18412033
    1842 /** Construct a new procedure activation record.
    1843  *
    1844  * @param run   Runner object
     2034/** Allocate a new procedure activation record.
     2035 *
    18452036 * @return      New procedure AR.
    18462037 */
     
    18582049}
    18592050
    1860 /** Construct a new block activation record.
     2051/** Deallocate a procedure activation record.
     2052 *
     2053 * @return      New procedure AR.
     2054 */
     2055void run_proc_ar_delete(run_proc_ar_t *proc_ar)
     2056{
     2057        assert(proc_ar != NULL);
     2058        free(proc_ar);
     2059}
     2060
     2061/** Allocate a new block activation record.
    18612062 *
    18622063 * @param run   Runner object
     
    18752076        return block_ar;
    18762077}
     2078
     2079/** Deallocate a new block activation record.
     2080 *
     2081 * @param run   Runner object
     2082 * @return      New block AR.
     2083 */
     2084void run_block_ar_delete(run_block_ar_t *block_ar)
     2085{
     2086        assert(block_ar != NULL);
     2087        free(block_ar);
     2088}
Note: See TracChangeset for help on using the changeset viewer.