~jsvoboda/helenos/sysel

« back to all changes in this revision

Viewing changes to uspace/app/sbi/src/run_expr.c

  • Committer: Jiri Svoboda
  • Date: 2010-06-09 19:01:08 UTC
  • Revision ID: jiri@wiwaxia-20100609190108-0q5s6iwfyy7481a8
Update SBI to rev. 291.

Show diffs side-by-side

added added

removed removed

Lines of Context:
103
103
    rdata_item_t *arg, rdata_item_t **res);
104
104
static void run_access_object(run_t *run, stree_access_t *access,
105
105
    rdata_item_t *arg, rdata_item_t **res);
 
106
static void run_access_object_static(run_t *run, stree_access_t *access,
 
107
    rdata_var_t *obj_var, rdata_item_t **res);
 
108
static void run_access_object_nonstatic(run_t *run, stree_access_t *access,
 
109
    rdata_var_t *obj_var, rdata_item_t **res);
106
110
static void run_access_symbol(run_t *run, stree_access_t *access,
107
111
    rdata_item_t *arg, rdata_item_t **res);
108
112
 
206
210
        rdata_object_t *obj;
207
211
        rdata_var_t *member_var;
208
212
 
 
213
        rdata_var_t *psobj;
 
214
        rdata_var_t *sobj;
 
215
        rdata_object_t *aobj;
 
216
 
209
217
#ifdef DEBUG_RUN_TRACE
210
218
        printf("Run nameref.\n");
211
219
#endif
237
245
 
238
246
        /* Determine currently active object or CSI. */
239
247
        proc_ar = run_get_current_proc_ar(run);
240
 
        if (proc_ar->obj != NULL) {
241
 
                assert(proc_ar->obj->vc == vc_object);
242
 
                obj = proc_ar->obj->u.object_v;
243
 
                csi_sym = obj->class_sym;
 
248
 
 
249
        assert (proc_ar->obj != NULL);
 
250
        assert(proc_ar->obj->vc == vc_object);
 
251
        obj = proc_ar->obj->u.object_v;
 
252
        csi_sym = obj->class_sym;
 
253
 
 
254
        if (csi_sym != NULL) {
244
255
                csi = symbol_to_csi(csi_sym);
245
256
                assert(csi != NULL);
246
257
        } else {
247
 
                csi = proc_ar->proc->outer_symbol->outer_csi;
248
 
                obj = NULL;
 
258
                /* This happens in interactive mode. */
 
259
                csi = NULL;
249
260
        }
250
261
 
251
262
        sym = symbol_lookup_in_csi(run->program, csi, nameref->name);
258
269
#ifdef DEBUG_RUN_TRACE
259
270
                printf("Referencing CSI.\n");
260
271
#endif
261
 
                item = rdata_item_new(ic_value);
262
 
                value = rdata_value_new();
263
 
                var = rdata_var_new(vc_deleg);
264
 
                deleg_v = rdata_deleg_new();
265
 
 
266
 
                item->u.value = value;
267
 
                value->var = var;
268
 
                var->u.deleg_v = deleg_v;
269
 
 
270
 
                deleg_v->obj = NULL;
271
 
                deleg_v->sym = sym;
272
 
                *res = item;
 
272
                /* Obtain static object for the referenced CSI. */
 
273
                psobj = run->gdata; /* XXX */
 
274
                sobj = run_sobject_get(run, sym->u.csi, psobj,
 
275
                    nameref->name->sid);
 
276
 
 
277
                /* Return reference to the object. */
 
278
                run_reference(run, sobj, res);
273
279
                break;
274
280
        case sc_ctor:
275
281
                /* It is not possible to reference a constructor explicitly. */
333
339
                /* There should be no global variables. */
334
340
                assert(csi != NULL);
335
341
 
336
 
                /* XXX Assume variable is not static for now. */
337
 
                assert(obj != NULL);
338
 
 
339
342
                if (symbol_search_csi(run->program, csi, nameref->name)
340
 
                    == NULL) {
 
343
                    == NULL && !stree_symbol_is_static(sym)) {
341
344
                        /* Variable is not in the current object. */
342
345
                        printf("Error: Cannot access non-static member "
343
346
                            "variable '");
348
351
                        exit(1);
349
352
                }
350
353
 
 
354
                if (stree_symbol_is_static(sym)) {
 
355
                        /*
 
356
                         * XXX This is too slow!
 
357
                         *
 
358
                         * However fixing this is non-trivial. We would
 
359
                         * have to have pointer to static object available
 
360
                         * for each object (therefore also for each object
 
361
                         * type).
 
362
                         */
 
363
                        sobj = run_sobject_find(run, sym->outer_csi);
 
364
                        assert(sobj->vc == vc_object);
 
365
                        aobj = sobj->u.object_v;
 
366
                } else {
 
367
                        aobj = obj;
 
368
                }
 
369
 
351
370
                /* Find member variable in object. */
352
 
                member_var = intmap_get(&obj->fields, nameref->name->sid);
 
371
                member_var = intmap_get(&aobj->fields, nameref->name->sid);
353
372
                assert(member_var != NULL);
354
373
 
355
374
                /* Return address of the variable. */
1360
1379
        }
1361
1380
 
1362
1381
        /* Create CSI instance. */
1363
 
        run_new_csi_inst(run, csi, res);
 
1382
        run_new_csi_inst_ref(run, csi, sn_nonstatic, res);
1364
1383
 
1365
1384
        /* Run the constructor. */
1366
1385
        run_dereference(run, *res, NULL, &obj_i);
1466
1485
        run_access_item(run, access, darg, res);
1467
1486
}
1468
1487
 
1469
 
/** Evaluate delegate-member acccess.
 
1488
/** Evaluate delegate member acccess.
1470
1489
 *
1471
1490
 * @param run           Runner object
1472
1491
 * @param access        Access operation
1476
1495
static void run_access_deleg(run_t *run, stree_access_t *access,
1477
1496
    rdata_item_t *arg, rdata_item_t **res)
1478
1497
{
1479
 
        rdata_item_t *arg_vi;
1480
 
        rdata_value_t *arg_val;
1481
 
        rdata_deleg_t *deleg_v;
1482
 
        stree_symbol_t *member;
1483
 
 
1484
 
#ifdef DEBUG_RUN_TRACE
1485
 
        printf("Run delegate access operation.\n");
1486
 
#endif
1487
 
        run_cvt_value_item(run, arg, &arg_vi);
1488
 
        arg_val = arg_vi->u.value;
1489
 
        assert(arg_val->var->vc == vc_deleg);
1490
 
 
1491
 
        deleg_v = arg_val->var->u.deleg_v;
1492
 
        if (deleg_v->obj != NULL || deleg_v->sym->sc != sc_csi) {
1493
 
                printf("Error: Using '.' with delegate to different object "
1494
 
                    "than a CSI (%d).\n", deleg_v->sym->sc);
1495
 
                exit(1);
1496
 
        }
1497
 
 
1498
 
        member = symbol_search_csi(run->program, deleg_v->sym->u.csi,
1499
 
            access->member_name);
1500
 
 
1501
 
        /* Member existence should be ensured by static type checking. */
1502
 
        assert(member != NULL);
1503
 
 
1504
 
#ifdef DEBUG_RUN_TRACE
1505
 
        printf("Found member '%s'.\n",
1506
 
            strtab_get_str(access->member_name->sid));
1507
 
#endif
1508
 
 
1509
 
        /*
1510
 
         * Reuse existing item, value, var, deleg.
1511
 
         * XXX This is maybe not a good idea because it complicates memory
1512
 
         * management as there is not a single owner 
1513
 
         */
1514
 
        deleg_v->sym = member;
1515
 
        *res = arg;
 
1498
        (void) run;
 
1499
        (void) access;
 
1500
        (void) arg;
 
1501
        (void) res;
 
1502
 
 
1503
        printf("Error: Using '.' with delegate.\n");
 
1504
        exit(1);
1516
1505
}
1517
1506
 
1518
1507
/** Evaluate object member acccess.
1525
1514
static void run_access_object(run_t *run, stree_access_t *access,
1526
1515
    rdata_item_t *arg, rdata_item_t **res)
1527
1516
{
1528
 
        stree_symbol_t *member;
1529
 
        rdata_var_t *object_var;
 
1517
        rdata_var_t *obj_var;
1530
1518
        rdata_object_t *object;
1531
 
        rdata_item_t *ritem;
1532
 
        rdata_address_t *address;
1533
 
        rdata_addr_var_t *addr_var;
1534
 
        rdata_addr_prop_t *addr_prop;
1535
 
        rdata_aprop_named_t *aprop_named;
1536
 
        rdata_deleg_t *deleg_p;
1537
 
 
1538
 
        rdata_value_t *value;
1539
 
        rdata_deleg_t *deleg_v;
1540
 
        rdata_var_t *var;
1541
1519
 
1542
1520
#ifdef DEBUG_RUN_TRACE
1543
1521
        printf("Run object access operation.\n");
1544
1522
#endif
1545
1523
        assert(arg->ic == ic_address);
1546
1524
        assert(arg->u.address->ac == ac_var);
1547
 
        assert(arg->u.address->u.var_a->vref->vc == vc_object);
1548
 
 
1549
 
        object_var = arg->u.address->u.var_a->vref;
1550
 
        object = object_var->u.object_v;
 
1525
 
 
1526
        obj_var = arg->u.address->u.var_a->vref;
 
1527
        assert(obj_var->vc == vc_object);
 
1528
 
 
1529
        object = obj_var->u.object_v;
 
1530
 
 
1531
        if (object->static_obj == sn_static)
 
1532
                run_access_object_static(run, access, obj_var, res);
 
1533
        else
 
1534
                run_access_object_nonstatic(run, access, obj_var, res);
 
1535
}
 
1536
 
 
1537
/** Evaluate static object member acccess.
 
1538
 *
 
1539
 * @param run           Runner object
 
1540
 * @param access        Access operation
 
1541
 * @param arg           Evaluated base expression
 
1542
 * @param res           Place to store result
 
1543
 */
 
1544
static void run_access_object_static(run_t *run, stree_access_t *access,
 
1545
    rdata_var_t *obj_var, rdata_item_t **res)
 
1546
{
 
1547
        rdata_object_t *object;
 
1548
        stree_symbol_t *member;
 
1549
        stree_csi_t *member_csi;
 
1550
 
 
1551
        rdata_deleg_t *deleg_v;
 
1552
        rdata_item_t *ritem;
 
1553
        rdata_value_t *rvalue;
 
1554
        rdata_var_t *rvar;
 
1555
        rdata_address_t *address;
 
1556
        rdata_addr_var_t *addr_var;
 
1557
        rdata_addr_prop_t *addr_prop;
 
1558
        rdata_aprop_named_t *aprop_named;
 
1559
        rdata_deleg_t *deleg_p;
 
1560
        rdata_var_t *mvar;
 
1561
 
 
1562
#ifdef DEBUG_RUN_TRACE
 
1563
        printf("Run static object access operation.\n");
 
1564
#endif
 
1565
        assert(obj_var->vc == vc_object);
 
1566
        object = obj_var->u.object_v;
 
1567
 
 
1568
        assert(object->static_obj == sn_static);
 
1569
 
 
1570
        member = symbol_search_csi(run->program, object->class_sym->u.csi,
 
1571
            access->member_name);
 
1572
 
 
1573
        /* Member existence should be ensured by static type checking. */
 
1574
        assert(member != NULL);
 
1575
 
 
1576
#ifdef DEBUG_RUN_TRACE
 
1577
        printf("Found member '%s'.\n",
 
1578
            strtab_get_str(access->member_name->sid));
 
1579
#endif
 
1580
 
 
1581
        switch (member->sc) {
 
1582
        case sc_csi:
 
1583
                /* Get child static object. */
 
1584
                member_csi = symbol_to_csi(member);
 
1585
                assert(member_csi != NULL);
 
1586
 
 
1587
                mvar = run_sobject_get(run, member_csi, obj_var,
 
1588
                    access->member_name->sid);
 
1589
 
 
1590
                ritem = rdata_item_new(ic_address);
 
1591
                address = rdata_address_new(ac_var);
 
1592
                ritem->u.address = address;
 
1593
 
 
1594
                addr_var = rdata_addr_var_new();
 
1595
                address->u.var_a = addr_var;
 
1596
                addr_var->vref = mvar;
 
1597
 
 
1598
                *res = ritem;
 
1599
                break;
 
1600
        case sc_ctor:
 
1601
                /* It is not possible to reference a constructor explicitly. */
 
1602
                assert(b_false);
 
1603
        case sc_deleg:
 
1604
                printf("Error: Accessing object member which is a delegate.\n");
 
1605
                exit(1);
 
1606
        case sc_enum:
 
1607
                printf("Error: Accessing object member which is an enum.\n");
 
1608
                exit(1);
 
1609
        case sc_fun:
 
1610
                /* Construct anonymous delegate. */
 
1611
                ritem = rdata_item_new(ic_value);
 
1612
                rvalue = rdata_value_new();
 
1613
                ritem->u.value = rvalue;
 
1614
 
 
1615
                rvar = rdata_var_new(vc_deleg);
 
1616
                rvalue->var = rvar;
 
1617
 
 
1618
                deleg_v = rdata_deleg_new();
 
1619
                rvar->u.deleg_v = deleg_v;
 
1620
 
 
1621
                deleg_v->obj = obj_var;
 
1622
                deleg_v->sym = member;
 
1623
                *res = ritem;
 
1624
                break;
 
1625
        case sc_var:
 
1626
                /* Get static object member variable. */
 
1627
                mvar = intmap_get(&object->fields, access->member_name->sid);
 
1628
 
 
1629
                ritem = rdata_item_new(ic_address);
 
1630
                address = rdata_address_new(ac_var);
 
1631
                ritem->u.address = address;
 
1632
 
 
1633
                addr_var = rdata_addr_var_new();
 
1634
                address->u.var_a = addr_var;
 
1635
                addr_var->vref = mvar;
 
1636
 
 
1637
                *res = ritem;
 
1638
                break;
 
1639
        case sc_prop:
 
1640
                /* Construct named property address. */
 
1641
                ritem = rdata_item_new(ic_address);
 
1642
                address = rdata_address_new(ac_prop);
 
1643
                addr_prop = rdata_addr_prop_new(apc_named);
 
1644
                aprop_named = rdata_aprop_named_new();
 
1645
                ritem->u.address = address;
 
1646
                address->u.prop_a = addr_prop;
 
1647
                addr_prop->u.named = aprop_named;
 
1648
 
 
1649
                deleg_p = rdata_deleg_new();
 
1650
                deleg_p->obj = obj_var;
 
1651
                deleg_p->sym = member;
 
1652
                addr_prop->u.named->prop_d = deleg_p;
 
1653
 
 
1654
                *res = ritem;
 
1655
                break;
 
1656
        }
 
1657
}
 
1658
 
 
1659
/** Evaluate object member acccess.
 
1660
 *
 
1661
 * @param run           Runner object
 
1662
 * @param access        Access operation
 
1663
 * @param arg           Evaluated base expression
 
1664
 * @param res           Place to store result
 
1665
 */
 
1666
static void run_access_object_nonstatic(run_t *run, stree_access_t *access,
 
1667
    rdata_var_t *obj_var, rdata_item_t **res)
 
1668
{
 
1669
        rdata_object_t *object;
 
1670
        stree_symbol_t *member;
 
1671
        rdata_item_t *ritem;
 
1672
        rdata_address_t *address;
 
1673
        rdata_addr_var_t *addr_var;
 
1674
        rdata_addr_prop_t *addr_prop;
 
1675
        rdata_aprop_named_t *aprop_named;
 
1676
        rdata_deleg_t *deleg_p;
 
1677
 
 
1678
        rdata_value_t *value;
 
1679
        rdata_deleg_t *deleg_v;
 
1680
        rdata_var_t *var;
 
1681
 
 
1682
#ifdef DEBUG_RUN_TRACE
 
1683
        printf("Run nonstatic object access operation.\n");
 
1684
#endif
 
1685
        assert(obj_var->vc == vc_object);
 
1686
        object = obj_var->u.object_v;
 
1687
 
 
1688
        assert(object->static_obj == sn_nonstatic);
1551
1689
 
1552
1690
        member = symbol_search_csi(run->program, object->class_sym->u.csi,
1553
1691
            access->member_name);
1572
1710
        case sc_csi:
1573
1711
                printf("Error: Accessing object member which is nested CSI.\n");
1574
1712
                exit(1);
 
1713
        case sc_ctor:
 
1714
                /* It is not possible to reference a constructor explicitly. */
 
1715
                assert(b_false);
1575
1716
        case sc_deleg:
1576
1717
                printf("Error: Accessing object member which is a delegate.\n");
1577
1718
                exit(1);
1578
1719
        case sc_enum:
1579
1720
                printf("Error: Accessing object member which is an enum.\n");
1580
1721
                exit(1);
1581
 
        case sc_ctor:
1582
 
                /* It is not possible to reference a constructor explicitly. */
1583
 
                assert(b_false);
1584
1722
        case sc_fun:
1585
1723
                /* Construct anonymous delegate. */
1586
1724
                ritem = rdata_item_new(ic_value);
1592
1730
                deleg_v = rdata_deleg_new();
1593
1731
                var->u.deleg_v = deleg_v;
1594
1732
 
1595
 
                deleg_v->obj = arg->u.address->u.var_a->vref;
 
1733
                deleg_v->obj = obj_var;
1596
1734
                deleg_v->sym = member;
1597
1735
                break;
1598
1736
        case sc_var:
1618
1756
                addr_prop->u.named = aprop_named;
1619
1757
 
1620
1758
                deleg_p = rdata_deleg_new();
1621
 
                deleg_p->obj = object_var;
 
1759
                deleg_p->obj = obj_var;
1622
1760
                deleg_p->sym = member;
1623
1761
                addr_prop->u.named->prop_d = deleg_p;
1624
1762
                break;
2167
2305
{
2168
2306
        rdata_item_t *rdest_i, *rsrc_i;
2169
2307
        rdata_item_t *rsrc_vi;
2170
 
        rdata_value_t *src_val;
2171
2308
 
2172
2309
#ifdef DEBUG_RUN_TRACE
2173
2310
        printf("Run assign operation.\n");
2186
2323
 
2187
2324
        run_cvt_value_item(run, rsrc_i, &rsrc_vi);
2188
2325
        assert(rsrc_vi->ic == ic_value);
2189
 
        src_val = rsrc_vi->u.value;
2190
2326
 
2191
2327
        if (rdest_i->ic != ic_address) {
2192
2328
                printf("Error: Address expression required on left side of "
2330
2466
        assert(csi != NULL);
2331
2467
 
2332
2468
        /* Construct object of the relevant boxed type. */
2333
 
        run_new_csi_inst(run, csi, res);
 
2469
        run_new_csi_inst_ref(run, csi, sn_nonstatic, res);
2334
2470
 
2335
2471
        /* Set the 'Value' field */
2336
2472
 
2347
2483
        rdata_var_write(mbr_var, rarg_vi->u.value);
2348
2484
}
2349
2485
 
 
2486
/** Create new CSI instance and return reference to it.
 
2487
 *
 
2488
 * Create a new object, instance of @a csi.
 
2489
 * XXX This does not work with generics as @a csi cannot specify a generic
 
2490
 * type.
 
2491
 *
 
2492
 * Initialize the fields with default values of their types, but do not
 
2493
 * run any constructor.
 
2494
 *
 
2495
 * If @a sn is @c sn_nonstatic a regular object is created, containing all
 
2496
 * non-static member variables. If @a sn is @c sn_static a static object
 
2497
 * is created, containing all static member variables.
 
2498
 *
 
2499
 * @param run           Runner object
 
2500
 * @param csi           CSI to create instance of
 
2501
 * @param sn            @c sn_static to create a static (class) object,
 
2502
 *                      @c sn_nonstatic to create a regular object
 
2503
 * @param res           Place to store result
 
2504
 */
 
2505
void run_new_csi_inst_ref(run_t *run, stree_csi_t *csi, statns_t sn,
 
2506
    rdata_item_t **res)
 
2507
{
 
2508
        rdata_var_t *obj_var;
 
2509
 
 
2510
        /* Create object. */
 
2511
        run_new_csi_inst(run, csi, sn, &obj_var);
 
2512
 
 
2513
        /* Create reference to the new object. */
 
2514
        run_reference(run, obj_var, res);
 
2515
}
 
2516
 
2350
2517
/** Create new CSI instance.
2351
2518
 *
2352
2519
 * Create a new object, instance of @a csi.
2356
2523
 * Initialize the fields with default values of their types, but do not
2357
2524
 * run any constructor.
2358
2525
 *
 
2526
 * If @a sn is @c sn_nonstatic a regular object is created, containing all
 
2527
 * non-static member variables. If @a sn is @c sn_static a static object
 
2528
 * is created, containing all static member variables.
 
2529
 *
2359
2530
 * @param run           Runner object
2360
 
 * @param as_op         @c as conversion expression
 
2531
 * @param csi           CSI to create instance of
 
2532
 * @param sn            @c sn_static to create a static (class) object,
 
2533
 *                      @c sn_nonstatic to create a regular object
2361
2534
 * @param res           Place to store result
2362
2535
 */
2363
 
void run_new_csi_inst(run_t *run, stree_csi_t *csi, rdata_item_t **res)
 
2536
void run_new_csi_inst(run_t *run, stree_csi_t *csi, statns_t sn,
 
2537
    rdata_var_t **res)
2364
2538
{
2365
2539
        rdata_object_t *obj;
2366
2540
        rdata_var_t *obj_var;
2367
2541
 
2368
2542
        stree_symbol_t *csi_sym;
2369
2543
        stree_csimbr_t *csimbr;
 
2544
        stree_var_t *var;
 
2545
        statns_t var_sn;
2370
2546
 
2371
2547
        rdata_var_t *mbr_var;
2372
2548
        list_node_t *node;
2383
2559
        /* Create the object. */
2384
2560
        obj = rdata_object_new();
2385
2561
        obj->class_sym = csi_sym;
 
2562
        obj->static_obj = sn;
2386
2563
        intmap_init(&obj->fields);
2387
2564
 
2388
2565
        obj_var = rdata_var_new(vc_object);
2389
2566
        obj_var->u.object_v = obj;
2390
2567
 
2391
 
        /* Create object fields. */
 
2568
        /* For this CSI and all base CSIs */
2392
2569
        while (csi != NULL) {
 
2570
 
 
2571
                /* For all members */
2393
2572
                node = list_first(&csi->members);
2394
2573
                while (node != NULL) {
2395
2574
                        csimbr = list_node_data(node, stree_csimbr_t *);
 
2575
 
 
2576
                        /* Is it a member variable? */
2396
2577
                        if (csimbr->cc == csimbr_var) {
2397
 
                                /* Compute field type. XXX Memoize. */
2398
 
                                run_texpr(run->program, csi,
2399
 
                                    csimbr->u.var->type,
2400
 
                                    &field_ti);
2401
 
 
2402
 
                                /* Create and initialize field. */
2403
 
                                run_var_new(run, field_ti, &mbr_var);
2404
 
 
2405
 
                                /* Add to field map. */
2406
 
                                intmap_set(&obj->fields,
2407
 
                                    csimbr->u.var->name->sid,
2408
 
                                    mbr_var);
 
2578
                                var = csimbr->u.var;
 
2579
 
 
2580
                                /* Is it static/nonstatic? */
 
2581
                                var_sn = stree_symbol_has_attr(
 
2582
                                    var_to_symbol(var), sac_static);
 
2583
                                if (var_sn == sn) {
 
2584
                                        /* Compute field type. XXX Memoize. */
 
2585
                                        run_texpr(run->program, csi, var->type,
 
2586
                                            &field_ti);
 
2587
 
 
2588
                                        /* Create and initialize field. */
 
2589
                                        run_var_new(run, field_ti, &mbr_var);
 
2590
 
 
2591
                                        /* Add to field map. */
 
2592
                                        intmap_set(&obj->fields, var->name->sid,
 
2593
                                            mbr_var);
 
2594
                                }
2409
2595
                        }
2410
2596
 
2411
2597
                        node = list_next(&csi->members, node);
2415
2601
                csi = csi->base_csi;
2416
2602
        }
2417
2603
 
2418
 
        /* Create reference to the new object. */
2419
 
        run_reference(run, obj_var, res);
 
2604
        *res = obj_var;
2420
2605
}
2421
2606
 
2422
2607
/** Run constructor on an object.