Changeset 94d484a in mainline for uspace/app/sbi/src/run.c
- Timestamp:
- 2010-03-07T17:45:33Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d0febca
- Parents:
- fa36f29
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/sbi/src/run.c
rfa36f29 r94d484a 39 39 #include "rdata.h" 40 40 #include "run_expr.h" 41 #include "run_texpr.h" 41 42 #include "stree.h" 42 43 #include "strtab.h" … … 51 52 static void run_if(run_t *run, stree_if_t *if_s); 52 53 static void run_while(run_t *run, stree_while_t *while_s); 54 static void run_raise(run_t *run, stree_raise_t *raise_s); 53 55 static void run_return(run_t *run, stree_return_t *return_s); 56 static void run_wef(run_t *run, stree_wef_t *wef_s); 57 58 static bool_t run_exc_match(run_t *run, stree_except_t *except_c); 54 59 55 60 /** Initialize runner instance. */ … … 101 106 run_fun_ar_set_args(run, fun_ar, &main_args); 102 107 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 } 103 115 } 104 116 … … 217 229 run_while(run, stat->u.while_s); 218 230 break; 231 case st_raise: 232 run_raise(run, stat->u.raise_s); 233 break; 219 234 case st_return: 220 235 run_return(run, stat->u.return_s); 221 236 break; 237 case st_wef: 238 run_wef(run, stat->u.wef_s); 239 break; 222 240 case st_for: 223 case st_raise:224 case st_wef:225 241 printf("Ignoring unimplemented statement type %d.\n", stat->sc); 226 242 break; … … 331 347 } 332 348 349 /** Run @c raise statement. */ 350 static 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 333 368 /** Run @c return statement. */ 334 369 static void run_return(run_t *run, stree_return_t *return_s) … … 349 384 if (run->thread_ar->bo_mode == bm_none) 350 385 run->thread_ar->bo_mode = bm_fun; 386 } 387 388 /** Run @c with-except-finally statement. */ 389 static 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 */ 460 static 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); 351 498 } 352 499 … … 395 542 node = list_last(&fun_ar->block_ar); 396 543 return list_node_data(node, run_block_ar_t *); 544 } 545 546 /** Get current CSI. */ 547 stree_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; 397 553 } 398 554 … … 468 624 run_block_ar_t *block_ar; 469 625 list_node_t *rarg_n, *farg_n; 626 list_node_t *cn; 470 627 rdata_item_t *rarg; 471 628 stree_fun_arg_t *farg; 472 629 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; 473 634 474 635 /* AR should have been created with run_fun_ar_create(). */ … … 511 672 } 512 673 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 513 715 /* Check for excess real parameters. */ 514 716 if (rarg_n != NULL) {
Note:
See TracChangeset
for help on using the changeset viewer.