added more preamable codes.

enhanced the system to be able to attach trailing spaces to an object upon instantiation, especially for external modules to be able to secure GC-safe free workspace inside an instantiated object
added moo_setclasstrsize(), moo_getobjtrailer() for the trailer feature
This commit is contained in:
hyunghwan.chung 2017-02-14 08:29:30 +00:00
parent d7cb283e44
commit 71aa1110ed
19 changed files with 383 additions and 293 deletions

View File

@ -31,15 +31,20 @@ class Apex(nil)
## -------------------------------------------------------
## -------------------------------------------------------
method(#class) __trailer_size
{
^0
}
method(#class) basicNew
{
<primitive: #_basic_new>
self primitiveFailed.
}
method(#class) basicNew: anInteger
method(#class) basicNew: size
{
<primitive: #_basic_new_with_size>
<primitive: #_basic_new>
self primitiveFailed.
}
@ -51,7 +56,7 @@ class Apex(nil)
method(#class) ngcNew: anInteger
{
<primitive: #_ngc_new_with_size>
<primitive: #_ngc_new>
self primitiveFailed.
}

View File

@ -4,7 +4,7 @@
##
class(#pointer) Class(Apex)
{
dcl spec selfspec superclass subclasses name instvars classvars classinstvars pooldics instmthdic classmthdic nsdic.
dcl spec selfspec superclass subclasses name instvars classvars classinstvars pooldics instmthdic classmthdic nsdic trsize.
method(#class) basicNew
{

View File

@ -187,14 +187,14 @@ extend MethodContext
{
method isExceptionContext
{
## 10 - MOO_METHOD_PREAMBLE_EXCEPTION in VM.
^self.method preambleCode == 10.
## 12 - MOO_METHOD_PREAMBLE_EXCEPTION in VM.
^self.method preambleCode == 12.
}
method isEnsureContext
{
## 10 - MOO_METHOD_PREAMBLE_ENSURE in VM.
^self.method preambleCode == 11
## 13 - MOO_METHOD_PREAMBLE_ENSURE in VM.
^self.method preambleCode == 13
}
method ensureBlock
@ -208,7 +208,7 @@ extend MethodContext
* 8 instance variables, the ensure block must be at the 9th position
* which translates to index 8 *)
(self.method preambleCode == 11) ifFalse: [^nil].
(self.method preambleCode == 13) ifFalse: [^nil].
^self basicAt: 8.
}

View File

@ -1,4 +1,4 @@
class(#byte) _FFI(Module) from 'ffi'
class _FFI(Object) from 'ffi'
{
(*
* the ffi module installs the following methods

View File

@ -1,18 +0,0 @@
class(#byte) Module(Object)
{
method(#class) _newInstSize
{
self subclassResponsibility: #_newInstSize
}
method(#class) new: size
{
## ignore the specified size
^(super new: (self _newInstSize))
}
method(#class) new
{
^(super new: (self _newInstSize))
}
}

View File

@ -8,8 +8,6 @@
#include 'Process.moo'.
(* -------------------------------------------------------------------------- *)
#include 'Module.moo'.
#include 'FFI.moo'.
#include 'Stdio.moo'.
#include 'Console.moo'.

View File

@ -1,5 +1,5 @@
class(#byte) Stdio(Module) from 'stdio'
class Stdio(Object) from 'stdio'
{
dcl(#class) in out err.
@ -63,7 +63,7 @@ extend Stdio
}
}
class(#byte) Stdio2(Stdio)
class Stdio2(Stdio)
{
method(#class) new
{

View File

@ -73,6 +73,7 @@ class MyObject(Object)
'duplicate class'
'contradictory class definition'
'wrong class name'
'non-pointer class inheriting superclass with trailer size set'
'dcl not allowed'
'wrong method name'
'duplicate method name'

View File

@ -5555,7 +5555,7 @@ static int add_compiled_method (moo_t* moo)
{
moo_oop_char_t name; /* selector */
moo_oop_method_t mth; /* method */
#if defined(MOO_USE_OBJECT_TRAILER)
#if defined(MOO_USE_METHOD_TRAILER)
/* nothing extra */
#else
moo_oop_byte_t code;
@ -5569,7 +5569,7 @@ static int add_compiled_method (moo_t* moo)
moo_pushtmp (moo, (moo_oop_t*)&name); tmp_count++;
/* The variadic data part passed to moo_instantiate() is not GC-safe */
#if defined(MOO_USE_OBJECT_TRAILER)
#if defined(MOO_USE_METHOD_TRAILER)
mth = (moo_oop_method_t)moo_instantiatewithtrailer (moo, moo->_method, moo->c->mth.literal_count, moo->c->mth.code.ptr, moo->c->mth.code.len);
#else
mth = (moo_oop_method_t)moo_instantiate (moo, moo->_method, MOO_NULL, moo->c->mth.literal_count);
@ -5583,7 +5583,7 @@ static int add_compiled_method (moo_t* moo)
}
moo_pushtmp (moo, (moo_oop_t*)&mth); tmp_count++;
#if defined(MOO_USE_OBJECT_TRAILER)
#if defined(MOO_USE_METHOD_TRAILER)
/* do nothing */
#else
code = (moo_oop_byte_t)moo_instantiate (moo, moo->_byte_array, moo->c->mth.code.ptr, moo->c->mth.code.len);
@ -5616,6 +5616,14 @@ static int add_compiled_method (moo_t* moo)
preamble_code = MOO_METHOD_PREAMBLE_RETURN_RECEIVER;
break;
case BCODE_PUSH_CONTEXT:
preamble_code = MOO_METHOD_PREAMBLE_RETURN_CONTEXT;
break;
case BCODE_PUSH_PROCESS:
preamble_code = MOO_METHOD_PREAMBLE_RETURN_PROCESS;
break;
case BCODE_PUSH_NIL:
preamble_code = MOO_METHOD_PREAMBLE_RETURN_NIL;
break;
@ -5731,7 +5739,7 @@ static int add_compiled_method (moo_t* moo)
mth->tmpr_count = MOO_SMOOI_TO_OOP(moo->c->mth.tmpr_count);
mth->tmpr_nargs = MOO_SMOOI_TO_OOP(moo->c->mth.tmpr_nargs);
#if defined(MOO_USE_OBJECT_TRAILER)
#if defined(MOO_USE_METHOD_TRAILER)
/* do nothing */
#else
mth->code = code;
@ -5927,6 +5935,9 @@ static int make_defined_class (moo_t* moo)
moo->c->cls.self_oop->mthdic[MOO_METHOD_CLASS] = (moo_oop_set_t)tmp;
#endif
/* [NOTE] don't create a dictionary on the nsdic. keep it to be nil */
/* [NOTE] don't set the trsize field yet here. */
/* TODO: initialize more fields??? whatelse. */
/* TODO: update the subclasses field of the superclass if it's not nil */
@ -6167,7 +6178,6 @@ static int __compile_class_definition (moo_t* moo, int extend)
}
else
{
/* ass = moo_lookupsysdic(moo, &moo->c->cls.supername); */
ass = moo_lookupdic (moo, moo->c->cls.superns_oop, &moo->c->cls.supername);
if (!ass && moo->c->cls.superns_oop != moo->sysdic)
ass = moo_lookupdic (moo, moo->sysdic, &moo->c->cls.supername);
@ -6176,8 +6186,21 @@ static int __compile_class_definition (moo_t* moo, int extend)
MOO_OBJ_GET_FLAGS_KERNEL(ass->value) != 1)
{
/* the value found must be a class and it must not be
* an incomplete internal class object */
* an incomplete internal class object.
* 0(non-kernel object)
* 1(incomplete kernel object),
* 2(complete kernel object) */
moo->c->cls.super_oop = ass->value;
/* the superclass became known. */
if (((moo_oop_class_t)moo->c->cls.super_oop)->trsize != moo->_nil &&
(moo->c->cls.flags & CLASS_INDEXED) &&
moo->c->cls.indexed_type != MOO_OBJ_TYPE_OOP)
{
/* non-pointer object cannot inherit from a superclass with trailer size set */
set_syntax_error (moo, MOO_SYNERR_CLASSTRSIZE, &moo->c->cls.fqn_loc, &moo->c->cls.fqn);
return -1;
}
}
else
{
@ -6320,6 +6343,15 @@ static int __compile_class_definition (moo_t* moo, int extend)
{
if (moo_importmod (moo, (moo_oop_t)moo->c->cls.self_oop, modname, modnamelen) <= -1) return -1;
}
if (moo->c->cls.self_oop->trsize == moo->_nil &&
moo->c->cls.self_oop->superclass != moo->_nil)
{
/* [NOTE]
* update the trailer size field after module importing
* as the importer can set the trailer size legitimately */
moo->c->cls.self_oop->trsize = ((moo_oop_class_t)moo->c->cls.self_oop->superclass)->trsize;
}
}
while (is_token_word(moo, VOCA_METHOD))

View File

@ -99,38 +99,39 @@ static moo_ooch_t synerrstr_27[] = {'u','n','d','e','f','i','n','e','d',' ','c',
static moo_ooch_t synerrstr_28[] = {'d','u','p','l','i','c','a','t','e',' ','c','l','a','s','s','\0'};
static moo_ooch_t synerrstr_29[] = {'c','o','n','t','r','a','d','i','c','t','o','r','y',' ','c','l','a','s','s',' ','d','e','f','i','n','i','t','i','o','n','\0'};
static moo_ooch_t synerrstr_30[] = {'w','r','o','n','g',' ','c','l','a','s','s',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_31[] = {'d','c','l',' ','n','o','t',' ','a','l','l','o','w','e','d','\0'};
static moo_ooch_t synerrstr_32[] = {'w','r','o','n','g',' ','m','e','t','h','o','d',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_33[] = {'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_34[] = {'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_35[] = {'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_36[] = {'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_37[] = {'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_38[] = {'u','n','d','e','c','l','a','r','e','d',' ','v','a','r','i','a','b','l','e','\0'};
static moo_ooch_t synerrstr_39[] = {'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_40[] = {'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_41[] = {'a','m','b','i','g','u','o','u','s',' ','v','a','r','i','a','b','l','e','\0'};
static moo_ooch_t synerrstr_42[] = {'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_43[] = {'t','o','o',' ','m','a','n','y',' ','t','e','m','p','o','r','a','r','i','e','s','\0'};
static moo_ooch_t synerrstr_44[] = {'t','o','o',' ','m','a','n','y',' ','a','r','g','u','m','e','n','t','s','\0'};
static moo_ooch_t synerrstr_45[] = {'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_46[] = {'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_47[] = {'t','o','o',' ','l','a','r','g','e',' ','b','l','o','c','k','\0'};
static moo_ooch_t synerrstr_48[] = {'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_49[] = {'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_50[] = {'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_51[] = {'w','r','o','n','g',' ','m','o','d','u','l','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_52[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'};
static moo_ooch_t synerrstr_53[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_54[] = {'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_55[] = {'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_56[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_57[] = {'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_58[] = {'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_59[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_60[] = {'m','i','s','s','i','n','g',' ','a','s','s','o','c','i','a','t','i','o','n',' ','k','e','y','\0'};
static moo_ooch_t synerrstr_61[] = {'m','i','s','s','i','n','g',' ','a','s','s','o','c','i','a','t','i','o','n',' ','v','a','l','u','e','\0'};
static moo_ooch_t synerrstr_62[] = {'m','i','s','s','i','n','g',' ','a','s','s','o','c','i','a','t','i','o','n','\0'};
static moo_ooch_t synerrstr_31[] = {'n','o','n','-','p','o','i','n','t','e','r',' ','c','l','a','s','s',' ','i','n','h','e','r','i','t','i','n','g',' ','s','u','p','e','r','c','l','a','s','s',' ','w','i','t','h',' ','t','r','a','i','l','e','r',' ','s','i','z','e',' ','s','e','t','\0'};
static moo_ooch_t synerrstr_32[] = {'d','c','l',' ','n','o','t',' ','a','l','l','o','w','e','d','\0'};
static moo_ooch_t synerrstr_33[] = {'w','r','o','n','g',' ','m','e','t','h','o','d',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_34[] = {'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_35[] = {'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_36[] = {'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_37[] = {'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_38[] = {'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_39[] = {'u','n','d','e','c','l','a','r','e','d',' ','v','a','r','i','a','b','l','e','\0'};
static moo_ooch_t synerrstr_40[] = {'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_41[] = {'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_42[] = {'a','m','b','i','g','u','o','u','s',' ','v','a','r','i','a','b','l','e','\0'};
static moo_ooch_t synerrstr_43[] = {'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_44[] = {'t','o','o',' ','m','a','n','y',' ','t','e','m','p','o','r','a','r','i','e','s','\0'};
static moo_ooch_t synerrstr_45[] = {'t','o','o',' ','m','a','n','y',' ','a','r','g','u','m','e','n','t','s','\0'};
static moo_ooch_t synerrstr_46[] = {'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_47[] = {'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_48[] = {'t','o','o',' ','l','a','r','g','e',' ','b','l','o','c','k','\0'};
static moo_ooch_t synerrstr_49[] = {'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_50[] = {'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_51[] = {'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_52[] = {'w','r','o','n','g',' ','m','o','d','u','l','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_53[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'};
static moo_ooch_t synerrstr_54[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_55[] = {'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_56[] = {'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_57[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_58[] = {'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_59[] = {'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_60[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_61[] = {'m','i','s','s','i','n','g',' ','a','s','s','o','c','i','a','t','i','o','n',' ','k','e','y','\0'};
static moo_ooch_t synerrstr_62[] = {'m','i','s','s','i','n','g',' ','a','s','s','o','c','i','a','t','i','o','n',' ','v','a','l','u','e','\0'};
static moo_ooch_t synerrstr_63[] = {'m','i','s','s','i','n','g',' ','a','s','s','o','c','i','a','t','i','o','n','\0'};
static moo_ooch_t* synerrstr[] =
{
synerrstr_0, synerrstr_1, synerrstr_2, synerrstr_3, synerrstr_4, synerrstr_5, synerrstr_6, synerrstr_7,
@ -140,7 +141,7 @@ static moo_ooch_t* synerrstr[] =
synerrstr_32, synerrstr_33, synerrstr_34, synerrstr_35, synerrstr_36, synerrstr_37, synerrstr_38, synerrstr_39,
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_56, synerrstr_57, synerrstr_58, synerrstr_59, synerrstr_60, synerrstr_61, synerrstr_62, synerrstr_63
};
#endif
/* END: GENERATED WITH generr.st */

View File

@ -1350,59 +1350,48 @@ static moo_pfrc_t pf_class (moo_t* moo, moo_ooi_t nargs)
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_basic_new (moo_t* moo, moo_ooi_t nargs)
static MOO_INLINE moo_pfrc_t pf_basic_new (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t rcv, obj;
moo_oop_t _class, szoop, obj;
moo_oow_t size = 0, trsz = 0;
MOO_ASSERT (moo, nargs == 0);
rcv = MOO_STACK_GETRCV (moo, nargs);
if (MOO_CLASSOF(moo, rcv) != moo->_class)
_class = MOO_STACK_GETRCV(moo, nargs);
if (MOO_CLASSOF(moo, _class) != moo->_class)
{
/* the receiver is not a class object */
return MOO_PF_FAILURE;
MOO_DEBUG0 (moo, "<pf_basic_new> Receiver is not a class\n");
goto inval;
}
obj = moo_instantiate (moo, rcv, MOO_NULL, 0);
if (!obj) return MOO_PF_HARD_FAILURE;
MOO_STACK_SETRET (moo, nargs, obj);
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_basic_new_with_size (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t rcv, szoop, obj;
moo_oow_t size;
MOO_ASSERT (moo, nargs == 1);
rcv = MOO_STACK_GETRCV(moo, nargs);
if (MOO_CLASSOF(moo, rcv) != moo->_class)
if (nargs >= 1)
{
/* the receiver is not a class object */
return MOO_PF_FAILURE;
szoop = MOO_STACK_GETARG(moo, nargs, 0);
if (moo_inttooow (moo, szoop, &size) <= 0)
{
/* integer out of range or not integer */
MOO_DEBUG0 (moo, "<pf_basic_new> Size out of range or not integer\n");
goto inval;
}
}
szoop = MOO_STACK_GETARG(moo, nargs, 0);
if (moo_inttooow (moo, szoop, &size) <= 0)
{
/* integer out of range or not integer */
return MOO_PF_FAILURE;
}
if (MOO_OOP_IS_SMOOI(((moo_oop_class_t)_class)->trsize))
trsz = MOO_OOP_TO_SMOOI(((moo_oop_class_t)_class)->trsize);
/* moo_instantiate() ignores size if the instance specification
* disallows indexed(variable) parts. */
/* TODO: should i check the specification before calling
* moo_instantiate()? */
obj = moo_instantiate (moo, rcv, MOO_NULL, size);
if (!obj)
{
return MOO_PF_HARD_FAILURE;
}
MOO_DEBUG2 (moo, "<basic new> SIZE ... %d TRSZ %d\n", (int)size, (int)trsz);
obj = trsz <= 0? moo_instantiate (moo, _class, MOO_NULL, size):
moo_instantiatewithtrailer (moo, _class, size, MOO_NULL, trsz);
if (!obj) return MOO_PF_HARD_FAILURE;
MOO_STACK_SETRET (moo, nargs, obj);
return MOO_PF_SUCCESS;
inval:
moo->errnum = MOO_EINVAL;
return MOO_PF_FAILURE;
}
static moo_pfrc_t pf_ngc_new (moo_t* moo, moo_ooi_t nargs)
@ -1416,11 +1405,6 @@ static moo_pfrc_t pf_ngc_new (moo_t* moo, moo_ooi_t nargs)
}
static moo_pfrc_t pf_ngc_new_with_size (moo_t* moo, moo_ooi_t nargs)
{
return pf_basic_new_with_size (moo, nargs);
}
static moo_pfrc_t pf_ngc_dispose (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t rcv;
@ -1827,7 +1811,7 @@ static moo_pfrc_t __block_value (moo_t* moo, moo_oop_context_t rcv_blkctx, moo_o
moo_oop_oop_t xarg;
MOO_ASSERT (moo, nargs == 1);
xarg = (moo_oop_oop_t)MOO_STACK_GETTOP (moo);
MOO_ASSERT (moo, MOO_ISTYPEOF(moo,xarg,MOO_OBJ_TYPE_OOP));
MOO_ASSERT (moo, MOO_OBJ_IS_OOP_POINTER(xarg));
MOO_ASSERT (moo, MOO_OBJ_GET_SIZE(xarg) == num_first_arg_elems);
for (i = 0; i < num_first_arg_elems; i++)
{
@ -1890,6 +1874,7 @@ static moo_pfrc_t pf_block_new_process (moo_t* moo, moo_ooi_t nargs)
{
/* too many arguments */
/* TODO: proper error handling */
moo->errnum = MOO_EINVAL;
return MOO_PF_FAILURE;
}
@ -1898,10 +1883,11 @@ static moo_pfrc_t pf_block_new_process (moo_t* moo, moo_ooi_t nargs)
moo_oop_t xarg;
xarg = MOO_STACK_GETARG(moo, nargs, 0);
if (!MOO_ISTYPEOF(moo,xarg,MOO_OBJ_TYPE_OOP))
if (!MOO_OBJ_IS_OOP_POINTER(xarg))
{
/* the only optional argument must be an OOP-indexable
* object like an array */
moo->errnum = MOO_EINVAL;
return MOO_PF_FAILURE;
}
@ -1914,6 +1900,7 @@ static moo_pfrc_t pf_block_new_process (moo_t* moo, moo_ooi_t nargs)
/* the receiver must be a block context */
MOO_LOG2 (moo, MOO_LOG_PRIMITIVE | MOO_LOG_ERROR,
"Error(%hs) - invalid receiver, not a block context - %O\n", __PRIMITIVE_NAME__, rcv_blkctx);
moo->errnum = MOO_EINVAL;
return MOO_PF_FAILURE;
}
@ -2657,10 +2644,8 @@ static pf_t pftab[] =
{ 1, 1, pf_not_equal, "_not_equal" },
{ 0, 0, pf_class, "_class" },
{ 0, 0, pf_basic_new, "_basic_new" },
{ 1, 1, pf_basic_new_with_size, "_basic_new_with_size" },
{ 0, 0, pf_ngc_new, "_ngc_new" },
{ 1, 1, pf_ngc_new_with_size, "_ngc_new_with_size" },
{ 0, 1, pf_basic_new, "_basic_new" },
{ 0, 1, pf_ngc_new, "_ngc_new" },
{ 0, 0, pf_ngc_dispose, "_ngc_dispose" },
{ 0, 0, pf_shallow_copy, "_shallow_copy" },
@ -2771,6 +2756,21 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
MOO_STACK_POPS (moo, nargs); /* pop arguments only*/
break;
/* [NOTE] this is useless becuase it returns a caller's context
* as the callee's context has not been created yet.
case MOO_METHOD_PREAMBLE_RETURN_CONTEXT:
LOG_INST_0 (moo, "preamble_return_context");
MOO_STACK_POPS (moo, nargs);
MOO_STACK_SETTOP (moo, (moo_oop_t)moo->active_context);
break;
*/
case MOO_METHOD_PREAMBLE_RETURN_PROCESS:
LOG_INST_0 (moo, "preamble_return_process");
MOO_STACK_POPS (moo, nargs);
MOO_STACK_SETTOP (moo, (moo_oop_t)moo->processor->active);
break;
case MOO_METHOD_PREAMBLE_RETURN_NIL:
LOG_INST_0 (moo, "preamble_return_nil");
MOO_STACK_POPS (moo, nargs);
@ -2877,7 +2877,7 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
MOO_ASSERT (moo, pf_name_index >= 0);
name = method->slot[pf_name_index];
MOO_ASSERT (moo, MOO_ISTYPEOF(moo,name,MOO_OBJ_TYPE_CHAR));
MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(name));
MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_EXTRA(name));
MOO_ASSERT (moo, MOO_CLASSOF(moo,name) == moo->_symbol);
#endif
@ -2930,7 +2930,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);
}
#if defined(MOO_USE_OBJECT_TRAILER)
#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 */
#else
@ -2954,8 +2954,9 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
default:
MOO_ASSERT (moo, preamble_code == MOO_METHOD_PREAMBLE_NONE ||
preamble_code == MOO_METHOD_PREAMBLE_EXCEPTION ||
preamble_code == MOO_METHOD_PREAMBLE_ENSURE);
preamble_code == MOO_METHOD_PREAMBLE_RETURN_CONTEXT ||
preamble_code == MOO_METHOD_PREAMBLE_EXCEPTION ||
preamble_code == MOO_METHOD_PREAMBLE_ENSURE);
if (activate_new_method (moo, method, nargs) <= -1) return -1;
break;
}

View File

@ -408,7 +408,7 @@ static MOO_INLINE moo_oow_t get_payload_bytes (moo_t* moo, moo_oop_t oop)
{
moo_oow_t nbytes_aligned;
#if defined(MOO_USE_OBJECT_TRAILER)
#if defined(MOO_USE_METHOD_TRAILER)
if (MOO_OBJ_GET_FLAGS_TRAILER(oop))
{
moo_oow_t nbytes;
@ -438,7 +438,7 @@ static MOO_INLINE moo_oow_t get_payload_bytes (moo_t* moo, moo_oop_t oop)
#endif
/* calculate the payload size in bytes */
nbytes_aligned = MOO_ALIGN (MOO_OBJ_BYTESOF(oop), MOO_SIZEOF(moo_oop_t));
#if defined(MOO_USE_OBJECT_TRAILER)
#if defined(MOO_USE_METHOD_TRAILER)
}
#endif
@ -506,7 +506,7 @@ static moo_uint8_t* scan_new_heap (moo_t* moo, moo_uint8_t* ptr)
oop = (moo_oop_t)ptr;
#if defined(MOO_USE_OBJECT_TRAILER)
#if defined(MOO_USE_METHOD_TRAILER)
if (MOO_OBJ_GET_FLAGS_TRAILER(oop))
{
moo_oow_t nbytes;
@ -523,7 +523,7 @@ static moo_uint8_t* scan_new_heap (moo_t* moo, moo_uint8_t* ptr)
{
#endif
nbytes_aligned = MOO_ALIGN (MOO_OBJ_BYTESOF(oop), MOO_SIZEOF(moo_oop_t));
#if defined(MOO_USE_OBJECT_TRAILER)
#if defined(MOO_USE_METHOD_TRAILER)
}
#endif

View File

@ -562,7 +562,7 @@ struct moo_oochbuf_t
#endif
#if defined(MOO_USE_OBJECT_TRAILER)
#if defined(MOO_USE_METHOD_TRAILER)
/* let it point to the trailer of the method */
# define SET_ACTIVE_METHOD_CODE(moo) ((moo)->active_code = (moo_oob_t*)&(moo)->active_method->slot[MOO_OBJ_GET_SIZE((moo)->active_method) + 1 - MOO_METHOD_NAMED_INSTVARS])
#else
@ -949,7 +949,7 @@ moo_oop_t moo_allocoopobj (
moo_oow_t size
);
#if defined(MOO_USE_OBJECT_TRAILER)
#if defined(MOO_USE_METHOD_TRAILER)
moo_oop_t moo_allocoopobjwithtrailer (
moo_t* moo,
moo_oow_t size,
@ -982,7 +982,7 @@ moo_oop_t moo_allocwordobj (
moo_oow_t len
);
#if defined(MOO_USE_OBJECT_TRAILER)
#if defined(MOO_USE_METHOD_TRAILER)
moo_oop_t moo_instantiatewithtrailer (
moo_t* moo,
moo_oop_t _class,

View File

@ -537,7 +537,7 @@ int moo_importmod (moo_t* moo, moo_oop_t _class, const moo_ooch_t* name, moo_oow
moo_mod_data_t* mdp;
int r = 0;
/* moo_openmod(), moo_closemod(), etc calls a user-defined callback.
/* moo_openmod(), moo_closemod(), etc call a user-defined callback.
* i need to protect _class in case the user-defined callback allocates
* a OOP memory chunk and GC occurs */
moo_pushtmp (moo, &_class);
@ -706,8 +706,6 @@ int moo_genpfmethod (moo_t* moo, moo_mod_t* mod, moo_oop_t _class, moo_method_ty
return -1;
}
MOO_DEBUG3 (moo, ">>>> PFGEN X11 [%.*js] %js\n", moo->sbuf[0].len, moo->sbuf[0].ptr, mod->name);
pfidsym = (moo_oop_char_t)moo_makesymbol (moo, moo->sbuf[0].ptr, moo->sbuf[0].len);
if (!pfidsym)
{
@ -716,7 +714,7 @@ MOO_DEBUG3 (moo, ">>>> PFGEN X11 [%.*js] %js\n", moo->sbuf[0].len, moo->sbuf[0].
}
moo_pushtmp (moo, (moo_oop_t*)&pfidsym); tmp_count++;
#if defined(MOO_USE_OBJECT_TRAILER)
#if defined(MOO_USE_METHOD_TRAILER)
mth = (moo_oop_method_t)moo_instantiatewithtrailer (moo, moo->_method, 1, MOO_NULL, 0);
#else
mth = (moo_oop_method_t)moo_instantiate (moo, moo->_method, MOO_NULL, 1);
@ -757,3 +755,78 @@ oops:
moo_poptmps (moo, tmp_count);
return -1;
}
int moo_setclasstrsize (moo_t* moo, moo_oop_t _class, moo_oow_t size)
{
register moo_oop_class_t c;
moo_oop_class_t sc;
moo_oow_t spec;
MOO_ASSERT (moo, MOO_CLASSOF(moo, _class) == moo->_class);
MOO_ASSERT (moo, size <= MOO_SMOOI_MAX);
c = (moo_oop_class_t)_class;
if ((moo_oop_t)c == moo->_method)
{
/* the bytes code emitted by the compiler go to the trailer part
* regardless of the trailer size. you're not allowed to change it */
MOO_DEBUG3 (moo, "Not allowed to set trailer size to %zu on the %.*js class\n",
size,
MOO_OBJ_GET_SIZE(c->name),
MOO_OBJ_GET_CHAR_SLOT(c->name));
goto eperm;
}
spec = MOO_OOP_TO_SMOOI(c->spec);
if (MOO_CLASS_SPEC_IS_INDEXED(spec) && MOO_CLASS_SPEC_INDEXED_TYPE(spec) != MOO_OBJ_TYPE_OOP)
{
MOO_DEBUG3 (moo, "Not allowed to set trailer size to %zu on the %.*js class representing a non-pointer object\n",
size,
MOO_OBJ_GET_SIZE(c->name),
MOO_OBJ_GET_CHAR_SLOT(c->name));
goto eperm;
}
if (c->trsize != moo->_nil)
{
MOO_DEBUG3 (moo, "Not allowed to reset trailer size to %zu on the %.*js class\n",
size,
MOO_OBJ_GET_SIZE(c->name),
MOO_OBJ_GET_CHAR_SLOT(c->name));
goto eperm;
}
sc = (moo_oop_class_t)c->superclass;
if (MOO_OOP_IS_SMOOI(sc->trsize) && size < MOO_OOP_TO_SMOOI(sc->trsize))
{
MOO_DEBUG6 (moo, "Not allowed to set the trailer size of %.*js to be smaller(%zu) than that(%zu) of the superclass %.*js\n",
size,
MOO_OBJ_GET_SIZE(c->name),
MOO_OBJ_GET_CHAR_SLOT(c->name),
MOO_OOP_TO_SMOOI(sc->trsize),
MOO_OBJ_GET_SIZE(sc->name),
MOO_OBJ_GET_CHAR_SLOT(sc->name));
goto eperm;
}
/* you can only set the trailer size once when it's not set yet */
c->trsize = MOO_SMOOI_TO_OOP(size);
MOO_DEBUG3 (moo, "Set trailer size to %zu on the %.*js class\n",
size,
MOO_OBJ_GET_SIZE(c->name),
MOO_OBJ_GET_CHAR_SLOT(c->name));
return 0;
eperm:
moo->errnum = MOO_EPERM;
return -1;
}
void* moo_getobjtrailer (moo_t* moo, moo_oop_t obj, moo_oow_t* size)
{
if (!MOO_OBJ_IS_OOP_POINTER(obj) || !MOO_OBJ_GET_FLAGS_TRAILER(obj)) return MOO_NULL;
if (size) *size = MOO_OBJ_GET_TRAILER_SIZE(obj);
return MOO_OBJ_GET_TRAILER_BYTE(obj);
}

View File

@ -36,7 +36,7 @@
/* define this to allow an pointer(OOP) object to have trailing bytes
* this is used to embed bytes codes into the back of a compile method
* object instead of putting in in a separate byte array. */
#define MOO_USE_OBJECT_TRAILER
#define MOO_USE_METHOD_TRAILER
/* ========================================================================== */
/**
@ -187,7 +187,7 @@ typedef enum moo_method_type_t moo_method_type_t;
* but some simple numeric values are also encoded into OOP using a simple
* bit-shifting and masking.
*
* A real OOP is stored without any bit-shifting while a non-OOP value encoded
* A real OOP is stored without any bit-shifting while a non-pointer value encoded
* in an OOP is bit-shifted to the left by 2 and the 2 least-significant bits
* are set to 1 or 2.
*
@ -286,9 +286,10 @@ typedef enum moo_obj_type_t moo_obj_type_t;
* item than the value of the size field. used for a
* terminating null in a variable-character object. internel
* use only.
* kernel: 0 or 1. indicates that the object is a kernel object.
* kernel: 0, 1, or 2. indicates that the object is a kernel object.
* VM disallows layout changes of a kernel object.
* internal use only.
* internal use only. during ignition, it's set to 1.
* when full definition is available, it's set to 2.
* moved: 0 or 1. used by GC. internal use only.
* ngc: 0 or 1, used by GC. internal use only.
* trailer: 0 or 1. indicates that there are trailing bytes
@ -360,6 +361,7 @@ typedef enum moo_obj_type_t moo_obj_type_t;
/* [NOTE] this macro doesn't include the size of the trailer */
#define MOO_OBJ_BYTESOF(oop) ((MOO_OBJ_GET_SIZE(oop) + MOO_OBJ_GET_FLAGS_EXTRA(oop)) * MOO_OBJ_GET_FLAGS_UNIT(oop))
#define MOO_OBJ_IS_OOP_POINTER(oop) (MOO_OOP_IS_POINTER(oop) && (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_OOP))
#define MOO_OBJ_IS_CHAR_POINTER(oop) (MOO_OOP_IS_POINTER(oop) && (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_CHAR))
#define MOO_OBJ_IS_BYTE_POINTER(oop) (MOO_OOP_IS_POINTER(oop) && (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_BYTE))
#define MOO_OBJ_IS_HALFWORD_POINTER(oop) (MOO_OOP_IS_POINTER(oop) && (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_HALFWORD))
@ -431,6 +433,8 @@ struct moo_trailer_t
moo_oob_t slot[1];
};
#define MOO_OBJ_GET_TRAILER_BYTE(oop) ((moo_oob_t*)&((moo_oop_oop_t)oop)->slot[MOO_OBJ_GET_SIZE(oop) + 1])
#define MOO_OBJ_GET_TRAILER_SIZE(oop) ((moo_oow_t)((moo_oop_oop_t)oop)->slot[MOO_OBJ_GET_SIZE(oop)])
#define MOO_SET_NAMED_INSTVARS 2
typedef struct moo_set_t moo_set_t;
@ -442,7 +446,7 @@ struct moo_set_t
moo_oop_oop_t bucket; /* Array */
};
#define MOO_CLASS_NAMED_INSTVARS 12
#define MOO_CLASS_NAMED_INSTVARS 13
typedef struct moo_class_t moo_class_t;
typedef struct moo_class_t* moo_oop_class_t;
struct moo_class_t
@ -469,8 +473,8 @@ struct moo_class_t
* [1] - class methods, MethodDictionary */
moo_oop_set_t mthdic[MOO_METHOD_TYPE_COUNT];
/* dictionary used for namespacing */
moo_oop_set_t nsdic;
moo_oop_set_t nsdic; /* dictionary used for namespacing */
moo_oop_t trsize; /* trailer size for new instances */
/* indexed part afterwards */
moo_oop_t slot[1]; /* class instance variables and class variables. */
@ -486,7 +490,7 @@ struct moo_association_t
moo_oop_t value;
};
#if defined(MOO_USE_OBJECT_TRAILER)
#if defined(MOO_USE_METHOD_TRAILER)
# define MOO_METHOD_NAMED_INSTVARS 8
#else
# define MOO_METHOD_NAMED_INSTVARS 9
@ -511,7 +515,7 @@ struct moo_method_t
/* number of arguments in temporaries */
moo_oop_t tmpr_nargs; /* SmallInteger */
#if defined(MOO_USE_OBJECT_TRAILER)
#if defined(MOO_USE_METHOD_TRAILER)
/* no code field is used */
#else
moo_oop_byte_t code; /* ByteArray */
@ -523,14 +527,17 @@ struct moo_method_t
moo_oop_t slot[1]; /* it stores literals */
};
#if defined(MOO_USE_OBJECT_TRAILER)
#if defined(MOO_USE_METHOD_TRAILER)
/* if m is to be type-cast to moo_oop_method_t, the macro must be
* redefined to this:
* (&((moo_oop_method_t)m)>slot[MOO_OBJ_GET_SIZE(m) + 1 - MOO_METHOD_NAMED_INSTVARS])
*/
# define MOO_METHOD_GET_CODE_BYTE(m) ((moo_oob_t*)&((moo_oop_oop_t)m)->slot[MOO_OBJ_GET_SIZE(m) + 1])
# define MOO_METHOD_GET_CODE_SIZE(m) ((moo_oow_t)((moo_oop_oop_t)m)->slot[MOO_OBJ_GET_SIZE(m)])
/*((moo_oob_t*)&((moo_oop_oop_t)m)->slot[MOO_OBJ_GET_SIZE(m) + 1])*/
# define MOO_METHOD_GET_CODE_BYTE(m) MOO_OBJ_GET_TRAILER_BYTE(m)
/*((moo_oow_t)((moo_oop_oop_t)m)->slot[MOO_OBJ_GET_SIZE(m)])*/
# define MOO_METHOD_GET_CODE_SIZE(m) MOO_OBJ_GET_TRAILER_SIZE(m)
#else
# define MOO_METHOD_GET_CODE_BYTE(m) ((m)->code->slot)
# define MOO_METHOD_GET_CODE_SIZE(m) MOO_OBJ_GET_SIZE((m)->code)
@ -544,16 +551,18 @@ struct moo_method_t
* The code can be one of the following values:
* 0 - no special action
* 1 - return self
* 2 - return nil
* 3 - return true
* 4 - return false
* 5 - return index.
* 6 - return -index.
* 7 - return instvar[index]
* 8 - do primitive[index]
* 9 - do named primitive[index]
* 10 - exception handler
* 11 - ensure block
* 2 - return thisContext (not used)
* 3 - return thisProcess
* 4 - return nil
* 5 - return true
* 6 - return false
* 7 - return index.
* 8 - return -index.
* 9 - return instvar[index]
* 10 - do primitive[index]
* 11 - do named primitive[index]
* 12 - exception handler
* 13 - ensure block
*/
/* NOTE: changing preamble code bit structure requires changes to CompiledMethod>>preambleCode */
@ -563,19 +572,21 @@ struct moo_method_t
#define MOO_METHOD_GET_PREAMBLE_FLAGS(preamble) (((moo_ooi_t)preamble) & 0x3)
/* preamble codes */
#define MOO_METHOD_PREAMBLE_NONE 0
#define MOO_METHOD_PREAMBLE_RETURN_RECEIVER 1
#define MOO_METHOD_PREAMBLE_RETURN_NIL 2
#define MOO_METHOD_PREAMBLE_RETURN_TRUE 3
#define MOO_METHOD_PREAMBLE_RETURN_FALSE 4
#define MOO_METHOD_PREAMBLE_RETURN_INDEX 5
#define MOO_METHOD_PREAMBLE_RETURN_NEGINDEX 6
#define MOO_METHOD_PREAMBLE_RETURN_INSTVAR 7
#define MOO_METHOD_PREAMBLE_PRIMITIVE 8
#define MOO_METHOD_PREAMBLE_NAMED_PRIMITIVE 9 /* index is an index to the symbol table */
#define MOO_METHOD_PREAMBLE_NONE 0
#define MOO_METHOD_PREAMBLE_RETURN_RECEIVER 1
#define MOO_METHOD_PREAMBLE_RETURN_CONTEXT 2
#define MOO_METHOD_PREAMBLE_RETURN_PROCESS 3
#define MOO_METHOD_PREAMBLE_RETURN_NIL 4
#define MOO_METHOD_PREAMBLE_RETURN_TRUE 5
#define MOO_METHOD_PREAMBLE_RETURN_FALSE 6
#define MOO_METHOD_PREAMBLE_RETURN_INDEX 7
#define MOO_METHOD_PREAMBLE_RETURN_NEGINDEX 8
#define MOO_METHOD_PREAMBLE_RETURN_INSTVAR 9
#define MOO_METHOD_PREAMBLE_PRIMITIVE 10
#define MOO_METHOD_PREAMBLE_NAMED_PRIMITIVE 11 /* index is an index to the symbol table */
#define MOO_METHOD_PREAMBLE_EXCEPTION 10 /* NOTE changing this requires changes in Except.st */
#define MOO_METHOD_PREAMBLE_ENSURE 11 /* NOTE changing this requires changes in Except.st */
#define MOO_METHOD_PREAMBLE_EXCEPTION 12 /* NOTE changing this requires changes in Except.st */
#define MOO_METHOD_PREAMBLE_ENSURE 13 /* NOTE changing this requires changes in Except.st */
/* the index is an 16-bit unsigned integer. */
#define MOO_METHOD_PREAMBLE_INDEX_MIN 0x0000
@ -718,11 +729,6 @@ struct moo_process_scheduler_t
#define MOO_BYTESOF(moo,oop) \
(MOO_OOP_IS_NUMERIC(oop)? MOO_SIZEOF(moo_oow_t): MOO_OBJ_BYTESOF(oop))
/**
* The MOO_ISTYPEOF() macro is a safe replacement for MOO_OBJ_GET_FLAGS_TYPE()
*/
#define MOO_ISTYPEOF(moo,oop,type) \
(!MOO_OOP_IS_NUMERIC(oop) && MOO_OBJ_GET_FLAGS_TYPE(oop) == (type))
typedef struct moo_heap_t moo_heap_t;
@ -1042,7 +1048,7 @@ struct moo_t
#define MOO_STACK_ISEMPTY(moo) ((moo)->sp <= -1)
#define MOO_STACK_GETARG(moo,nargs,idx) MOO_STACK_GET(moo, (moo)->sp - ((nargs) - (idx) - 1))
#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.
* also you must not call this macro more than once */
@ -1180,6 +1186,7 @@ enum moo_synerrnum_t
MOO_SYNERR_CLASSDUP, /* duplicate class */
MOO_SYNERR_CLASSCONTRA, /* contradictory class */
MOO_SYNERR_CLASSNAME, /* wrong class name */
MOO_SYNERR_CLASSTRSIZE, /* non-pointer class inheriting a superclass with trailer size set */
MOO_SYNERR_DCLBANNED, /* #dcl not allowed */
MOO_SYNERR_MTHNAME, /* wrong method name */
MOO_SYNERR_MTHNAMEDUP, /* duplicate method name */
@ -1323,13 +1330,15 @@ MOO_EXPORT void moo_gc (
/**
* The moo_instantiate() function creates a new object of the class
* The moo_instantiate() function creates a new object instance of the class
* \a _class. The size of the fixed part is taken from the information
* contained in the class defintion. The \a vlen parameter specifies
* the length of the variable part. The \a vptr parameter points to
* the memory area to copy into the variable part of the new object.
* If \a vptr is #MOO_NULL, the variable part is initialized to 0 or
* an equivalent value depending on the type.
* contained in the class defintion. The \a vlen parameter specifies the length
* of the variable part. The \a vptr parameter points to the memory area to
* copy into the variable part of the new object. If \a vptr is #MOO_NULL,
* the variable part is initialized to 0 or an equivalent value depending
* on the type. \a vptr is not used when the new instance is of the
* #MOO_OBJ_TYPE_OOP type.
*
*/
MOO_EXPORT moo_oop_t moo_instantiate (
moo_t* moo,
@ -1417,6 +1426,22 @@ MOO_EXPORT int moo_inttoooi (
moo_ooi_t* i
);
/* =========================================================================
* TRAILER MANAGEMENT
* ========================================================================= */
MOO_EXPORT int moo_setclasstrsize (
moo_t* moo,
moo_oop_t _class,
moo_oow_t size
);
MOO_EXPORT void* moo_getobjtrailer (
moo_t* moo,
moo_oop_t obj,
moo_oow_t* size
);
/* =========================================================================
* TEMPORARY OOP MANAGEMENT FUNCTIONS
* ========================================================================= */

View File

@ -72,7 +72,7 @@ moo_oop_t moo_allocoopobj (moo_t* moo, moo_oow_t size)
return (moo_oop_t)hdr;
}
#if defined(MOO_USE_OBJECT_TRAILER)
#if defined(MOO_USE_METHOD_TRAILER)
moo_oop_t moo_allocoopobjwithtrailer (moo_t* moo, moo_oow_t size, const moo_oob_t* bptr, moo_oow_t blen)
{
moo_oop_oop_t hdr;
@ -333,7 +333,7 @@ moo_oop_t moo_instantiate2 (moo_t* moo, moo_oop_t _class, const void* vptr, moo_
switch (type)
{
case MOO_OBJ_TYPE_OOP:
/* NOTE: vptr is not used for GC unsafety */
/* [NOTE] vptr is not used for GC unsafety. read comment in moo_instantiate() */
oop = moo_allocoopobj (moo, alloclen);
break;
@ -365,7 +365,7 @@ moo_oop_t moo_instantiate2 (moo_t* moo, moo_oop_t _class, const void* vptr, moo_
}
#if defined(MOO_USE_OBJECT_TRAILER)
#if defined(MOO_USE_METHOD_TRAILER)
moo_oop_t moo_instantiatewithtrailer (moo_t* moo, moo_oop_t _class, moo_oow_t vlen, const moo_oob_t* tptr, moo_oow_t tlen)
{
@ -387,12 +387,16 @@ moo_oop_t moo_instantiatewithtrailer (moo_t* moo, moo_oop_t _class, moo_oow_t vl
switch (type)
{
case MOO_OBJ_TYPE_OOP:
/* NOTE: vptr is not used for GC unsafety */
oop = moo_allocoopobjwithtrailer(moo, alloclen, tptr, tlen);
break;
default:
moo->errnum = MOO_EINTERN;
MOO_DEBUG3 (moo, "Not allowed to instantiate a non-pointer object of the %.*js class with trailer %zu\n",
MOO_OBJ_GET_SIZE(((moo_oop_class_t)_class)->name),
MOO_OBJ_GET_CHAR_SLOT(((moo_oop_class_t)_class)->name),
tlen);
moo->errnum = MOO_EPERM;
oop = MOO_NULL;
break;
}

View File

@ -47,7 +47,6 @@ struct link_t
typedef struct ffi_t ffi_t;
struct ffi_t
{
MOO_OBJ_HEADER;
void* handle;
#if defined(USE_DYNCALL)
@ -75,16 +74,9 @@ static void free_linked_cas (moo_t* moo, ffi_t* ffi)
}
}
static moo_pfrc_t pf_newinstsize (moo_t* moo, moo_ooi_t nargs)
{
moo_ooi_t newinstsize = MOO_SIZEOF(ffi_t) - MOO_SIZEOF(moo_obj_t);
MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(newinstsize));
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_open (moo_t* moo, moo_ooi_t nargs)
{
ffi_t* rcv;
ffi_t* ffi;
moo_oop_t name;
void* handle;
#if defined(USE_DYNCALL)
@ -97,10 +89,10 @@ static moo_pfrc_t pf_open (moo_t* moo, moo_ooi_t nargs)
goto softfail;
}
rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs);
ffi = (ffi_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
name = MOO_STACK_GETARG(moo, nargs, 0);
if (!MOO_ISTYPEOF(moo, name, MOO_OBJ_TYPE_CHAR))
if (!MOO_OBJ_IS_CHAR_POINTER(name))
{
moo_seterrnum (moo, MOO_EINVAL);
goto softfail;
@ -112,7 +104,7 @@ static moo_pfrc_t pf_open (moo_t* moo, moo_ooi_t nargs)
goto softfail;
}
if (rcv->handle)
if (ffi->handle)
{
moo_seterrnum (moo, MOO_EPERM); /* no allowed to open again */
goto softfail;
@ -131,13 +123,13 @@ static moo_pfrc_t pf_open (moo_t* moo, moo_ooi_t nargs)
}
#endif
rcv->handle = handle;
ffi->handle = handle;
#if defined(USE_DYNCALL)
rcv->dc = dc;
ffi->dc = dc;
#endif
MOO_DEBUG3 (moo, "<ffi.open> %.*js => %p\n", MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot, rcv->handle);
MOO_DEBUG3 (moo, "<ffi.open> %.*js => %p\n", MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot, ffi->handle);
MOO_STACK_SETRETTORCV (moo, nargs);
return MOO_PF_SUCCESS;
@ -148,7 +140,7 @@ softfail:
static moo_pfrc_t pf_close (moo_t* moo, moo_ooi_t nargs)
{
ffi_t* rcv;
ffi_t* ffi;
if (nargs != 0)
{
@ -156,7 +148,7 @@ static moo_pfrc_t pf_close (moo_t* moo, moo_ooi_t nargs)
goto softfail;
}
rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs);
ffi = (ffi_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
if (!moo->vmprim.dl_open)
{
@ -164,17 +156,17 @@ static moo_pfrc_t pf_close (moo_t* moo, moo_ooi_t nargs)
goto softfail;
}
MOO_DEBUG1 (moo, "<ffi.close> %p\n", rcv->handle);
MOO_DEBUG1 (moo, "<ffi.close> %p\n", ffi->handle);
free_linked_cas (moo, rcv);
free_linked_cas (moo, ffi);
#if defined(USE_DYNCALL)
dcFree (rcv->dc);
rcv->dc = MOO_NULL;
dcFree (ffi->dc);
ffi->dc = MOO_NULL;
#endif
moo->vmprim.dl_close (moo, rcv->handle);
rcv->handle = MOO_NULL;
moo->vmprim.dl_close (moo, ffi->handle);
ffi->handle = MOO_NULL;
MOO_STACK_SETRETTORCV (moo, nargs);
return MOO_PF_SUCCESS;
@ -187,14 +179,14 @@ softfail:
static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
{
#if defined(USE_DYNCALL)
ffi_t* rcv;
ffi_t* ffi;
moo_oop_t fun, sig, args;
moo_oow_t i, j;
void* f;
moo_oop_oop_t arr;
int ellipsis = 0;
rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs);
ffi = (ffi_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
if (nargs < 3) goto inval;
fun = MOO_STACK_GETARG(moo, nargs, 0);
@ -203,7 +195,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
/* the signature must not be empty. at least the return type must be
* specified */
if (!MOO_ISTYPEOF(moo, sig, MOO_OBJ_TYPE_CHAR) || MOO_OBJ_GET_SIZE(sig) <= 0) goto inval;
if (!MOO_OBJ_IS_CHAR_POINTER(sig) || MOO_OBJ_GET_SIZE(sig) <= 0) goto inval;
#if 0
/* TODO: check if arr is a kind of array??? or check if it's indexed */
@ -213,19 +205,19 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
f = MOO_OOP_TO_SMPTR(fun);
arr = (moo_oop_oop_t)args;
MOO_DEBUG2 (moo, "<ffi.call> %p in %p\n", f, rcv->handle);
MOO_DEBUG2 (moo, "<ffi.call> %p in %p\n", f, ffi->handle);
dcMode (rcv->dc, DC_CALL_C_DEFAULT);
dcReset (rcv->dc);
dcMode (ffi->dc, DC_CALL_C_DEFAULT);
dcReset (ffi->dc);
i = 0;
if (i < MOO_OBJ_GET_SIZE(sig) && ((moo_oop_char_t)sig)->slot[i] == '|')
{
dcMode (rcv->dc, DC_CALL_C_ELLIPSIS);
dcMode (ffi->dc, DC_CALL_C_ELLIPSIS);
/* the error code should be DC_ERROR_UNSUPPORTED_MODE */
if (dcGetError(rcv->dc) != DC_ERROR_NONE) goto noimpl;
dcReset (rcv->dc);
if (dcGetError(ffi->dc) != DC_ERROR_NONE) goto noimpl;
dcReset (ffi->dc);
ellipsis = 1;
i++;
}
@ -246,10 +238,10 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
{
if (ellipsis)
{
dcMode (rcv->dc, DC_CALL_C_ELLIPSIS_VARARGS);
dcMode (ffi->dc, DC_CALL_C_ELLIPSIS_VARARGS);
/* the error code should be DC_ERROR_UNSUPPORTED_MODE */
if (dcGetError(rcv->dc) != DC_ERROR_NONE) goto noimpl;
if (dcGetError(ffi->dc) != DC_ERROR_NONE) goto noimpl;
}
continue;
}
@ -263,7 +255,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
/* TODO: support more types... */
case 'c':
if (!MOO_OOP_IS_CHAR(arg)) goto inval;
dcArgChar (rcv->dc, MOO_OOP_TO_CHAR(arr->slot[j]));
dcArgChar (ffi->dc, MOO_OOP_TO_CHAR(arr->slot[j]));
j++;
break;
@ -272,7 +264,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
{
moo_ooi_t v;
if (moo_inttoooi(moo, arg, &v) == 0) goto inval;
dcArgInt (rcv->dc, i);
dcArgInt (ffi->dc, i);
j++;
break;
}
@ -282,7 +274,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
moo_ooi_t v;
arg_as_long:
if (moo_inttoooi(moo, arg, &v) == 0) goto inval;
dcArgLong (rcv->dc, v);
dcArgLong (ffi->dc, v);
j++;
break;
}
@ -298,7 +290,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
if (moo_inttointmax (moo, arg, &v) == 0) goto inval; */
# error UNSUPPORTED MOO_SIZEOF_LONG_LONG.
# endif
dcArgLongLong (rcv->dc, v);
dcArgLongLong (ffi->dc, v);
j++;
break;
#else
@ -313,19 +305,19 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
{
moo_bch_t* ptr;
if (!MOO_ISTYPEOF(moo,arg,MOO_OBJ_TYPE_CHAR)) goto inval;
if (!MOO_OBJ_IS_CHAR_POINTER(arg)) goto inval;
#if defined(MOO_OOCH_IS_UCH)
ptr = moo_dupootobcharswithheadroom (moo, MOO_SIZEOF_VOID_P, MOO_OBJ_GET_CHAR_SLOT(arg), MOO_OBJ_GET_SIZE(arg), MOO_NULL);
if (!ptr) goto softfail; /* out of system memory or conversion error - soft failure */
link_ca (rcv, ptr);
link_ca (ffi, ptr);
#else
ptr = MOO_OBJ_GET_CHAR_SLOT(arg);
/*ptr = moo_dupoochars (moo, MOO_OBJ_GET_CHAR_SLOT(arg), MOO_OBJ_GET_SIZE(arg));
if (!ptr) goto softfail;*/ /* out of system memory or conversion error - soft failure */
#endif
dcArgPointer (rcv->dc, ptr);
dcArgPointer (ffi->dc, ptr);
j++;
break;
}
@ -334,7 +326,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
{
moo_uch_t* ptr;
if (!MOO_ISTYPEOF(moo,arg,MOO_OBJ_TYPE_CHAR)) goto inval;
if (!MOO_OBJ_IS_CHAR_POINTER(arg)) goto inval;
#if defined(MOO_OOCH_IS_UCH)
ptr = MOO_OBJ_GET_CHAR_SLOT(arg);
@ -343,10 +335,10 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
#else
ptr = moo_dupootoucharswithheadroom (moo, MOO_SIZEOF_VOID_P, MOO_OBJ_GET_CHAR_SLOT(arg), MOO_OBJ_GET_SIZE(arg), MOO_NULL);
if (!ptr) goto softfail; /* out of system memory or conversion error - soft failure */
link_ca (rcv, ptr);
link_ca (ffi, ptr);
#endif
dcArgPointer (rcv->dc, ptr);
dcArgPointer (ffi->dc, ptr);
j++;
break;
}
@ -365,7 +357,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
/* TODO: proper return value conversion */
case 'c':
{
char r = dcCallChar (rcv->dc, f);
char r = dcCallChar (ffi->dc, f);
MOO_STACK_SETRET (moo, nargs, MOO_CHAR_TO_OOP(r));
break;
}
@ -374,7 +366,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t r;
r = moo_ooitoint (moo, dcCallInt (rcv->dc, f));
r = moo_ooitoint (moo, dcCallInt (ffi->dc, f));
if (!r) goto hardfail;
MOO_STACK_SETRET (moo, nargs, r);
break;
@ -384,7 +376,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t r;
ret_as_long:
r = moo_ooitoint (moo, dcCallLong (rcv->dc, f));
r = moo_ooitoint (moo, dcCallLong (ffi->dc, f));
if (!r) goto hardfail;
MOO_STACK_SETRET (moo, nargs, r);
break;
@ -395,7 +387,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
#if (MOO_SIZEOF_LONG_LONG > 0)
moo_oop_t r;
# if (MOO_SIZEOF_LONG_LONG <= MOO_SIZEOF_OOI_T)
r = moo_ooitoint (moo, dcCallLongLong (rcv->dc, f));
r = moo_ooitoint (moo, dcCallLongLong (ffi->dc, f));
# else
# error UNSUPPORTED MOO_SIZEOF_LONG_LONG
# endif
@ -419,7 +411,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
moo_oop_t s;
moo_bch_t* r;
r = dcCallPointer (rcv->dc, f);
r = dcCallPointer (ffi->dc, f);
#if defined(MOO_OOCH_IS_UCH)
s = moo_makestringwithbchars (moo, r, moo_countbcstr(r));
@ -441,7 +433,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
moo_oop_t s;
moo_uch_t* r;
r = dcCallPointer (rcv->dc, f);
r = dcCallPointer (ffi->dc, f);
#if defined(MOO_OOCH_IS_UCH)
s = moo_makestring(moo, r, moo_countucstr(r));
@ -460,12 +452,12 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs)
default:
call_void:
dcCallVoid (rcv->dc, f);
dcCallVoid (ffi->dc, f);
MOO_STACK_SETRETTORCV (moo, nargs);
break;
}
free_linked_cas (moo, rcv);
free_linked_cas (moo, ffi);
return MOO_PF_SUCCESS;
noimpl:
@ -477,12 +469,12 @@ inval:
goto softfail;
softfail:
free_linked_cas (moo, rcv);
free_linked_cas (moo, ffi);
MOO_STACK_SETRETTOERROR (moo, nargs);
return MOO_PF_SUCCESS;
hardfail:
free_linked_cas (moo, rcv);
free_linked_cas (moo, ffi);
return MOO_PF_HARD_FAILURE;
#else
@ -494,7 +486,7 @@ hardfail:
static moo_pfrc_t pf_getsym (moo_t* moo, moo_ooi_t nargs)
{
ffi_t* rcv;
ffi_t* ffi;
moo_oop_t name;
void* sym;
@ -504,10 +496,10 @@ static moo_pfrc_t pf_getsym (moo_t* moo, moo_ooi_t nargs)
goto softfail;
}
rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs);
ffi = (ffi_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
name = MOO_STACK_GETARG(moo, nargs, 0);
if (!MOO_ISTYPEOF(moo,name,MOO_OBJ_TYPE_CHAR))
if (!MOO_OBJ_IS_CHAR_POINTER(name))
{
moo_seterrnum (moo, MOO_EINVAL);
goto softfail;
@ -519,10 +511,10 @@ static moo_pfrc_t pf_getsym (moo_t* moo, moo_ooi_t nargs)
goto softfail;
}
sym = moo->vmprim.dl_getsym (moo, rcv->handle, ((moo_oop_char_t)name)->slot);
sym = moo->vmprim.dl_getsym (moo, ffi->handle, ((moo_oop_char_t)name)->slot);
if (!sym) goto softfail;
MOO_DEBUG4 (moo, "<ffi.getsym> %.*js => %p in %p\n", MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot, sym, rcv->handle);
MOO_DEBUG4 (moo, "<ffi.getsym> %.*js => %p in %p\n", MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot, sym, ffi->handle);
MOO_ASSERT (moo, MOO_IN_SMPTR_RANGE(sym));
MOO_STACK_SETRET (moo, nargs, MOO_SMPTR_TO_OOP(sym));
@ -549,7 +541,6 @@ struct fnctab_t
static fnctab_t fnctab[] =
{
{ C, { '_','n','e','w','I','n','s','t','S','i','z','e','\0' }, 0, pf_newinstsize },
{ I, { 'c','a','l','l','\0' }, 1, pf_call },
{ I, { 'c','a','l','l',':','s','i','g',':','w','i','t','h',':','\0' }, 0, pf_call },
{ I, { 'c','l','o','s','e','\0' }, 0, pf_close },
@ -564,6 +555,8 @@ static int import (moo_t* moo, moo_mod_t* mod, moo_oop_t _class)
int ret = 0;
moo_oow_t i;
if (moo_setclasstrsize (moo, _class, MOO_SIZEOF(ffi_t)) <= -1) return -1;
moo_pushtmp (moo, &_class);
for (i = 0; i < MOO_COUNTOF(fnctab); i++)
{

View File

@ -39,30 +39,22 @@
typedef struct stdio_t stdio_t;
struct stdio_t
{
MOO_OBJ_HEADER;
FILE* fp;
};
static moo_pfrc_t pf_newinstsize (moo_t* moo, moo_ooi_t nargs)
{
moo_ooi_t newinstsize = MOO_SIZEOF(stdio_t) - MOO_SIZEOF(moo_obj_t);
MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(newinstsize));
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_open (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_char_t name;
moo_oop_char_t mode;
stdio_t* rcv;
stdio_t* stdio;
#if defined(MOO_OOCH_IS_UCH)
moo_oow_t ucslen, bcslen;
moo_bch_t namebuf[PATH_MAX];
moo_bch_t modebuf[32]; /* TODO: dynamic-sized conversion?? */
moo_bch_t modebuf[32]; /* TODO: mode should not be long but use dynamic-sized conversion?? */
#endif
rcv = (stdio_t*)MOO_STACK_GETRCV(moo, nargs);
stdio = (stdio_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
name = (moo_oop_char_t)MOO_STACK_GETARG(moo, nargs, 0);
mode = (moo_oop_char_t)MOO_STACK_GETARG(moo, nargs, 1);
@ -77,11 +69,11 @@ static moo_pfrc_t pf_open (moo_t* moo, moo_ooi_t nargs)
if (moo_convootobchars (moo, mode->slot, &ucslen, modebuf, &bcslen) <= -1) goto softfail;
modebuf[bcslen] = '\0';
rcv->fp = fopen (namebuf, modebuf);
stdio->fp = fopen (namebuf, modebuf);
#else
rcv->fp = fopen (name->slot, mode->slot);
stdio->fp = fopen (name->slot, mode->slot);
#endif
if (!rcv->fp)
if (!stdio->fp)
{
moo_seterrnum (moo, moo_syserrtoerrnum(errno));
goto softfail;
@ -97,13 +89,13 @@ softfail:
static moo_pfrc_t pf_close (moo_t* moo, moo_ooi_t nargs)
{
stdio_t* rcv;
stdio_t* stdio;
rcv = (stdio_t*)MOO_STACK_GETRCV(moo, nargs);
if (rcv->fp)
stdio = (stdio_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
if (stdio->fp)
{
fclose (rcv->fp);
rcv->fp = NULL;
fclose (stdio->fp);
stdio->fp = NULL;
}
MOO_STACK_SETRETTORCV (moo, nargs);
@ -112,17 +104,17 @@ static moo_pfrc_t pf_close (moo_t* moo, moo_ooi_t nargs)
static moo_pfrc_t pf_gets (moo_t* moo, moo_ooi_t nargs)
{
/* return how many bytes have been written.. */
/* TODO: ...*/
MOO_STACK_SETRETTORCV (moo, nargs);
return MOO_PF_SUCCESS;
}
static moo_pfrc_t __pf_puts (moo_t* moo, moo_ooi_t nargs, moo_oow_t limit)
{
stdio_t* rcv;
stdio_t* stdio;
moo_ooi_t i;
rcv = (stdio_t*)MOO_STACK_GETRCV(moo, nargs);
stdio = (stdio_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL);
for (i = 0; i < nargs; i++)
{
@ -163,7 +155,7 @@ static moo_pfrc_t __pf_puts (moo_t* moo, moo_ooi_t nargs, moo_oow_t limit)
if (n != -2 || ucslen <= 0) goto softfail;
}
if (fwrite (bcs, 1, bcslen, rcv->fp) < bcslen)
if (fwrite (bcs, 1, bcslen, stdio->fp) < bcslen)
{
moo_seterrnum (moo, moo_syserrtoerrnum(errno));
goto softfail;
@ -175,7 +167,7 @@ static moo_pfrc_t __pf_puts (moo_t* moo, moo_ooi_t nargs, moo_oow_t limit)
}
#else
puts_string:
if (fwrite (x->slot, 1, MOO_OBJ_GET_SIZE(x), rcv->fp) < MOO_OBJ_GET_SIZE(x))
if (fwrite (x->slot, 1, MOO_OBJ_GET_SIZE(x), stdio->fp) < MOO_OBJ_GET_SIZE(x))
{
moo_seterrnum (moo, moo_syserrtoerrnum(errno));
moo_seterrnum (moo, moo_syserrtoerrnum(errno));
@ -228,7 +220,6 @@ struct fnctab_t
static fnctab_t fnctab[] =
{
{ C, { '_','n','e','w','I','n','s','t','S','i','z','e','\0' }, 0, pf_newinstsize },
{ I, { 'c','l','o','s','e','\0' }, 0, pf_close },
{ I, { 'g','e','t','s','\0' }, 0, pf_gets },
{ I, { 'o','p','e','n',':','f','o','r',':','\0' }, 0, pf_open },
@ -245,6 +236,8 @@ static int import (moo_t* moo, moo_mod_t* mod, moo_oop_t _class)
int ret = 0;
moo_oow_t i;
if (moo_setclasstrsize (moo, _class, MOO_SIZEOF(stdio_t)) <= -1) return -1;
moo_pushtmp (moo, &_class);
for (i = 0; i < MOO_COUNTOF(fnctab); i++)
{

View File

@ -48,26 +48,17 @@ struct fnctab_t
typedef struct x11_t x11_t;
struct x11_t
{
MOO_OBJ_HEADER;
xcb_connection_t* c;
};
typedef struct x11_window_t x11_window_t;
struct x11_window_t
typedef struct x11_win_t x11_win_t;
struct x11_win_t
{
MOO_OBJ_HEADER;
xcb_window_t w;
};
/* ------------------------------------------------------------------------ */
static moo_pfrc_t pf_newinstsize (moo_t* moo, moo_ooi_t nargs)
{
moo_ooi_t newinstsize = MOO_SIZEOF(x11_t) - MOO_SIZEOF(moo_obj_t);
MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(newinstsize));
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_connect (moo_t* moo, moo_ooi_t nargs)
{
x11_t* x11;
@ -84,7 +75,7 @@ static moo_pfrc_t pf_connect (moo_t* moo, moo_ooi_t nargs)
/*
name = MOO_STACK_GETARG(moo, nargs, 0);
if (!MOO_ISTYPEOF(moo, name, MOO_OBJ_TYPE_CHAR))
if (!MOO_OBJ_IS_CHAR_POINTER(name))
{
moo_seterrnum (moo, MOO_EINVAL);
goto softfail;
@ -135,14 +126,6 @@ softfail:
/* ------------------------------------------------------------------------ */
static moo_pfrc_t pf_win_newinstsize (moo_t* moo, moo_ooi_t nargs)
{
moo_ooi_t newinstsize = MOO_SIZEOF(x11_window_t) - MOO_SIZEOF(moo_obj_t);
MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(newinstsize));
MOO_DEBUG0 (moo, "x11.window.newinstsize....\n");
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_win_create (moo_t* moo, moo_ooi_t nargs)
{
MOO_STACK_SETRET (moo, nargs, moo->_nil);
@ -181,7 +164,6 @@ MOO_DEBUG0 (moo, "x11.window.destroy....\n");
/* ------------------------------------------------------------------------ */
static moo_pfimpl_t search_fnctab (moo_t* moo, const fnctab_t* fnctab, moo_oow_t fnclen, const moo_ooch_t* name)
{
int left, right, mid, n;
@ -230,13 +212,13 @@ static int import_fnctab (moo_t* moo, moo_mod_t* mod, moo_oop_t _class, const fn
static fnctab_t x11_fnctab[] =
{
{ C, { '_','n','e','w','I','n','s','t','S','i','z','e','\0' }, 0, pf_newinstsize },
{ I, { 'c','o','n','n','e','c','t','\0' }, 0, pf_connect },
{ I, { 'd','i','s','c','o','n','n','e','c','t','\0' }, 0, pf_disconnect }
};
static int x11_import (moo_t* moo, moo_mod_t* mod, moo_oop_t _class)
{
if (moo_setclasstrsize (moo, _class, MOO_SIZEOF(x11_t)) <= -1) return -1;
return import_fnctab (moo, mod, _class, x11_fnctab, MOO_COUNTOF(x11_fnctab));
}
@ -263,13 +245,13 @@ int moo_mod_x11 (moo_t* moo, moo_mod_t* mod)
static fnctab_t x11_win_fnctab[] =
{
{ C, { '_','n','e','w','I','n','s','t','S','i','z','e','\0' }, 0, pf_win_newinstsize },
{ I, { 'c','r','e','a','t','e','\0' }, 0, pf_win_create },
{ I, { 'd','i','s','t','r','o','y','\0' }, 0, pf_win_destroy }
};
static int x11_win_import (moo_t* moo, moo_mod_t* mod, moo_oop_t _class)
{
if (moo_setclasstrsize (moo, _class, MOO_SIZEOF(x11_win_t)) <= -1) return -1;
return import_fnctab (moo, mod, _class, x11_win_fnctab, MOO_COUNTOF(x11_win_fnctab));
}