Changes in uspace/app/sbi/src/run_expr.c [c5cb943d:051b3db8] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/sbi/src/run_expr.c
rc5cb943d r051b3db8 1 1 /* 2 * Copyright (c) 201 0Jiri Svoboda2 * Copyright (c) 2011 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 113 113 static void run_call(run_t *run, stree_call_t *call, rdata_item_t **res); 114 114 static void run_call_args(run_t *run, list_t *args, list_t *arg_vals); 115 static void run_destroy_arg_vals(list_t *arg_vals); 115 116 116 117 static void run_index(run_t *run, stree_index_t *index, rdata_item_t **res); … … 200 201 rdata_address_t *address; 201 202 rdata_addr_var_t *addr_var; 203 rdata_addr_prop_t *addr_prop; 204 rdata_aprop_named_t *aprop_named; 205 rdata_deleg_t *deleg_p; 202 206 rdata_value_t *value; 203 207 rdata_var_t *var; … … 334 338 break; 335 339 case sc_var: 336 #ifdef DEBUG_RUN_TRACE 337 printf("Referencing member variable.\n"); 338 #endif 339 /* There should be no global variables. */ 340 case sc_prop: 341 #ifdef DEBUG_RUN_TRACE 342 if (sym->sc == sc_var) 343 printf("Referencing member variable.\n"); 344 else 345 printf("Referencing unqualified property.\n"); 346 #endif 347 /* There should be no global variables or properties. */ 340 348 assert(csi != NULL); 341 349 342 350 if (symbol_search_csi(run->program, csi, nameref->name) 343 351 == NULL && !stree_symbol_is_static(sym)) { 344 /* Variableis not in the current object. */352 /* Symbol is not in the current object. */ 345 353 printf("Error: Cannot access non-static member " 346 354 "variable '"); … … 352 360 } 353 361 362 /* 363 * Determine object in which the symbol resides 364 */ 354 365 if (stree_symbol_is_static(sym)) { 355 366 /* 367 * Class object 356 368 * XXX This is too slow! 357 369 * … … 365 377 aobj = sobj->u.object_v; 366 378 } else { 367 aobj = obj; 379 /* 380 * Instance object. Currently we don't support 381 * true inner classes, thus we know the symbol is 382 * in the active object (there is no dynamic parent). 383 */ 384 sobj = proc_ar->obj; 385 aobj = sobj->u.object_v;; 368 386 } 369 387 370 /* Find member variable in object. */ 371 member_var = intmap_get(&aobj->fields, nameref->name->sid); 372 assert(member_var != NULL); 373 374 /* Return address of the variable. */ 375 item = rdata_item_new(ic_address); 376 address = rdata_address_new(ac_var); 377 addr_var = rdata_addr_var_new(); 378 379 item->u.address = address; 380 address->u.var_a = addr_var; 381 addr_var->vref = member_var; 382 383 *res = item; 384 break; 385 case sc_prop: 386 /* XXX TODO */ 387 printf("Unimplemented: Property name reference.\n"); 388 abort(); 388 if (sym->sc == sc_var) { 389 /* Find member variable in object. */ 390 member_var = intmap_get(&aobj->fields, 391 nameref->name->sid); 392 assert(member_var != NULL); 393 394 /* Return address of the variable. */ 395 item = rdata_item_new(ic_address); 396 address = rdata_address_new(ac_var); 397 addr_var = rdata_addr_var_new(); 398 399 item->u.address = address; 400 address->u.var_a = addr_var; 401 addr_var->vref = member_var; 402 403 *res = item; 404 } else { 405 /* Construct named property address. */ 406 item = rdata_item_new(ic_address); 407 address = rdata_address_new(ac_prop); 408 addr_prop = rdata_addr_prop_new(apc_named); 409 aprop_named = rdata_aprop_named_new(); 410 item->u.address = address; 411 address->u.prop_a = addr_prop; 412 addr_prop->u.named = aprop_named; 413 414 deleg_p = rdata_deleg_new(); 415 deleg_p->obj = sobj; 416 deleg_p->sym = sym; 417 addr_prop->u.named->prop_d = deleg_p; 418 419 *res = item; 420 } 389 421 break; 390 422 } … … 611 643 rdata_value_t *v1, *v2; 612 644 645 rarg1_i = NULL; 646 rarg2_i = NULL; 647 rarg1_vi = NULL; 648 rarg2_vi = NULL; 649 613 650 #ifdef DEBUG_RUN_TRACE 614 651 printf("Run binary operation.\n"); … … 616 653 run_expr(run, binop->arg1, &rarg1_i); 617 654 if (run_is_bo(run)) { 618 *res = NULL; 619 return; 655 *res = run_recovery_item(run); 656 goto cleanup; 657 } 658 659 #ifdef DEBUG_RUN_TRACE 660 printf("Check binop argument result.\n"); 661 #endif 662 run_cvt_value_item(run, rarg1_i, &rarg1_vi); 663 if (run_is_bo(run)) { 664 *res = run_recovery_item(run); 665 goto cleanup; 620 666 } 621 667 622 668 run_expr(run, binop->arg2, &rarg2_i); 623 669 if (run_is_bo(run)) { 624 *res = NULL; 625 return; 626 } 627 628 #ifdef DEBUG_RUN_TRACE 629 printf("Check binop argument results.\n"); 630 #endif 631 632 run_cvt_value_item(run, rarg1_i, &rarg1_vi); 670 *res = run_recovery_item(run); 671 goto cleanup; 672 } 673 674 #ifdef DEBUG_RUN_TRACE 675 printf("Check binop argument result.\n"); 676 #endif 633 677 run_cvt_value_item(run, rarg2_i, &rarg2_vi); 678 if (run_is_bo(run)) { 679 *res = run_recovery_item(run); 680 goto cleanup; 681 } 634 682 635 683 v1 = rarg1_vi->u.value; … … 668 716 assert(b_false); 669 717 } 718 719 cleanup: 720 if (rarg1_i != NULL) 721 rdata_item_destroy(rarg1_i); 722 if (rarg2_i != NULL) 723 rdata_item_destroy(rarg2_i); 724 if (rarg1_vi != NULL) 725 rdata_item_destroy(rarg1_vi); 726 if (rarg2_vi != NULL) 727 rdata_item_destroy(rarg2_vi); 670 728 } 671 729 … … 1054 1112 rdata_bool_t *bool_v; 1055 1113 1056 rdata_var_t *ref1, *ref2;1114 stree_embr_t *e1, *e2; 1057 1115 1058 1116 (void) run; … … 1067 1125 var->u.bool_v = bool_v; 1068 1126 1069 ref1 = v1->var->u.ref_v->vref;1070 ref2 = v2->var->u.ref_v->vref;1127 e1 = v1->var->u.enum_v->value; 1128 e2 = v2->var->u.enum_v->value; 1071 1129 1072 1130 switch (binop->bc) { 1073 1131 case bo_equal: 1074 bool_v->value = ( ref1 == ref2);1132 bool_v->value = (e1 == e2); 1075 1133 break; 1076 1134 case bo_notequal: 1077 bool_v->value = ( ref1 != ref2);1135 bool_v->value = (e1 != e2); 1078 1136 break; 1079 1137 default: … … 1100 1158 printf("Run unary operation.\n"); 1101 1159 #endif 1160 rarg_i = NULL; 1161 rarg_vi = NULL; 1162 1102 1163 run_expr(run, unop->arg, &rarg_i); 1103 1164 if (run_is_bo(run)) { 1104 *res = NULL;1105 return;1165 *res = run_recovery_item(run); 1166 goto cleanup; 1106 1167 } 1107 1168 … … 1110 1171 #endif 1111 1172 run_cvt_value_item(run, rarg_i, &rarg_vi); 1173 if (run_is_bo(run)) { 1174 *res = run_recovery_item(run); 1175 goto cleanup; 1176 } 1112 1177 1113 1178 val = rarg_vi->u.value; … … 1124 1189 "type %d.\n", val->var->vc); 1125 1190 run_raise_error(run); 1126 *res = NULL; 1127 break; 1128 } 1191 *res = run_recovery_item(run); 1192 break; 1193 } 1194 cleanup: 1195 if (rarg_i != NULL) 1196 rdata_item_destroy(rarg_i); 1197 if (rarg_vi != NULL) 1198 rdata_item_destroy(rarg_vi); 1129 1199 } 1130 1200 … … 1208 1278 *res = item; 1209 1279 } 1280 1281 /** Run equality comparison of two values 1282 * 1283 * This should be equivalent to equality ('==') binary operation. 1284 * XXX Duplicating code of run_binop_xxx(). 1285 * 1286 * @param run Runner object 1287 * @param v1 Value of first argument 1288 * @param v2 Value of second argument 1289 * @param res Place to store result (plain boolean value) 1290 */ 1291 void run_equal(run_t *run, rdata_value_t *v1, rdata_value_t *v2, bool_t *res) 1292 { 1293 bool_t b1, b2; 1294 bigint_t *c1, *c2; 1295 bigint_t *i1, *i2; 1296 bigint_t diff; 1297 const char *s1, *s2; 1298 rdata_var_t *ref1, *ref2; 1299 stree_embr_t *e1, *e2; 1300 1301 (void) run; 1302 assert(v1->var->vc == v2->var->vc); 1303 1304 switch (v1->var->vc) { 1305 case vc_bool: 1306 b1 = v1->var->u.bool_v->value; 1307 b2 = v2->var->u.bool_v->value; 1308 1309 *res = (b1 == b2); 1310 break; 1311 case vc_char: 1312 c1 = &v1->var->u.char_v->value; 1313 c2 = &v2->var->u.char_v->value; 1314 1315 bigint_sub(c1, c2, &diff); 1316 *res = bigint_is_zero(&diff); 1317 break; 1318 case vc_int: 1319 i1 = &v1->var->u.int_v->value; 1320 i2 = &v2->var->u.int_v->value; 1321 1322 bigint_sub(i1, i2, &diff); 1323 *res = bigint_is_zero(&diff); 1324 break; 1325 case vc_string: 1326 s1 = v1->var->u.string_v->value; 1327 s2 = v2->var->u.string_v->value; 1328 1329 *res = os_str_cmp(s1, s2) == 0; 1330 break; 1331 case vc_ref: 1332 ref1 = v1->var->u.ref_v->vref; 1333 ref2 = v2->var->u.ref_v->vref; 1334 1335 *res = (ref1 == ref2); 1336 break; 1337 case vc_enum: 1338 e1 = v1->var->u.enum_v->value; 1339 e2 = v2->var->u.enum_v->value; 1340 1341 *res = (e1 == e2); 1342 break; 1343 1344 case vc_deleg: 1345 case vc_array: 1346 case vc_object: 1347 case vc_resource: 1348 case vc_symbol: 1349 assert(b_false); 1350 } 1351 } 1352 1210 1353 1211 1354 /** Evaluate @c new operation. … … 1297 1440 run_expr(run, expr, &rexpr); 1298 1441 if (run_is_bo(run)) { 1299 *res = NULL;1442 *res = run_recovery_item(run); 1300 1443 return; 1301 1444 } 1302 1445 1303 1446 run_cvt_value_item(run, rexpr, &rexpr_vi); 1447 if (run_is_bo(run)) { 1448 *res = run_recovery_item(run); 1449 return; 1450 } 1451 1304 1452 assert(rexpr_vi->ic == ic_value); 1305 1453 rexpr_var = rexpr_vi->u.value->var; … … 1375 1523 run_call_args(run, &new_op->ctor_args, &arg_vals); 1376 1524 if (run_is_bo(run)) { 1377 *res = NULL;1525 *res = run_recovery_item(run); 1378 1526 return; 1379 1527 } … … 1387 1535 assert(obj_i->u.address->ac == ac_var); 1388 1536 run_object_ctor(run, obj_i->u.address->u.var_a->vref, &arg_vals); 1537 rdata_item_destroy(obj_i); 1538 1539 /* Destroy argument values */ 1540 run_destroy_arg_vals(&arg_vals); 1389 1541 } 1390 1542 … … 1404 1556 printf("Run access operation.\n"); 1405 1557 #endif 1558 rarg = NULL; 1559 1406 1560 run_expr(run, access->arg, &rarg); 1407 1561 if (run_is_bo(run)) { 1408 *res = NULL;1409 return;1562 *res = run_recovery_item(run); 1563 goto cleanup; 1410 1564 } 1411 1565 … … 1416 1570 1417 1571 run_access_item(run, access, rarg, res); 1572 cleanup: 1573 if (rarg != NULL) 1574 rdata_item_destroy(rarg); 1418 1575 } 1419 1576 … … 1484 1641 /* Try again. */ 1485 1642 run_access_item(run, access, darg, res); 1643 1644 /* Destroy temporary */ 1645 rdata_item_destroy(darg); 1486 1646 } 1487 1647 … … 1790 1950 #endif 1791 1951 run_cvt_value_item(run, arg, &arg_vi); 1952 if (run_is_bo(run)) { 1953 *res = run_recovery_item(run); 1954 return; 1955 } 1956 1792 1957 arg_val = arg_vi->u.value; 1793 1958 assert(arg_val->var->vc == vc_symbol); … … 1800 1965 embr = stree_enum_find_mbr(symbol_v->sym->u.enum_d, 1801 1966 access->member_name); 1967 1968 rdata_item_destroy(arg_vi); 1802 1969 1803 1970 /* Member existence should be ensured by static type checking. */ … … 1841 2008 printf("Run call operation.\n"); 1842 2009 #endif 2010 rdeleg = NULL; 2011 rdeleg_vi = NULL; 2012 1843 2013 run_expr(run, call->fun, &rdeleg); 1844 2014 if (run_is_bo(run)) { 1845 *res = NULL;1846 return;1847 }1848 1849 if (run->thread_ar->bo_mode != bm_none) {1850 2015 *res = run_recovery_item(run); 1851 return;2016 goto cleanup; 1852 2017 } 1853 2018 1854 2019 run_cvt_value_item(run, rdeleg, &rdeleg_vi); 2020 if (run_is_bo(run)) { 2021 *res = run_recovery_item(run); 2022 goto cleanup; 2023 } 2024 1855 2025 assert(rdeleg_vi->ic == ic_value); 1856 2026 … … 1877 2047 run_call_args(run, &call->args, &arg_vals); 1878 2048 if (run_is_bo(run)) { 1879 *res = NULL;1880 return;2049 *res = run_recovery_item(run); 2050 goto cleanup; 1881 2051 } 1882 2052 … … 1889 2059 /* Fill in argument values. */ 1890 2060 run_proc_ar_set_args(run, proc_ar, &arg_vals); 2061 2062 /* Destroy arg_vals, they are no longer needed. */ 2063 run_destroy_arg_vals(&arg_vals); 1891 2064 1892 2065 /* Run the function. */ … … 1900 2073 } 1901 2074 2075 /* Destroy procedure activation record. */ 2076 run_proc_ar_destroy(run, proc_ar); 2077 2078 cleanup: 2079 if (rdeleg != NULL) 2080 rdata_item_destroy(rdeleg); 2081 if (rdeleg_vi != NULL) 2082 rdata_item_destroy(rdeleg_vi); 2083 1902 2084 #ifdef DEBUG_RUN_TRACE 1903 2085 printf("Returned from function call.\n"); … … 1928 2110 run_expr(run, arg, &rarg_i); 1929 2111 if (run_is_bo(run)) 1930 return;2112 goto error; 1931 2113 1932 2114 run_cvt_value_item(run, rarg_i, &rarg_vi); 2115 rdata_item_destroy(rarg_i); 2116 if (run_is_bo(run)) 2117 goto error; 1933 2118 1934 2119 list_append(arg_vals, rarg_vi); 1935 2120 arg_n = list_next(args, arg_n); 1936 2121 } 2122 return; 2123 2124 error: 2125 /* 2126 * An exception or error occured while evaluating one of the 2127 * arguments. Destroy already obtained argument values and 2128 * dismantle the list. 2129 */ 2130 run_destroy_arg_vals(arg_vals); 2131 } 2132 2133 /** Destroy list of evaluated arguments. 2134 * 2135 * Provided a list of evaluated arguments, destroy them, removing them 2136 * from the list and fini the list itself. 2137 * 2138 * @param arg_vals List of evaluated arguments (value items, 2139 * rdata_item_t). 2140 */ 2141 static void run_destroy_arg_vals(list_t *arg_vals) 2142 { 2143 list_node_t *val_n; 2144 rdata_item_t *val_i; 2145 2146 /* 2147 * An exception or error occured while evaluating one of the 2148 * arguments. Destroy already obtained argument values and 2149 * dismantle the list. 2150 */ 2151 while (!list_is_empty(arg_vals)) { 2152 val_n = list_first(arg_vals); 2153 val_i = list_node_data(val_n, rdata_item_t *); 2154 2155 rdata_item_destroy(val_i); 2156 list_remove(arg_vals, val_n); 2157 } 2158 list_fini(arg_vals); 1937 2159 } 1938 2160 … … 1954 2176 var_class_t vc; 1955 2177 list_t arg_vals; 2178 list_node_t *val_n; 2179 rdata_item_t *val_i; 1956 2180 1957 2181 #ifdef DEBUG_RUN_TRACE … … 1960 2184 run_expr(run, index->base, &rbase); 1961 2185 if (run_is_bo(run)) { 1962 *res = NULL;2186 *res = run_recovery_item(run); 1963 2187 return; 1964 2188 } … … 1969 2193 if (vc == vc_ref) { 1970 2194 run_dereference(run, rbase, index->base->cspan, &base_i); 2195 rdata_item_destroy(rbase); 1971 2196 if (run_is_bo(run)) { 1972 *res = NULL;2197 *res = run_recovery_item(run); 1973 2198 return; 1974 2199 } … … 1987 2212 run_expr(run, arg, &rarg_i); 1988 2213 if (run_is_bo(run)) { 1989 *res = NULL;1990 return;2214 *res = run_recovery_item(run); 2215 goto cleanup; 1991 2216 } 1992 2217 1993 2218 run_cvt_value_item(run, rarg_i, &rarg_vi); 2219 rdata_item_destroy(rarg_i); 2220 if (run_is_bo(run)) { 2221 *res = run_recovery_item(run); 2222 goto cleanup; 2223 } 1994 2224 1995 2225 list_append(&arg_vals, rarg_vi); … … 2012 2242 exit(1); 2013 2243 } 2244 2245 /* Destroy the indexing base temporary */ 2246 rdata_item_destroy(base_i); 2247 cleanup: 2248 /* 2249 * An exception or error occured while evaluating one of the 2250 * arguments. Destroy already obtained argument values and 2251 * dismantle the list. 2252 */ 2253 while (!list_is_empty(&arg_vals)) { 2254 val_n = list_first(&arg_vals); 2255 val_i = list_node_data(val_n, rdata_item_t *); 2256 2257 rdata_item_destroy(val_i); 2258 list_remove(&arg_vals, val_n); 2259 } 2260 2261 list_fini(&arg_vals); 2014 2262 } 2015 2263 … … 2136 2384 2137 2385 list_node_t *node; 2138 rdata_item_t *arg ;2386 rdata_item_t *arg, *arg_copy; 2139 2387 2140 2388 #ifdef DEBUG_RUN_TRACE … … 2186 2434 while (node != NULL) { 2187 2435 arg = list_node_data(node, rdata_item_t *); 2188 list_append(&aprop_indexed->args, arg); 2436 2437 /* 2438 * Clone argument so that original can 2439 * be freed. 2440 */ 2441 assert(arg->ic == ic_value); 2442 arg_copy = rdata_item_new(ic_value); 2443 rdata_value_copy(arg->u.value, &arg_copy->u.value); 2444 2445 list_append(&aprop_indexed->args, arg_copy); 2189 2446 node = list_next(args, node); 2190 2447 } … … 2225 2482 2226 2483 run_cvt_value_item(run, base, &base_vi); 2484 if (run_is_bo(run)) { 2485 *res = run_recovery_item(run); 2486 return; 2487 } 2488 2227 2489 assert(base_vi->u.value->var->vc == vc_string); 2228 2490 string = base_vi->u.value->var->u.string_v; … … 2277 2539 index->expr->cspan); 2278 2540 *res = run_recovery_item(run); 2279 return;2541 goto cleanup; 2280 2542 } 2281 2543 … … 2291 2553 2292 2554 *res = ritem; 2555 cleanup: 2556 rdata_item_destroy(base_vi); 2293 2557 } 2294 2558 … … 2310 2574 printf("Run assign operation.\n"); 2311 2575 #endif 2576 rdest_i = NULL; 2577 rsrc_i = NULL; 2578 rsrc_vi = NULL; 2579 2312 2580 run_expr(run, assign->dest, &rdest_i); 2313 2581 if (run_is_bo(run)) { 2314 *res = NULL;2315 return;2582 *res = run_recovery_item(run); 2583 goto cleanup; 2316 2584 } 2317 2585 2318 2586 run_expr(run, assign->src, &rsrc_i); 2319 2587 if (run_is_bo(run)) { 2320 *res = NULL;2321 return;2588 *res = run_recovery_item(run); 2589 goto cleanup; 2322 2590 } 2323 2591 2324 2592 run_cvt_value_item(run, rsrc_i, &rsrc_vi); 2593 if (run_is_bo(run)) { 2594 *res = run_recovery_item(run); 2595 goto cleanup; 2596 } 2597 2325 2598 assert(rsrc_vi->ic == ic_value); 2326 2599 … … 2334 2607 2335 2608 *res = NULL; 2609 cleanup: 2610 if (rdest_i != NULL) 2611 rdata_item_destroy(rdest_i); 2612 if (rsrc_i != NULL) 2613 rdata_item_destroy(rsrc_i); 2614 if (rsrc_vi != NULL) 2615 rdata_item_destroy(rsrc_vi); 2336 2616 } 2337 2617 … … 2359 2639 run_expr(run, as_op->arg, &rarg_i); 2360 2640 if (run_is_bo(run)) { 2361 *res = NULL;2641 *res = run_recovery_item(run); 2362 2642 return; 2363 2643 } … … 2369 2649 assert(run_item_get_vc(run, rarg_i) == vc_ref); 2370 2650 run_cvt_value_item(run, rarg_i, &rarg_vi); 2651 rdata_item_destroy(rarg_i); 2652 2653 if (run_is_bo(run)) { 2654 *res = run_recovery_item(run); 2655 return; 2656 } 2657 2371 2658 assert(rarg_vi->ic == ic_value); 2372 2659 … … 2405 2692 } 2406 2693 2694 /* The dereferenced item is not used anymore. */ 2695 rdata_item_destroy(rarg_di); 2696 2407 2697 *res = rarg_vi; 2408 2698 } … … 2435 2725 run_expr(run, box->arg, &rarg_i); 2436 2726 if (run_is_bo(run)) { 2437 *res = NULL;2727 *res = run_recovery_item(run); 2438 2728 return; 2439 2729 } 2440 2730 2441 2731 run_cvt_value_item(run, rarg_i, &rarg_vi); 2732 rdata_item_destroy(rarg_i); 2733 if (run_is_bo(run)) { 2734 *res = run_recovery_item(run); 2735 return; 2736 } 2737 2442 2738 assert(rarg_vi->ic == ic_value); 2443 2739 … … 2482 2778 2483 2779 rdata_var_write(mbr_var, rarg_vi->u.value); 2780 rdata_item_destroy(rarg_vi); 2484 2781 } 2485 2782 … … 2657 2954 assert(res == NULL); 2658 2955 2956 /* Destroy procedure activation record. */ 2957 run_proc_ar_destroy(run, proc_ar); 2958 2659 2959 #ifdef DEBUG_RUN_TRACE 2660 2960 printf("Returned from constructor..\n"); … … 2675 2975 rdata_item_t *vitem; 2676 2976 rdata_var_t *var; 2977 bool_t res; 2677 2978 2678 2979 (void) run; 2679 2980 run_cvt_value_item(run, item, &vitem); 2981 if (run_is_bo(run)) 2982 return b_true; 2680 2983 2681 2984 assert(vitem->ic == ic_value); … … 2683 2986 2684 2987 assert(var->vc == vc_bool); 2685 return var->u.bool_v->value; 2686 } 2988 res = var->u.bool_v->value; 2989 2990 /* Free value item */ 2991 rdata_item_destroy(vitem); 2992 return res; 2993 }
Note:
See TracChangeset
for help on using the changeset viewer.