NewtVM.c

説明を見る。
00001 /*------------------------------------------------------------------------*/
00013 /* ヘッダファイル */
00014 #include <stdlib.h>
00015 
00016 #include "NewtErrs.h"
00017 #include "NewtVM.h"
00018 #include "NewtBC.h"
00019 #include "NewtGC.h"
00020 #include "NewtMem.h"
00021 #include "NewtEnv.h"
00022 #include "NewtObj.h"
00023 #include "NewtFns.h"
00024 #include "NewtStr.h"
00025 #include "NewtFile.h"
00026 #include "NewtIO.h"
00027 #include "NewtPrint.h"
00028 #include "NewtNSOF.h"
00029 
00030 
00031 /* 型宣言 */
00032 typedef void(*instruction_t)(int16_t b);            
00033 typedef void(*simple_instruction_t)(void);          
00034 typedef newtRef(*nvm_func_t)();                     
00035 
00036 
00037 /* グローバル変数 */
00038 vm_env_t    vm_env;
00039 
00040 
00041 #pragma mark -
00042 /* マクロ */
00043 
00044 #define START_LOCALARGS     3                                       
00045 
00046 
00047 #define BC                  (vm_env.bc)                             
00048 #define BCLEN               (vm_env.bclen)                          
00049 
00050 #define CALLSTACK           ((vm_reg_t *)vm_env.callstack.stackp)   
00051 #define CALLSP              (vm_env.callstack.sp)                   
00052 #define EXCPSTACK           ((vm_excp_t *)vm_env.excpstack.stackp)  
00053 #define EXCPSP              (vm_env.excpstack.sp)                   
00054 #define CURREXCP            (vm_env.currexcp)                       
00055 
00056 #define REG                 (vm_env.reg)                            
00057 #define STACK               ((newtRef *)vm_env.stack.stackp)        
00058 
00059 #define FUNC                ((REG).func)                            
00060 #define PC                  ((REG).pc)                              
00061 #define SP                  ((REG).sp)                              
00062 #define LOCALS              ((REG).locals)                          
00063 #define RCVR                ((REG).rcvr)                            
00064 #define IMPL                ((REG).impl)                            
00065 
00066 
00067 #pragma mark -
00068 /* 関数プロトタイプ */
00069 
00070 static newtErr      NVMGetExceptionErrCode(newtRefArg r, bool dump);
00071 static newtRef      NVMMakeExceptionFrame(newtRefArg name, newtRefArg data);
00072 static void         NVMClearCurrException(void);
00073 
00074 static void         NVMSetFn(newtRefArg fn);
00075 static void         NVMNoStackFrameForReturn(void);
00076 
00077 static void         reg_rewind(int32_t sp);
00078 static void         reg_pop(void);
00079 static void         reg_push(int32_t sp);
00080 static void         reg_save(int32_t sp);
00081 
00082 static newtRef      stk_pop0(void);
00083 static newtRef      stk_pop(void);
00084 static void         stk_pop_n(int32_t n, newtRef a[]);
00085 static void         stk_remove(uint16_t n);
00086 static newtRef      stk_top(void);
00087 static void         stk_push(newtRefArg value);
00088 
00089 static bool         excp_push(newtRefArg sym, newtRefArg pc);
00090 static void         excp_pop(void);
00091 static vm_excp_t *  excp_top(void);
00092 static void         excp_pop_handlers(void);
00093 
00094 static newtRef      liter_get(int16_t n);
00095 
00096 static newtRef      iter_new(newtRefArg r, newtRefArg deeply);
00097 static void         iter_next(newtRefArg iter);
00098 static bool         iter_done(newtRefArg iter);
00099 
00100 static newtRef      NVMMakeArgsArray(uint16_t numArgs);
00101 static void         NVMBindArgs(uint16_t numArgs);
00102 static void         NVMThrowBC(newtErr err, newtRefArg value, int16_t pop, bool push);
00103 static newtErr      NVMFuncCheck(newtRefArg fn, int16_t numArgs);
00104 static void         NVMCallNativeFn(newtRefArg fn, int16_t numArgs);
00105 static void         NVMCallNativeFunc(newtRefArg fn, newtRefArg rcvr, int16_t numArgs);
00106 static void         NVMFuncCall(newtRefArg fn, int16_t numArgs);
00107 static void         NVMMessageSend(newtRefArg impl, newtRefArg receiver, newtRefArg fn, int16_t numArgs);
00108 
00109 static newtRef      vm_send(int16_t b, newtErr * errP);
00110 static newtRef      vm_resend(int16_t b, newtErr * errP);
00111 
00112 static void         si_pop(void);
00113 static void         si_dup(void);
00114 static void         si_return(void);
00115 static void         si_pushself(void);
00116 static void         si_set_lex_scope(void);
00117 static void         si_iternext(void);
00118 static void         si_iterdone(void);
00119 static void         si_pop_handlers(void);
00120 
00121 static void         fn_add(void);
00122 static void         fn_subtract(void);
00123 static void         fn_aref(void);
00124 static void         fn_set_aref(void);
00125 static void         fn_equals(void);
00126 static void         fn_not(void);
00127 static void         fn_not_equals(void);
00128 static void         fn_multiply(void);
00129 static void         fn_divide(void);
00130 static void         fn_div(void);
00131 static void         fn_less_than(void);
00132 static void         fn_greater_than(void);
00133 static void         fn_greater_or_equal(void);
00134 static void         fn_less_or_equal(void);
00135 static void         fn_bit_and(void);
00136 static void         fn_bit_or(void);
00137 static void         fn_bit_not(void);
00138 static void         fn_new_iterator(void);
00139 static void         fn_length(void);
00140 static void         fn_clone(void);
00141 static void         fn_set_class(void);
00142 static void         fn_add_array_slot(void);
00143 static void         fn_stringer(void);
00144 static void         fn_has_path(void);
00145 static void         fn_classof(void);
00146 
00147 static void         is_dummy(int16_t b);
00148 static void         is_simple_instructions(int16_t b);
00149 static void         is_push(int16_t b);
00150 static void         is_push_constant(int16_t b);
00151 static void         is_call(int16_t b);
00152 static void         is_invoke(int16_t b);
00153 static void         is_send(int16_t b);
00154 static void         is_send_if_defined(int16_t b);
00155 static void         is_resend(int16_t b);
00156 static void         is_resend_if_defined(int16_t b);
00157 static void         is_branch(int16_t b);
00158 static void         is_branch_if_true(int16_t b);
00159 static void         is_branch_if_false(int16_t b);
00160 static void         is_find_var(int16_t b);
00161 static void         is_get_var(int16_t b);
00162 static void         is_make_frame(int16_t b);
00163 static void         is_make_array(int16_t b);
00164 static void         is_get_path(int16_t b);
00165 static void         is_set_path(int16_t b);
00166 static void         is_set_var(int16_t b);
00167 static void         is_find_and_set_var(int16_t b);
00168 static void         is_incr_var(int16_t b);
00169 static void         is_branch_if_loop_not_done(int16_t b);
00170 static void         is_freq_func(int16_t b);
00171 static void         is_new_handlers(int16_t b);
00172 
00173 static void         NVMDumpInstResult(FILE * f);
00174 static void         NVMDumpInstCode(FILE * f, uint8_t * bc, uint32_t pc, uint16_t len);
00175 
00176 static void         NVMInitREG(void);
00177 static void         NVMInitSTACK(void);
00178 static void         NVMCleanSTACK(void);
00179 
00180 static void         NVMInitGlobalFns0(void);
00181 static void         NVMInitGlobalFns1(void);
00182 static void         NVMInitExGlobalFns(void);
00183 static void         NVMInitDebugGlobalFns(void);
00184 static void         NVMInitGlobalFns(void);
00185 
00186 static void         NVMInitGlobalVars(void);
00187 
00188 static void         NVMInit(void);
00189 static void         NVMClean(void);
00190 static void         NVMLoop(uint32_t callsp);
00191 
00192 static newtRef      NVMInterpret2(nps_syntax_node_t * stree, uint32_t numStree, newtErr * errP);
00193 
00194 
00195 /* ローカル変数 */
00196 
00198 static simple_instruction_t simple_instructions[] =
00199             {
00200                 si_pop,             // 000 pop
00201                 si_dup,             // 001 dup
00202                 si_return,          // 002 return
00203                 si_pushself,        // 003 push-self
00204                 si_set_lex_scope,   // 004 set-lex-scope
00205                 si_iternext,        // 005 iter-next
00206                 si_iterdone,        // 006 iter-done
00207                 si_pop_handlers     // 007 000 001 pop-handlers
00208             };
00209 
00210 
00212 static simple_instruction_t fn_instructions[] =
00213             {
00214                 fn_add,                 //  0 add               |+|
00215                 fn_subtract,            //  1 subtract          |-|
00216                 fn_aref,                //  2 aref              aref
00217                 fn_set_aref,            //  3 set-aref          setAref
00218                 fn_equals,              //  4 equals            |=|
00219                 fn_not,                 //  5 not               |not|
00220                 fn_not_equals,          //  6 not-equals        |<>|
00221                 fn_multiply,            //  7 multiply          |*|
00222                 fn_divide,              //  8 divide            |/|
00223                 fn_div,                 //  9 div               |div|
00224                 fn_less_than,           // 10 less-than         |<|
00225                 fn_greater_than,        // 11 greater-than      |>|
00226                 fn_greater_or_equal,    // 12 greater-or-equal  |>=|
00227                 fn_less_or_equal,       // 13 less-or-equal     |<=|
00228                 fn_bit_and,             // 14 bit-and           BAnd
00229                 fn_bit_or,              // 15 bit-or            BOr
00230                 fn_bit_not,             // 16 bit-not           BNot
00231                 fn_new_iterator,        // 17 new-iterator      newIterator
00232                 fn_length,              // 18 length            Length
00233                 fn_clone,               // 19 clone             Clone
00234                 fn_set_class,           // 20 set-class         SetClass
00235                 fn_add_array_slot,      // 21 add-array-slot    AddArraySlot
00236                 fn_stringer,            // 22 stringer          Stringer
00237                 fn_has_path,            // 23 has-path          none
00238                 fn_classof              // 24 class-of          ClassOf
00239             };
00240 
00242 static instruction_t    is_instructions[] =
00243             {
00244                 is_simple_instructions,     // 00x simple instructions
00245                 is_dummy,                   // 01x
00246                 is_dummy,                   // 02x
00247                 is_push,                    // 03x push
00248                 is_push_constant,           // 04x (B signed) push-constant
00249                 is_call,                    // 05x call
00250                 is_invoke,                  // 06x invoke
00251                 is_send,                    // 07x send
00252                 is_send_if_defined,         // 10x send-if-defined
00253                 is_resend,                  // 11x resend
00254                 is_resend_if_defined,       // 12x resend-if-defined
00255                 is_branch,                  // 13x branch
00256                 is_branch_if_true,          // 14x branch-if-true
00257                 is_branch_if_false,         // 15x branch-if-false
00258                 is_find_var,                // 16x find-var
00259                 is_get_var,                 // 17x get-var
00260                 is_make_frame,              // 20x make-frame
00261                 is_make_array,              // 21x make-array
00262                 is_get_path,                // 220/221 get-path
00263                 is_set_path,                // 230/231 set-path
00264                 is_set_var,                 // 24x set-var
00265                 is_find_and_set_var,        // 25x find-and-set-var
00266                 is_incr_var,                // 26x incr-var
00267                 is_branch_if_loop_not_done, // 27x branch-if-loop-not-done
00268                 is_freq_func,               // 30x freq-func
00269                 is_new_handlers             // 31x new-handlers
00270             };
00271 
00273 static char *   simple_instruction_names[] =
00274             {
00275                 "pop",              // 000 pop
00276                 "dup",              // 001 dup
00277                 "return",           // 002 return
00278                 "push-self",        // 003 push-self
00279                 "set-lex-scope",    // 004 set-lex-scope
00280                 "iter-next",        // 005 iter-next
00281                 "iter-done",        // 006 iter-done
00282                 "pop-handlers"      // 007 000 001 pop-handlers
00283             };
00284 
00286 static char *   fn_instruction_names[] =
00287             {
00288                 "add",              //  0 add       |+|
00289                 "subtract",         //  1 subtract      |-|
00290                 "aref",             //  2 aref      aref
00291                 "set-aref",         //  3 set-aref      setAref
00292                 "equals",           //  4 equals        |=|
00293                 "not",              //  5 not       |not|
00294                 "not-equals",       //  6 not-equals    |<>|
00295                 "multiply",         //  7 multiply      |*|
00296                 "divide",           //  8 divide        |/|
00297                 "div",              //  9 div       |div|
00298                 "less-than",        // 10 less-than     |<|
00299                 "greater-than",     // 11 greater-than  |>|
00300                 "greateror-equal",  // 12 greater-or-equal  |>=|
00301                 "lessor-equal",     // 13 less-or-equal |<=|
00302                 "bit-and",          // 14 bit-and       BAnd
00303                 "bit-or",           // 15 bit-or        BOr
00304                 "bit-not",          // 16 bit-not       BNot
00305                 "new-iterator",     // 17 new-iterator  newIterator
00306                 "length",           // 18 length        Length
00307                 "clone",            // 19 clone     Clone
00308                 "set-class",        // 20 set-class     SetClass
00309                 "add-array-slot",   // 21 add-array-slot    AddArraySlot
00310                 "stringer",         // 22 stringer      Stringer
00311                 "has-path",         // 23 has-path      none
00312                 "class-of"          // 24 class-of      ClassOf
00313             };
00314 
00316 static char *   vm_instruction_names[] =
00317             {
00318                 "simple-instructions",      // 00x simple instructions
00319                 NULL,                       // 01x
00320                 NULL,                       // 02x
00321                 "push",                     // 03x push
00322                 "push-constant",            // 04x (B signed) push-constant
00323                 "call",                     // 05x call
00324                 "invoke",                   // 06x invoke
00325                 "send",                     // 07x send
00326                 "send-if-defined",          // 10x send-if-defined
00327                 "resend",                   // 11x resend
00328                 "resend-if-defined",        // 12x resend-if-defined
00329                 "branch",                   // 13x branch
00330                 "branch-if-true",           // 14x branch-if-true
00331                 "branch-if-false",          // 15x branch-if-false
00332                 "find-var",                 // 16x find-var
00333                 "get-var",                  // 17x get-var
00334                 "make-frame",               // 20x make-frame
00335                 "make-array",               // 21x make-array
00336                 "get-path",                 // 220/221 get-path
00337                 "set-path",                 // 230/231 set-path
00338                 "set-var",                  // 24x set-var
00339                 "find-and-set-var",         // 25x find-and-set-var
00340                 "incr-var",                 // 26x incr-var
00341                 "branch-if-loop-not-done",  // 27x branch-if-loop-not-done
00342                 "freq-func",                // 30x freq-func
00343                 "new-handlers"              // 31x new-handlers
00344             };
00345 
00346 
00347 #pragma mark -
00348 /*------------------------------------------------------------------------*/
00354 newtRef NVMSelf(void)
00355 {
00356     return RCVR;
00357 }
00358 
00359 
00360 /*------------------------------------------------------------------------*/
00365 newtRef NVMCurrentFunction(void)
00366 {
00367     return FUNC;
00368 }
00369 
00370 
00371 /*------------------------------------------------------------------------*/
00376 newtRef NVMCurrentImplementor(void)
00377 {
00378     return IMPL;
00379 }
00380 
00381 
00382 /*------------------------------------------------------------------------*/
00391 bool NVMHasVar(newtRefArg name)
00392 {
00393     if (NewtHasLexical(LOCALS, name))
00394         return true;
00395 
00396     if (NewtHasVariable(RCVR, name))
00397         return true;
00398 
00399     if (NewtHasGlobalVar(name))
00400         return true;
00401 
00402     return false;
00403 }
00404 
00405 
00406 /*------------------------------------------------------------------------*/
00415 newtErr NVMGetExceptionErrCode(newtRefArg r, bool dump)
00416 {
00417     newtRefVar  err;
00418 
00419     if (NewtRefIsNIL(r))
00420         return kNErrNone;
00421 
00422     if (dump)
00423         NewtPrintObject(stderr, r);
00424 
00425     err = NcGetSlot(r, NSSYM0(error));
00426 
00427     if (NewtRefIsNotNIL(err))
00428         return NewtRefToInteger(err);
00429 
00430     return kNErrBadExceptionName;
00431 }
00432 
00433 
00434 /*------------------------------------------------------------------------*/
00443 newtRef NVMMakeExceptionFrame(newtRefArg name, newtRefArg data)
00444 {
00445     newtRefVar  r;
00446 
00447     r = NcMakeFrame();
00448     NcSetSlot(r, NSSYM0(name), name);
00449 
00450     if (NewtHasSubclass(name, NSSYM0(type.ref)))
00451         NcSetSlot(r, NSSYM0(data), data);
00452     else if (NewtHasSubclass(name, NSSYM0(ext.ex.msg)))
00453         NcSetSlot(r, NSSYM0(message), data);
00454     else
00455         NcSetSlot(r, NSSYM0(error), data);
00456 
00457     return r;
00458 }
00459 
00460 
00461 /*------------------------------------------------------------------------*/
00470 void NVMThrowData(newtRefArg name, newtRefArg data)
00471 {
00472     vm_excp_t * excp;
00473     uint32_t    i;
00474 
00475     // 例外処理中ならクリアする
00476     NVMClearCurrException();
00477 
00478     CURREXCP = data;
00479 
00480     for (i = EXCPSP; 0 < i; i--)
00481     {
00482         excp = &EXCPSTACK[i - 1];
00483 
00484         if (NewtHasSubclass(name, excp->sym))
00485         {
00486             reg_rewind(excp->callsp);
00487             PC = excp->pc;
00488             return;
00489         }
00490     }
00491 
00492     NVMNoStackFrameForReturn();
00493 }
00494 
00495 
00496 /*------------------------------------------------------------------------*/
00505 void NVMThrow(newtRefArg name, newtRefArg data)
00506 {
00507     newtRefVar  r;
00508 
00509     r = NVMMakeExceptionFrame(name, data);
00510     NVMThrowData(name, r);
00511 }
00512 
00513 
00514 /*------------------------------------------------------------------------*/
00520 void NVMRethrow(void)
00521 {
00522     if (NewtRefIsNotNIL(CURREXCP))
00523     {
00524         newtRefVar  currexcp;
00525         newtRefVar  name;
00526 
00527         currexcp = CURREXCP;
00528         name = NcGetSlot(currexcp, NSSYM0(name));
00529 
00530 //        excp_pop_handlers();
00531         NVMThrowData(name, currexcp);
00532     }
00533 }
00534 
00535 
00536 /*------------------------------------------------------------------------*/
00542 newtRef NVMCurrentException(void)
00543 {
00544     return CURREXCP;
00545 }
00546 
00547 
00548 /*------------------------------------------------------------------------*/
00554 void NVMClearCurrException(void)
00555 {
00556     if (NewtRefIsNotNIL(CURREXCP))
00557     {
00558         excp_pop_handlers();
00559         CURREXCP = kNewtRefUnbind;
00560     }
00561 }
00562 
00563 
00564 /*------------------------------------------------------------------------*/
00572 void NVMClearException(void)
00573 {
00574     CURREXCP = kNewtRefUnbind;
00575 }
00576 
00577 
00578 #pragma mark -
00579 /*------------------------------------------------------------------------*/
00587 void NVMSetFn(newtRefArg fn)
00588 {
00589     FUNC = fn;
00590 
00591     if (NewtRefIsNIL(FUNC) || ! NewtRefIsCodeBlock(FUNC))
00592     {
00593         BC = NULL;
00594         BCLEN = 0;
00595     }
00596     else
00597     {
00598         newtRefVar  instr;
00599 
00600         instr = NcGetSlot(FUNC, NSSYM0(instructions));
00601         BC = NewtRefToBinary(instr);
00602         BCLEN = NewtLength(instr);
00603     }
00604 }
00605 
00606 
00607 /*------------------------------------------------------------------------*/
00613 void NVMNoStackFrameForReturn(void)
00614 {
00615     BC = NULL;
00616     BCLEN = 0;
00617     CALLSP = 0;
00618 }
00619 
00620 
00621 #pragma mark *** 呼出しスタック
00622 /*------------------------------------------------------------------------*/
00630 void reg_rewind(int32_t sp)
00631 {
00632     if (sp == CALLSP)
00633         return;
00634 
00635     if (sp < CALLSP)
00636     {
00637         CALLSP = sp;
00638         REG = CALLSTACK[CALLSP];
00639         NVMSetFn(FUNC);
00640     }
00641     else
00642     {
00643         NVMNoStackFrameForReturn();
00644     }
00645 }
00646 
00647 
00648 /*------------------------------------------------------------------------*/
00654 void reg_pop(void)
00655 {
00656     reg_rewind(CALLSP - 1);
00657 }
00658 
00659 
00660 /*------------------------------------------------------------------------*/
00668 void reg_push(int32_t sp)
00669 {
00670     if (! NewtStackExpand(&vm_env.callstack, CALLSP + 1))
00671         return;
00672 
00673     CALLSTACK[CALLSP] = REG;
00674     CALLSTACK[CALLSP].sp = sp;
00675     CALLSP++;
00676 }
00677 
00678 
00679 /*------------------------------------------------------------------------*/
00687 void reg_save(int32_t sp)
00688 {
00689 //    PC++;
00690     reg_push(sp);
00691 }
00692 
00693 
00694 #pragma mark *** スタック
00695 /*------------------------------------------------------------------------*/
00701 newtRef stk_pop0(void)
00702 {
00703     newtRefVar  x = kNewtRefUnbind;
00704 
00705     if (0 < SP)
00706     {
00707         SP--;
00708         x = STACK[SP];
00709     }
00710 
00711     return x;
00712 }
00713 
00714 
00715 /*------------------------------------------------------------------------*/
00721 newtRef stk_pop(void)
00722 {
00723     return NcResolveMagicPointer(stk_pop0());
00724 }
00725 
00726 
00727 /*------------------------------------------------------------------------*/
00736 void stk_pop_n(int32_t n, newtRef a[])
00737 {
00738     for (n--; 0 <= n; n--)
00739     {
00740         a[n] = stk_pop();
00741     }
00742 }
00743 
00744 
00745 /*------------------------------------------------------------------------*/
00751 void stk_remove(uint16_t n)
00752 {
00753     if (n < SP)
00754         SP -= n;
00755     else
00756         SP = 0;
00757 }
00758 
00759 
00760 /*------------------------------------------------------------------------*/
00766 newtRef stk_top(void)
00767 {
00768     if (0 < SP)
00769         return STACK[SP - 1];
00770     else
00771         return kNewtRefNIL;
00772 }
00773 
00774 
00775 /*------------------------------------------------------------------------*/
00783 void stk_push(newtRefArg value)
00784 {
00785     if (! NewtStackExpand(&vm_env.stack, SP + 1))
00786         return;
00787 
00788     STACK[SP] = value;
00789     SP++;
00790 }
00791 
00792 
00793 #pragma mark *** 例外ハンドラスタック
00794 /*------------------------------------------------------------------------*/
00804 bool excp_push(newtRefArg sym, newtRefArg pc)
00805 {
00806     vm_excp_t * excp;
00807 
00808     if (! NewtRefIsSymbol(sym))
00809         return false;
00810 
00811     if (! NewtRefIsInteger(pc))
00812         return false;
00813 
00814     if (! NewtStackExpand(&vm_env.excpstack, EXCPSP + 1))
00815         return false;
00816 
00817     excp = &EXCPSTACK[EXCPSP];
00818 
00819     excp->callsp = CALLSP;
00820     excp->excppc = PC;
00821     excp->sym = sym;
00822     excp->pc = NewtRefToInteger(pc);
00823 
00824     EXCPSP++;
00825 
00826     return true;
00827 }
00828 
00829 /*------------------------------------------------------------------------*/
00835 void excp_pop(void)
00836 {
00837     if (0 < EXCPSP)
00838         EXCPSP--;
00839 }
00840 
00841 /*------------------------------------------------------------------------*/
00847 vm_excp_t * excp_top(void)
00848 {
00849     if (0 < EXCPSP)
00850         return &EXCPSTACK[EXCPSP - 1];
00851     else
00852         return NULL;
00853 }
00854 
00855 
00856 /*------------------------------------------------------------------------*/
00862 void excp_pop_handlers(void)
00863 {
00864     vm_excp_t * excp;
00865 
00866     excp = excp_top();
00867 
00868     if (excp != NULL)
00869     {
00870         uint32_t    excppc;
00871 
00872         excppc = excp->excppc;
00873 
00874         while (excp != NULL)
00875         {
00876             if (excp->excppc != excppc)
00877                 break;
00878 
00879             excp_pop();
00880             excp = excp_top();
00881         }
00882     }
00883 }
00884 
00885 
00886 #pragma mark *** Literals
00887 /*------------------------------------------------------------------------*/
00895 newtRef liter_get(int16_t n)
00896 {
00897     newtRefVar  literals;
00898 
00899     literals = NcGetSlot(FUNC, NSSYM0(literals));
00900 
00901     if (NewtRefIsNotNIL(literals))
00902         return NewtGetArraySlot(literals, n);
00903     else
00904         return kNewtRefNIL;
00905 }
00906 
00907 
00908 #pragma mark *** Iterator
00909 /*------------------------------------------------------------------------*/
00918 newtRef iter_new(newtRefArg r, newtRefArg deeply)
00919 {
00920     newtRefVar  iter;
00921 
00922     iter = NewtMakeArray(NSSYM0(forEachState), kIterALength);
00923 
00924     NewtSetArraySlot(iter, kIterObj, r);
00925 
00926     if (NewtRefIsNIL(deeply))
00927         NewtSetArraySlot(iter, kIterDeeply, deeply);
00928     else
00929         NewtSetArraySlot(iter, kIterDeeply, NcDeeplyLength(r));
00930 
00931     NewtSetArraySlot(iter, kIterPos, NSINT(-1));
00932     NewtSetArraySlot(iter, kIterMax, NcLength(r));
00933 
00934     if (NewtRefIsFrame(r))
00935         NewtSetArraySlot(iter, kIterMap, NewtFrameMap(r));
00936     else
00937         NewtSetArraySlot(iter, kIterMap, kNewtRefNIL);
00938 
00939     iter_next(iter);
00940 
00941     return iter;
00942 }
00943 
00944 
00945 /*------------------------------------------------------------------------*/
00953 void iter_next(newtRefArg iter)
00954 {
00955     newtRefVar  deeply;
00956     newtRefVar  obj;
00957     newtRefVar  index = kNewtRefUnbind;
00958     newtRefVar  value = kNewtRefUnbind;
00959     newtRefVar  map;
00960     int32_t pos;
00961     int32_t len;
00962 
00963     obj = NewtGetArraySlot(iter, kIterObj);
00964     deeply = NewtGetArraySlot(iter, kIterDeeply);
00965     pos = NewtRefToInteger(NewtGetArraySlot(iter, kIterPos));
00966     len = NewtRefToInteger(NewtGetArraySlot(iter, kIterMax));
00967     map = NewtGetArraySlot(iter, kIterMap);
00968 
00969     if (NewtRefIsNIL(deeply) || NewtRefIsNIL(map))
00970     {
00971         pos++;
00972 
00973         if (pos < len)
00974         {
00975             if (NewtRefIsNIL(map))
00976             {
00977                 index = NewtMakeInteger(pos);
00978                 value = NewtARef(obj, pos);
00979             }
00980             else
00981             {
00982                 index = NewtGetArraySlot(map, pos + 1);
00983                 value = NewtGetFrameSlot(obj, pos);
00984             }
00985         }
00986     }
00987     else
00988     {
00989         while (true)
00990         {
00991             pos++;
00992 
00993             if (len <= pos)
00994             {
00995                 obj = NcGetSlot(obj, NSSYM0(_proto));
00996 
00997                 if (NewtRefIsNIL(obj))
00998                 {
00999                     index = kNewtRefUnbind;
01000                     break;
01001                 }
01002 
01003                 map = NewtFrameMap(obj);
01004                 len = NewtLength(obj);
01005 
01006                 NewtSetArraySlot(iter, kIterObj, obj);
01007                 NewtSetArraySlot(iter, kIterMap, map);
01008                 NewtSetArraySlot(iter, kIterMax, NewtMakeInteger(len));
01009 
01010                 pos = -1;
01011                 continue;
01012             }
01013 
01014             index = NewtGetArraySlot(map, pos + 1);
01015 
01016             if (index != NSSYM0(_proto))
01017             {
01018                 value = NewtGetFrameSlot(obj, pos);
01019                 break;
01020             }
01021         }
01022     }
01023 
01024     NewtSetArraySlot(iter, kIterIndex, index);
01025     NewtSetArraySlot(iter, kIterPos, NewtMakeInteger(pos));
01026     NewtSetArraySlot(iter, kIterValue, value);
01027 }
01028 
01029 
01030 /*------------------------------------------------------------------------*/
01039 bool iter_done(newtRefArg iter)
01040 {
01041     int32_t pos;
01042     int32_t len;
01043 
01044     pos = NewtRefToInteger(NewtGetArraySlot(iter, kIterPos));
01045     len = NewtRefToInteger(NewtGetArraySlot(iter, kIterMax));
01046 
01047     return (len <= pos);
01048 }
01049 
01050 
01051 #pragma mark -
01052 /*------------------------------------------------------------------------*/
01060 newtRef NVMMakeArgsArray(uint16_t numArgs)
01061 {
01062     newtRefVar  args;
01063     int16_t     i;
01064 
01065     args = NewtMakeArray(kNewtRefUnbind, numArgs);
01066 
01067     for (i = numArgs - 1; 0 <= i; i--)
01068     {
01069         NewtSetArraySlot(args, i, stk_pop());
01070     }
01071 
01072     return args;
01073 }
01074 
01075 
01076 /*------------------------------------------------------------------------*/
01084 void NVMBindArgs(uint16_t numArgs)
01085 {
01086     newtRefVar  indefinite;
01087     int32_t     minArgs;
01088     int16_t     i;
01089     newtRefVar  v;
01090 
01091     minArgs = NewtRefToInteger(NcGetSlot(FUNC, NSSYM0(numArgs)));
01092     indefinite = NcGetSlot(FUNC, NSSYM0(indefinite));
01093 
01094     if (NewtRefIsNotNIL(indefinite))
01095     {
01096         newtRefVar  args;
01097 
01098         args = NVMMakeArgsArray(numArgs - minArgs);
01099         NewtSetFrameSlot(LOCALS, START_LOCALARGS + minArgs, args);
01100     }
01101 
01102     for (i = START_LOCALARGS + minArgs - 1; START_LOCALARGS <= i; i--)
01103     {
01104         v = stk_pop();
01105         NewtSetFrameSlot(LOCALS, i, v);
01106     }
01107 }
01108 
01109 
01110 /*------------------------------------------------------------------------*/
01121 void NVMThrowBC(newtErr err, newtRefArg value, int16_t pop, bool push)
01122 {
01123     stk_remove(pop);
01124 
01125     if (push)
01126         stk_push(kNewtRefUnbind);
01127 
01128     if (NewtRefIsSymbol(value))
01129         NewtThrowSymbol(err, value);
01130     else
01131         NewtThrow(err, value);
01132 }
01133 
01134 
01135 /*------------------------------------------------------------------------*/
01145 bool NVMFuncCheckNumArgs(newtRefArg fn, int16_t numArgs)
01146 {
01147     newtRefVar  indefinite;
01148     int32_t     minArgs;
01149 
01150     minArgs = NewtRefToInteger(NcGetSlot(fn, NSSYM0(numArgs)));
01151     indefinite = NcGetSlot(fn, NSSYM0(indefinite));
01152 
01153     if (NewtRefIsNIL(indefinite))
01154         return (minArgs == numArgs);
01155     else
01156         return (minArgs <= numArgs);
01157 }
01158 
01159 
01160 /*------------------------------------------------------------------------*/
01169 newtErr NVMFuncCheck(newtRefArg fn, int16_t numArgs)
01170 {
01171     // 1. 関数オブジェクトでなければ例外を発生
01172 
01173     if (! NewtRefIsFunction(fn))
01174         return kNErrInvalidFunc;
01175 
01176     // 2. 引数の数が一致さなければ WrongNumberOfArgs 例外を発生
01177 
01178     if (! NVMFuncCheckNumArgs(fn, numArgs))
01179         return kNErrWrongNumberOfArgs;
01180 
01181     return kNErrNone;
01182 }
01183 
01184 
01185 /*------------------------------------------------------------------------*/
01194 void NVMCallNativeFn(newtRefArg fn, int16_t numArgs)
01195 {
01196     newtRefVar  r = kNewtRefUnbind;
01197     newtRefVar  indefinite;
01198     nvm_func_t  funcPtr;
01199     int32_t     minArgs;
01200 
01201     funcPtr = (nvm_func_t)NewtRefToAddress(NcGetSlot(fn, NSSYM0(funcPtr)));
01202 
01203     if (funcPtr == NULL)
01204         return;
01205 
01206     minArgs = NewtRefToInteger(NcGetSlot(fn, NSSYM0(numArgs)));
01207     indefinite = NcGetSlot(fn, NSSYM0(indefinite));
01208 
01209     if (NewtRefIsNIL(indefinite))
01210     {
01211         switch (minArgs)
01212         {
01213             case 0:
01214                 r = (*funcPtr)();
01215                 break;
01216 
01217             case 1:
01218                 {
01219                     newtRefVar  a;
01220 
01221                     a = stk_pop();
01222                     r = (*funcPtr)(a);
01223                 }
01224                 break;
01225 
01226             case 2:
01227                 {
01228                     newtRefVar  a[2];
01229 
01230                     stk_pop_n(2, a);
01231                     r = (*funcPtr)(a[0], a[1]);
01232                 }
01233                 break;
01234 
01235             case 3:
01236                 {
01237                     newtRefVar  a[3];
01238 
01239                     stk_pop_n(3, a);
01240                     r = (*funcPtr)(a[0], a[1], a[2]);
01241                 }
01242                 break;
01243 
01244             case 4:
01245                 {
01246                     newtRefVar  a[4];
01247 
01248                     stk_pop_n(4, a);
01249                     r = (*funcPtr)(a[0], a[1], a[2], a[3]);
01250                 }
01251                 break;
01252 
01253             case 5:
01254                 {
01255                     newtRefVar  a[5];
01256 
01257                     stk_pop_n(5, a);
01258                     r = (*funcPtr)(a[0], a[1], a[2], a[3], a[4]);
01259                 }
01260                 break</