added a new method modifier #lenient that applies to a primitive method. when set, it turns soft failure to error return
This commit is contained in:
parent
f45cde7ba7
commit
937895ef59
@ -2,7 +2,7 @@ class Apex(nil)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
class Error(Apex)
|
class(#limited) Error(Apex)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,12 +37,7 @@ extend Apex
|
|||||||
## -------------------------------------------------------
|
## -------------------------------------------------------
|
||||||
## -------------------------------------------------------
|
## -------------------------------------------------------
|
||||||
|
|
||||||
method(#class) dump
|
method(#dual) dump
|
||||||
{
|
|
||||||
<primitive: #_dump>
|
|
||||||
}
|
|
||||||
|
|
||||||
method dump
|
|
||||||
{
|
{
|
||||||
<primitive: #_dump>
|
<primitive: #_dump>
|
||||||
}
|
}
|
||||||
@ -50,12 +45,7 @@ extend Apex
|
|||||||
## -------------------------------------------------------
|
## -------------------------------------------------------
|
||||||
## -------------------------------------------------------
|
## -------------------------------------------------------
|
||||||
|
|
||||||
method(#class) yourself
|
method(#dual) yourself
|
||||||
{
|
|
||||||
^self.
|
|
||||||
}
|
|
||||||
|
|
||||||
method yourself
|
|
||||||
{
|
{
|
||||||
^self.
|
^self.
|
||||||
}
|
}
|
||||||
@ -63,6 +53,15 @@ extend Apex
|
|||||||
## -------------------------------------------------------
|
## -------------------------------------------------------
|
||||||
## INSTANTIATION & INITIALIZATION
|
## INSTANTIATION & INITIALIZATION
|
||||||
## -------------------------------------------------------
|
## -------------------------------------------------------
|
||||||
|
method(#class,#lenient) _basicNew
|
||||||
|
{
|
||||||
|
<primitive: #_basic_new>
|
||||||
|
}
|
||||||
|
method(#class,#lenient) _basicNew: size
|
||||||
|
{
|
||||||
|
<primitive: #_basic_new>
|
||||||
|
}
|
||||||
|
|
||||||
method(#class) basicNew
|
method(#class) basicNew
|
||||||
{
|
{
|
||||||
| perr |
|
| perr |
|
||||||
@ -79,6 +78,7 @@ extend Apex
|
|||||||
{
|
{
|
||||||
| perr |
|
| perr |
|
||||||
|
|
||||||
|
## <primitive: #_basicNew>
|
||||||
<primitive: #_basic_new>
|
<primitive: #_basic_new>
|
||||||
self primitiveFailed.
|
self primitiveFailed.
|
||||||
|
|
||||||
|
@ -339,7 +339,7 @@ class(#pointer) CompiledMethod(Object)
|
|||||||
method preambleCode
|
method preambleCode
|
||||||
{
|
{
|
||||||
(* TODO: make this a primtive for performance *)
|
(* TODO: make this a primtive for performance *)
|
||||||
^(self.preamble bitAnd: 16rFF) bitShift: -3.
|
^(self.preamble bitShift: -4) bitAnd: 16r1F.
|
||||||
}
|
}
|
||||||
|
|
||||||
method owner
|
method owner
|
||||||
|
@ -43,7 +43,7 @@ class Association(Magnitude)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Character(Magnitude)
|
class(#limited) Character(Magnitude)
|
||||||
{
|
{
|
||||||
## method basicSize
|
## method basicSize
|
||||||
## {
|
## {
|
||||||
@ -53,7 +53,7 @@ class Character(Magnitude)
|
|||||||
method(#primitive) asInteger.
|
method(#primitive) asInteger.
|
||||||
}
|
}
|
||||||
|
|
||||||
class Number(Magnitude)
|
class(#limited) Number(Magnitude)
|
||||||
{
|
{
|
||||||
method + aNumber
|
method + aNumber
|
||||||
{
|
{
|
||||||
@ -300,7 +300,7 @@ class(#limited) Integer(Number)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SmallInteger(Integer)
|
class(#limited) SmallInteger(Integer)
|
||||||
{
|
{
|
||||||
## method basicSize
|
## method basicSize
|
||||||
## {
|
## {
|
||||||
|
@ -111,6 +111,7 @@ static struct voca_t
|
|||||||
{ 10, { '#','i','m','m','u','t','a','b','l','e' } },
|
{ 10, { '#','i','m','m','u','t','a','b','l','e' } },
|
||||||
{ 6, { 'i','m','p','o','r','t' } },
|
{ 6, { 'i','m','p','o','r','t' } },
|
||||||
{ 8, { '#','i','n','c','l','u','d','e' } },
|
{ 8, { '#','i','n','c','l','u','d','e' } },
|
||||||
|
{ 8, { '#','l','e','n','i','e','n','t' } },
|
||||||
{ 8, { '#','l','i','b','e','r','a','l' } },
|
{ 8, { '#','l','i','b','e','r','a','l' } },
|
||||||
{ 8, { '#','l','i','m','i','t','e','d' } },
|
{ 8, { '#','l','i','m','i','t','e','d' } },
|
||||||
{ 7, { '#','l','i','w','o','r','d' } },
|
{ 7, { '#','l','i','w','o','r','d' } },
|
||||||
@ -170,6 +171,7 @@ enum voca_id_t
|
|||||||
VOCA_IMMUTABLE_S,
|
VOCA_IMMUTABLE_S,
|
||||||
VOCA_IMPORT,
|
VOCA_IMPORT,
|
||||||
VOCA_INCLUDE_S,
|
VOCA_INCLUDE_S,
|
||||||
|
VOCA_LENIENT_S,
|
||||||
VOCA_LIBERAL_S,
|
VOCA_LIBERAL_S,
|
||||||
VOCA_LIMITED_S,
|
VOCA_LIMITED_S,
|
||||||
VOCA_LIWORD_S,
|
VOCA_LIWORD_S,
|
||||||
@ -3725,7 +3727,7 @@ static int compile_method_pragma (moo_t* moo)
|
|||||||
|
|
||||||
if (moo->c->mth.tmpr_nargs < pfbase->minargs || moo->c->mth.tmpr_nargs > pfbase->maxargs)
|
if (moo->c->mth.tmpr_nargs < pfbase->minargs || moo->c->mth.tmpr_nargs > pfbase->maxargs)
|
||||||
{
|
{
|
||||||
MOO_DEBUG5 (moo, "Unsupported argument count in primitive method pragma of %.*js - %zd-%zd expected, %zd specified\n",
|
MOO_DEBUG5 (moo, "Unsupported argument count in primitive method definition of %.*js - %zd-%zd expected, %zd specified\n",
|
||||||
tlen, tptr, pfbase->minargs, pfbase->maxargs, moo->c->mth.tmpr_nargs);
|
tlen, tptr, pfbase->minargs, pfbase->maxargs, moo->c->mth.tmpr_nargs);
|
||||||
set_syntax_error (moo, MOO_SYNERR_PFARGDEFINVAL, &moo->c->mth.name_loc, &moo->c->mth.name);
|
set_syntax_error (moo, MOO_SYNERR_PFARGDEFINVAL, &moo->c->mth.name_loc, &moo->c->mth.name);
|
||||||
return -1;
|
return -1;
|
||||||
@ -3749,7 +3751,7 @@ static int compile_method_pragma (moo_t* moo)
|
|||||||
{
|
{
|
||||||
if (moo->c->mth.tmpr_nargs < pfbase->minargs || moo->c->mth.tmpr_nargs > pfbase->maxargs)
|
if (moo->c->mth.tmpr_nargs < pfbase->minargs || moo->c->mth.tmpr_nargs > pfbase->maxargs)
|
||||||
{
|
{
|
||||||
MOO_DEBUG5 (moo, "Unsupported argument count in primitive method pragma of %.*js - %zd-%zd expected, %zd specified\n",
|
MOO_DEBUG5 (moo, "Unsupported argument count in primitive method definition of %.*js - %zd-%zd expected, %zd specified\n",
|
||||||
tlen, tptr, pfbase->minargs, pfbase->maxargs, moo->c->mth.tmpr_nargs);
|
tlen, tptr, pfbase->minargs, pfbase->maxargs, moo->c->mth.tmpr_nargs);
|
||||||
set_syntax_error (moo, MOO_SYNERR_PFARGDEFINVAL, &moo->c->mth.name_loc, &moo->c->mth.name);
|
set_syntax_error (moo, MOO_SYNERR_PFARGDEFINVAL, &moo->c->mth.name_loc, &moo->c->mth.name);
|
||||||
return -1;
|
return -1;
|
||||||
@ -6025,6 +6027,7 @@ static int add_compiled_method (moo_t* moo)
|
|||||||
/*if (moo->c->mth.variadic) */
|
/*if (moo->c->mth.variadic) */
|
||||||
preamble_flags |= moo->c->mth.variadic;
|
preamble_flags |= moo->c->mth.variadic;
|
||||||
if (moo->c->mth.type == MOO_METHOD_DUAL) preamble_flags |= MOO_METHOD_PREAMBLE_FLAG_DUAL;
|
if (moo->c->mth.type == MOO_METHOD_DUAL) preamble_flags |= MOO_METHOD_PREAMBLE_FLAG_DUAL;
|
||||||
|
if (moo->c->mth.lenient) preamble_flags |= MOO_METHOD_PREAMBLE_FLAG_LENIENT;
|
||||||
|
|
||||||
MOO_ASSERT (moo, MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(preamble_index));
|
MOO_ASSERT (moo, MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(preamble_index));
|
||||||
|
|
||||||
@ -6081,6 +6084,7 @@ static int compile_method_definition (moo_t* moo)
|
|||||||
/* clear data required to compile a method */
|
/* clear data required to compile a method */
|
||||||
moo->c->mth.type = MOO_METHOD_INSTANCE;
|
moo->c->mth.type = MOO_METHOD_INSTANCE;
|
||||||
moo->c->mth.primitive = 0;
|
moo->c->mth.primitive = 0;
|
||||||
|
moo->c->mth.lenient = 0;
|
||||||
moo->c->mth.text.len = 0;
|
moo->c->mth.text.len = 0;
|
||||||
moo->c->mth.assignees.len = 0;
|
moo->c->mth.assignees.len = 0;
|
||||||
moo->c->mth.binsels.len = 0;
|
moo->c->mth.binsels.len = 0;
|
||||||
@ -6143,7 +6147,17 @@ static int compile_method_definition (moo_t* moo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
moo->c->mth.primitive = 1;
|
moo->c->mth.primitive = 1;
|
||||||
|
GET_TOKEN (moo);
|
||||||
|
}
|
||||||
|
else if (is_token_symbol(moo, VOCA_LENIENT_S))
|
||||||
|
{
|
||||||
|
/* method(#lenient) */
|
||||||
|
if (moo->c->mth.lenient)
|
||||||
|
{
|
||||||
|
set_syntax_error (moo, MOO_SYNERR_MODIFIERDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
moo->c->mth.lenient = 1;
|
||||||
GET_TOKEN (moo);
|
GET_TOKEN (moo);
|
||||||
}
|
}
|
||||||
else if (is_token_symbol(moo, VOCA_VARIADIC_S) ||
|
else if (is_token_symbol(moo, VOCA_VARIADIC_S) ||
|
||||||
|
@ -3963,7 +3963,11 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
|
|||||||
moo_pushtmp (moo, (moo_oop_t*)&method);
|
moo_pushtmp (moo, (moo_oop_t*)&method);
|
||||||
n = pftab[pfnum].pfbase.handler (moo, nargs);
|
n = pftab[pfnum].pfbase.handler (moo, nargs);
|
||||||
moo_poptmp (moo);
|
moo_poptmp (moo);
|
||||||
if (n <= MOO_PF_HARD_FAILURE) return -1;
|
if (n <= MOO_PF_HARD_FAILURE)
|
||||||
|
{
|
||||||
|
MOO_DEBUG3 (moo, "Hard failure indicated by primitive function %p - %hs - return code %d\n", pftab[pfnum].pfbase.handler, pftab[pfnum].name, n);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (n >= MOO_PF_SUCCESS) break;
|
if (n >= MOO_PF_SUCCESS) break;
|
||||||
|
|
||||||
MOO_DEBUG2 (moo, "Soft failure indicated by primitive function %p - %hs\n", pftab[pfnum].pfbase.handler, pftab[pfnum].name);
|
MOO_DEBUG2 (moo, "Soft failure indicated by primitive function %p - %hs\n", pftab[pfnum].pfbase.handler, pftab[pfnum].name);
|
||||||
@ -3971,61 +3975,56 @@ 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_EINVAL;
|
||||||
MOO_DEBUG1 (moo, "Cannot call primitive numbered %zd - invalid number\n", pfnum);
|
MOO_DEBUG1 (moo, "Cannot call primitive function numbered %zd - invalid number\n", pfnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
moo->processor->active->perr = MOO_ERROR_TO_OOP(moo->errnum);
|
|
||||||
goto activate_primitive_method_body;
|
goto activate_primitive_method_body;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MOO_METHOD_PREAMBLE_NAMED_PRIMITIVE:
|
case MOO_METHOD_PREAMBLE_NAMED_PRIMITIVE:
|
||||||
{
|
{
|
||||||
moo_ooi_t pf_name_index;
|
moo_ooi_t pf_name_index;
|
||||||
moo_oop_t name;
|
|
||||||
moo_pfbase_t* pfbase;
|
moo_pfbase_t* pfbase;
|
||||||
|
moo_oop_t pfname;
|
||||||
moo_oow_t w;
|
moo_oow_t w;
|
||||||
|
|
||||||
stack_base = moo->sp - nargs - 1; /* stack base before receiver and arguments */
|
stack_base = moo->sp - nargs - 1; /* stack base before receiver and arguments */
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
/* index to the primitive function identifier in the literal frame */
|
||||||
pf_name_index = MOO_METHOD_GET_PREAMBLE_INDEX(preamble);
|
pf_name_index = MOO_METHOD_GET_PREAMBLE_INDEX(preamble);
|
||||||
LOG_INST_1 (moo, "preamble_named_primitive %zd", pf_name_index);
|
|
||||||
MOO_ASSERT (moo, pf_name_index >= 0);
|
MOO_ASSERT (moo, pf_name_index >= 0);
|
||||||
|
pfname = method->slot[pf_name_index];
|
||||||
|
|
||||||
name = method->slot[pf_name_index];
|
#if !defined(NDEBUG)
|
||||||
MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(name));
|
LOG_INST_1 (moo, "preamble_named_primitive %zd", pf_name_index);
|
||||||
MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_EXTRA(name));
|
MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(pfname));
|
||||||
MOO_ASSERT (moo, MOO_CLASSOF(moo,name) == moo->_symbol);
|
MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_EXTRA(pfname));
|
||||||
|
MOO_ASSERT (moo, MOO_CLASSOF(moo,pfname) == moo->_symbol);
|
||||||
#endif
|
#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) |
|
||||||
(moo_oow_t)MOO_OOP_TO_SMOOI(method->preamble_data[1]);
|
(moo_oow_t)MOO_OOP_TO_SMOOI(method->preamble_data[1]);
|
||||||
pfbase = (moo_pfbase_t*)w;
|
pfbase = (moo_pfbase_t*)w;
|
||||||
if (pfbase) goto exec_handler;
|
if (pfbase) goto exec_handler; /* skip moo_querymod() */
|
||||||
|
|
||||||
#if defined(NDEBUG)
|
pfbase = moo_querymod (moo, MOO_OBJ_GET_CHAR_SLOT(pfname), MOO_OBJ_GET_SIZE(pfname));
|
||||||
pf_name_index = MOO_METHOD_GET_PREAMBLE_INDEX(preamble);
|
|
||||||
name = method->slot[pf_name_index];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pfbase = moo_querymod (moo, MOO_OBJ_GET_CHAR_SLOT(name), MOO_OBJ_GET_SIZE(name));
|
|
||||||
if (pfbase)
|
if (pfbase)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (nargs < pfbase->minargs || nargs > pfbase->maxargs)
|
|
||||||
{
|
|
||||||
MOO_DEBUG5 (moo, "Soft failure due to argument count mismatch for primitive function %.*js - %zu-%zu expected, %zu given\n",
|
|
||||||
MOO_OBJ_GET_SIZE(name), MOO_OBJ_GET_CHAR_SLOT(name), pfbase->minargs, pfbase->maxargs, nargs);
|
|
||||||
goto activate_primitive_method_body;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* split a pointer to two OOP fields as SmallIntegers for storing/caching. */
|
/* split a pointer to two OOP fields as SmallIntegers for storing/caching. */
|
||||||
method->preamble_data[0] = MOO_SMOOI_TO_OOP((moo_oow_t)pfbase >> (MOO_OOW_BITS / 2));
|
method->preamble_data[0] = MOO_SMOOI_TO_OOP((moo_oow_t)pfbase >> (MOO_OOW_BITS / 2));
|
||||||
method->preamble_data[1] = MOO_SMOOI_TO_OOP((moo_oow_t)pfbase & MOO_LBMASK(moo_oow_t, MOO_OOW_BITS / 2));
|
method->preamble_data[1] = MOO_SMOOI_TO_OOP((moo_oow_t)pfbase & MOO_LBMASK(moo_oow_t, MOO_OOW_BITS / 2));
|
||||||
|
|
||||||
exec_handler:
|
exec_handler:
|
||||||
|
if (nargs < pfbase->minargs || nargs > pfbase->maxargs)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
goto activate_primitive_method_body;
|
||||||
|
}
|
||||||
|
|
||||||
moo_pushtmp (moo, (moo_oop_t*)&method);
|
moo_pushtmp (moo, (moo_oop_t*)&method);
|
||||||
|
|
||||||
/* the primitive handler is executed without activating the method itself.
|
/* the primitive handler is executed without activating the method itself.
|
||||||
@ -4039,21 +4038,31 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
|
|||||||
moo_poptmp (moo);
|
moo_poptmp (moo);
|
||||||
if (n <= MOO_PF_HARD_FAILURE)
|
if (n <= MOO_PF_HARD_FAILURE)
|
||||||
{
|
{
|
||||||
MOO_DEBUG4 (moo, "Hard failure indicated by primitive function %p - %.*js - return code %d\n", pfbase->handler, MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot, n);
|
MOO_DEBUG4 (moo, "Hard failure indicated by primitive function %p - %.*js - return code %d\n", pfbase->handler, MOO_OBJ_GET_SIZE(pfname), MOO_OBJ_GET_CHAR_SLOT(pfname), n);
|
||||||
return -1; /* hard primitive failure */
|
return -1; /* hard primitive failure */
|
||||||
}
|
}
|
||||||
if (n >= MOO_PF_SUCCESS) break; /* primitive ok*/
|
if (n >= MOO_PF_SUCCESS) break; /* primitive ok*/
|
||||||
|
|
||||||
/* soft primitive failure */
|
/* soft primitive failure */
|
||||||
MOO_DEBUG3 (moo, "Soft failure indicated by primitive function %p - %.*js\n", pfbase->handler, MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot);
|
MOO_DEBUG3 (moo, "Soft failure indicated by primitive function %p - %.*js\n", pfbase->handler, MOO_OBJ_GET_SIZE(pfname), MOO_OBJ_GET_CHAR_SLOT(pfname));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* no handler found */
|
/* no handler found */
|
||||||
MOO_DEBUG2 (moo, "Soft failure for non-existent primitive function - %.*js\n", MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot);
|
MOO_DEBUG2 (moo, "Soft failure for non-existent primitive function - %.*js\n", MOO_OBJ_GET_SIZE(pfname), MOO_OBJ_GET_CHAR_SLOT(pfname));
|
||||||
}
|
}
|
||||||
|
|
||||||
activate_primitive_method_body:
|
activate_primitive_method_body:
|
||||||
|
if (MOO_METHOD_GET_PREAMBLE_FLAGS(preamble) & MOO_METHOD_PREAMBLE_FLAG_LENIENT)
|
||||||
|
{
|
||||||
|
/* convert a soft failure to error return */
|
||||||
|
moo->sp = stack_base;
|
||||||
|
MOO_STACK_PUSH (moo, MOO_ERROR_TO_OOP(moo->errnum));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 not a small integer */
|
||||||
@ -4062,17 +4071,19 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* no byte code to execute - make it a hard failure */
|
/* no byte code to execute - make it a hard failure */
|
||||||
/* 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. */
|
||||||
MOO_DEBUG0 (moo, "Empty primitive body\n");
|
MOO_DEBUG0 (moo, "Empty primitive body\n");
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
/* i assume that the failed primitive handler function set the error number.
|
||||||
|
* so i don't set it here */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (activate_new_method (moo, method, nargs) <= -1) return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (activate_new_method (moo, method, nargs) <= -1) return -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,14 +204,14 @@ static int ignite_1 (moo_t* moo)
|
|||||||
MOO_CLASS_SELFSPEC_FLAG_FINAL | MOO_CLASS_SELFSPEC_FLAG_LIMITED,
|
MOO_CLASS_SELFSPEC_FLAG_FINAL | MOO_CLASS_SELFSPEC_FLAG_LIMITED,
|
||||||
0, MOO_CLASS_SPEC_MAKE(MOO_PROCESS_SCHEDULER_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP));
|
0, MOO_CLASS_SPEC_MAKE(MOO_PROCESS_SCHEDULER_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP));
|
||||||
|
|
||||||
moo->_error_class = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP));
|
moo->_error_class = alloc_kernel_class (moo, MOO_CLASS_SELFSPEC_FLAG_LIMITED, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP));
|
||||||
moo->_true_class = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP));
|
moo->_true_class = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP));
|
||||||
moo->_false_class = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP));
|
moo->_false_class = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP));
|
||||||
/* TOOD: what is a proper spec for Character and SmallInteger?
|
/* TOOD: what is a proper spec for Character and SmallInteger?
|
||||||
* If the fixed part is 0, its instance must be an object of 0 payload fields.
|
* If the fixed part is 0, its instance must be an object of 0 payload fields.
|
||||||
* Does this make sense? */
|
* Does this make sense? */
|
||||||
moo->_character = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP));
|
moo->_character = alloc_kernel_class (moo, MOO_CLASS_SELFSPEC_FLAG_LIMITED, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP));
|
||||||
moo->_small_integer = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP));
|
moo->_small_integer = alloc_kernel_class (moo, MOO_CLASS_SELFSPEC_FLAG_LIMITED, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP));
|
||||||
moo->_large_positive_integer = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, MOO_CLASS_SPEC_FLAG_INDEXED | MOO_CLASS_SPEC_FLAG_IMMUTABLE, MOO_OBJ_TYPE_LIWORD));
|
moo->_large_positive_integer = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, MOO_CLASS_SPEC_FLAG_INDEXED | MOO_CLASS_SPEC_FLAG_IMMUTABLE, MOO_OBJ_TYPE_LIWORD));
|
||||||
moo->_large_negative_integer = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, MOO_CLASS_SPEC_FLAG_INDEXED | MOO_CLASS_SPEC_FLAG_IMMUTABLE, MOO_OBJ_TYPE_LIWORD));
|
moo->_large_negative_integer = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, MOO_CLASS_SPEC_FLAG_INDEXED | MOO_CLASS_SPEC_FLAG_IMMUTABLE, MOO_OBJ_TYPE_LIWORD));
|
||||||
|
|
||||||
|
@ -512,6 +512,7 @@ struct moo_compiler_t
|
|||||||
{
|
{
|
||||||
moo_method_type_t type;
|
moo_method_type_t type;
|
||||||
int primitive; /* true if method(#primitive) */
|
int primitive; /* true if method(#primitive) */
|
||||||
|
int lenient;
|
||||||
|
|
||||||
/* method source text */
|
/* method source text */
|
||||||
moo_oocs_t text;
|
moo_oocs_t text;
|
||||||
|
@ -586,7 +586,7 @@ struct moo_method_t
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The preamble field is composed of:
|
/* The preamble field is composed of:
|
||||||
* 3-bit flag
|
* 4-bit flag
|
||||||
* 5-bit code (0 to 31)
|
* 5-bit code (0 to 31)
|
||||||
* 16-bit index
|
* 16-bit index
|
||||||
*
|
*
|
||||||
@ -607,11 +607,11 @@ struct moo_method_t
|
|||||||
* 13 - ensure block
|
* 13 - ensure block
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* NOTE: changing preamble code bit structure requires changes to CompiledMethod>>preambleCode */
|
/* [NOTE] changing preamble code bit structure requires changes to CompiledMethod>>preambleCode */
|
||||||
#define MOO_METHOD_MAKE_PREAMBLE(code,index,flags) ((((moo_ooi_t)index) << 8) | ((moo_ooi_t)code << 3) | flags)
|
#define MOO_METHOD_MAKE_PREAMBLE(code,index,flags) ((((moo_ooi_t)index) << 9) | ((moo_ooi_t)code << 4) | flags)
|
||||||
#define MOO_METHOD_GET_PREAMBLE_CODE(preamble) ((((moo_ooi_t)preamble) & 0xFF) >> 3)
|
#define MOO_METHOD_GET_PREAMBLE_CODE(preamble) ((((moo_ooi_t)preamble) >> 4) & 0x1F)
|
||||||
#define MOO_METHOD_GET_PREAMBLE_INDEX(preamble) (((moo_ooi_t)preamble) >> 8)
|
#define MOO_METHOD_GET_PREAMBLE_INDEX(preamble) (((moo_ooi_t)preamble) >> 9)
|
||||||
#define MOO_METHOD_GET_PREAMBLE_FLAGS(preamble) (((moo_ooi_t)preamble) & 0x7)
|
#define MOO_METHOD_GET_PREAMBLE_FLAGS(preamble) (((moo_ooi_t)preamble) & 0xF)
|
||||||
|
|
||||||
/* preamble codes */
|
/* preamble codes */
|
||||||
#define MOO_METHOD_PREAMBLE_NONE 0
|
#define MOO_METHOD_PREAMBLE_NONE 0
|
||||||
@ -636,9 +636,10 @@ struct moo_method_t
|
|||||||
#define MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(num) ((num) >= MOO_METHOD_PREAMBLE_INDEX_MIN && (num) <= MOO_METHOD_PREAMBLE_INDEX_MAX)
|
#define MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(num) ((num) >= MOO_METHOD_PREAMBLE_INDEX_MIN && (num) <= MOO_METHOD_PREAMBLE_INDEX_MAX)
|
||||||
|
|
||||||
/* preamble flags */
|
/* preamble flags */
|
||||||
#define MOO_METHOD_PREAMBLE_FLAG_VARIADIC (1 << 0)
|
#define MOO_METHOD_PREAMBLE_FLAG_VARIADIC (1 << 0) /* allows variable arguments. but all named paramenters must be passed in */
|
||||||
#define MOO_METHOD_PREAMBLE_FLAG_LIBERAL (1 << 1)
|
#define MOO_METHOD_PREAMBLE_FLAG_LIBERAL (1 << 1) /* not all named parameters need to get passed in */
|
||||||
#define MOO_METHOD_PREAMBLE_FLAG_DUAL (1 << 2)
|
#define MOO_METHOD_PREAMBLE_FLAG_DUAL (1 << 2)
|
||||||
|
#define MOO_METHOD_PREAMBLE_FLAG_LENIENT (1 << 3) /* lenient primitive method - no exception upon failure. return an error instead */
|
||||||
|
|
||||||
/* NOTE: if you change the number of instance variables for moo_context_t,
|
/* NOTE: if you change the number of instance variables for moo_context_t,
|
||||||
* you need to change the defintion of BlockContext and MethodContext.
|
* you need to change the defintion of BlockContext and MethodContext.
|
||||||
|
Loading…
Reference in New Issue
Block a user