1476
1495
static void run_access_deleg(run_t *run, stree_access_t *access,
1477
1496
rdata_item_t *arg, rdata_item_t **res)
1479
rdata_item_t *arg_vi;
1480
rdata_value_t *arg_val;
1481
rdata_deleg_t *deleg_v;
1482
stree_symbol_t *member;
1484
#ifdef DEBUG_RUN_TRACE
1485
printf("Run delegate access operation.\n");
1487
run_cvt_value_item(run, arg, &arg_vi);
1488
arg_val = arg_vi->u.value;
1489
assert(arg_val->var->vc == vc_deleg);
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);
1498
member = symbol_search_csi(run->program, deleg_v->sym->u.csi,
1499
access->member_name);
1501
/* Member existence should be ensured by static type checking. */
1502
assert(member != NULL);
1504
#ifdef DEBUG_RUN_TRACE
1505
printf("Found member '%s'.\n",
1506
strtab_get_str(access->member_name->sid));
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
1514
deleg_v->sym = member;
1503
printf("Error: Using '.' with delegate.\n");
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)
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;
1538
rdata_value_t *value;
1539
rdata_deleg_t *deleg_v;
1542
1520
#ifdef DEBUG_RUN_TRACE
1543
1521
printf("Run object access operation.\n");
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);
1549
object_var = arg->u.address->u.var_a->vref;
1550
object = object_var->u.object_v;
1526
obj_var = arg->u.address->u.var_a->vref;
1527
assert(obj_var->vc == vc_object);
1529
object = obj_var->u.object_v;
1531
if (object->static_obj == sn_static)
1532
run_access_object_static(run, access, obj_var, res);
1534
run_access_object_nonstatic(run, access, obj_var, res);
1537
/** Evaluate static object member acccess.
1539
* @param run Runner object
1540
* @param access Access operation
1541
* @param arg Evaluated base expression
1542
* @param res Place to store result
1544
static void run_access_object_static(run_t *run, stree_access_t *access,
1545
rdata_var_t *obj_var, rdata_item_t **res)
1547
rdata_object_t *object;
1548
stree_symbol_t *member;
1549
stree_csi_t *member_csi;
1551
rdata_deleg_t *deleg_v;
1552
rdata_item_t *ritem;
1553
rdata_value_t *rvalue;
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;
1562
#ifdef DEBUG_RUN_TRACE
1563
printf("Run static object access operation.\n");
1565
assert(obj_var->vc == vc_object);
1566
object = obj_var->u.object_v;
1568
assert(object->static_obj == sn_static);
1570
member = symbol_search_csi(run->program, object->class_sym->u.csi,
1571
access->member_name);
1573
/* Member existence should be ensured by static type checking. */
1574
assert(member != NULL);
1576
#ifdef DEBUG_RUN_TRACE
1577
printf("Found member '%s'.\n",
1578
strtab_get_str(access->member_name->sid));
1581
switch (member->sc) {
1583
/* Get child static object. */
1584
member_csi = symbol_to_csi(member);
1585
assert(member_csi != NULL);
1587
mvar = run_sobject_get(run, member_csi, obj_var,
1588
access->member_name->sid);
1590
ritem = rdata_item_new(ic_address);
1591
address = rdata_address_new(ac_var);
1592
ritem->u.address = address;
1594
addr_var = rdata_addr_var_new();
1595
address->u.var_a = addr_var;
1596
addr_var->vref = mvar;
1601
/* It is not possible to reference a constructor explicitly. */
1604
printf("Error: Accessing object member which is a delegate.\n");
1607
printf("Error: Accessing object member which is an enum.\n");
1610
/* Construct anonymous delegate. */
1611
ritem = rdata_item_new(ic_value);
1612
rvalue = rdata_value_new();
1613
ritem->u.value = rvalue;
1615
rvar = rdata_var_new(vc_deleg);
1618
deleg_v = rdata_deleg_new();
1619
rvar->u.deleg_v = deleg_v;
1621
deleg_v->obj = obj_var;
1622
deleg_v->sym = member;
1626
/* Get static object member variable. */
1627
mvar = intmap_get(&object->fields, access->member_name->sid);
1629
ritem = rdata_item_new(ic_address);
1630
address = rdata_address_new(ac_var);
1631
ritem->u.address = address;
1633
addr_var = rdata_addr_var_new();
1634
address->u.var_a = addr_var;
1635
addr_var->vref = mvar;
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;
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;
1659
/** Evaluate object member acccess.
1661
* @param run Runner object
1662
* @param access Access operation
1663
* @param arg Evaluated base expression
1664
* @param res Place to store result
1666
static void run_access_object_nonstatic(run_t *run, stree_access_t *access,
1667
rdata_var_t *obj_var, rdata_item_t **res)
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;
1678
rdata_value_t *value;
1679
rdata_deleg_t *deleg_v;
1682
#ifdef DEBUG_RUN_TRACE
1683
printf("Run nonstatic object access operation.\n");
1685
assert(obj_var->vc == vc_object);
1686
object = obj_var->u.object_v;
1688
assert(object->static_obj == sn_nonstatic);
1552
1690
member = symbol_search_csi(run->program, object->class_sym->u.csi,
1553
1691
access->member_name);
2347
2483
rdata_var_write(mbr_var, rarg_vi->u.value);
2486
/** Create new CSI instance and return reference to it.
2488
* Create a new object, instance of @a csi.
2489
* XXX This does not work with generics as @a csi cannot specify a generic
2492
* Initialize the fields with default values of their types, but do not
2493
* run any constructor.
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.
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
2505
void run_new_csi_inst_ref(run_t *run, stree_csi_t *csi, statns_t sn,
2508
rdata_var_t *obj_var;
2510
/* Create object. */
2511
run_new_csi_inst(run, csi, sn, &obj_var);
2513
/* Create reference to the new object. */
2514
run_reference(run, obj_var, res);
2350
2517
/** Create new CSI instance.
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.
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.
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
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,
2365
2539
rdata_object_t *obj;
2366
2540
rdata_var_t *obj_var;
2368
2542
stree_symbol_t *csi_sym;
2369
2543
stree_csimbr_t *csimbr;
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);
2388
2565
obj_var = rdata_var_new(vc_object);
2389
2566
obj_var->u.object_v = obj;
2391
/* Create object fields. */
2568
/* For this CSI and all base CSIs */
2392
2569
while (csi != NULL) {
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 *);
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,
2402
/* Create and initialize field. */
2403
run_var_new(run, field_ti, &mbr_var);
2405
/* Add to field map. */
2406
intmap_set(&obj->fields,
2407
csimbr->u.var->name->sid,
2578
var = csimbr->u.var;
2580
/* Is it static/nonstatic? */
2581
var_sn = stree_symbol_has_attr(
2582
var_to_symbol(var), sac_static);
2584
/* Compute field type. XXX Memoize. */
2585
run_texpr(run->program, csi, var->type,
2588
/* Create and initialize field. */
2589
run_var_new(run, field_ti, &mbr_var);
2591
/* Add to field map. */
2592
intmap_set(&obj->fields, var->name->sid,
2411
2597
node = list_next(&csi->members, node);