added a new modifier #variadic to make variadic method definition more obvious.

allowed the #primitive modifier in a method definition not associated with an external module.
fixed a bug in handling soft failure from numbered primitive functions
This commit is contained in:
hyunghwan.chung 2017-03-23 16:14:22 +00:00
parent 65722cf89b
commit 3fcfcff0ad
12 changed files with 475 additions and 177 deletions

View File

@ -328,13 +328,13 @@ class Apex(nil)
## -------------------------------------------------------
## -------------------------------------------------------
method(#class) perform()
method(#class,#variadic) perform()
{
<primitive: #_perform>
self primitiveFailed
}
method perform()
method(#variadic) perform()
{
<primitive: #_perform>
self primitiveFailed
@ -540,85 +540,3 @@ extend Error
}
}
class System(Apex)
{
}
pooldic System.Log
{
## -----------------------------------------------------------
## defines log levels
## these items must follow defintions in moo.h
## -----------------------------------------------------------
DEBUG := 1.
INFO := 2.
WARN := 4.
ERROR := 8.
FATAL := 16.
}
extend System
{
## the following methods may not look suitable to be placed
## inside a system dictionary. but they are here for quick and dirty
## output production from the moo code.
## System logNl: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'.
##
method(#class) atLevel: level log: message
{
<primitive: #_log>
## do nothing upon logging failure
}
method(#class) atLevel: level log: message and: message2
{
<primitive: #_log>
## do nothing upon logging failure
}
method(#class) atLevel: level log: message and: message2 and: message3
{
<primitive: #_log>
## do nothing upon logging failure
}
method(#class) atLevel: level logNl: message
{
## the #_log primitive accepts an array.
## so the following lines should work also.
## | x |
## x := Array new: 2.
## x at: 0 put: message.
## x at: 1 put: S'\n'.
## ^self atLevel: level log: x.
^self atLevel: level log: message and: S'\n'.
}
method(#class) atLevel: level logNl: message and: message2
{
^self atLevel: level log: message and: message2 and: S'\n'.
}
method(#class) log: message
{
^self atLevel: System.Log.INFO log: message.
}
method(#class) log: message and: message2
{
^self atLevel: System.Log.INFO log: message and: message2.
}
method(#class) logNl: message
{
^self atLevel: System.Log.INFO logNl: message.
}
method(#class) logNl: message and: message2
{
^self atLevel: System.Log.INFO logNl: message and: message2.
}
}

View File

@ -47,4 +47,9 @@ class(#pointer) Class(Apex)
].
^false
}*)
method nsdic
{
^self.nsdic
}
}

View File

@ -268,7 +268,11 @@ class MyObject(Object)
method(#class) main
{
|a i |
|a i|
System _getUint8(1,2).
'JJJJJJJJJJ' dump.
a := 100.
## PROBLEM: the following double loop will exhaust the stack
@ -318,16 +322,20 @@ class MyObject(Object)
}
}*)
System logNl: 'Sleeping start now....'.
(* basicAt: 12 to access the nsdic field. use a proper method once it's defined in Class *)
(System basicAt: 12) keysAndValuesDo: [:k :v |
(System nsdic) keysAndValuesDo: [:k :v |
k dump.
v dump.
'------------' dump.
].
Processor sleepFor: 3. ## DEBUG VM... VM WAITING FOR 10 SECS instead of 3.
(System at: #Processor) dump.
System logNl: 'Sleeping start now....'.
Processor sleepFor: 2.
}
(*

View File

@ -2,6 +2,7 @@
#include 'Context.moo'.
#include 'Except.moo'.
#include 'Class.moo'.
#include 'System.moo'.
#include 'Boolean.moo'.
#include 'Magnitu.moo'.
#include 'Collect.moo'.

View File

@ -42,7 +42,7 @@ class Stdio(Object) from 'stdio'
}
*)
method format (fmt)
method(#variadic) format (fmt)
{
| a b c |
'THIS IS FORMAT' dump.

150
moo/kernel/System.moo Normal file
View File

@ -0,0 +1,150 @@
## TODO: consider if System can replace Apex itself.
## System, being the top class, seems to give very natural way of
## offering global system-level functions and interfaces.
##
## class System(nil) { ... }
## class Object(System) { .... }
## System at: #
## System logNl: 'xxxxx'.
## System getUint8(ptr,offset)
class System(Apex)
{
}
pooldic System.Log
{
## -----------------------------------------------------------
## defines log levels
## these items must follow defintions in moo.h
## -----------------------------------------------------------
DEBUG := 1.
INFO := 2.
WARN := 4.
ERROR := 8.
FATAL := 16.
}
extend System
{
## the following methods may not look suitable to be placed
## inside a system dictionary. but they are here for quick and dirty
## output production from the moo code.
## System logNl: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'.
##
method(#class) atLevel: level log: message
{
<primitive: #_log>
## do nothing upon logging failure
}
method(#class) atLevel: level log: message and: message2
{
<primitive: #_log>
## do nothing upon logging failure
}
method(#class) atLevel: level log: message and: message2 and: message3
{
<primitive: #_log>
## do nothing upon logging failure
}
method(#class) atLevel: level logNl: message
{
## the #_log primitive accepts an array.
## so the following lines should work also.
## | x |
## x := Array new: 2.
## x at: 0 put: message.
## x at: 1 put: S'\n'.
## ^self atLevel: level log: x.
^self atLevel: level log: message and: S'\n'.
}
method(#class) atLevel: level logNl: message and: message2
{
^self atLevel: level log: message and: message2 and: S'\n'.
}
method(#class) log: message
{
^self atLevel: System.Log.INFO log: message.
}
method(#class) log: message and: message2
{
^self atLevel: System.Log.INFO log: message and: message2.
}
method(#class) logNl: message
{
^self atLevel: System.Log.INFO logNl: message.
}
method(#class) logNl: message and: message2
{
^self atLevel: System.Log.INFO logNl: message and: message2.
}
(* nsdic access *)
method(#class) at: key
{
^self nsdic at: key
}
method(#class) at: key put: value
{
^self nsdic at: key put: value
}
(* raw memory access *)
method(#class,#primitive) _getInt8 (rawptr, offset). ## <primitive: #System__getInt8>
method(#class,#primitive) _getInt16 (rawptr, offset).
method(#class,#primitive) _getInt32 (rawptr, offset).
method(#class,#primitive) _getInt64 (rawptr, offset).
method(#class,#primitive) _getUint8 (rawptr, offset). ## <primitive: #System__getUint8>
method(#class,#primitive) _getUint16 (rawptr, offset).
method(#class,#primitive) _getUint32 (rawptr, offset).
method(#class,#primitive) _getUint64 (rawptr, offset).
(*
method(#class,#primitive) _putInt8 (rawptr, offset, value).
method(#class,#primitive) _putInt16 (rawptr, offset, value).
method(#class,#primitive) _putInt32 (rawptr, offset, value).
method(#class,#primitive) _putInt64 (rawptr, offset, value).
method(#class,#primitive) _putUint8 (rawptr, offset, value).
method(#class,#primitive) _putUint16 (rawptr, offset, value).
method(#class,#primitive) _putUint32 (rawptr, offset, value).
method(#class,#primitive) _putUint64 (rawptr, offset, value),
*)
(*
method(#class) getUint8: rawptr at: offset
{
<primitive: #_get_uint8>
}
method(#class) getUint16: rawptr at: offset
{
<primitive: #_get_uint16>
}
method(#class) getUint32: rawptr at: offset
{
<primitive: #_get_uint32>
}
method(#class) getUint64: rawptr at: offset
{
<primitive: #_get_uint64>
}
method(#class) putUint8: value rawptr: rawptr at: offset
{
<primitive: #_get_uint8>
}*)
}

View File

@ -81,6 +81,7 @@ class MyObject(Object)
'duplicate modifier'
'wrong method name'
'duplicate method name'
'invalid variadic method definition'
'duplicate argument name'
'duplicate temporary variable name'
'duplicate variable name'

View File

@ -116,6 +116,7 @@ static struct voca_t
{ 11, { 't','h','i','s','C','o','n','t','e','x','t' } },
{ 11, { 't','h','i','s','P','r','o','c','e','s','s' } },
{ 4, { 't','r','u','e' } },
{ 9, { '#','v','a','r','i','a','d','i','c' } },
{ 5, { 'w','h','i','l','e' } },
{ 5, { '#','w','o','r','d' } },
@ -162,6 +163,7 @@ enum voca_id_t
VOCA_THIS_CONTEXT,
VOCA_THIS_PROCESS,
VOCA_TRUE,
VOCA_VARIADIC_S,
VOCA_WHILE,
VOCA_WORD_S,
@ -3169,9 +3171,8 @@ static int compile_unary_method_name (moo_t* moo)
while (1);
}
/* indicate that the unary method name is followed by a parameter list */
moo->c->mth.variadic = 1;
GET_TOKEN (moo);
return 9999; /* to indicate the method definition is in a procedural style */
}
return 0;
@ -3288,6 +3289,13 @@ static int compile_method_name (moo_t* moo)
set_syntax_error (moo, MOO_SYNERR_MTHNAMEDUPL, &moo->c->mth.name_loc, &moo->c->mth.name);
return -1;
}
/* compile_unary_method_name() returns 9999 if the name is followed by () */
if (moo->c->mth.variadic && n != 9999)
{
set_syntax_error (moo, MOO_SYNERR_VARIADMTHINVAL, &moo->c->mth.name_loc, &moo->c->mth.name);
return -1;
}
}
MOO_ASSERT (moo, moo->c->mth.tmpr_nargs < MAX_CODE_NARGS);
@ -5799,22 +5807,29 @@ static int compile_method_definition (moo_t* moo)
else if (is_token_symbol(moo, VOCA_PRIMITIVE_S))
{
/* method(#primitive) */
if (moo->c->cls.self_oop->modname == moo->_nil)
{
MOO_DEBUG2 (moo, "Disallowed #primitive method modifier in the class %.*js without 'from'\n",
MOO_OBJ_GET_SIZE(moo->c->cls.self_oop->name),
MOO_OBJ_GET_CHAR_SLOT(moo->c->cls.self_oop->name));
set_syntax_error (moo, MOO_SYNERR_MODIFIERBANNED, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
if (moo->c->mth.primitive)
{
/* #primitive duplicate modifier */
set_syntax_error (moo, MOO_SYNERR_MODIFIERDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
moo->c->mth.primitive = 1;
GET_TOKEN (moo);
}
else if (is_token_symbol(moo, VOCA_VARIADIC_S))
{
/* method(#variadic) */
if (moo->c->mth.variadic)
{
/* #variadic duplicate modifier */
set_syntax_error (moo, MOO_SYNERR_MODIFIERDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
moo->c->mth.variadic = 1;
GET_TOKEN (moo);
}
else if (TOKEN_TYPE(moo) == MOO_IOTOK_COMMA || TOKEN_TYPE(moo) == MOO_IOTOK_EOF || TOKEN_TYPE(moo) == MOO_IOTOK_RPAREN)
@ -5853,9 +5868,6 @@ static int compile_method_definition (moo_t* moo)
/* the primitive method must be of this form
* method(#primitive) method_name.
*/
moo_oow_t litidx, savedlen;
moo_oocs_t tmp;
if (TOKEN_TYPE(moo) != MOO_IOTOK_PERIOD)
{
/* . expected */
@ -5863,16 +5875,55 @@ static int compile_method_definition (moo_t* moo)
return -1;
}
/* TODO: i can check if the primitive method is available at compile time by querying the module.
* do the check depending on the compiler option */
if (moo->c->cls.self_oop->modname == moo->_nil)
{
moo_oow_t savedlen;
moo_ooi_t pfnum;
savedlen = moo->c->cls.modname.len;
/* primitive identifer = classname_methodname
* let me compose the identifer into the back of the cls.modname buffer.
* i'll revert it when done */
if (copy_string_to (moo, &moo->c->cls.name, &moo->c->cls.modname, &moo->c->cls.modname_capa, 1, '\0') <= -1 ||
copy_string_to (moo, &moo->c->mth.name, &moo->c->cls.modname, &moo->c->cls.modname_capa, 1, '_') <= -1)
{
moo->c->cls.modname.len = savedlen;
return -1;
}
pfnum = moo_getpfnum (moo, &moo->c->cls.modname.ptr[savedlen], moo->c->cls.modname.len - savedlen);
if (pfnum <= -1 || !MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(pfnum))
{
MOO_DEBUG2 (moo, "Cannot find intrinsic primitive handler - %.*js\n",
moo->c->cls.modname.len - savedlen, &moo->c->cls.modname.ptr[savedlen]);
moo->c->cls.modname.len = savedlen;
set_syntax_error (moo, MOO_SYNERR_PFIDINVAL, &moo->c->mth.name_loc, &moo->c->mth.name);
return -1;
}
moo->c->cls.modname.len = savedlen;
moo->c->mth.pftype = PFTYPE_NUMBERED;
moo->c->mth.pfnum = pfnum;
}
else
{
moo_oow_t litidx, savedlen;
moo_oocs_t tmp;
/* combine the module name and the method name delimited by a period
* when doing it, let me reuse the cls.modname buffer and restore it
* back once done */
MOO_ASSERT (moo, MOO_CLASSOF(moo, moo->c->cls.self_oop->modname) == moo->_symbol);
savedlen = moo->c->cls.modname.len;
MOO_ASSERT (moo, MOO_CLASSOF(moo, moo->c->cls.self_oop->modname) == moo->_symbol);
tmp.ptr = MOO_OBJ_GET_CHAR_SLOT(moo->c->cls.self_oop->modname);
tmp.len = MOO_OBJ_GET_SIZE(moo->c->cls.self_oop->modname);
/* TODO: i can check if the primitive method is available at compile time by querying the module.
* do the check depending on the compiler option */
if (copy_string_to (moo, &tmp, &moo->c->cls.modname, &moo->c->cls.modname_capa, 1, '\0') <= -1 ||
copy_string_to (moo, &moo->c->mth.name, &moo->c->cls.modname, &moo->c->cls.modname_capa, 1, '.') <= -1 ||
add_symbol_literal(moo, &moo->c->cls.modname, savedlen, &litidx) <= -1)
@ -5880,6 +5931,7 @@ static int compile_method_definition (moo_t* moo)
moo->c->cls.modname.len = savedlen;
return -1;
}
moo->c->cls.modname.len = savedlen;
/* the symbol added must be the first literal to the current method.
@ -5890,6 +5942,7 @@ static int compile_method_definition (moo_t* moo)
moo->c->mth.pftype = PFTYPE_NAMED;
moo->c->mth.pfnum = litidx;
}
}
else
{
if (TOKEN_TYPE(moo) != MOO_IOTOK_LBRACE)

View File

@ -107,33 +107,33 @@ static moo_ooch_t synerrstr_35[] = {'d','i','s','a','l','l','o','w','e','d',' ',
static moo_ooch_t synerrstr_36[] = {'d','u','p','l','i','c','a','t','e',' ','m','o','d','i','f','i','e','r','\0'};
static moo_ooch_t synerrstr_37[] = {'w','r','o','n','g',' ','m','e','t','h','o','d',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_38[] = {'d','u','p','l','i','c','a','t','e',' ','m','e','t','h','o','d',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_39[] = {'d','u','p','l','i','c','a','t','e',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_40[] = {'d','u','p','l','i','c','a','t','e',' ','t','e','m','p','o','r','a','r','y',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_41[] = {'d','u','p','l','i','c','a','t','e',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_42[] = {'d','u','p','l','i','c','a','t','e',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_43[] = {'u','n','d','e','c','l','a','r','e','d',' ','v','a','r','i','a','b','l','e','\0'};
static moo_ooch_t synerrstr_44[] = {'u','n','u','s','a','b','l','e',' ','v','a','r','i','a','b','l','e',' ','i','n',' ','c','o','m','p','i','l','e','d',' ','c','o','d','e','\0'};
static moo_ooch_t synerrstr_45[] = {'i','n','a','c','c','e','s','s','i','b','l','e',' ','v','a','r','i','a','b','l','e','\0'};
static moo_ooch_t synerrstr_46[] = {'a','m','b','i','g','u','o','u','s',' ','v','a','r','i','a','b','l','e','\0'};
static moo_ooch_t synerrstr_47[] = {'w','r','o','n','g',' ','e','x','p','r','e','s','s','i','o','n',' ','p','r','i','m','a','r','y','\0'};
static moo_ooch_t synerrstr_48[] = {'t','o','o',' ','m','a','n','y',' ','t','e','m','p','o','r','a','r','i','e','s','\0'};
static moo_ooch_t synerrstr_49[] = {'t','o','o',' ','m','a','n','y',' ','a','r','g','u','m','e','n','t','s','\0'};
static moo_ooch_t synerrstr_50[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','t','e','m','p','o','r','a','r','i','e','s','\0'};
static moo_ooch_t synerrstr_51[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t','s','\0'};
static moo_ooch_t synerrstr_52[] = {'t','o','o',' ','l','a','r','g','e',' ','b','l','o','c','k','\0'};
static moo_ooch_t synerrstr_53[] = {'t','o','o',' ','l','a','r','g','e',' ','a','r','r','a','y',' ','e','x','p','r','e','s','s','i','o','n','\0'};
static moo_ooch_t synerrstr_54[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','n','u','m','b','e','r','\0'};
static moo_ooch_t synerrstr_55[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','i','d','e','n','t','i','f','i','e','r','\0'};
static moo_ooch_t synerrstr_56[] = {'w','r','o','n','g',' ','m','o','d','u','l','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_57[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'};
static moo_ooch_t synerrstr_58[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_59[] = {'w','r','o','n','g',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_60[] = {'d','u','p','l','i','c','a','t','e',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_61[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_62[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','n','o','t',' ','w','i','t','h','i','n',' ','a',' ','l','o','o','p','\0'};
static moo_ooch_t synerrstr_63[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','w','i','t','h','i','n',' ','a',' ','b','l','o','c','k','\0'};
static moo_ooch_t synerrstr_64[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_39[] = {'i','n','v','a','l','i','d',' ','v','a','r','i','a','d','i','c',' ','m','e','t','h','o','d',' ','d','e','f','i','n','i','t','i','o','n','\0'};
static moo_ooch_t synerrstr_40[] = {'d','u','p','l','i','c','a','t','e',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_41[] = {'d','u','p','l','i','c','a','t','e',' ','t','e','m','p','o','r','a','r','y',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_42[] = {'d','u','p','l','i','c','a','t','e',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_43[] = {'d','u','p','l','i','c','a','t','e',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_44[] = {'u','n','d','e','c','l','a','r','e','d',' ','v','a','r','i','a','b','l','e','\0'};
static moo_ooch_t synerrstr_45[] = {'u','n','u','s','a','b','l','e',' ','v','a','r','i','a','b','l','e',' ','i','n',' ','c','o','m','p','i','l','e','d',' ','c','o','d','e','\0'};
static moo_ooch_t synerrstr_46[] = {'i','n','a','c','c','e','s','s','i','b','l','e',' ','v','a','r','i','a','b','l','e','\0'};
static moo_ooch_t synerrstr_47[] = {'a','m','b','i','g','u','o','u','s',' ','v','a','r','i','a','b','l','e','\0'};
static moo_ooch_t synerrstr_48[] = {'w','r','o','n','g',' ','e','x','p','r','e','s','s','i','o','n',' ','p','r','i','m','a','r','y','\0'};
static moo_ooch_t synerrstr_49[] = {'t','o','o',' ','m','a','n','y',' ','t','e','m','p','o','r','a','r','i','e','s','\0'};
static moo_ooch_t synerrstr_50[] = {'t','o','o',' ','m','a','n','y',' ','a','r','g','u','m','e','n','t','s','\0'};
static moo_ooch_t synerrstr_51[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','t','e','m','p','o','r','a','r','i','e','s','\0'};
static moo_ooch_t synerrstr_52[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t','s','\0'};
static moo_ooch_t synerrstr_53[] = {'t','o','o',' ','l','a','r','g','e',' ','b','l','o','c','k','\0'};
static moo_ooch_t synerrstr_54[] = {'t','o','o',' ','l','a','r','g','e',' ','a','r','r','a','y',' ','e','x','p','r','e','s','s','i','o','n','\0'};
static moo_ooch_t synerrstr_55[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','n','u','m','b','e','r','\0'};
static moo_ooch_t synerrstr_56[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','i','d','e','n','t','i','f','i','e','r','\0'};
static moo_ooch_t synerrstr_57[] = {'w','r','o','n','g',' ','m','o','d','u','l','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_58[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'};
static moo_ooch_t synerrstr_59[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_60[] = {'w','r','o','n','g',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_61[] = {'d','u','p','l','i','c','a','t','e',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_62[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_63[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','n','o','t',' ','w','i','t','h','i','n',' ','a',' ','l','o','o','p','\0'};
static moo_ooch_t synerrstr_64[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','w','i','t','h','i','n',' ','a',' ','b','l','o','c','k','\0'};
static moo_ooch_t synerrstr_65[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t* synerrstr[] =
{
synerrstr_0, synerrstr_1, synerrstr_2, synerrstr_3, synerrstr_4, synerrstr_5, synerrstr_6, synerrstr_7,
@ -144,7 +144,7 @@ static moo_ooch_t* synerrstr[] =
synerrstr_40, synerrstr_41, synerrstr_42, synerrstr_43, synerrstr_44, synerrstr_45, synerrstr_46, synerrstr_47,
synerrstr_48, synerrstr_49, synerrstr_50, synerrstr_51, synerrstr_52, synerrstr_53, synerrstr_54, synerrstr_55,
synerrstr_56, synerrstr_57, synerrstr_58, synerrstr_59, synerrstr_60, synerrstr_61, synerrstr_62, synerrstr_63,
synerrstr_64
synerrstr_64, synerrstr_65
};
#endif
/* END: GENERATED WITH generr.moo */

View File

@ -1739,6 +1739,139 @@ static moo_pfrc_t pf_hash (moo_t* moo, moo_ooi_t nargs)
return MOO_PF_SUCCESS;
}
static moo_pfrc_t _get_raw_int (moo_t* moo, moo_ooi_t nargs, int size)
{
moo_uint8_t* rawptr;
moo_oow_t offset;
moo_ooi_t value;
moo_oop_t result;
if (moo_inttooow (moo, MOO_STACK_GETARG(moo, nargs, 0), (moo_oow_t*)&rawptr) <= 0 ||
moo_inttooow (moo, MOO_STACK_GETARG(moo, nargs, 1), &offset) <= 0)
{
moo->errnum = MOO_EINVAL;
return MOO_PF_FAILURE;
}
switch (size)
{
case 1:
value = *(moo_int8_t*)&rawptr[offset];
break;
case 2:
value = *(moo_int16_t*)&rawptr[offset];
break;
case 4:
value = *(moo_int32_t*)&rawptr[offset];
break;
case 8:
value = *(moo_int64_t*)&rawptr[offset];
break;
default:
moo->errnum = MOO_EINVAL;
return MOO_PF_FAILURE;
}
result = moo_ooitoint (moo, value);
if (!result) return MOO_PF_FAILURE;
MOO_STACK_SETRET (moo, nargs, result);
return MOO_PF_SUCCESS;
}
static moo_pfrc_t _get_raw_uint (moo_t* moo, moo_ooi_t nargs, int size)
{
moo_uint8_t* rawptr;
moo_oow_t offset;
moo_oow_t value;
moo_oop_t result;
MOO_DEBUG1 (moo, "get_raw_uint ..%d\n", size);
if (moo_inttooow (moo, MOO_STACK_GETARG(moo, nargs, 0), (moo_oow_t*)&rawptr) <= 0 ||
moo_inttooow (moo, MOO_STACK_GETARG(moo, nargs, 1), &offset) <= 0)
{
MOO_DEBUG0 (moo, "get_raw_uint failure...\n");
moo->errnum = MOO_EINVAL;
return MOO_PF_FAILURE;
}
switch (size)
{
case 1:
value = *(moo_uint8_t*)&rawptr[offset];
break;
case 2:
value = *(moo_uint16_t*)&rawptr[offset];
break;
case 4:
value = *(moo_uint32_t*)&rawptr[offset];
break;
case 8:
value = *(moo_uint64_t*)&rawptr[offset];
break;
default:
moo->errnum = MOO_EINVAL;
return MOO_PF_FAILURE;
}
result = moo_oowtoint (moo, value);
if (!result) return MOO_PF_FAILURE;
MOO_DEBUG1 (moo, "get_raw_uint failure..%O.\n", result);
MOO_STACK_SETRET (moo, nargs, result);
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_get_int8 (moo_t* moo, moo_ooi_t nargs)
{
return _get_raw_int (moo, nargs, 1);
}
static moo_pfrc_t pf_get_int16 (moo_t* moo, moo_ooi_t nargs)
{
return _get_raw_int (moo, nargs, 2);
}
static moo_pfrc_t pf_get_int32 (moo_t* moo, moo_ooi_t nargs)
{
return _get_raw_int (moo, nargs, 4);
}
static moo_pfrc_t pf_get_int64 (moo_t* moo, moo_ooi_t nargs)
{
return _get_raw_int (moo, nargs, 8);
}
static moo_pfrc_t pf_get_uint8 (moo_t* moo, moo_ooi_t nargs)
{
return _get_raw_uint (moo, nargs, 1);
}
static moo_pfrc_t pf_get_uint16 (moo_t* moo, moo_ooi_t nargs)
{
return _get_raw_uint (moo, nargs, 2);
}
static moo_pfrc_t pf_get_uint32 (moo_t* moo, moo_ooi_t nargs)
{
return _get_raw_uint (moo, nargs, 4);
}
static moo_pfrc_t pf_get_uint64 (moo_t* moo, moo_ooi_t nargs)
{
return _get_raw_uint (moo, nargs, 8);
}
static moo_pfrc_t pf_responds_to (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t rcv, selector;
@ -1896,7 +2029,7 @@ static moo_pfrc_t __block_value (moo_t* moo, moo_oop_context_t rcv_blkctx, moo_o
if (MOO_OOP_TO_SMOOI(rcv_blkctx->method_or_nargs) != actual_arg_count /* nargs */)
{
MOO_LOG4 (moo, MOO_LOG_PRIMITIVE | MOO_LOG_ERROR,
"Error(%hs) - wrong number of arguments to a block context %O - expecting %zd, got %zd\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);
return MOO_PF_FAILURE;
}
@ -2759,11 +2892,11 @@ static moo_pfrc_t pf_error_as_string (moo_t* moo, moo_ooi_t nargs)
}
#define MAX_NARGS MOO_TYPE_MAX(moo_ooi_t)
#define MAX_NARGS MOO_TYPE_MAX(moo_oow_t)
struct pf_t
{
moo_ooi_t min_nargs; /* expected number of arguments */
moo_ooi_t max_nargs; /* expected number of arguments */
moo_oow_t min_nargs; /* expected number of arguments */
moo_oow_t max_nargs; /* expected number of arguments */
moo_pfimpl_t handler;
const char* name; /* the name is supposed to be 7-bit ascii only */
};
@ -2791,6 +2924,26 @@ static pf_t pftab[] =
{ 0, 0, pf_hash, "_hash" },
{ 2, 2, pf_get_int8, "System__getInt8" },
{ 2, 2, pf_get_int16, "System__getInt16" },
{ 2, 2, pf_get_int32, "System__getInt32" },
{ 2, 2, pf_get_int64, "System__getInt64" },
{ 2, 2, pf_get_uint8, "System__getUint8" },
{ 2, 2, pf_get_uint16, "System__getUint16" },
{ 2, 2, pf_get_uint32, "System__getUint32" },
{ 2, 2, pf_get_uint64, "System__getUint64" },
/*
{ 3, 3, pf_put_int8, "System__putInt8" },
{ 3, 3, pf_put_int16, "System__putInt16" },
{ 3, 3, pf_put_int32, "System__putInt32" },
{ 3, 3, pf_put_int64, "System__putInt64" },
{ 3, 3, pf_put_uint8, "System__putUint8" },
{ 3, 3, pf_put_uint16, "System__putUint16" },
{ 3, 3, pf_put_uint32, "System__putUint32" },
{ 3, 3, pf_put_uint64, "System__putUint64" },
*/
{ 1, 1, pf_responds_to, "_responds_to" },
{ 1, MAX_NARGS, pf_perform, "_perform" },
{ 1, 1, pf_exceptionize_error, "_exceptionize_error" },
@ -2799,7 +2952,6 @@ static pf_t pftab[] =
{ 0, MAX_NARGS, pf_block_value, "_block_value" },
{ 0, MAX_NARGS, pf_block_new_process, "_block_new_process" },
{ 0, 0, pf_process_resume, "_process_resume" },
{ 0, 0, pf_process_terminate, "_process_terminate" },
{ 0, 0, pf_process_yield, "_process_yield" },
@ -2852,10 +3004,7 @@ int moo_getpfnum (moo_t* moo, const moo_ooch_t* ptr, moo_oow_t len)
/* TODO: have the pftable sorted alphabetically and do binary search */
for (i = 0; i < MOO_COUNTOF(pftab); i++)
{
if (moo_compoocharsbcstr(ptr, len, pftab[i].name) == 0)
{
return i;
}
if (moo_compoocharsbcstr(ptr, len, pftab[i].name) == 0) return i;
}
moo->errnum = MOO_ENOENT;
@ -2866,6 +3015,7 @@ int moo_getpfnum (moo_t* moo, const moo_ooch_t* ptr, moo_oow_t len)
static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
{
moo_ooi_t preamble, preamble_code;
moo_ooi_t /*sp,*/ stack_base;
#if defined(MOO_DEBUG_VM_EXEC)
moo_ooi_t fetched_instruction_pointer = 0; /* set it to a fake value */
@ -2982,24 +3132,36 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
{
moo_ooi_t pfnum;
stack_base = moo->sp - nargs - 1; /* stack base before receiver and arguments */
pfnum = MOO_METHOD_GET_PREAMBLE_INDEX(preamble);
LOG_INST_1 (moo, "preamble_primitive %zd", pf_no);
if (pfnum >= 0 && pfnum < MOO_COUNTOF(pftab) &&
(nargs >= pftab[pfnum].min_nargs && nargs <= pftab[pfnum].max_nargs))
if (pfnum >= 0 && pfnum < MOO_COUNTOF(pftab))
{
int n;
if ((nargs < pftab[pfnum].min_nargs || nargs > pftab[pfnum].max_nargs))
{
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].min_nargs, pftab[pfnum].max_nargs, nargs);
goto activate_primitive_method_body;
}
moo_pushtmp (moo, (moo_oop_t*)&method);
n = pftab[pfnum].handler (moo, nargs);
moo_poptmp (moo);
if (n <= MOO_PF_HARD_FAILURE) return -1;
if (n >= MOO_PF_SUCCESS) break;
MOO_DEBUG2 (moo, "Soft failure indicated by primitive function %p - %hs\n", pftab[pfnum].handler, pftab[pfnum].name);
}
else
{
MOO_DEBUG1 (moo, "Cannot call primitive numbered %zd - invalid number\n", pfnum);
}
/* soft primitive failure */
if (activate_new_method (moo, method, nargs) <= -1) return -1;
break;
goto activate_primitive_method_body;
}
case MOO_METHOD_PREAMBLE_NAMED_PRIMITIVE:
@ -3008,10 +3170,8 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
moo_oop_t name;
moo_pfimpl_t handler;
moo_oow_t w;
moo_ooi_t /*sp,*/ sb;
/*sp = moo->sp;*/
sb = 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)
pf_name_index = MOO_METHOD_GET_PREAMBLE_INDEX(preamble);
@ -3072,6 +3232,7 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
MOO_DEBUG2 (moo, "Soft failure for non-existent primitive function - %.*js\n", MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot);
}
activate_primitive_method_body:
#if defined(MOO_USE_METHOD_TRAILER)
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 */
@ -3079,11 +3240,10 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
if (method->code == moo->_nil)
#endif
{
/* no byte code to execute */
/* TODO: what is the best tactics? emulate "self primitiveFailed"? */
/* force restore stack pointers */
moo->sp = sb;
/* 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 */
MOO_DEBUG0 (moo, "Empty primitive body\n");
moo->sp = stack_base; /* force restore stack pointer */
MOO_STACK_PUSH (moo, moo->_nil);
return -1;
}
@ -3091,6 +3251,7 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
{
if (activate_new_method (moo, method, nargs) <= -1) return -1;
}
break;
}

View File

@ -1014,7 +1014,7 @@ static void vm_muxwait (moo_t* moo, const moo_ntime_t* dur, moo_vmprim_muxwait_c
if (xtn->ev.len <= 0)
{
/* the event buffer is still empty */
pthread_cond_wait (&xtn->ev.cnd2, &xtn->ev.mtx);
pthread_cond_timedwait (&xtn->ev.cnd2, &xtn->ev.mtx, &ts);
}
pthread_mutex_unlock (&xtn->ev.mtx);
}
@ -1151,7 +1151,7 @@ static void vm_sleep (moo_t* moo, const moo_ntime_t* dur)
#if defined(USE_THREAD)
/* the sleep callback is called only if there is no IO semaphore
* waiting. so i can safely call vm_muxwait() wihtout a muxwait callback
* waiting. so i can safely call vm_muxwait() without a muxwait callback
* when USE_THREAD is true */
vm_muxwait (moo, dur, MOO_NULL);
#else

View File

@ -1229,6 +1229,7 @@ enum moo_synerrnum_t
MOO_SYNERR_MODIFIERDUPL, /* duplicate modifier */
MOO_SYNERR_MTHNAME, /* wrong method name */
MOO_SYNERR_MTHNAMEDUPL, /* duplicate method name */
MOO_SYNERR_VARIADMTHINVAL, /* invalid variadic method definition */
MOO_SYNERR_ARGNAMEDUPL, /* duplicate argument name */
MOO_SYNERR_TMPRNAMEDUPL, /* duplicate temporary variable name */
MOO_SYNERR_VARNAMEDUPL, /* duplicate variable name */