Index: uspace/app/sbi/src/run_expr.c
===================================================================
--- uspace/app/sbi/src/run_expr.c	(revision 051bc69a7034999d45c93c61a56e515474aa78e3)
+++ uspace/app/sbi/src/run_expr.c	(revision c5cb943d5d19ad0d75578f54188f2491dfd64937)
@@ -104,4 +104,8 @@
 static void run_access_object(run_t *run, stree_access_t *access,
     rdata_item_t *arg, rdata_item_t **res);
+static void run_access_object_static(run_t *run, stree_access_t *access,
+    rdata_var_t *obj_var, rdata_item_t **res);
+static void run_access_object_nonstatic(run_t *run, stree_access_t *access,
+    rdata_var_t *obj_var, rdata_item_t **res);
 static void run_access_symbol(run_t *run, stree_access_t *access,
     rdata_item_t *arg, rdata_item_t **res);
@@ -207,4 +211,8 @@
 	rdata_var_t *member_var;
 
+	rdata_var_t *psobj;
+	rdata_var_t *sobj;
+	rdata_object_t *aobj;
+
 #ifdef DEBUG_RUN_TRACE
 	printf("Run nameref.\n");
@@ -238,13 +246,16 @@
 	/* Determine currently active object or CSI. */
 	proc_ar = run_get_current_proc_ar(run);
-	if (proc_ar->obj != NULL) {
-		assert(proc_ar->obj->vc == vc_object);
-		obj = proc_ar->obj->u.object_v;
-		csi_sym = obj->class_sym;
+
+	assert (proc_ar->obj != NULL);
+	assert(proc_ar->obj->vc == vc_object);
+	obj = proc_ar->obj->u.object_v;
+	csi_sym = obj->class_sym;
+
+	if (csi_sym != NULL) {
 		csi = symbol_to_csi(csi_sym);
 		assert(csi != NULL);
 	} else {
-		csi = proc_ar->proc->outer_symbol->outer_csi;
-		obj = NULL;
+		/* This happens in interactive mode. */
+		csi = NULL;
 	}
 
@@ -259,16 +270,11 @@
 		printf("Referencing CSI.\n");
 #endif
-		item = rdata_item_new(ic_value);
-		value = rdata_value_new();
-		var = rdata_var_new(vc_deleg);
-		deleg_v = rdata_deleg_new();
-
-		item->u.value = value;
-		value->var = var;
-		var->u.deleg_v = deleg_v;
-
-		deleg_v->obj = NULL;
-		deleg_v->sym = sym;
-		*res = item;
+		/* Obtain static object for the referenced CSI. */
+		psobj = run->gdata; /* XXX */
+		sobj = run_sobject_get(run, sym->u.csi, psobj,
+		    nameref->name->sid);
+
+		/* Return reference to the object. */
+		run_reference(run, sobj, res);
 		break;
 	case sc_ctor:
@@ -334,9 +340,6 @@
 		assert(csi != NULL);
 
-		/* XXX Assume variable is not static for now. */
-		assert(obj != NULL);
-
 		if (symbol_search_csi(run->program, csi, nameref->name)
-		    == NULL) {
+		    == NULL && !stree_symbol_is_static(sym)) {
 			/* Variable is not in the current object. */
 			printf("Error: Cannot access non-static member "
@@ -349,6 +352,22 @@
 		}
 
+		if (stree_symbol_is_static(sym)) {
+			/*
+			 * XXX This is too slow!
+			 *
+			 * However fixing this is non-trivial. We would
+			 * have to have pointer to static object available
+			 * for each object (therefore also for each object
+			 * type).
+			 */
+			sobj = run_sobject_find(run, sym->outer_csi);
+			assert(sobj->vc == vc_object);
+			aobj = sobj->u.object_v;
+		} else {
+			aobj = obj;
+		}
+
 		/* Find member variable in object. */
-		member_var = intmap_get(&obj->fields, nameref->name->sid);
+		member_var = intmap_get(&aobj->fields, nameref->name->sid);
 		assert(member_var != NULL);
 
@@ -1361,5 +1380,5 @@
 
 	/* Create CSI instance. */
-	run_new_csi_inst(run, csi, res);
+	run_new_csi_inst_ref(run, csi, sn_nonstatic, res);
 
 	/* Run the constructor. */
@@ -1467,5 +1486,5 @@
 }
 
-/** Evaluate delegate-member acccess.
+/** Evaluate delegate member acccess.
  *
  * @param run		Runner object
@@ -1477,41 +1496,11 @@
     rdata_item_t *arg, rdata_item_t **res)
 {
-	rdata_item_t *arg_vi;
-	rdata_value_t *arg_val;
-	rdata_deleg_t *deleg_v;
-	stree_symbol_t *member;
-
-#ifdef DEBUG_RUN_TRACE
-	printf("Run delegate access operation.\n");
-#endif
-	run_cvt_value_item(run, arg, &arg_vi);
-	arg_val = arg_vi->u.value;
-	assert(arg_val->var->vc == vc_deleg);
-
-	deleg_v = arg_val->var->u.deleg_v;
-	if (deleg_v->obj != NULL || deleg_v->sym->sc != sc_csi) {
-		printf("Error: Using '.' with delegate to different object "
-		    "than a CSI (%d).\n", deleg_v->sym->sc);
-		exit(1);
-	}
-
-	member = symbol_search_csi(run->program, deleg_v->sym->u.csi,
-	    access->member_name);
-
-	/* Member existence should be ensured by static type checking. */
-	assert(member != NULL);
-
-#ifdef DEBUG_RUN_TRACE
-	printf("Found member '%s'.\n",
-	    strtab_get_str(access->member_name->sid));
-#endif
-
-	/*
-	 * Reuse existing item, value, var, deleg.
-	 * XXX This is maybe not a good idea because it complicates memory
-	 * management as there is not a single owner 
-	 */
-	deleg_v->sym = member;
-	*res = arg;
+	(void) run;
+	(void) access;
+	(void) arg;
+	(void) res;
+
+	printf("Error: Using '.' with delegate.\n");
+	exit(1);
 }
 
@@ -1526,8 +1515,42 @@
     rdata_item_t *arg, rdata_item_t **res)
 {
+	rdata_var_t *obj_var;
+	rdata_object_t *object;
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Run object access operation.\n");
+#endif
+	assert(arg->ic == ic_address);
+	assert(arg->u.address->ac == ac_var);
+
+	obj_var = arg->u.address->u.var_a->vref;
+	assert(obj_var->vc == vc_object);
+
+	object = obj_var->u.object_v;
+
+	if (object->static_obj == sn_static)
+		run_access_object_static(run, access, obj_var, res);
+	else
+		run_access_object_nonstatic(run, access, obj_var, res);
+}
+
+/** Evaluate static object member acccess.
+ *
+ * @param run		Runner object
+ * @param access	Access operation
+ * @param arg		Evaluated base expression
+ * @param res		Place to store result
+ */
+static void run_access_object_static(run_t *run, stree_access_t *access,
+    rdata_var_t *obj_var, rdata_item_t **res)
+{
+	rdata_object_t *object;
 	stree_symbol_t *member;
-	rdata_var_t *object_var;
-	rdata_object_t *object;
+	stree_csi_t *member_csi;
+
+	rdata_deleg_t *deleg_v;
 	rdata_item_t *ritem;
+	rdata_value_t *rvalue;
+	rdata_var_t *rvar;
 	rdata_address_t *address;
 	rdata_addr_var_t *addr_var;
@@ -1535,29 +1558,19 @@
 	rdata_aprop_named_t *aprop_named;
 	rdata_deleg_t *deleg_p;
-
-	rdata_value_t *value;
-	rdata_deleg_t *deleg_v;
-	rdata_var_t *var;
-
-#ifdef DEBUG_RUN_TRACE
-	printf("Run object access operation.\n");
-#endif
-	assert(arg->ic == ic_address);
-	assert(arg->u.address->ac == ac_var);
-	assert(arg->u.address->u.var_a->vref->vc == vc_object);
-
-	object_var = arg->u.address->u.var_a->vref;
-	object = object_var->u.object_v;
+	rdata_var_t *mvar;
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Run static object access operation.\n");
+#endif
+	assert(obj_var->vc == vc_object);
+	object = obj_var->u.object_v;
+
+	assert(object->static_obj == sn_static);
 
 	member = symbol_search_csi(run->program, object->class_sym->u.csi,
 	    access->member_name);
 
-	if (member == NULL) {
-		printf("Error: Object of class '");
-		symbol_print_fqn(object->class_sym);
-		printf("' has no member named '%s'.\n",
-		    strtab_get_str(access->member_name->sid));
-		exit(1);
-	}
+	/* Member existence should be ensured by static type checking. */
+	assert(member != NULL);
 
 #ifdef DEBUG_RUN_TRACE
@@ -1566,11 +1579,26 @@
 #endif
 
-	/* Make compiler happy. */
-	ritem = NULL;
-
 	switch (member->sc) {
 	case sc_csi:
-		printf("Error: Accessing object member which is nested CSI.\n");
-		exit(1);
+		/* Get child static object. */
+		member_csi = symbol_to_csi(member);
+		assert(member_csi != NULL);
+
+		mvar = run_sobject_get(run, member_csi, obj_var,
+		    access->member_name->sid);
+
+		ritem = rdata_item_new(ic_address);
+		address = rdata_address_new(ac_var);
+		ritem->u.address = address;
+
+		addr_var = rdata_addr_var_new();
+		address->u.var_a = addr_var;
+		addr_var->vref = mvar;
+
+		*res = ritem;
+		break;
+	case sc_ctor:
+		/* It is not possible to reference a constructor explicitly. */
+		assert(b_false);
 	case sc_deleg:
 		printf("Error: Accessing object member which is a delegate.\n");
@@ -1579,32 +1607,33 @@
 		printf("Error: Accessing object member which is an enum.\n");
 		exit(1);
-	case sc_ctor:
-		/* It is not possible to reference a constructor explicitly. */
-		assert(b_false);
 	case sc_fun:
 		/* Construct anonymous delegate. */
 		ritem = rdata_item_new(ic_value);
-		value = rdata_value_new();
-		ritem->u.value = value;
-
-		var = rdata_var_new(vc_deleg);
-		value->var = var;
+		rvalue = rdata_value_new();
+		ritem->u.value = rvalue;
+
+		rvar = rdata_var_new(vc_deleg);
+		rvalue->var = rvar;
+
 		deleg_v = rdata_deleg_new();
-		var->u.deleg_v = deleg_v;
-
-		deleg_v->obj = arg->u.address->u.var_a->vref;
+		rvar->u.deleg_v = deleg_v;
+
+		deleg_v->obj = obj_var;
 		deleg_v->sym = member;
+		*res = ritem;
 		break;
 	case sc_var:
-		/* Construct variable address item. */
+		/* Get static object member variable. */
+		mvar = intmap_get(&object->fields, access->member_name->sid);
+
 		ritem = rdata_item_new(ic_address);
 		address = rdata_address_new(ac_var);
+		ritem->u.address = address;
+
 		addr_var = rdata_addr_var_new();
-		ritem->u.address = address;
 		address->u.var_a = addr_var;
-
-		addr_var->vref = intmap_get(&object->fields,
-		    access->member_name->sid);
-		assert(addr_var->vref != NULL);
+		addr_var->vref = mvar;
+
+		*res = ritem;
 		break;
 	case sc_prop:
@@ -1619,5 +1648,114 @@
 
 		deleg_p = rdata_deleg_new();
-		deleg_p->obj = object_var;
+		deleg_p->obj = obj_var;
+		deleg_p->sym = member;
+		addr_prop->u.named->prop_d = deleg_p;
+
+		*res = ritem;
+		break;
+	}
+}
+
+/** Evaluate object member acccess.
+ *
+ * @param run		Runner object
+ * @param access	Access operation
+ * @param arg		Evaluated base expression
+ * @param res		Place to store result
+ */
+static void run_access_object_nonstatic(run_t *run, stree_access_t *access,
+    rdata_var_t *obj_var, rdata_item_t **res)
+{
+	rdata_object_t *object;
+	stree_symbol_t *member;
+	rdata_item_t *ritem;
+	rdata_address_t *address;
+	rdata_addr_var_t *addr_var;
+	rdata_addr_prop_t *addr_prop;
+	rdata_aprop_named_t *aprop_named;
+	rdata_deleg_t *deleg_p;
+
+	rdata_value_t *value;
+	rdata_deleg_t *deleg_v;
+	rdata_var_t *var;
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Run nonstatic object access operation.\n");
+#endif
+	assert(obj_var->vc == vc_object);
+	object = obj_var->u.object_v;
+
+	assert(object->static_obj == sn_nonstatic);
+
+	member = symbol_search_csi(run->program, object->class_sym->u.csi,
+	    access->member_name);
+
+	if (member == NULL) {
+		printf("Error: Object of class '");
+		symbol_print_fqn(object->class_sym);
+		printf("' has no member named '%s'.\n",
+		    strtab_get_str(access->member_name->sid));
+		exit(1);
+	}
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Found member '%s'.\n",
+	    strtab_get_str(access->member_name->sid));
+#endif
+
+	/* Make compiler happy. */
+	ritem = NULL;
+
+	switch (member->sc) {
+	case sc_csi:
+		printf("Error: Accessing object member which is nested CSI.\n");
+		exit(1);
+	case sc_ctor:
+		/* It is not possible to reference a constructor explicitly. */
+		assert(b_false);
+	case sc_deleg:
+		printf("Error: Accessing object member which is a delegate.\n");
+		exit(1);
+	case sc_enum:
+		printf("Error: Accessing object member which is an enum.\n");
+		exit(1);
+	case sc_fun:
+		/* Construct anonymous delegate. */
+		ritem = rdata_item_new(ic_value);
+		value = rdata_value_new();
+		ritem->u.value = value;
+
+		var = rdata_var_new(vc_deleg);
+		value->var = var;
+		deleg_v = rdata_deleg_new();
+		var->u.deleg_v = deleg_v;
+
+		deleg_v->obj = obj_var;
+		deleg_v->sym = member;
+		break;
+	case sc_var:
+		/* Construct variable address item. */
+		ritem = rdata_item_new(ic_address);
+		address = rdata_address_new(ac_var);
+		addr_var = rdata_addr_var_new();
+		ritem->u.address = address;
+		address->u.var_a = addr_var;
+
+		addr_var->vref = intmap_get(&object->fields,
+		    access->member_name->sid);
+		assert(addr_var->vref != NULL);
+		break;
+	case sc_prop:
+		/* Construct named property address. */
+		ritem = rdata_item_new(ic_address);
+		address = rdata_address_new(ac_prop);
+		addr_prop = rdata_addr_prop_new(apc_named);
+		aprop_named = rdata_aprop_named_new();
+		ritem->u.address = address;
+		address->u.prop_a = addr_prop;
+		addr_prop->u.named = aprop_named;
+
+		deleg_p = rdata_deleg_new();
+		deleg_p->obj = obj_var;
 		deleg_p->sym = member;
 		addr_prop->u.named->prop_d = deleg_p;
@@ -2168,5 +2306,4 @@
 	rdata_item_t *rdest_i, *rsrc_i;
 	rdata_item_t *rsrc_vi;
-	rdata_value_t *src_val;
 
 #ifdef DEBUG_RUN_TRACE
@@ -2187,5 +2324,4 @@
 	run_cvt_value_item(run, rsrc_i, &rsrc_vi);
 	assert(rsrc_vi->ic == ic_value);
-	src_val = rsrc_vi->u.value;
 
 	if (rdest_i->ic != ic_address) {
@@ -2331,5 +2467,5 @@
 
 	/* Construct object of the relevant boxed type. */
-	run_new_csi_inst(run, csi, res);
+	run_new_csi_inst_ref(run, csi, sn_nonstatic, res);
 
 	/* Set the 'Value' field */
@@ -2348,5 +2484,5 @@
 }
 
-/** Create new CSI instance.
+/** Create new CSI instance and return reference to it.
  *
  * Create a new object, instance of @a csi.
@@ -2357,9 +2493,47 @@
  * run any constructor.
  *
- * @param run		Runner object
- * @param as_op		@c as conversion expression
- * @param res		Place to store result
- */
-void run_new_csi_inst(run_t *run, stree_csi_t *csi, rdata_item_t **res)
+ * If @a sn is @c sn_nonstatic a regular object is created, containing all
+ * non-static member variables. If @a sn is @c sn_static a static object
+ * is created, containing all static member variables.
+ *
+ * @param run		Runner object
+ * @param csi		CSI to create instance of
+ * @param sn		@c sn_static to create a static (class) object,
+ *			@c sn_nonstatic to create a regular object
+ * @param res		Place to store result
+ */
+void run_new_csi_inst_ref(run_t *run, stree_csi_t *csi, statns_t sn,
+    rdata_item_t **res)
+{
+	rdata_var_t *obj_var;
+
+	/* Create object. */
+	run_new_csi_inst(run, csi, sn, &obj_var);
+
+	/* Create reference to the new object. */
+	run_reference(run, obj_var, res);
+}
+
+/** Create new CSI instance.
+ *
+ * Create a new object, instance of @a csi.
+ * XXX This does not work with generics as @a csi cannot specify a generic
+ * type.
+ *
+ * Initialize the fields with default values of their types, but do not
+ * run any constructor.
+ *
+ * If @a sn is @c sn_nonstatic a regular object is created, containing all
+ * non-static member variables. If @a sn is @c sn_static a static object
+ * is created, containing all static member variables.
+ *
+ * @param run		Runner object
+ * @param csi		CSI to create instance of
+ * @param sn		@c sn_static to create a static (class) object,
+ *			@c sn_nonstatic to create a regular object
+ * @param res		Place to store result
+ */
+void run_new_csi_inst(run_t *run, stree_csi_t *csi, statns_t sn,
+    rdata_var_t **res)
 {
 	rdata_object_t *obj;
@@ -2368,4 +2542,6 @@
 	stree_symbol_t *csi_sym;
 	stree_csimbr_t *csimbr;
+	stree_var_t *var;
+	statns_t var_sn;
 
 	rdata_var_t *mbr_var;
@@ -2384,4 +2560,5 @@
 	obj = rdata_object_new();
 	obj->class_sym = csi_sym;
+	obj->static_obj = sn;
 	intmap_init(&obj->fields);
 
@@ -2389,22 +2566,31 @@
 	obj_var->u.object_v = obj;
 
-	/* Create object fields. */
+	/* For this CSI and all base CSIs */
 	while (csi != NULL) {
+
+		/* For all members */
 		node = list_first(&csi->members);
 		while (node != NULL) {
 			csimbr = list_node_data(node, stree_csimbr_t *);
+
+			/* Is it a member variable? */
 			if (csimbr->cc == csimbr_var) {
-				/* Compute field type. XXX Memoize. */
-				run_texpr(run->program, csi,
-				    csimbr->u.var->type,
-				    &field_ti);
-
-				/* Create and initialize field. */
-				run_var_new(run, field_ti, &mbr_var);
-
-				/* Add to field map. */
-				intmap_set(&obj->fields,
-				    csimbr->u.var->name->sid,
-				    mbr_var);
+				var = csimbr->u.var;
+
+				/* Is it static/nonstatic? */
+				var_sn = stree_symbol_has_attr(
+				    var_to_symbol(var), sac_static);
+				if (var_sn == sn) {
+					/* Compute field type. XXX Memoize. */
+					run_texpr(run->program, csi, var->type,
+					    &field_ti);
+
+					/* Create and initialize field. */
+					run_var_new(run, field_ti, &mbr_var);
+
+					/* Add to field map. */
+					intmap_set(&obj->fields, var->name->sid,
+					    mbr_var);
+				}
 			}
 
@@ -2416,6 +2602,5 @@
 	}
 
-	/* Create reference to the new object. */
-	run_reference(run, obj_var, res);
+	*res = obj_var;
 }
 
