diff --git a/moo/README.md b/moo/README.md index 75b2e0f..d5b0fb4 100644 --- a/moo/README.md +++ b/moo/README.md @@ -81,3 +81,14 @@ while (true) 1 to: 20 do: [:count | ... ]. ~~~ + +### Exception handling +Exception signal. +Exception signal: "message". + +[ ... ] on: Exception do: [:ex | ... ]. + +ex retry. +ex resume. +ex resume: value. +ex return: value. diff --git a/moo/kernel/Apex.moo b/moo/kernel/Apex.moo index cff1240..10146f8 100644 --- a/moo/kernel/Apex.moo +++ b/moo/kernel/Apex.moo @@ -313,8 +313,6 @@ class UndefinedObject(Apex) } } - - extend Error { /* ---------------------------- @@ -343,6 +341,7 @@ extend Error method(#primitive) asString. +/* ----------------------- method signal { | exctx exblk retval actpos ctx | @@ -367,17 +366,8 @@ extend Error // ----------------------------------------------------------------- //thisContext unwindTo: nil return: nil. //thisContext unwindTo: (Processor activeProcess initialContext) return: nil. - -// TOOD: IMPROVE THIS EXPERIMENTAL BACKTRACE... -System logNl: "== BACKTRACE ==". -ctx := thisContext. -while (ctx notNil) -{ - if (ctx class == MethodContext) { System logNl: (" " & ctx method owner name & ">>" & ctx method name) }. - // TODO: include blockcontext??? - ctx := ctx sender. -}. -System logNl: "== END OF BACKTRACE ==". + + System backtrace. thisContext unwindTo: (thisProcess initialContext) return: nil. ("### ERROR NOT HANDLED #### " & self class name & " - " & self asString) dump. @@ -386,4 +376,5 @@ System logNl: "== END OF BACKTRACE ==". //Processor activeProcess terminate. thisProcess terminate. } +---------------------- */ } diff --git a/moo/kernel/Except.moo b/moo/kernel/Except.moo index a20fa52..bc1f2b2 100644 --- a/moo/kernel/Except.moo +++ b/moo/kernel/Except.moo @@ -69,21 +69,7 @@ TODO: can i convert 'thisProcess primError' to a relevant exception? //thisContext unwindTo: nil return: nil. //thisContext unwindTo: (Processor activeProcess initialContext) return: nil. -// TOOD: IMPROVE THIS EXPERIMENTAL BACKTRACE... MOVE THIS TO System>>backtrace and skip the first method context for backtrace itself. -System logNl: "== BACKTRACE ==". -ctx := thisContext. -while (ctx notNil) -{ - if (ctx class == MethodContext) - { - System logNl: (" " & ctx method owner name & ">>" & ctx method name & - " (" & ctx method sourceFile & " " & (ctx method ipSourceLine: (ctx pc)) asString & ")"). -// TODO: get location of the current pc and include it... (ctx method sourceLine: ctx pc) asString dump. - }. - // TODO: include blockcontext??? - ctx := ctx sender. -}. -System logNl: "== END OF BACKTRACE ==". + System backtrace. thisContext unwindTo: (thisProcess initialContext) return: nil. ("### EXCEPTION NOT HANDLED(Exception) #### " & self class name & " - " & self messageText) dump. @@ -540,17 +526,7 @@ extend Apex | class_name ctx | class_name := if (self class == Class) { self name } else { self class name }. -// TOOD: IMPROVE THIS EXPERIMENTAL BACKTRACE... -System logNl: "== BACKTRACE ==". -ctx := thisContext. -while (ctx notNil) -{ - if (ctx class == MethodContext) { System logNl: (" " & ctx method owner name & ">>" & ctx method name) }. - // TODO: include blockcontext??? - ctx := ctx sender. -}. -System logNl: "== END OF BACKTRACE ==". - + System backtrace. NoSuchMessageException signal: (message_name & " not understood by " & class_name). } diff --git a/moo/kernel/System.moo b/moo/kernel/System.moo index 74d2890..23825e3 100644 --- a/moo/kernel/System.moo +++ b/moo/kernel/System.moo @@ -214,6 +214,28 @@ TODO: how to pass all variadic arguments to another variadic methods??? ^self atLevel: System.Log.INFO logNl: message and: message2. } + method(#class) backtrace + { + | ctx | + // TOOD: IMPROVE THIS EXPERIMENTAL BACKTRACE... MOVE THIS TO System>>backtrace and skip the first method context for backtrace itself. + System logNl: "== BACKTRACE ==". + + //ctx := thisContext. + ctx := thisContext sender. // skip the current context. skip to the caller context. + while (ctx notNil) + { + if (ctx class == MethodContext) + { + System logNl: (" " & ctx method owner name & ">>" & ctx method name & + " (" & ctx method sourceFile & " " & (ctx method ipSourceLine: (ctx pc)) asString & ")"). + // TODO: get location of the current pc and include it... (ctx method sourceLine: ctx pc) asString dump. + }. + // TODO: include blockcontext??? + ctx := ctx sender. + }. + System logNl: "== END OF BACKTRACE ==". + } + /* nsdic access */ method(#class) at: key { diff --git a/moo/kernel/test-003.moo b/moo/kernel/test-003.moo index affb216..22dd24b 100644 --- a/moo/kernel/test-003.moo +++ b/moo/kernel/test-003.moo @@ -92,7 +92,8 @@ class MyObject(Object) tb := tc at: idx. System log(System.Log.INFO, idx asString, (if (tb value) { " PASS" } else { " FAIL" }), "\n"). ]. -Exception signal: 'xxx'. + +Exception signal: 'experiment with exception signalling'. // TODO: String format("%s", " 나 는\\\"") dump. diff --git a/moo/lib/debug.c b/moo/lib/debug.c index 021af28..1423e0a 100644 --- a/moo/lib/debug.c +++ b/moo/lib/debug.c @@ -241,9 +241,9 @@ int moo_addmethodtodbgi (moo_t* moo, moo_oow_t file_offset, moo_oow_t class_offs di->_file = file_offset; di->_class = class_offset; di->start_line = start_line; - di->code_loc_start = name_bytes_aligned; + di->code_loc_start = name_bytes_aligned; /* distance from the beginning of the variable payload */ di->code_loc_len = code_loc_len; - di->text_start = name_bytes_aligned + code_loc_bytes_aligned; + di->text_start = name_bytes_aligned + code_loc_bytes_aligned; /* distance from the beginning of the variable payload */ di->text_len = text_len; curptr = (moo_uint8_t*)(di + 1); diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 20f2742..8fe95ff 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -2228,7 +2228,7 @@ static MOO_INLINE moo_dbgi_method_t* get_dbgi_method (moo_t* moo, moo_oop_method if (dbgi_method_offset > 0) { MOO_ASSERT (moo, dbgi_method_offset < moo->dbgi->_len); - di = (moo_dbgi_method_t*)&((moo_uint8_t*)moo->dbgi)[dbgi_method_offset]; + di = (moo_dbgi_method_t*)MOO_DBGI_GET_DATA(moo, dbgi_method_offset); MOO_ASSERT (moo, MOO_DBGI_GET_TYPE_CODE(di->_type) == MOO_DBGI_TYPE_CODE_METHOD); } } @@ -2258,7 +2258,7 @@ static moo_pfrc_t pf_method_get_source_file (moo_t* moo, moo_mod_t* mod, moo_ooi const moo_ooch_t* file_name; MOO_ASSERT (moo, dbgi_file_offset < moo->dbgi->_len); - di = (moo_dbgi_file_t*)&((moo_uint8_t*)moo->dbgi)[dbgi_file_offset]; + di = (moo_dbgi_file_t*)MOO_DBGI_GET_DATA(moo, dbgi_file_offset); MOO_ASSERT (moo, MOO_DBGI_GET_TYPE_CODE(di->_type) == MOO_DBGI_TYPE_CODE_FILE); file_name = (const moo_ooch_t*)(di + 1); @@ -2300,7 +2300,6 @@ static moo_pfrc_t pf_method_get_ip_source_line (moo_t* moo, moo_mod_t* mod, moo_ retv = moo_oowtoint(moo, code_loc_ptr[ipv]); if (!retv) return MOO_PF_FAILURE; } -/* TODO: security check for data corruption? check if the ipv offset and the size calcualted doesn't exceed di->_len... */ } MOO_STACK_SETRET (moo, nargs, retv); diff --git a/moo/lib/moo.h b/moo/lib/moo.h index a1693f2..2552ada 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -973,6 +973,8 @@ typedef enum moo_dbgi_type_t moo_dbgi_type_t; #define MOO_DBGI_GET_TYPE_CODE(type) ((type) >> 8) #define MOO_DBGI_GET_TYPE_FLAGS(type) ((type) & 0xFF) +#define MOO_DBGI_GET_DATA(moo, offset) ((moo_uint8_t*)(moo)->dbgi + (offset)) + typedef struct moo_dbgi_file_t moo_dbgi_file_t; struct moo_dbgi_file_t {