Index: uspace/app/sbi/src/run.c
===================================================================
--- uspace/app/sbi/src/run.c	(revision 1ebc1a62b0e759c001488fc0e221be6347082167)
+++ uspace/app/sbi/src/run.c	(revision 23de644e12ee218601dd193540374b779a6364d7)
@@ -32,4 +32,5 @@
 #include <stdlib.h>
 #include <assert.h>
+#include "bigint.h"
 #include "builtin.h"
 #include "debug.h"
@@ -57,4 +58,6 @@
 
 static bool_t run_exc_match(run_t *run, stree_except_t *except_c);
+static stree_csi_t *run_exc_payload_get_csi(run_t *run);
+
 static rdata_var_t *run_aprop_get_tpos(run_t *run, rdata_address_t *aprop);
 
@@ -113,10 +116,5 @@
 	run_proc(run, proc_ar, &res);
 
-	/* Check for unhandled exceptions. */
-	if (run->thread_ar->bo_mode != bm_none) {
-		assert(run->thread_ar->bo_mode == bm_exc);
-		printf("Error: Unhandled exception.\n");
-		exit(1);
-	}
+	run_exc_check_unhandled(run);
 }
 
@@ -302,5 +300,5 @@
 
 	var->u.int_v = int_v;
-	int_v->value = 0;
+	bigint_init(&int_v->value, 0);
 
 	block_ar = run_get_current_block_ar(run);
@@ -329,4 +327,6 @@
 #endif
 	run_expr(run, if_s->cond, &rcond);
+	if (run_is_bo(run))
+		return;
 
 	if (run_item_boolean_value(run, rcond) == b_true) {
@@ -357,8 +357,12 @@
 #endif
 	run_expr(run, while_s->cond, &rcond);
+	if (run_is_bo(run))
+		return;
 
 	while (run_item_boolean_value(run, rcond) == b_true) {
 		run_block(run, while_s->body);
 		run_expr(run, while_s->cond, &rcond);
+		if (run_is_bo(run))
+			return;
 
 		if (run->thread_ar->bo_mode != bm_none)
@@ -381,4 +385,7 @@
 #endif
 	run_expr(run, raise_s->expr, &rexpr);
+	if (run_is_bo(run))
+		return;
+
 	run_cvt_value_item(run, rexpr, &rexpr_vi);
 
@@ -401,4 +408,7 @@
 #endif
 	run_expr(run, return_s->expr, &rexpr);
+	if (run_is_bo(run))
+		return;
+
 	run_cvt_value_item(run, rexpr, &rexpr_vi);
 
@@ -477,6 +487,5 @@
  *
  * Checks if the currently active exception in the runner object @c run
- * matches except clause @c except_c. Generates an error if the exception
- * payload has invalid type (i.e. not an object).
+ * matches except clause @c except_c.
  *
  * @param run		Runner object.
@@ -486,8 +495,28 @@
 static bool_t run_exc_match(run_t *run, stree_except_t *except_c)
 {
+	stree_csi_t *exc_csi;
+	tdata_item_t *etype;
+
+	/* Get CSI of active exception. */
+	exc_csi = run_exc_payload_get_csi(run);
+
+	/* Evaluate type expression in except clause. */
+	run_texpr(run->program, run_get_current_csi(run), except_c->etype,
+	    &etype);
+
+	/* Determine if active exc. is derived from type in exc. clause. */
+	return tdata_is_csi_derived_from_ti(exc_csi, etype);
+}
+
+/** Return CSI of the active exception.
+ *
+ * @param run		Runner object.
+ * @return		CSI of the active exception.
+ */
+static stree_csi_t *run_exc_payload_get_csi(run_t *run)
+{
 	rdata_value_t *payload;
 	rdata_var_t *payload_v;
 	rdata_object_t *payload_o;
-	tdata_item_t *etype;
 
 	payload = run->thread_ar->exc_payload;
@@ -495,4 +524,5 @@
 
 	if (payload->var->vc != vc_ref) {
+		/* XXX Prevent this via static type checking. */
 		printf("Error: Exception payload must be an object "
 		    "(found type %d).\n", payload->var->vc);
@@ -502,4 +532,5 @@
 	payload_v = payload->var->u.ref_v->vref;
 	if (payload_v->vc != vc_object) {
+		/* XXX Prevent this via static type checking. */
 		printf("Error: Exception payload must be an object "
 		    "(found type %d).\n", payload_v->vc);
@@ -517,10 +548,30 @@
 	assert(payload_o->class_sym->sc == sc_csi);
 
-	/* Evaluate type expression in except clause. */
-	run_texpr(run->program, run_get_current_csi(run), except_c->etype,
-	    &etype);
-
-	return tdata_is_csi_derived_from_ti(payload_o->class_sym->u.csi,
-	    etype);
+	return payload_o->class_sym->u.csi;
+}
+
+
+/** Check for unhandled exception.
+ *
+ * Checks whether there is an active exception. If so, it prints an
+ * error message and raises a run-time error.
+ *
+ * @param run		Runner object.
+ */
+void run_exc_check_unhandled(run_t *run)
+{
+	stree_csi_t *exc_csi;
+
+	if (run->thread_ar->bo_mode != bm_none) {
+		assert(run->thread_ar->bo_mode == bm_exc);
+
+		exc_csi = run_exc_payload_get_csi(run);
+
+		printf("Error: Unhandled exception '");
+		symbol_print_fqn(csi_to_symbol(exc_csi));
+		printf("'.\n");
+
+		run_raise_error(run);
+	}
 }
 
@@ -620,5 +671,6 @@
 
 		(*var)->u.int_v = int_v;
-		int_v->value = item->u.value->var->u.int_v->value;
+		bigint_clone(&item->u.value->var->u.int_v->value,
+		    &int_v->value);
 		break;
 	case vc_string:
@@ -1171,6 +1223,9 @@
 
 	if (addr_var->vref == NULL) {
+#ifdef DEBUG_RUN_TRACE
 		printf("Error: Accessing null reference.\n");
-		run_raise_error(run);
+#endif
+		/* Raise Error.NilReference */
+		run_raise_exc(run, run->program->builtin->error_nilreference);
 		*ritem = run_recovery_item(run);
 		return;
@@ -1181,4 +1236,33 @@
 #endif
 	*ritem = item;
+}
+
+/** Raise an exception of the given class.
+ *
+ * Used when the interpreter generates an exception due to a run-time
+ * error (not for the @c raise statement).
+ *
+ * @param run		Runner object.
+ * @param csi		Exception class.
+ */
+void run_raise_exc(run_t *run, stree_csi_t *csi)
+{
+	rdata_item_t *exc_vi;
+
+	/* Create exception object. */
+	run_new_csi_inst(run, csi, &exc_vi);
+	assert(exc_vi->ic == ic_value);
+
+	/* Store exception object in thread AR. */
+	run->thread_ar->exc_payload = exc_vi->u.value;
+
+	/* Start exception bailout. */
+	run->thread_ar->bo_mode = bm_exc;
+}
+
+/** Determine if we are bailing out. */
+bool_t run_is_bo(run_t *run)
+{
+	return run->thread_ar->bo_mode != bm_none;
 }
 
