Ignore:
File:
1 edited

Legend:

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

    r23de644 r1ebc1a62  
    3232#include <stdlib.h>
    3333#include <assert.h>
    34 #include "bigint.h"
    3534#include "builtin.h"
    3635#include "debug.h"
     
    5857
    5958static bool_t run_exc_match(run_t *run, stree_except_t *except_c);
    60 static stree_csi_t *run_exc_payload_get_csi(run_t *run);
    61 
    6259static rdata_var_t *run_aprop_get_tpos(run_t *run, rdata_address_t *aprop);
    6360
     
    116113        run_proc(run, proc_ar, &res);
    117114
    118         run_exc_check_unhandled(run);
     115        /* Check for unhandled exceptions. */
     116        if (run->thread_ar->bo_mode != bm_none) {
     117                assert(run->thread_ar->bo_mode == bm_exc);
     118                printf("Error: Unhandled exception.\n");
     119                exit(1);
     120        }
    119121}
    120122
     
    300302
    301303        var->u.int_v = int_v;
    302         bigint_init(&int_v->value, 0);
     304        int_v->value = 0;
    303305
    304306        block_ar = run_get_current_block_ar(run);
     
    327329#endif
    328330        run_expr(run, if_s->cond, &rcond);
    329         if (run_is_bo(run))
    330                 return;
    331331
    332332        if (run_item_boolean_value(run, rcond) == b_true) {
     
    357357#endif
    358358        run_expr(run, while_s->cond, &rcond);
    359         if (run_is_bo(run))
    360                 return;
    361359
    362360        while (run_item_boolean_value(run, rcond) == b_true) {
    363361                run_block(run, while_s->body);
    364362                run_expr(run, while_s->cond, &rcond);
    365                 if (run_is_bo(run))
    366                         return;
    367363
    368364                if (run->thread_ar->bo_mode != bm_none)
     
    385381#endif
    386382        run_expr(run, raise_s->expr, &rexpr);
    387         if (run_is_bo(run))
    388                 return;
    389 
    390383        run_cvt_value_item(run, rexpr, &rexpr_vi);
    391384
     
    408401#endif
    409402        run_expr(run, return_s->expr, &rexpr);
    410         if (run_is_bo(run))
    411                 return;
    412 
    413403        run_cvt_value_item(run, rexpr, &rexpr_vi);
    414404
     
    487477 *
    488478 * Checks if the currently active exception in the runner object @c run
    489  * matches except clause @c except_c.
     479 * matches except clause @c except_c. Generates an error if the exception
     480 * payload has invalid type (i.e. not an object).
    490481 *
    491482 * @param run           Runner object.
     
    495486static bool_t run_exc_match(run_t *run, stree_except_t *except_c)
    496487{
    497         stree_csi_t *exc_csi;
     488        rdata_value_t *payload;
     489        rdata_var_t *payload_v;
     490        rdata_object_t *payload_o;
    498491        tdata_item_t *etype;
    499492
    500         /* Get CSI of active exception. */
    501         exc_csi = run_exc_payload_get_csi(run);
     493        payload = run->thread_ar->exc_payload;
     494        assert(payload != NULL);
     495
     496        if (payload->var->vc != vc_ref) {
     497                printf("Error: Exception payload must be an object "
     498                    "(found type %d).\n", payload->var->vc);
     499                exit(1);
     500        }
     501
     502        payload_v = payload->var->u.ref_v->vref;
     503        if (payload_v->vc != vc_object) {
     504                printf("Error: Exception payload must be an object "
     505                    "(found type %d).\n", payload_v->vc);
     506                exit(1);
     507        }
     508
     509        payload_o = payload_v->u.object_v;
     510
     511#ifdef DEBUG_RUN_TRACE
     512        printf("Active exception: '");
     513        symbol_print_fqn(payload_o->class_sym);
     514        printf("'.\n");
     515#endif
     516        assert(payload_o->class_sym != NULL);
     517        assert(payload_o->class_sym->sc == sc_csi);
    502518
    503519        /* Evaluate type expression in except clause. */
     
    505521            &etype);
    506522
    507         /* Determine if active exc. is derived from type in exc. clause. */
    508         return tdata_is_csi_derived_from_ti(exc_csi, etype);
    509 }
    510 
    511 /** Return CSI of the active exception.
    512  *
    513  * @param run           Runner object.
    514  * @return              CSI of the active exception.
    515  */
    516 static stree_csi_t *run_exc_payload_get_csi(run_t *run)
    517 {
    518         rdata_value_t *payload;
    519         rdata_var_t *payload_v;
    520         rdata_object_t *payload_o;
    521 
    522         payload = run->thread_ar->exc_payload;
    523         assert(payload != NULL);
    524 
    525         if (payload->var->vc != vc_ref) {
    526                 /* XXX Prevent this via static type checking. */
    527                 printf("Error: Exception payload must be an object "
    528                     "(found type %d).\n", payload->var->vc);
    529                 exit(1);
    530         }
    531 
    532         payload_v = payload->var->u.ref_v->vref;
    533         if (payload_v->vc != vc_object) {
    534                 /* XXX Prevent this via static type checking. */
    535                 printf("Error: Exception payload must be an object "
    536                     "(found type %d).\n", payload_v->vc);
    537                 exit(1);
    538         }
    539 
    540         payload_o = payload_v->u.object_v;
    541 
    542 #ifdef DEBUG_RUN_TRACE
    543         printf("Active exception: '");
    544         symbol_print_fqn(payload_o->class_sym);
    545         printf("'.\n");
    546 #endif
    547         assert(payload_o->class_sym != NULL);
    548         assert(payload_o->class_sym->sc == sc_csi);
    549 
    550         return payload_o->class_sym->u.csi;
    551 }
    552 
    553 
    554 /** Check for unhandled exception.
    555  *
    556  * Checks whether there is an active exception. If so, it prints an
    557  * error message and raises a run-time error.
    558  *
    559  * @param run           Runner object.
    560  */
    561 void run_exc_check_unhandled(run_t *run)
    562 {
    563         stree_csi_t *exc_csi;
    564 
    565         if (run->thread_ar->bo_mode != bm_none) {
    566                 assert(run->thread_ar->bo_mode == bm_exc);
    567 
    568                 exc_csi = run_exc_payload_get_csi(run);
    569 
    570                 printf("Error: Unhandled exception '");
    571                 symbol_print_fqn(csi_to_symbol(exc_csi));
    572                 printf("'.\n");
    573 
    574                 run_raise_error(run);
    575         }
     523        return tdata_is_csi_derived_from_ti(payload_o->class_sym->u.csi,
     524            etype);
    576525}
    577526
     
    671620
    672621                (*var)->u.int_v = int_v;
    673                 bigint_clone(&item->u.value->var->u.int_v->value,
    674                     &int_v->value);
     622                int_v->value = item->u.value->var->u.int_v->value;
    675623                break;
    676624        case vc_string:
     
    12231171
    12241172        if (addr_var->vref == NULL) {
    1225 #ifdef DEBUG_RUN_TRACE
    12261173                printf("Error: Accessing null reference.\n");
    1227 #endif
    1228                 /* Raise Error.NilReference */
    1229                 run_raise_exc(run, run->program->builtin->error_nilreference);
     1174                run_raise_error(run);
    12301175                *ritem = run_recovery_item(run);
    12311176                return;
     
    12361181#endif
    12371182        *ritem = item;
    1238 }
    1239 
    1240 /** Raise an exception of the given class.
    1241  *
    1242  * Used when the interpreter generates an exception due to a run-time
    1243  * error (not for the @c raise statement).
    1244  *
    1245  * @param run           Runner object.
    1246  * @param csi           Exception class.
    1247  */
    1248 void run_raise_exc(run_t *run, stree_csi_t *csi)
    1249 {
    1250         rdata_item_t *exc_vi;
    1251 
    1252         /* Create exception object. */
    1253         run_new_csi_inst(run, csi, &exc_vi);
    1254         assert(exc_vi->ic == ic_value);
    1255 
    1256         /* Store exception object in thread AR. */
    1257         run->thread_ar->exc_payload = exc_vi->u.value;
    1258 
    1259         /* Start exception bailout. */
    1260         run->thread_ar->bo_mode = bm_exc;
    1261 }
    1262 
    1263 /** Determine if we are bailing out. */
    1264 bool_t run_is_bo(run_t *run)
    1265 {
    1266         return run->thread_ar->bo_mode != bm_none;
    12671183}
    12681184
Note: See TracChangeset for help on using the changeset viewer.