Changeset 94d484a in mainline for uspace/app/sbi/src/run.c


Ignore:
Timestamp:
2010-03-07T17:45:33Z (14 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d0febca
Parents:
fa36f29
Message:

Update SBI to rev. 90.

File:
1 edited

Legend:

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

    rfa36f29 r94d484a  
    3939#include "rdata.h"
    4040#include "run_expr.h"
     41#include "run_texpr.h"
    4142#include "stree.h"
    4243#include "strtab.h"
     
    5152static void run_if(run_t *run, stree_if_t *if_s);
    5253static void run_while(run_t *run, stree_while_t *while_s);
     54static void run_raise(run_t *run, stree_raise_t *raise_s);
    5355static void run_return(run_t *run, stree_return_t *return_s);
     56static void run_wef(run_t *run, stree_wef_t *wef_s);
     57
     58static bool_t run_exc_match(run_t *run, stree_except_t *except_c);
    5459
    5560/** Initialize runner instance. */
     
    101106        run_fun_ar_set_args(run, fun_ar, &main_args);
    102107        run_fun(run, fun_ar, &res);
     108
     109        /* Check for unhandled exceptions. */
     110        if (run->thread_ar->bo_mode != bm_none) {
     111                assert(run->thread_ar->bo_mode == bm_exc);
     112                printf("Error: Unhandled exception.\n");
     113                exit(1);
     114        }
    103115}
    104116
     
    217229                run_while(run, stat->u.while_s);
    218230                break;
     231        case st_raise:
     232                run_raise(run, stat->u.raise_s);
     233                break;
    219234        case st_return:
    220235                run_return(run, stat->u.return_s);
    221236                break;
     237        case st_wef:
     238                run_wef(run, stat->u.wef_s);
     239                break;
    222240        case st_for:
    223         case st_raise:
    224         case st_wef:
    225241                printf("Ignoring unimplemented statement type %d.\n", stat->sc);
    226242                break;
     
    331347}
    332348
     349/** Run @c raise statement. */
     350static void run_raise(run_t *run, stree_raise_t *raise_s)
     351{
     352        rdata_item_t *rexpr;
     353        rdata_item_t *rexpr_vi;
     354
     355#ifdef DEBUG_RUN_TRACE
     356        printf("Executing raise statement.\n");
     357#endif
     358        run_expr(run, raise_s->expr, &rexpr);
     359        rdata_cvt_value_item(rexpr, &rexpr_vi);
     360
     361        /* Store expression result in thread AR. */
     362        run->thread_ar->exc_payload = rexpr_vi->u.value;
     363
     364        /* Start exception bailout. */
     365        run->thread_ar->bo_mode = bm_exc;
     366}
     367
    333368/** Run @c return statement. */
    334369static void run_return(run_t *run, stree_return_t *return_s)
     
    349384        if (run->thread_ar->bo_mode == bm_none)
    350385                run->thread_ar->bo_mode = bm_fun;
     386}
     387
     388/** Run @c with-except-finally statement. */
     389static void run_wef(run_t *run, stree_wef_t *wef_s)
     390{
     391        list_node_t *except_n;
     392        stree_except_t *except_c;
     393        rdata_value_t *exc_payload;
     394        run_bailout_mode_t bo_mode;
     395
     396#ifdef DEBUG_RUN_TRACE
     397        printf("Executing with-except-finally statement.\n");
     398#endif
     399        run_block(run, wef_s->with_block);
     400
     401        if (run->thread_ar->bo_mode == bm_exc) {
     402#ifdef DEBUG_RUN_TRACE
     403                printf("With statement detected exception.\n");
     404#endif
     405                /* Reset to normal execution. */
     406                run->thread_ar->bo_mode = bm_none;
     407
     408                /* Look for an except block. */
     409                except_n = list_first(&wef_s->except_clauses);
     410                while (except_n != NULL) {
     411                        except_c = list_node_data(except_n, stree_except_t *);
     412                        if (run_exc_match(run, except_c))
     413                                break;
     414
     415                        except_n = list_next(&wef_s->except_clauses, except_n);
     416                }
     417
     418                /* If one was found, execute it. */
     419                if (except_n != NULL)
     420                        run_block(run, except_c->block);
     421
     422                /* Execute finally block */
     423                if (wef_s->finally_block != NULL) {
     424                        /* Put exception on the side temporarily. */
     425                        bo_mode = run->thread_ar->bo_mode;
     426                        exc_payload = run->thread_ar->exc_payload;
     427
     428                        run->thread_ar->bo_mode = bm_none;
     429                        run->thread_ar->exc_payload = NULL;
     430
     431                        run_block(run, wef_s->finally_block);
     432
     433                        if (bo_mode == bm_exc) {
     434                                /*
     435                                 * Restore the original exception. If another
     436                                 * exception occured in the finally block (i.e.
     437                                 * double fault), it is forgotten.
     438                                 */
     439                                run->thread_ar->bo_mode = bm_exc;
     440                                run->thread_ar->exc_payload = exc_payload;
     441                        }
     442                }
     443        }
     444
     445#ifdef DEBUG_RUN_TRACE
     446        printf("With-except-finally statement terminated.\n");
     447#endif
     448}
     449
     450/** Determine whether currently active exception matches @c except clause.
     451 *
     452 * Checks if the currently active exception in the runner object @c run
     453 * matches except clause @c except_c. Generates an error if the exception
     454 * payload has invalid type (i.e. not an object).
     455 *
     456 * @param run           Runner object.
     457 * @param except_c      @c except clause.
     458 * @return              @c b_true if there is a match, @c b_false otherwise.
     459 */
     460static bool_t run_exc_match(run_t *run, stree_except_t *except_c)
     461{
     462        rdata_value_t *payload;
     463        rdata_var_t *payload_v;
     464        rdata_object_t *payload_o;
     465        rdata_titem_t *etype;
     466
     467        payload = run->thread_ar->exc_payload;
     468        assert(payload != NULL);
     469
     470        if (payload->var->vc != vc_ref) {
     471                printf("Error: Exception payload must be an object "
     472                    "(found type %d).\n", payload->var->vc);
     473                exit(1);
     474        }
     475
     476        payload_v = payload->var->u.ref_v->vref;
     477        if (payload_v->vc != vc_object) {
     478                printf("Error: Exception payload must be an object "
     479                    "(found type %d).\n", payload_v->vc);
     480                exit(1);
     481        }
     482
     483        payload_o = payload_v->u.object_v;
     484
     485#ifdef DEBUG_RUN_TRACE
     486        printf("Active exception: '");
     487        symbol_print_fqn(run->program, payload_o->class_sym);
     488        printf("'.\n");
     489#endif
     490        assert(payload_o->class_sym != NULL);
     491        assert(payload_o->class_sym->sc == sc_csi);
     492
     493        /* Evaluate type expression in except clause. */
     494        run_texpr(run, except_c->etype, &etype);
     495
     496        return rdata_is_csi_derived_from_ti(payload_o->class_sym->u.csi,
     497            etype);
    351498}
    352499
     
    395542        node = list_last(&fun_ar->block_ar);
    396543        return list_node_data(node, run_block_ar_t *);
     544}
     545
     546/** Get current CSI. */
     547stree_csi_t *run_get_current_csi(run_t *run)
     548{
     549        run_fun_ar_t *fun_ar;
     550
     551        fun_ar = run_get_current_fun_ar(run);
     552        return fun_ar->fun_sym->outer_csi;
    397553}
    398554
     
    468624        run_block_ar_t *block_ar;
    469625        list_node_t *rarg_n, *farg_n;
     626        list_node_t *cn;
    470627        rdata_item_t *rarg;
    471628        stree_fun_arg_t *farg;
    472629        rdata_var_t *var;
     630        rdata_var_t *ref_var;
     631        rdata_ref_t *ref;
     632        rdata_array_t *array;
     633        int n_vargs, idx;
    473634
    474635        /* AR should have been created with run_fun_ar_create(). */
     
    511672        }
    512673
     674        if (fun->varg != NULL) {
     675                /* Function is variadic. Count number of variadic arguments. */
     676                cn = rarg_n;
     677                n_vargs = 0;
     678                while (cn != NULL) {
     679                        n_vargs += 1;
     680                        cn = list_next(args, cn);
     681                }
     682
     683                /* Prepare array to store variadic arguments. */
     684                array = rdata_array_new(1);
     685                array->extent[0] = n_vargs;
     686                rdata_array_alloc_element(array);
     687
     688                /* Read variadic arguments. */
     689
     690                idx = 0;
     691                while (rarg_n != NULL) {
     692                        rarg = list_node_data(rarg_n, rdata_item_t *);
     693                        assert(rarg->ic == ic_value);
     694
     695                        rdata_var_write(array->element[idx], rarg->u.value);
     696
     697                        rarg_n = list_next(args, rarg_n);
     698                        idx += 1;
     699                }
     700
     701                var = rdata_var_new(vc_array);
     702                var->u.array_v = array;
     703
     704                /* Create reference to the new array. */
     705                ref_var = rdata_var_new(vc_ref);
     706                ref = rdata_ref_new();
     707                ref_var->u.ref_v = ref;
     708                ref->vref = var;
     709
     710                /* Declare variable using name of formal argument. */
     711                intmap_set(&block_ar->vars, fun->varg->name->sid,
     712                    ref_var);
     713        }
     714
    513715        /* Check for excess real parameters. */
    514716        if (rarg_n != NULL) {
Note: See TracChangeset for help on using the changeset viewer.