removed send_message_with_str(), find_method_with_str()
registered some commonly used method names as symbols - doesNotUnderstand:, unwindTo:return:, primitiveFailed invocation of the above methods doesn't need send_message_with_str() changed startup method invocation to look up for a symbol first instead of using the above functions removed
This commit is contained in:
parent
ae20171772
commit
3419097054
@ -8,6 +8,53 @@
|
|||||||
class MyObject(Object)
|
class MyObject(Object)
|
||||||
{
|
{
|
||||||
var(#class) a := 100.
|
var(#class) a := 100.
|
||||||
|
var(#class) ensure_tester_v := 0.
|
||||||
|
|
||||||
|
method(#class) test_quicksort: anArray
|
||||||
|
{
|
||||||
|
| quicksort |
|
||||||
|
quicksort := nil.
|
||||||
|
quicksort := [ :data :from :to |
|
||||||
|
(from < to)
|
||||||
|
ifTrue: [ | pivot index |
|
||||||
|
pivot := data at: from.
|
||||||
|
data swap: from with: to.
|
||||||
|
index := from.
|
||||||
|
from to: (to - 1) do: [ :each |
|
||||||
|
(data at: each) < pivot
|
||||||
|
ifTrue: [
|
||||||
|
data swap: each with: index.
|
||||||
|
index := index + 1
|
||||||
|
]
|
||||||
|
].
|
||||||
|
|
||||||
|
data swap: to with: index.
|
||||||
|
quicksort value: data value: from value: index - 1.
|
||||||
|
quicksort value: data value: index + 1 value: to
|
||||||
|
].
|
||||||
|
data
|
||||||
|
].
|
||||||
|
|
||||||
|
^(quicksort value: anArray value: 0 value: (anArray size - 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
method(#class) test_on_do_with: dividend with: divisor
|
||||||
|
{
|
||||||
|
## it returns 0 upon an exception otherwise, division result.
|
||||||
|
^[ dividend div: divisor ] on: Exception do: [:ex | 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
method(#class) test_ensure_with: v
|
||||||
|
{
|
||||||
|
[
|
||||||
|
[ Exception signal: "test ensure exception" ] ensure: [ self.ensure_tester_v := v ].
|
||||||
|
] on: Exception do: [:ex | /* do nothing */ ].
|
||||||
|
}
|
||||||
|
|
||||||
|
method(#class) test_ensure2_with: v
|
||||||
|
{
|
||||||
|
[ ^v * v ] ensure: [ self.ensure_tester_v := v ].
|
||||||
|
}
|
||||||
|
|
||||||
method(#class) proc1
|
method(#class) proc1
|
||||||
{
|
{
|
||||||
@ -103,48 +150,27 @@ class MyObject(Object)
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
method(#class) test_quicksort: anArray
|
|
||||||
{
|
|
||||||
| quicksort |
|
|
||||||
quicksort := nil.
|
|
||||||
quicksort := [ :data :from :to |
|
|
||||||
(from < to)
|
|
||||||
ifTrue: [ | pivot index |
|
|
||||||
pivot := data at: from.
|
|
||||||
data swap: from with: to.
|
|
||||||
index := from.
|
|
||||||
from to: (to - 1) do: [ :each |
|
|
||||||
(data at: each) < pivot
|
|
||||||
ifTrue: [
|
|
||||||
data swap: each with: index.
|
|
||||||
index := index + 1
|
|
||||||
]
|
|
||||||
].
|
|
||||||
|
|
||||||
data swap: to with: index.
|
|
||||||
quicksort value: data value: from value: index - 1.
|
|
||||||
quicksort value: data value: index + 1 value: to
|
|
||||||
].
|
|
||||||
data
|
|
||||||
].
|
|
||||||
|
|
||||||
^(quicksort value: anArray value: 0 value: (anArray size - 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
method(#class) main
|
method(#class) main
|
||||||
{
|
{
|
||||||
| tc limit |
|
| tc limit |
|
||||||
|
|
||||||
tc := %(
|
tc := %(
|
||||||
## 0 - 4
|
## 0 - 4
|
||||||
|
[ (self test_quicksort: #(7 12 3 20 5 8 2) copy) = #(2 3 5 7 8 12 20)],
|
||||||
|
[ (self test_quicksort: %(99, 12, 18, 7, 12, 3, 20, 5, 8, 2)) = #(2 3 5 7 8 12 12 18 20 99)],
|
||||||
|
[ (self test_on_do_with: 10 with: 2) == 5 ],
|
||||||
|
[ (self test_on_do_with: -10 with: 0) == 0 ],
|
||||||
|
[ self test_ensure_with: -20945. self.ensure_tester_v == -20945 ],
|
||||||
|
|
||||||
|
## 5-9
|
||||||
|
[ ((self test_ensure2_with: 8) == 64) and: [self.ensure_tester_v == 8] ],
|
||||||
[ self proc1 == 100 ],
|
[ self proc1 == 100 ],
|
||||||
[ System sleepForSecs: 2. self proc1 == 200 ],
|
[ System sleepForSecs: 2. self proc1 == 200 ],
|
||||||
[ self test_semaphore_heap == true ],
|
[ self test_semaphore_heap == true ],
|
||||||
[ self test_mutex = #(2000 6000) ],
|
[ self test_mutex = #(2000 6000) ],
|
||||||
####[ self test_sem_sig ],
|
|
||||||
[ (self test_quicksort: #(7 12 3 20 5 8 2) copy) = #(2 3 5 7 8 12 20)],
|
|
||||||
[ (self test_quicksort: %(99, 12, 18, 7, 12, 3, 20, 5, 8, 2)) = #(2 3 5 7 8 12 12 18 20 99)],
|
|
||||||
|
|
||||||
|
## 10-14
|
||||||
|
####[ self test_sem_sig ],
|
||||||
[ System sleepForSecs: 2. self.a == 300 ] ## sleep before checking self.a to prevent different result depending on process switching frequency and speed
|
[ System sleepForSecs: 2. self.a == 300 ] ## sleep before checking self.a to prevent different result depending on process switching frequency and speed
|
||||||
).
|
).
|
||||||
|
|
||||||
|
163
moo/lib/exec.c
163
moo/lib/exec.c
@ -136,7 +136,6 @@ static MOO_INLINE const char* proc_state_to_string (int state)
|
|||||||
static int delete_sem_from_sem_io_tuple (moo_t* moo, moo_oop_semaphore_t sem, int force);
|
static int delete_sem_from_sem_io_tuple (moo_t* moo, moo_oop_semaphore_t sem, int force);
|
||||||
static void signal_io_semaphore (moo_t* moo, moo_ooi_t io_handle, moo_ooi_t mask);
|
static void signal_io_semaphore (moo_t* moo, moo_ooi_t io_handle, moo_ooi_t mask);
|
||||||
static int send_message (moo_t* moo, moo_oop_char_t selector, moo_ooi_t nargs, int to_super);
|
static int send_message (moo_t* moo, moo_oop_char_t selector, moo_ooi_t nargs, int to_super);
|
||||||
static int send_message_with_str (moo_t* moo, const moo_ooch_t* nameptr, moo_oow_t namelen, moo_ooi_t nargs);
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
static MOO_INLINE int vm_startup (moo_t* moo)
|
static MOO_INLINE int vm_startup (moo_t* moo)
|
||||||
@ -1686,58 +1685,6 @@ moo_oop_method_t moo_findmethodinclasschain (moo_t* moo, moo_oop_class_t _class,
|
|||||||
return mth;
|
return mth;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOO_INLINE moo_oop_method_t find_method_with_str (moo_t* moo, moo_oop_t receiver, const moo_oocs_t* message, int in_super)
|
|
||||||
{
|
|
||||||
/* this function should be the same as moo_findmethod() mostly except cache management.
|
|
||||||
* this function can get removed if the callers create a symbol before look-up. TODO: << */
|
|
||||||
moo_oop_class_t _class;
|
|
||||||
moo_oop_class_t c;
|
|
||||||
int mth_type;
|
|
||||||
moo_oop_method_t mth;
|
|
||||||
|
|
||||||
_class = MOO_CLASSOF(moo, receiver);
|
|
||||||
if (_class == moo->_class)
|
|
||||||
{
|
|
||||||
/* receiver is a class object (an instance of Class) */
|
|
||||||
c = (moo_oop_class_t)receiver;
|
|
||||||
mth_type = MOO_METHOD_CLASS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* receiver is not a class object. so take its class */
|
|
||||||
c = _class;
|
|
||||||
mth_type = MOO_METHOD_INSTANCE;
|
|
||||||
}
|
|
||||||
MOO_ASSERT (moo, (moo_oop_t)c != moo->_nil);
|
|
||||||
|
|
||||||
if (in_super)
|
|
||||||
{
|
|
||||||
MOO_ASSERT (moo, moo->active_method);
|
|
||||||
MOO_ASSERT (moo, moo->active_method->owner);
|
|
||||||
c = (moo_oop_class_t)((moo_oop_class_t)moo->active_method->owner)->superclass;
|
|
||||||
if ((moo_oop_t)c == moo->_nil) goto not_found;
|
|
||||||
/* c is nil if it reached the top of the hierarchy.
|
|
||||||
* otherwise c points to a class object */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* [IMPORT] the method lookup logic should be the same as ciim_on_each_method() in comp.c */
|
|
||||||
mth = find_method_in_class_chain(moo, c, mth_type, message);
|
|
||||||
if (mth) return mth;
|
|
||||||
|
|
||||||
not_found:
|
|
||||||
if (_class == moo->_class)
|
|
||||||
{
|
|
||||||
/* the object is an instance of Class. find the method
|
|
||||||
* in an instance method dictionary of Class also */
|
|
||||||
mth = find_method_in_class(moo, _class, MOO_METHOD_INSTANCE, message);
|
|
||||||
if (mth) return mth;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOO_LOG3 (moo, MOO_LOG_DEBUG, "Method '%.*js' not found in receiver %O\n", message->len, message->ptr, receiver);
|
|
||||||
moo_seterrbfmt (moo, MOO_ENOENT, "unable to find the method '%.*js' in %O", message->len, message->ptr, receiver);
|
|
||||||
return MOO_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
moo_oop_method_t moo_findmethod (moo_t* moo, moo_oop_t receiver, moo_oop_char_t selector, int in_super)
|
moo_oop_method_t moo_findmethod (moo_t* moo, moo_oop_t receiver, moo_oop_char_t selector, int in_super)
|
||||||
{
|
{
|
||||||
moo_oop_class_t _class;
|
moo_oop_class_t _class;
|
||||||
@ -1836,8 +1783,8 @@ not_found:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MOO_LOG3 (moo, MOO_LOG_DEBUG, "Method '%.*js' not found in receiver %O\n", message.len, message.ptr, receiver);
|
MOO_LOG4 (moo, MOO_LOG_DEBUG, "Method '%O>>%.*js' not found in receiver %O\n", _class, message.len, message.ptr, receiver);
|
||||||
moo_seterrbfmt (moo, MOO_ENOENT, "unable to find the method '%.*js' in %O", message.len, message.ptr, receiver);
|
moo_seterrbfmt (moo, MOO_ENOENT, "unable to find the method '%O>>%.*js' in %O", _class, message.len, message.ptr, receiver);
|
||||||
return MOO_NULL;
|
return MOO_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1858,29 +1805,38 @@ static int start_initial_process_and_context (moo_t* moo, const moo_oocs_t* objn
|
|||||||
moo_oop_context_t ctx;
|
moo_oop_context_t ctx;
|
||||||
moo_oop_method_t mth;
|
moo_oop_method_t mth;
|
||||||
moo_oop_process_t proc;
|
moo_oop_process_t proc;
|
||||||
|
moo_oow_t tmp_count = 0;
|
||||||
|
moo_oop_t sym_startup;
|
||||||
|
|
||||||
#if defined(INVOKE_DIRECTLY)
|
#if defined(INVOKE_DIRECTLY)
|
||||||
moo_oop_association_t ass;
|
moo_oop_association_t ass;
|
||||||
#else
|
#else
|
||||||
moo_oop_t s1, s2;
|
moo_oop_t s1, s2;
|
||||||
#endif
|
|
||||||
moo_oow_t tmp_count = 0;
|
|
||||||
|
|
||||||
moo_oocs_t startup;
|
|
||||||
static moo_ooch_t str_startup[] = { 's', 't', 'a', 'r', 't', 'u', 'p' };
|
static moo_ooch_t str_startup[] = { 's', 't', 'a', 'r', 't', 'u', 'p' };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(INVOKE_DIRECTLY)
|
#if defined(INVOKE_DIRECTLY)
|
||||||
|
|
||||||
ass = moo_lookupsysdic(moo, objname);
|
ass = moo_lookupsysdic(moo, objname);
|
||||||
if (!ass || MOO_CLASSOF(moo, ass->value) != moo->_class)
|
if (!ass || MOO_CLASSOF(moo, ass->value) != moo->_class)
|
||||||
{
|
{
|
||||||
MOO_LOG2 (moo, MOO_LOG_DEBUG, "Cannot find a class '%.*js'", objname->len, objname->ptr);
|
MOO_LOG2 (moo, MOO_LOG_DEBUG, "Cannot find a class '%.*js'", objname->len, objname->ptr);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sym_statup = moo_findsymbol(moo, mthname->ptr, mthname->len;
|
||||||
|
if (!sym_startup)
|
||||||
|
{
|
||||||
|
/* the method name should exist as a symbol in the system.
|
||||||
|
* otherwise, a method of such a name also doesn't exist */
|
||||||
|
MOO_LOG4 (moo, MOO_LOG_DEBUG, "Cannot find a startup method symbol %.*js>>%.*js", objname->len, objname->ptr, mthname->len, mthname->ptr);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
mth = moo_findmethowithstr(moo, ass->value, mthname, 0);
|
mth = moo_findmethod(moo, moo, ass->value, sym_startup, 0);
|
||||||
if (!mth)
|
if (!mth)
|
||||||
{
|
{
|
||||||
MOO_LOG4 (moo, MOO_LOG_DEBUG, "Cannot find a method %.*js>>%.*js", objname->len, objname->ptr, mthname->len, mthname->ptr);
|
MOO_LOG4 (moo, MOO_LOG_DEBUG, "Cannot find a startup method %.*js>>%.*js", objname->len, objname->ptr, mthname->len, mthname->ptr);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1898,9 +1854,16 @@ TODO: overcome this problem - accept parameters....
|
|||||||
moo_pushvolat (moo, (moo_oop_t*)&mth); tmp_count++;
|
moo_pushvolat (moo, (moo_oop_t*)&mth); tmp_count++;
|
||||||
moo_pushvolat (moo, (moo_oop_t*)&ass); tmp_count++;
|
moo_pushvolat (moo, (moo_oop_t*)&ass); tmp_count++;
|
||||||
#else
|
#else
|
||||||
startup.ptr = str_startup;
|
sym_startup = moo_findsymbol(moo, str_startup, MOO_COUNTOF(str_startup));
|
||||||
startup.len = 7;
|
if (!sym_startup)
|
||||||
mth = find_method_with_str(moo, (moo_oop_t)moo->_system, &startup, 0);
|
{
|
||||||
|
/* the method name should exist as a symbol in the system.
|
||||||
|
* otherwise, a method of such a name also doesn't exist */
|
||||||
|
MOO_LOG0 (moo, MOO_LOG_DEBUG, "Cannot find the startup method name symbol in the system class");
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
|
mth = moo_findmethod(moo, (moo_oop_t)moo->_system, (moo_oop_char_t)sym_startup, 0);
|
||||||
if (!mth)
|
if (!mth)
|
||||||
{
|
{
|
||||||
MOO_LOG0 (moo, MOO_LOG_DEBUG, "Cannot find the startup method in the system class");
|
MOO_LOG0 (moo, MOO_LOG_DEBUG, "Cannot find the startup method in the system class");
|
||||||
@ -1932,7 +1895,6 @@ TODO: overcome this problem - accept parameters....
|
|||||||
|
|
||||||
moo_pushvolat (moo, (moo_oop_t*)&ctx); tmp_count++;
|
moo_pushvolat (moo, (moo_oop_t*)&ctx); tmp_count++;
|
||||||
|
|
||||||
|
|
||||||
/* TODO: handle preamble */
|
/* TODO: handle preamble */
|
||||||
|
|
||||||
/* the initial context starts the life of the entire VM
|
/* the initial context starts the life of the entire VM
|
||||||
@ -4402,11 +4364,6 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* no byte code to execute - invoke 'self primitiveFailed' */
|
/* no byte code to execute - invoke 'self primitiveFailed' */
|
||||||
|
|
||||||
static moo_ooch_t prim_fail_msg[] = {
|
|
||||||
'p', 'r', 'i', 'm', 'i', 't', 'i', 'v', 'e',
|
|
||||||
'F', 'a', 'i', 'l', 'e', 'd'
|
|
||||||
};
|
|
||||||
moo_oow_t i;
|
moo_oow_t i;
|
||||||
|
|
||||||
if (stack_base != moo->sp - nargs - 1)
|
if (stack_base != moo->sp - nargs - 1)
|
||||||
@ -4432,12 +4389,12 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
|
|||||||
MOO_STACK_SET (moo, stack_base + 2, (moo_oop_t)method);
|
MOO_STACK_SET (moo, stack_base + 2, (moo_oop_t)method);
|
||||||
|
|
||||||
/* send primitiveFailed to self */
|
/* send primitiveFailed to self */
|
||||||
if (send_message_with_str (moo, prim_fail_msg, 15, nargs + 1) <= -1) return -1;
|
if (send_message(moo, moo->primitive_failed_sym, nargs + 1, 0) <= -1) return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* arrange to execute the method body */
|
/* arrange to execute the method body */
|
||||||
if (activate_new_method (moo, method, nargs) <= -1) return -1;
|
if (activate_new_method(moo, method, nargs) <= -1) return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -4447,7 +4404,7 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
|
|||||||
preamble_code == MOO_METHOD_PREAMBLE_RETURN_CONTEXT ||
|
preamble_code == MOO_METHOD_PREAMBLE_RETURN_CONTEXT ||
|
||||||
preamble_code == MOO_METHOD_PREAMBLE_EXCEPTION ||
|
preamble_code == MOO_METHOD_PREAMBLE_EXCEPTION ||
|
||||||
preamble_code == MOO_METHOD_PREAMBLE_ENSURE);
|
preamble_code == MOO_METHOD_PREAMBLE_ENSURE);
|
||||||
if (activate_new_method (moo, method, nargs) <= -1) return -1;
|
if (activate_new_method(moo, method, nargs) <= -1) return -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4468,27 +4425,18 @@ static int send_message (moo_t* moo, moo_oop_char_t selector, moo_ooi_t nargs, i
|
|||||||
|
|
||||||
method = moo_findmethod(moo, receiver, selector, to_super);
|
method = moo_findmethod(moo, receiver, selector, to_super);
|
||||||
if (!method)
|
if (!method)
|
||||||
{
|
{
|
||||||
static moo_ooch_t fbm[] = {
|
method = moo_findmethod(moo, receiver, moo->does_not_understand_sym, 0);
|
||||||
'd', 'o', 'e', 's',
|
|
||||||
'N', 'o', 't',
|
|
||||||
'U', 'n', 'd', 'e', 'r', 's', 't', 'a', 'n', 'd', ':'
|
|
||||||
};
|
|
||||||
moo_oocs_t mthname;
|
|
||||||
|
|
||||||
mthname.ptr = fbm;
|
|
||||||
mthname.len = 18;
|
|
||||||
|
|
||||||
method = find_method_with_str(moo, receiver, &mthname, 0);
|
|
||||||
if (!method)
|
if (!method)
|
||||||
{
|
{
|
||||||
/* this must not happen as long as doesNotUnderstand: is implemented under Apex.
|
/* this must not happen as long as doesNotUnderstand: is implemented under Apex.
|
||||||
* this check should indicate a very serious internal problem */
|
* this check should indicate a very serious internal problem */
|
||||||
MOO_LOG4 (moo, MOO_LOG_IC | MOO_LOG_FATAL,
|
MOO_LOG4 (moo, MOO_LOG_IC | MOO_LOG_FATAL,
|
||||||
"Fatal error - receiver [%O] of class [%O] does not understand a message [%.*js]\n",
|
"Fatal error - unable to find a fallback method [%O<<%.*js] for receiver [%O]\n",
|
||||||
receiver, MOO_CLASSOF(moo, receiver), mthname.len, mthname.ptr);
|
MOO_CLASSOF(moo, receiver), MOO_OBJ_GET_SIZE(moo->does_not_understand_sym), MOO_OBJ_GET_CHAR_SLOT(moo->does_not_understand_sym), receiver);
|
||||||
|
|
||||||
moo_seterrnum (moo, MOO_EMSGSND);
|
moo_seterrbfmt (moo, MOO_EMSGSND, "unable to find a fallback method - %O<<%.*js",
|
||||||
|
MOO_CLASSOF(moo, receiver), MOO_OBJ_GET_SIZE(moo->does_not_understand_sym), MOO_OBJ_GET_CHAR_SLOT(moo->does_not_understand_sym));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -4503,30 +4451,7 @@ static int send_message (moo_t* moo, moo_oop_char_t selector, moo_ooi_t nargs, i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return start_method (moo, method, nargs);
|
return start_method(moo, method, nargs);
|
||||||
}
|
|
||||||
|
|
||||||
static int send_message_with_str (moo_t* moo, const moo_ooch_t* nameptr, moo_oow_t namelen, moo_ooi_t nargs)
|
|
||||||
{
|
|
||||||
moo_oocs_t mthname;
|
|
||||||
moo_oop_t receiver;
|
|
||||||
moo_oop_method_t method;
|
|
||||||
|
|
||||||
receiver = MOO_STACK_GET(moo, moo->sp - nargs);
|
|
||||||
|
|
||||||
mthname.ptr = (moo_ooch_t*)nameptr;
|
|
||||||
mthname.len = namelen;
|
|
||||||
method = find_method_with_str(moo, receiver, &mthname, 0);
|
|
||||||
if (!method)
|
|
||||||
{
|
|
||||||
MOO_LOG4 (moo, MOO_LOG_IC | MOO_LOG_FATAL,
|
|
||||||
"Fatal error - receiver [%O] of class [%O] does not understand a private message [%.*js]\n",
|
|
||||||
receiver, MOO_CLASSOF(moo, receiver), mthname.len, mthname.ptr);
|
|
||||||
moo_seterrnum (moo, MOO_EMSGSND);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return start_method (moo, method, nargs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
@ -4935,16 +4860,12 @@ static MOO_INLINE int do_return (moo_t* moo, moo_oob_t bcode, moo_oop_t return_v
|
|||||||
|
|
||||||
if (unwind_protect)
|
if (unwind_protect)
|
||||||
{
|
{
|
||||||
static moo_ooch_t fbm[] = {
|
/* if ensure: is used over a non-local return, it should reach here.
|
||||||
'u', 'n', 'w', 'i', 'n', 'd', 'T', 'o', ':',
|
* [^10] ensure: [...] */
|
||||||
'r', 'e', 't', 'u', 'r', 'n', ':'
|
|
||||||
};
|
|
||||||
|
|
||||||
MOO_STACK_PUSH (moo, (moo_oop_t)unwind_start);
|
MOO_STACK_PUSH (moo, (moo_oop_t)unwind_start);
|
||||||
MOO_STACK_PUSH (moo, (moo_oop_t)unwind_stop);
|
MOO_STACK_PUSH (moo, (moo_oop_t)unwind_stop);
|
||||||
MOO_STACK_PUSH (moo, (moo_oop_t)return_value);
|
MOO_STACK_PUSH (moo, (moo_oop_t)return_value);
|
||||||
|
if (send_message(moo, moo->unwindto_return_sym, 2, 0) <= -1) return -1;
|
||||||
if (send_message_with_str(moo, fbm, 16, 2) <= -1) return -1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
20
moo/lib/gc.c
20
moo/lib/gc.c
@ -566,7 +566,10 @@ static int ignite_3 (moo_t* moo)
|
|||||||
static moo_ooch_t str_processor[] = { 'P', 'r', 'o', 'c', 'e', 's', 's', 'o', 'r' };
|
static moo_ooch_t str_processor[] = { 'P', 'r', 'o', 'c', 'e', 's', 's', 'o', 'r' };
|
||||||
static moo_ooch_t str_dicnew[] = { 'n', 'e', 'w', ':' };
|
static moo_ooch_t str_dicnew[] = { 'n', 'e', 'w', ':' };
|
||||||
static moo_ooch_t str_dicputassoc[] = { '_','_','p', 'u', 't', '_', 'a', 's', 's', 'o', 'c', ':' };
|
static moo_ooch_t str_dicputassoc[] = { '_','_','p', 'u', 't', '_', 'a', 's', 's', 'o', 'c', ':' };
|
||||||
|
static moo_ooch_t str_does_not_understand[] = { 'd', 'o', 'e', 's', 'N', 'o', 't', 'U', 'n', 'd', 'e', 'r', 's', 't', 'a', 'n', 'd', ':' };
|
||||||
|
static moo_ooch_t str_primitive_failed[] = { 'p', 'r', 'i', 'm', 'i', 't', 'i', 'v', 'e', 'F', 'a', 'i', 'l', 'e', 'd' };
|
||||||
|
static moo_ooch_t str_unwindto_return[] = { 'u', 'n', 'w', 'i', 'n', 'd', 'T', 'o', ':', 'r', 'e', 't', 'u', 'r', 'n', ':' };
|
||||||
|
|
||||||
moo_oow_t i;
|
moo_oow_t i;
|
||||||
moo_oop_t sym;
|
moo_oop_t sym;
|
||||||
moo_oop_class_t cls;
|
moo_oop_class_t cls;
|
||||||
@ -603,6 +606,18 @@ static int ignite_3 (moo_t* moo)
|
|||||||
if (!sym) return -1;
|
if (!sym) return -1;
|
||||||
moo->dicputassocsym = (moo_oop_char_t)sym;
|
moo->dicputassocsym = (moo_oop_char_t)sym;
|
||||||
|
|
||||||
|
sym = moo_makesymbol(moo, str_does_not_understand, MOO_COUNTOF(str_does_not_understand));
|
||||||
|
if (!sym) return -1;
|
||||||
|
moo->does_not_understand_sym = (moo_oop_char_t)sym;
|
||||||
|
|
||||||
|
sym = moo_makesymbol(moo, str_primitive_failed, MOO_COUNTOF(str_primitive_failed));
|
||||||
|
if (!sym) return -1;
|
||||||
|
moo->primitive_failed_sym = (moo_oop_char_t)sym;
|
||||||
|
|
||||||
|
sym = moo_makesymbol(moo, str_unwindto_return, MOO_COUNTOF(str_unwindto_return));
|
||||||
|
if (!sym) return -1;
|
||||||
|
moo->unwindto_return_sym = (moo_oop_char_t)sym;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -937,6 +952,9 @@ void moo_gc (moo_t* moo)
|
|||||||
moo->nil_process = (moo_oop_process_t)moo_moveoop(moo, (moo_oop_t)moo->nil_process);
|
moo->nil_process = (moo_oop_process_t)moo_moveoop(moo, (moo_oop_t)moo->nil_process);
|
||||||
moo->dicnewsym = (moo_oop_char_t)moo_moveoop(moo, (moo_oop_t)moo->dicnewsym);
|
moo->dicnewsym = (moo_oop_char_t)moo_moveoop(moo, (moo_oop_t)moo->dicnewsym);
|
||||||
moo->dicputassocsym = (moo_oop_char_t)moo_moveoop(moo, (moo_oop_t)moo->dicputassocsym);
|
moo->dicputassocsym = (moo_oop_char_t)moo_moveoop(moo, (moo_oop_t)moo->dicputassocsym);
|
||||||
|
moo->does_not_understand_sym = (moo_oop_char_t)moo_moveoop(moo, (moo_oop_t)moo->does_not_understand_sym);
|
||||||
|
moo->primitive_failed_sym = (moo_oop_char_t)moo_moveoop(moo, (moo_oop_t)moo->primitive_failed_sym);
|
||||||
|
moo->unwindto_return_sym = (moo_oop_char_t)moo_moveoop(moo, (moo_oop_t)moo->unwindto_return_sym);
|
||||||
|
|
||||||
for (i = 0; i < moo->sem_list_count; i++)
|
for (i = 0; i < moo->sem_list_count; i++)
|
||||||
{
|
{
|
||||||
|
@ -1491,7 +1491,11 @@ struct moo_t
|
|||||||
moo_oop_process_t nil_process; /* instance of Process */
|
moo_oop_process_t nil_process; /* instance of Process */
|
||||||
moo_oop_char_t dicnewsym; /* symbol new: for dictionary */
|
moo_oop_char_t dicnewsym; /* symbol new: for dictionary */
|
||||||
moo_oop_char_t dicputassocsym; /* symbol put_assoc: for dictionary */
|
moo_oop_char_t dicputassocsym; /* symbol put_assoc: for dictionary */
|
||||||
|
moo_oop_char_t does_not_understand_sym; /* symbol doesNotUnderstand: */
|
||||||
|
moo_oop_char_t primitive_failed_sym; /* symbol primitiveFailed */
|
||||||
|
moo_oop_char_t unwindto_return_sym; /* symbol unwindTo:return: */
|
||||||
|
|
||||||
|
|
||||||
/* pending asynchronous semaphores */
|
/* pending asynchronous semaphores */
|
||||||
moo_oop_semaphore_t* sem_list;
|
moo_oop_semaphore_t* sem_list;
|
||||||
moo_oow_t sem_list_count;
|
moo_oow_t sem_list_count;
|
||||||
|
@ -809,7 +809,7 @@ moo_pfrc_t moo_pf_responds_to (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
|||||||
return MOO_PF_FAILURE;
|
return MOO_PF_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (moo_findmethod(moo, rcv, selector, 0))
|
if (moo_findmethod(moo, rcv, (moo_oop_char_t)selector, 0))
|
||||||
{
|
{
|
||||||
MOO_STACK_SETRET (moo, nargs, moo->_true);
|
MOO_STACK_SETRET (moo, nargs, moo->_true);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user