touched up primitive failure handling in exec.c

This commit is contained in:
hyunghwan.chung 2017-05-08 16:00:55 +00:00
parent 95f3df6424
commit a1782753a9
8 changed files with 124 additions and 132 deletions

View File

@ -36,7 +36,6 @@ extend Apex
{ {
## ------------------------------------------------------- ## -------------------------------------------------------
## ------------------------------------------------------- ## -------------------------------------------------------
method(#dual) dump method(#dual) dump
{ {
<primitive: #_dump> <primitive: #_dump>
@ -44,29 +43,22 @@ extend Apex
## ------------------------------------------------------- ## -------------------------------------------------------
## ------------------------------------------------------- ## -------------------------------------------------------
method(#dual) yourself { ^self }
method(#dual) yourself
{
^self.
}
## ------------------------------------------------------- ## -------------------------------------------------------
## INSTANTIATION & INITIALIZATION ## INSTANTIATION & INITIALIZATION
## ------------------------------------------------------- ## -------------------------------------------------------
method(#class,#lenient) _basicNew method(#class,#primitive,#lenient) _basicNew.
{ method(#class,#primitive,#lenient) _basicNew: size.
<primitive: #_basic_new>
}
method(#class,#lenient) _basicNew: size
{
<primitive: #_basic_new>
}
method(#class,#primitive) basicNew.
method(#class,#primitive) basicNew: size.
(*
method(#class) basicNew method(#class) basicNew
{ {
| perr | | perr |
<primitive: #Apex__basicNew>
<primitive: #_basic_new>
self primitiveFailed. self primitiveFailed.
## perr := thisProcess primError. ## perr := thisProcess primError.
@ -77,93 +69,51 @@ extend Apex
method(#class) basicNew: size method(#class) basicNew: size
{ {
| perr | | perr |
<primitive: #Apex__basicNew:>
## <primitive: #_basicNew>
<primitive: #_basic_new>
self primitiveFailed. self primitiveFailed.
## perr := thisProcess primError. ## perr := thisProcess primError.
## if (perr == xxxx) { self cannotInstantiate } ## if (perr == xxxx) { self cannotInstantiate }
## else { self primitiveFailed }. ## else { self primitiveFailed }.
} }*)
method(#class) ngcNew
{
<primitive: #_ngc_new>
self primitiveFailed.
}
method(#class) ngcNew: anInteger
{
<primitive: #_ngc_new>
self primitiveFailed.
}
method(#class) new method(#class) new
{ {
| x | | x |
x := self basicNew. x := self basicNew.
x initialize. "TODO: assess if it's good to call 'initialize' from new." x initialize. ## TODO: assess if it's good to call 'initialize' from new
^x. ^x.
} }
method(#class) new: anInteger method(#class) new: anInteger
{ {
| x | | x |
## TODO: check if the class is a fixed class.
## if so, raise an exception.
x := self basicNew: anInteger. x := self basicNew: anInteger.
x initialize. "TODO: assess if it's good to call 'initialize' from new." x initialize. ## TODO: assess if it's good to call 'initialize' from new.
^x. ^x.
} }
method initialize method initialize
{ {
"a subclass may override this method." (* a subclass may override this method *)
^self. ^self.
} }
method ngcDispose
{
<primitive: #_ngc_dispose>
self primitiveFailed.
}
## ------------------------------------------------------- ## -------------------------------------------------------
## ------------------------------------------------------- ## -------------------------------------------------------
method shallowCopy ##method(#primitive,#lenient) _shallowCopy.
method(#dual) shallowCopy
{ {
<primitive: #_shallow_copy> <primitive: #_shallow_copy>
self primitiveFailed. self primitiveFailed.
} }
## ------------------------------------------------------- ## -------------------------------------------------------
## ------------------------------------------------------- ## -------------------------------------------------------
method(#dual,#primitive,#lenient) _basicSize.
method class method(#dual,#primitive) basicSize.
{
<primitive: #_class>
}
method(#class) class
{
<primitive: #_class>
^Class
}
## -------------------------------------------------------
## -------------------------------------------------------
method basicSize
{
<primitive: #_basic_size>
self primitiveFailed.
}
method(#class) basicSize
{
<primitive: #_basic_size>
self primitiveFailed.
}
method(#dual) basicAt: index method(#dual) basicAt: index
{ {
@ -237,6 +187,8 @@ extend Apex
* COMMON QUERIES * COMMON QUERIES
* ------------------------------------------------------------------ *) * ------------------------------------------------------------------ *)
method(#dual,#primitive) class.
method(#dual) isNil method(#dual) isNil
{ {
"^self == nil." "^self == nil."

View File

@ -35,9 +35,9 @@ class(#pointer) Class(Apex)
method specNumInstVars method specNumInstVars
{ {
## shift right by 7 bits. ## shift right by 8 bits.
## see moo-prv.h for details. ## see MOO_CLASS_SPEC_NAMED_INSTVARS in moo-prv.h for details.
^self.spec bitShift: -7 ^self.spec bitShift: -8
} }
(*method inheritsFrom: aSuperclass (*method inheritsFrom: aSuperclass

View File

@ -413,8 +413,23 @@ class ProhibitedMessageException(Exception)
extend Apex extend Apex
{ {
method(#dual) primitiveFailed method(#dual,#variadic) primitiveFailed()
{ {
| a b |
thisContext vargCount dump.
a := 1.
b := thisContext vargCount.
'PRIMITIVE FAILED............................................' dump.
self dump.
while (a < b)
{
(thisContext vargAt: a) dump.
a := a + 1.
}.
('PRIMITIVE FAILED....' & (thisContext vargAt: 0)) dump.
PrimitiveFailureException signal: 'PRIMITIVE FAILED'. PrimitiveFailureException signal: 'PRIMITIVE FAILED'.
} }

View File

@ -30,6 +30,7 @@ class MyObject(Object)
'data too large' 'data too large'
'message receiver error' 'message receiver error'
'message sending error' 'message sending error'
'wrong number of arguments'
'range error' 'range error'
'byte-code full' 'byte-code full'
'dictionary full' 'dictionary full'

View File

@ -50,22 +50,23 @@ static moo_ooch_t errstr_16[] = {'r','e','s','o','u','r','c','e',' ','t','e','m'
static moo_ooch_t errstr_17[] = {'d','a','t','a',' ','t','o','o',' ','l','a','r','g','e','\0'}; static moo_ooch_t errstr_17[] = {'d','a','t','a',' ','t','o','o',' ','l','a','r','g','e','\0'};
static moo_ooch_t errstr_18[] = {'m','e','s','s','a','g','e',' ','r','e','c','e','i','v','e','r',' ','e','r','r','o','r','\0'}; static moo_ooch_t errstr_18[] = {'m','e','s','s','a','g','e',' ','r','e','c','e','i','v','e','r',' ','e','r','r','o','r','\0'};
static moo_ooch_t errstr_19[] = {'m','e','s','s','a','g','e',' ','s','e','n','d','i','n','g',' ','e','r','r','o','r','\0'}; static moo_ooch_t errstr_19[] = {'m','e','s','s','a','g','e',' ','s','e','n','d','i','n','g',' ','e','r','r','o','r','\0'};
static moo_ooch_t errstr_20[] = {'r','a','n','g','e',' ','e','r','r','o','r','\0'}; static moo_ooch_t errstr_20[] = {'w','r','o','n','g',' ','n','u','m','b','e','r',' ','o','f',' ','a','r','g','u','m','e','n','t','s','\0'};
static moo_ooch_t errstr_21[] = {'b','y','t','e','-','c','o','d','e',' ','f','u','l','l','\0'}; static moo_ooch_t errstr_21[] = {'r','a','n','g','e',' ','e','r','r','o','r','\0'};
static moo_ooch_t errstr_22[] = {'d','i','c','t','i','o','n','a','r','y',' ','f','u','l','l','\0'}; static moo_ooch_t errstr_22[] = {'b','y','t','e','-','c','o','d','e',' ','f','u','l','l','\0'};
static moo_ooch_t errstr_23[] = {'p','r','o','c','e','s','s','o','r',' ','f','u','l','l','\0'}; static moo_ooch_t errstr_23[] = {'d','i','c','t','i','o','n','a','r','y',' ','f','u','l','l','\0'};
static moo_ooch_t errstr_24[] = {'s','e','m','a','p','h','o','r','e',' ','h','e','a','p',' ','f','u','l','l','\0'}; static moo_ooch_t errstr_24[] = {'p','r','o','c','e','s','s','o','r',' ','f','u','l','l','\0'};
static moo_ooch_t errstr_25[] = {'s','e','m','a','p','h','o','r','e',' ','l','i','s','t',' ','f','u','l','l','\0'}; static moo_ooch_t errstr_25[] = {'s','e','m','a','p','h','o','r','e',' ','h','e','a','p',' ','f','u','l','l','\0'};
static moo_ooch_t errstr_26[] = {'d','i','v','i','d','e',' ','b','y',' ','z','e','r','o','\0'}; static moo_ooch_t errstr_26[] = {'s','e','m','a','p','h','o','r','e',' ','l','i','s','t',' ','f','u','l','l','\0'};
static moo_ooch_t errstr_27[] = {'I','/','O',' ','e','r','r','o','r','\0'}; static moo_ooch_t errstr_27[] = {'d','i','v','i','d','e',' ','b','y',' ','z','e','r','o','\0'};
static moo_ooch_t errstr_28[] = {'e','n','c','o','d','i','n','g',' ','c','o','n','v','e','r','s','i','o','n',' ','e','r','r','o','r','\0'}; static moo_ooch_t errstr_28[] = {'I','/','O',' ','e','r','r','o','r','\0'};
static moo_ooch_t errstr_29[] = {'b','u','f','f','e','r',' ','f','u','l','l','\0'}; static moo_ooch_t errstr_29[] = {'e','n','c','o','d','i','n','g',' ','c','o','n','v','e','r','s','i','o','n',' ','e','r','r','o','r','\0'};
static moo_ooch_t errstr_30[] = {'b','u','f','f','e','r',' ','f','u','l','l','\0'};
static moo_ooch_t* errstr[] = static moo_ooch_t* errstr[] =
{ {
errstr_0, errstr_1, errstr_2, errstr_3, errstr_4, errstr_5, errstr_6, errstr_7, errstr_0, errstr_1, errstr_2, errstr_3, errstr_4, errstr_5, errstr_6, errstr_7,
errstr_8, errstr_9, errstr_10, errstr_11, errstr_12, errstr_13, errstr_14, errstr_15, errstr_8, errstr_9, errstr_10, errstr_11, errstr_12, errstr_13, errstr_14, errstr_15,
errstr_16, errstr_17, errstr_18, errstr_19, errstr_20, errstr_21, errstr_22, errstr_23, errstr_16, errstr_17, errstr_18, errstr_19, errstr_20, errstr_21, errstr_22, errstr_23,
errstr_24, errstr_25, errstr_26, errstr_27, errstr_28, errstr_29 errstr_24, errstr_25, errstr_26, errstr_27, errstr_28, errstr_29, errstr_30
}; };
#if defined(MOO_INCLUDE_COMPILER) #if defined(MOO_INCLUDE_COMPILER)

View File

@ -109,6 +109,7 @@
static void signal_io_semaphore (moo_t* moo, moo_ooi_t mask, void* ctx); static void signal_io_semaphore (moo_t* moo, moo_ooi_t mask, void* ctx);
static int send_message (moo_t* moo, moo_oop_char_t selector, int to_super, moo_ooi_t nargs); static int send_message (moo_t* moo, moo_oop_char_t selector, int to_super, moo_ooi_t nargs);
static int send_private_message (moo_t* moo, const moo_ooch_t* nameptr, moo_oow_t namelen, int to_super, moo_ooi_t nargs);
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
static MOO_INLINE int vm_startup (moo_t* moo) static MOO_INLINE int vm_startup (moo_t* moo)
@ -1414,6 +1415,8 @@ static moo_pfrc_t _equal_objects (moo_t* moo, moo_ooi_t nargs)
/* MOO_OBJ_TYPE_OOP, ... */ /* MOO_OBJ_TYPE_OOP, ... */
MOO_DEBUG1 (moo, "<_equal_objects> Cannot compare objects of type %d\n", (int)MOO_OBJ_GET_FLAGS_TYPE(rcv)); MOO_DEBUG1 (moo, "<_equal_objects> Cannot compare objects of type %d\n", (int)MOO_OBJ_GET_FLAGS_TYPE(rcv));
moo->errnum = MOO_ENOIMPL; /* TODO: better error code */
return -1; return -1;
} }
} }
@ -1430,6 +1433,7 @@ static moo_pfrc_t pf_equal (moo_t* moo, moo_ooi_t nargs)
MOO_STACK_SETRET (moo, nargs, (n? moo->_true: moo->_false)); MOO_STACK_SETRET (moo, nargs, (n? moo->_true: moo->_false));
return MOO_PF_SUCCESS; return MOO_PF_SUCCESS;
} }
static moo_pfrc_t pf_not_equal (moo_t* moo, moo_ooi_t nargs) static moo_pfrc_t pf_not_equal (moo_t* moo, moo_ooi_t nargs)
{ {
int n; int n;
@ -1444,14 +1448,8 @@ static moo_pfrc_t pf_not_equal (moo_t* moo, moo_ooi_t nargs)
static moo_pfrc_t pf_class (moo_t* moo, moo_ooi_t nargs) static moo_pfrc_t pf_class (moo_t* moo, moo_ooi_t nargs)
{ {
moo_oop_t rcv; moo_oop_t rcv;
moo_oop_class_t _class;
MOO_ASSERT (moo, nargs == 0);
rcv = MOO_STACK_GETRCV(moo, nargs); rcv = MOO_STACK_GETRCV(moo, nargs);
_class = MOO_CLASSOF(moo, rcv); MOO_STACK_SETRET (moo, nargs, (moo_oop_t)MOO_CLASSOF(moo, rcv));
MOO_STACK_SETRET (moo, nargs, (moo_oop_t)_class);
return MOO_PF_SUCCESS; return MOO_PF_SUCCESS;
} }
@ -1465,7 +1463,7 @@ static MOO_INLINE moo_pfrc_t pf_basic_new (moo_t* moo, moo_ooi_t nargs)
if (MOO_CLASSOF(moo, _class) != moo->_class) if (MOO_CLASSOF(moo, _class) != moo->_class)
{ {
/* the receiver is not a class object */ /* the receiver is not a class object */
MOO_DEBUG0 (moo, "<pf_basic_new> Receiver is not a class\n"); MOO_DEBUG1 (moo, "<pf_basic_new> Receiver is not a class - %O\n", _class);
moo->errnum = MOO_EMSGRCV; moo->errnum = MOO_EMSGRCV;
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
} }
@ -1473,7 +1471,7 @@ static MOO_INLINE moo_pfrc_t pf_basic_new (moo_t* moo, moo_ooi_t nargs)
/* check if #limited is set on the class */ /* check if #limited is set on the class */
if (MOO_CLASS_SELFSPEC_FLAGS(MOO_OOP_TO_SMOOI(_class->selfspec)) & MOO_CLASS_SELFSPEC_FLAG_LIMITED) if (MOO_CLASS_SELFSPEC_FLAGS(MOO_OOP_TO_SMOOI(_class->selfspec)) & MOO_CLASS_SELFSPEC_FLAG_LIMITED)
{ {
MOO_DEBUG0 (moo, "<pf_basic_new> Receiver is #limited\n"); MOO_DEBUG1 (moo, "<pf_basic_new> Receiver is #limited - %O\n", _class);
moo->errnum = MOO_EPERM; moo->errnum = MOO_EPERM;
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
} }
@ -1508,29 +1506,6 @@ static MOO_INLINE moo_pfrc_t pf_basic_new (moo_t* moo, moo_ooi_t nargs)
return MOO_PF_SUCCESS; return MOO_PF_SUCCESS;
} }
static moo_pfrc_t pf_ngc_new (moo_t* moo, moo_ooi_t nargs)
{
/* TODO: implement this.
* if NGC is allowed for non-OOP objects, GC issues get very simple.
*
* also allow NGC code in non-safe mode. in safe mode, ngc_new is same as normal new.
* ngc_dispose should not do anything in safe mode. */
return pf_basic_new (moo, nargs);
}
static moo_pfrc_t pf_ngc_dispose (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t rcv;
MOO_ASSERT (moo, nargs == 0);
rcv = MOO_STACK_GETRCV (moo, nargs);
moo_freemem (moo, rcv);
MOO_STACK_SETRET (moo, nargs, moo->_nil);
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_shallow_copy (moo_t* moo, moo_ooi_t nargs) static moo_pfrc_t pf_shallow_copy (moo_t* moo, moo_ooi_t nargs)
{ {
moo_oop_t rcv, obj; moo_oop_t rcv, obj;
@ -1785,7 +1760,7 @@ static moo_pfrc_t pf_hash (moo_t* moo, moo_ooi_t nargs)
default: default:
/* MOO_OBJ_TYPE_OOP, ... */ /* MOO_OBJ_TYPE_OOP, ... */
MOO_DEBUG1 (moo, "<pf_hash> Cannot hash an object of type %d\n", type); MOO_DEBUG1 (moo, "<pf_hash> Cannot hash an object of type %d\n", type);
moo->errnum = MOO_EINVAL; moo->errnum = MOO_ENOIMPL; /* TODO: better error code? */
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
} }
break; break;
@ -1872,6 +1847,7 @@ static moo_pfrc_t pf_exceptionize_error (moo_t* moo, moo_ooi_t nargs)
/* the receiver is a special numeric object, not a normal pointer. /* the receiver is a special numeric object, not a normal pointer.
* excceptionization is not supported for small integers, characters, and errors. * excceptionization is not supported for small integers, characters, and errors.
* first of all, methods of these classes must not return errors */ * first of all, methods of these classes must not return errors */
moo->errnum = MOO_EMSGRCV;
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
} }
@ -1898,6 +1874,7 @@ static moo_pfrc_t pf_context_goto (moo_t* moo, moo_ooi_t nargs)
{ {
MOO_LOG2 (moo, MOO_LOG_PRIMITIVE | MOO_LOG_ERROR, MOO_LOG2 (moo, MOO_LOG_PRIMITIVE | MOO_LOG_ERROR,
"Error(%hs) - invalid receiver, not a method context - %O\n", __PRIMITIVE_NAME__, rcv); "Error(%hs) - invalid receiver, not a method context - %O\n", __PRIMITIVE_NAME__, rcv);
moo->errnum = MOO_EMSGRCV;
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
} }
@ -1906,6 +1883,7 @@ static moo_pfrc_t pf_context_goto (moo_t* moo, moo_ooi_t nargs)
{ {
MOO_LOG1 (moo, MOO_LOG_PRIMITIVE | MOO_LOG_ERROR, MOO_LOG1 (moo, MOO_LOG_PRIMITIVE | MOO_LOG_ERROR,
"Error(%hs) - invalid pc\n", __PRIMITIVE_NAME__); "Error(%hs) - invalid pc\n", __PRIMITIVE_NAME__);
moo->errnum = MOO_EINVAL;
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
} }
@ -1951,6 +1929,8 @@ static moo_pfrc_t __block_value (moo_t* moo, moo_oop_context_t rcv_blkctx, moo_o
MOO_ASSERT (moo, MOO_OBJ_GET_SIZE(rcv_blkctx) > MOO_CONTEXT_NAMED_INSTVARS); MOO_ASSERT (moo, MOO_OBJ_GET_SIZE(rcv_blkctx) > MOO_CONTEXT_NAMED_INSTVARS);
MOO_LOG2 (moo, MOO_LOG_PRIMITIVE | MOO_LOG_ERROR, MOO_LOG2 (moo, MOO_LOG_PRIMITIVE | MOO_LOG_ERROR,
"Error(%hs) - re-valuing of a block context - %O\n", __PRIMITIVE_NAME__, rcv_blkctx); "Error(%hs) - re-valuing of a block context - %O\n", __PRIMITIVE_NAME__, rcv_blkctx);
moo->errnum = MOO_EPERM;
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
} }
MOO_ASSERT (moo, MOO_OBJ_GET_SIZE(rcv_blkctx) == MOO_CONTEXT_NAMED_INSTVARS); MOO_ASSERT (moo, MOO_OBJ_GET_SIZE(rcv_blkctx) == MOO_CONTEXT_NAMED_INSTVARS);
@ -1960,6 +1940,8 @@ static moo_pfrc_t __block_value (moo_t* moo, moo_oop_context_t rcv_blkctx, moo_o
MOO_LOG4 (moo, MOO_LOG_PRIMITIVE | MOO_LOG_ERROR, MOO_LOG4 (moo, MOO_LOG_PRIMITIVE | MOO_LOG_ERROR,
"Error(%hs) - wrong number of arguments to a block context %O - %zd expected, %zd given\n", "Error(%hs) - wrong number of arguments to a block context %O - %zd expected, %zd given\n",
__PRIMITIVE_NAME__, rcv_blkctx, MOO_OOP_TO_SMOOI(rcv_blkctx->method_or_nargs), actual_arg_count); __PRIMITIVE_NAME__, rcv_blkctx, MOO_OOP_TO_SMOOI(rcv_blkctx->method_or_nargs), actual_arg_count);
moo->errnum = MOO_ENUMARGS;
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
} }
@ -1974,7 +1956,10 @@ static moo_pfrc_t __block_value (moo_t* moo, moo_oop_context_t rcv_blkctx, moo_o
moo_pushtmp (moo, (moo_oop_t*)&rcv_blkctx); moo_pushtmp (moo, (moo_oop_t*)&rcv_blkctx);
blkctx = (moo_oop_context_t) moo_instantiate (moo, moo->_block_context, MOO_NULL, local_ntmprs); blkctx = (moo_oop_context_t) moo_instantiate (moo, moo->_block_context, MOO_NULL, local_ntmprs);
moo_poptmp (moo); moo_poptmp (moo);
if (!blkctx) return MOO_PF_HARD_FAILURE; if (!blkctx)
{
return MOO_PF_FAILURE;
}
#if 0 #if 0
/* shallow-copy the named part including home, origin, etc. */ /* shallow-copy the named part including home, origin, etc. */
@ -2035,6 +2020,7 @@ static moo_pfrc_t pf_block_value (moo_t* moo, moo_ooi_t nargs)
/* the receiver must be a block context */ /* the receiver must be a block context */
MOO_LOG2 (moo, MOO_LOG_PRIMITIVE | MOO_LOG_ERROR, MOO_LOG2 (moo, MOO_LOG_PRIMITIVE | MOO_LOG_ERROR,
"Error(%hs) - invalid receiver, not a block context - %O\n", __PRIMITIVE_NAME__, rcv_blkctx); "Error(%hs) - invalid receiver, not a block context - %O\n", __PRIMITIVE_NAME__, rcv_blkctx);
moo->errnum = MOO_EMSGRCV;
return MOO_PF_FAILURE; return MOO_PF_FAILURE;
} }
@ -3686,14 +3672,11 @@ static pf_t pftab[] =
{ "_not_identical", { pf_not_identical, 1, 1 } }, { "_not_identical", { pf_not_identical, 1, 1 } },
{ "_equal", { pf_equal, 1, 1 } }, { "_equal", { pf_equal, 1, 1 } },
{ "_not_equal", { pf_not_equal, 1, 1 } }, { "_not_equal", { pf_not_equal, 1, 1 } },
{ "_class", { pf_class, 0, 0 } },
{ "_basic_new", { pf_basic_new, 0, 1 } },
{ "_ngc_new", { pf_ngc_new, 0, 1 } },
{ "_ngc_dispose", { pf_ngc_dispose, 0, 0 } },
{ "_shallow_copy", { pf_shallow_copy, 0, 0 } }, { "_shallow_copy", { pf_shallow_copy, 0, 0 } },
{ "_basic_size", { pf_basic_size, 0, 0 } },
{ "_basic_at", { pf_basic_at, 1, 1 } }, { "_basic_at", { pf_basic_at, 1, 1 } },
{ "_basic_at_put", { pf_basic_at_put, 2, 2 } }, { "_basic_at_put", { pf_basic_at_put, 2, 2 } },
@ -3742,6 +3725,14 @@ static pf_t pftab[] =
{ "_integer_ge", { pf_integer_ge, 1, 1 } }, { "_integer_ge", { pf_integer_ge, 1, 1 } },
{ "_integer_inttostr", { pf_integer_inttostr, 1, 1 } }, { "_integer_inttostr", { pf_integer_inttostr, 1, 1 } },
{ "Apex__basicNew", { pf_basic_new, 0, 0 } },
{ "Apex__basicNew:", { pf_basic_new, 1, 1 } },
{ "Apex__basicSize", { pf_basic_size, 0, 0 } },
{ "Apex_basicNew", { pf_basic_new, 0, 0 } },
{ "Apex_basicNew:", { pf_basic_new, 1, 1 } },
{ "Apex_basicSize", { pf_basic_size, 0, 0 } },
{ "Apex_class", { pf_class, 0, 0 } },
{ "Character_asInteger", { pf_character_as_smooi, 0, 0 } }, { "Character_asInteger", { pf_character_as_smooi, 0, 0 } },
{ "Error_asCharacter", { pf_error_as_character, 0, 0 } }, { "Error_asCharacter", { pf_error_as_character, 0, 0 } },
@ -3957,6 +3948,7 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
{ {
MOO_DEBUG4 (moo, "Soft failure due to argument count mismatch for primitive function %hs - %zu-%zu expected, %zu given\n", MOO_DEBUG4 (moo, "Soft failure due to argument count mismatch for primitive function %hs - %zu-%zu expected, %zu given\n",
pftab[pfnum].name, pftab[pfnum].pfbase.minargs, pftab[pfnum].pfbase.maxargs, nargs); pftab[pfnum].name, pftab[pfnum].pfbase.minargs, pftab[pfnum].pfbase.maxargs, nargs);
moo->errnum = MOO_ENUMARGS;
goto activate_primitive_method_body; goto activate_primitive_method_body;
} }
@ -3974,8 +3966,8 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
} }
else else
{ {
moo->errnum = MOO_EINVAL; moo->errnum = MOO_ENOENT;
MOO_DEBUG1 (moo, "Cannot call primitive function numbered %zd - invalid number\n", pfnum); MOO_DEBUG1 (moo, "Cannot call primitive function numbered %zd - unknown primitive function number\n", pfnum);
} }
goto activate_primitive_method_body; goto activate_primitive_method_body;
@ -3997,10 +3989,10 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
#if !defined(NDEBUG) #if !defined(NDEBUG)
LOG_INST_1 (moo, "preamble_named_primitive %zd", pf_name_index); LOG_INST_1 (moo, "preamble_named_primitive %zd", pf_name_index);
#endif
MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(pfname)); MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(pfname));
MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_EXTRA(pfname)); MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_EXTRA(pfname));
MOO_ASSERT (moo, MOO_CLASSOF(moo,pfname) == moo->_symbol); MOO_ASSERT (moo, MOO_CLASSOF(moo,pfname) == moo->_symbol);
#endif
/* merge two SmallIntegers to get a full pointer from the cached data */ /* merge two SmallIntegers to get a full pointer from the cached data */
w = (moo_oow_t)MOO_OOP_TO_SMOOI(method->preamble_data[0]) << (MOO_OOW_BITS / 2) | w = (moo_oow_t)MOO_OOP_TO_SMOOI(method->preamble_data[0]) << (MOO_OOW_BITS / 2) |
@ -4022,6 +4014,8 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
{ {
MOO_DEBUG5 (moo, "Soft failure due to argument count mismatch for primitive function %.*js - %zu-%zu expected, %zu given\n", MOO_DEBUG5 (moo, "Soft failure due to argument count mismatch for primitive function %.*js - %zu-%zu expected, %zu given\n",
MOO_OBJ_GET_SIZE(pfname), MOO_OBJ_GET_CHAR_SLOT(pfname), pfbase->minargs, pfbase->maxargs, nargs); MOO_OBJ_GET_SIZE(pfname), MOO_OBJ_GET_CHAR_SLOT(pfname), pfbase->minargs, pfbase->maxargs, nargs);
moo->errnum = MOO_ENUMARGS;
goto activate_primitive_method_body; goto activate_primitive_method_body;
} }
@ -4055,25 +4049,28 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
activate_primitive_method_body: activate_primitive_method_body:
if (MOO_METHOD_GET_PREAMBLE_FLAGS(preamble) & MOO_METHOD_PREAMBLE_FLAG_LENIENT) if (MOO_METHOD_GET_PREAMBLE_FLAGS(preamble) & MOO_METHOD_PREAMBLE_FLAG_LENIENT)
{ {
/* convert a soft failure to error return */ /* convert soft failure to error return */
moo->sp = stack_base; moo->sp = stack_base;
MOO_STACK_PUSH (moo, MOO_ERROR_TO_OOP(moo->errnum)); MOO_STACK_PUSH (moo, MOO_ERROR_TO_OOP(moo->errnum));
break; break;
} }
/* set the error number in the current process for 'thisProcess primError' */
moo->processor->active->perr = MOO_ERROR_TO_OOP(moo->errnum); moo->processor->active->perr = MOO_ERROR_TO_OOP(moo->errnum);
#if defined(MOO_USE_METHOD_TRAILER) #if defined(MOO_USE_METHOD_TRAILER)
MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_TRAILER(method)); MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_TRAILER(method));
if (MOO_METHOD_GET_CODE_SIZE(method) == 0) /* this trailer size field not a small integer */ if (MOO_METHOD_GET_CODE_SIZE(method) == 0) /* this trailer size field is not a small integer */
#else #else
if (method->code == moo->_nil) if (method->code == moo->_nil)
#endif #endif
{ {
/* no byte code to execute - make it a hard failure */ /* no byte code to execute - make it a hard failure */
#if 0
/* TODO: what is the best tactics? emulate "self primitiveFailed"? or should this be generated by the compiler /* TODO: what is the best tactics? emulate "self primitiveFailed"? or should this be generated by the compiler
* the compiler produces no code for the body of a method(#primitive). so it will reach here if it fails when executed. */ * the compiler produces no code for the body of a method(#primitive). so it will reach here if it fails when executed. */
MOO_DEBUG0 (moo, "Empty primitive body\n"); MOO_DEBUG2 (moo, "Empty primitive body - %.*js\n", MOO_OBJ_GET_SIZE(method->name), MOO_OBJ_GET_CHAR_SLOT(method->name));
moo->sp = stack_base; /* force restore stack pointer */ moo->sp = stack_base; /* force restore stack pointer */
MOO_STACK_PUSH (moo, moo->_nil); MOO_STACK_PUSH (moo, moo->_nil);
@ -4081,6 +4078,27 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
/* i assume that the failed primitive handler function set the error number. /* i assume that the failed primitive handler function set the error number.
* so i don't set it here */ * so i don't set it here */
return -1; return -1;
#else
/* emulate '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_DEBUG2 (moo, "Sending primitiveFailed for empty primitive body - %.*js\n", MOO_OBJ_GET_SIZE(method->name), MOO_OBJ_GET_CHAR_SLOT(method->name));
////// //moo->sp = stack_base + 1; /* keep the receiver only. drop all arguments */
//if the primitive handler function screwed the stack??? partially popped??? can't handle excessive pops...
MOO_STACK_PUSH (moo, moo->_nil); /* fake */
for (i = moo->sp; i > stack_base + 2; i--) MOO_STACK_SET (moo, i, MOO_STACK_GET(moo, i - 1));
MOO_STACK_SET (moo, stack_base + 2, (moo_oop_t)method->name);
if (send_private_message (moo, prim_fail_msg, 15, 0, nargs + 1) <= -1) return -1;
break;
#endif
} }
if (activate_new_method (moo, method, nargs) <= -1) return -1; if (activate_new_method (moo, method, nargs) <= -1) return -1;
@ -4173,6 +4191,7 @@ static int send_private_message (moo_t* moo, const moo_ooch_t* nameptr, moo_oow_
return start_method (moo, method, nargs); return start_method (moo, method, nargs);
} }
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
static MOO_INLINE int switch_process_if_needed (moo_t* moo) static MOO_INLINE int switch_process_if_needed (moo_t* moo)

View File

@ -156,8 +156,8 @@
(((moo_oow_t)(indexed_type)) << 2) | (((moo_oow_t)flags) & 3) ) (((moo_oow_t)(indexed_type)) << 2) | (((moo_oow_t)flags) & 3) )
/* what is the number of named instance variables? /* what is the number of named instance variables?
* MOO_CLASS_SPEC_NAMED_INSTVARS(MOO_OOP_TO_SMOOI(_class->spec)) * MOO_CLASS_SPEC_NAMED_INSTVARS(MOO_OOP_TO_SMOOI(_class->spec))
*/ * ensure to update Class<<specNumInstVars if you change this macro. */
#define MOO_CLASS_SPEC_NAMED_INSTVARS(spec) \ #define MOO_CLASS_SPEC_NAMED_INSTVARS(spec) \
(((moo_oow_t)(spec)) >> (MOO_OBJ_FLAGS_TYPE_BITS + 2)) (((moo_oow_t)(spec)) >> (MOO_OBJ_FLAGS_TYPE_BITS + 2))

View File

@ -67,6 +67,7 @@ enum moo_errnum_t
MOO_ETOOBIG, /**< data too large */ MOO_ETOOBIG, /**< data too large */
MOO_EMSGRCV, /**< mesasge receiver error */ MOO_EMSGRCV, /**< mesasge receiver error */
MOO_EMSGSND, /**< message sending error. even doesNotUnderstand: is not found */ MOO_EMSGSND, /**< message sending error. even doesNotUnderstand: is not found */
MOO_ENUMARGS, /**< wrong number of arguments */
MOO_ERANGE, /**< range error. overflow and underflow */ MOO_ERANGE, /**< range error. overflow and underflow */
MOO_EBCFULL, /**< byte-code full */ MOO_EBCFULL, /**< byte-code full */
MOO_EDFULL, /**< dictionary full */ MOO_EDFULL, /**< dictionary full */
@ -1128,7 +1129,7 @@ struct moo_t
#define MOO_STACK_PUSH(moo,v) \ #define MOO_STACK_PUSH(moo,v) \
do { \ do { \
(moo)->sp = (moo)->sp + 1; \ (moo)->sp = (moo)->sp + 1; \
MOO_ASSERT (moo, (moo)->sp < (unsigned int)(MOO_OBJ_GET_SIZE((moo)->processor->active) - MOO_PROCESS_NAMED_INSTVARS)); \ MOO_ASSERT (moo, (moo)->sp < (moo_ooi_t)(MOO_OBJ_GET_SIZE((moo)->processor->active) - MOO_PROCESS_NAMED_INSTVARS)); \
(moo)->processor->active->slot[(moo)->sp] = v; \ (moo)->processor->active->slot[(moo)->sp] = v; \
} while (0) } while (0)
@ -1142,8 +1143,11 @@ struct moo_t
#define MOO_STACK_POPS(moo,count) ((moo)->sp = (moo)->sp - (count)) #define MOO_STACK_POPS(moo,count) ((moo)->sp = (moo)->sp - (count))
#define MOO_STACK_ISEMPTY(moo) ((moo)->sp <= -1) #define MOO_STACK_ISEMPTY(moo) ((moo)->sp <= -1)
/* get the stack pointer of the argument at the given index */
#define MOO_STACK_GETARGSP(moo,nargs,idx) ((moo)->sp - ((nargs) - (idx) - 1)) #define MOO_STACK_GETARGSP(moo,nargs,idx) ((moo)->sp - ((nargs) - (idx) - 1))
/* get the argument at the given index */
#define MOO_STACK_GETARG(moo,nargs,idx) MOO_STACK_GET(moo, (moo)->sp - ((nargs) - (idx) - 1)) #define MOO_STACK_GETARG(moo,nargs,idx) MOO_STACK_GET(moo, (moo)->sp - ((nargs) - (idx) - 1))
/* get the receiver of a message */
#define MOO_STACK_GETRCV(moo,nargs) MOO_STACK_GET(moo, (moo)->sp - nargs) #define MOO_STACK_GETRCV(moo,nargs) MOO_STACK_GET(moo, (moo)->sp - nargs)
/* you can't access arguments and receiver after this macro. /* you can't access arguments and receiver after this macro.