Changeset 112 for NEWT0/trunk
- Timestamp:
- 08/19/07 17:19:36 (17 months ago)
- Location:
- NEWT0/trunk/src/newt_core
- Files:
-
- 4 modified
-
NewtGC.c (modified) (1 diff)
-
NewtVM.c (modified) (10 diffs)
-
incs/NewtEnv.h (modified) (1 diff)
-
incs/NewtVM.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
NEWT0/trunk/src/newt_core/NewtGC.c
r68 r112 507 507 { 508 508 // NewtPoolMarkClean(NEWT_POOL); 509 NewtGCMark(&vm_env, NEWT_SWEEP); 509 vm_env_t * env; 510 511 for (env = &vm_env; env; env = env->next) 512 { 513 NewtGCMark(&vm_env, NEWT_SWEEP); 514 } 515 510 516 NewtPoolSweep(NEWT_POOL, NEWT_SWEEP); 511 517 -
NEWT0/trunk/src/newt_core/NewtVM.c
r105 r112 13 13 /* ヘッダファイル */ 14 14 #include <stdlib.h> 15 #include <stdarg.h> 15 16 16 17 #include "NewtErrs.h" … … 99 100 static newtRef stk_top(void); 100 101 static void stk_push(newtRefArg value); 102 static void stk_push_varg(int argc, va_list ap); 103 static void stk_push_array(newtRefVar argArray); 101 104 102 105 static bool excp_push(newtRefArg sym, newtRefArg pc); … … 187 190 static void NVMDumpInstCode(FILE * f, uint8_t * bc, uint32_t pc, uint16_t len); 188 191 192 static void vm_env_push(vm_env_t * next); 193 static void vm_env_pop(void); 194 189 195 static void NVMInitREG(void); 190 196 static void NVMInitSTACK(void); … … 204 210 205 211 static newtRef NVMInterpret2(nps_syntax_node_t * stree, uint32_t numStree, newtErr * errP); 212 213 static newtRef NVMFuncCallWithValist(newtRefArg fn, int argc, va_list ap); 214 static newtRef NVMMessageSendWithValist(newtRefArg impl, newtRefArg receiver, newtRefArg fn, int argc, va_list ap); 206 215 207 216 … … 824 833 825 834 835 /*------------------------------------------------------------------------*/ 836 /** 可変引数をスタックにプッシュする 837 * 838 * @param argc [in] 引数の数 839 * @param ap [in] 可変引数 840 * 841 * @return なし 842 */ 843 844 void stk_push_varg(int argc, va_list ap) 845 { 846 int i; 847 848 for (i = 0; i < argc; i++) 849 { 850 stk_push(va_arg(ap, newtRefArg)); 851 } 852 } 853 854 855 /*------------------------------------------------------------------------*/ 856 /** 配列の要素をスタックにプッシュする 857 * 858 * @param argArray [in] 引数配列 859 * 860 * @return なし 861 */ 862 863 void stk_push_array(newtRefVar argArray) 864 { 865 int numArgs; 866 int i; 867 868 numArgs = NewtArrayLength(argArray); 869 870 for (i = 0; i < numArgs; i++) 871 { 872 stk_push(NewtGetArraySlot(argArray, i)); 873 } 874 } 875 876 826 877 #ifndef _MSC_VER 827 878 … … 3417 3468 #endif 3418 3469 3470 /*------------------------------------------------------------------------*/ 3471 /** VM環境をプッシュする 3472 * 3473 * @param next [in] 新しいVM環境 3474 * 3475 * @return なし 3476 */ 3477 3478 void vm_env_push(vm_env_t * next) 3479 { 3480 *next = vm_env; 3481 vm_env.next = next; 3482 } 3483 3484 3485 /*------------------------------------------------------------------------*/ 3486 /** VM環境をポップする 3487 * 3488 * @return なし 3489 */ 3490 3491 void vm_env_pop(void) 3492 { 3493 vm_env_t * next = vm_env.next; 3494 3495 if (next) 3496 { 3497 vm_env = *next; 3498 } 3499 } 3419 3500 3420 3501 … … 3790 3871 newtRef NVMCall(newtRefArg fn, int16_t numArgs, newtErr * errP) 3791 3872 { 3792 3793 3873 newtRefVar result = kNewtRefUnbind; 3794 3874 newtErr err = kNErrNone; … … 3796 3876 if (NewtRefIsNotNIL(fn)) 3797 3877 { 3878 vm_env_t saveVM; 3879 3880 // save the VM 3881 vm_env_push(&saveVM); 3882 3798 3883 NVMFnCall(fn, numArgs); 3799 3884 NVMLoop(CALLSP - 1); 3800 3885 result = stk_top(); 3886 3887 // restore the VM 3888 vm_env_pop(); 3801 3889 } 3802 3890 … … 3988 4076 3989 4077 /* save the VM */ 3990 saveVM = vm_env;3991 4078 vm_env_push(&saveVM); 4079 3992 4080 nbArgs = NewtArrayLength(inArgs); 3993 4081 /* Push the arguments on the stack */ … … 4003 4091 4004 4092 /* restore the VM */ 4005 vm_env = saveVM;4093 vm_env_pop(); 4006 4094 4007 4095 return result; 4008 4096 } 4097 4098 4099 /*------------------------------------------------------------------------*/ 4100 /** 関数オブジェクトを va_list で実行 4101 * 4102 * @param fn [in] 関数オブジェクト 4103 * @param argc [in] 引数の数 4104 * @param ap [in] va_list 4105 * 4106 * @return スタックのトップオブジェクト 4107 */ 4108 4109 newtRef NVMFuncCallWithValist(newtRefArg fn, int argc, va_list ap) 4110 { 4111 vm_env_t saveVM; 4112 newtRefVar result; 4113 4114 // save the VM 4115 vm_env_push(&saveVM); 4116 4117 // Push the arguments on the stack 4118 stk_push_varg(argc, ap); 4119 4120 // Call function 4121 NVMFuncCall(fn, argc); 4122 NVMLoop(CALLSP - 1); 4123 result = stk_top(); 4124 4125 // restore the VM 4126 vm_env_pop(); 4127 4128 return result; 4129 } 4130 4131 4132 /*------------------------------------------------------------------------*/ 4133 /** メソッドを va_list で実行 4134 * 4135 * @param impl [in] インプリメンタ 4136 * @param receiver [in] レシーバー 4137 * @param fn [in] 関数オブジェクト 4138 * @param argc [in] 引数の数 4139 * @param ap [in] va_list 4140 * 4141 * @return スタックのトップオブジェクト 4142 */ 4143 4144 newtRef NVMMessageSendWithValist(newtRefArg impl, newtRefArg receiver, newtRefArg fn, int argc, va_list ap) 4145 { 4146 newtRefVar result; 4147 vm_env_t saveVM; 4148 4149 // save the VM 4150 vm_env_push(&saveVM); 4151 4152 // Push the arguments on the stack 4153 stk_push_varg(argc, ap); 4154 4155 // Send the message 4156 NVMMessageSend(impl, receiver, fn, argc); 4157 NVMLoop(CALLSP - 1); 4158 result = stk_top(); 4159 4160 /* restore the VM */ 4161 vm_env_pop(); 4162 4163 return result; 4164 } 4165 4166 4167 /*------------------------------------------------------------------------*/ 4168 /** 関数オブジェクトを可変引数で実行 4169 * 4170 * @param fn [in] 関数オブジェクト 4171 * @param argc [in] 引数の数 4172 * 4173 * @return スタックのトップオブジェクト 4174 */ 4175 4176 newtRef NcCall(newtRefArg fn, int argc, ...) 4177 { 4178 newtRefVar result; 4179 va_list ap; 4180 4181 va_start(ap, argc); 4182 result = NVMFuncCallWithValist(fn, argc, ap); 4183 va_end(ap); 4184 4185 return result; 4186 } 4187 4188 4189 /*------------------------------------------------------------------------*/ 4190 /** 配列を引数にして関数オブジェクトを実行 4191 * 4192 * @param fn [in] 関数オブジェクト 4193 * @param args [in] 配列 4194 * 4195 * @return スタックのトップオブジェクト 4196 */ 4197 4198 newtRef NcCallWithArgArray(newtRefArg fn, newtRefArg args) 4199 { 4200 vm_env_t saveVM; 4201 newtRefVar result; 4202 newtErr err; 4203 4204 if (! NewtRefIsFrame(args)) 4205 { 4206 return NewtThrow(kNErrNotAFrame, args); 4207 } 4208 4209 // save the VM 4210 vm_env_push(&saveVM); 4211 4212 stk_push_array(args); 4213 result = NVMCall(fn, NewtArrayLength(args), &err); 4214 4215 // restore the VM 4216 vm_env_pop(); 4217 4218 return result; 4219 } 4220 4221 4222 /*------------------------------------------------------------------------*/ 4223 /** グローバル関数を可変引数で実行 4224 * 4225 * @param sym [in] シンボル 4226 * @param argc [in] 引数の数 4227 * 4228 * @return スタックのトップオブジェクト 4229 */ 4230 4231 newtRef NcCallGlobalFn(newtRefArg sym, int argc, ...) 4232 { 4233 newtRefVar result; 4234 newtRefVar fn; 4235 va_list ap; 4236 4237 fn = NcGetGlobalFn(sym); 4238 if (NewtRefIsNIL(fn)) 4239 { 4240 return NewtThrow(kNErrUndefinedGlobalFunction, sym); 4241 } 4242 4243 va_start(ap, argc); 4244 result = NVMFuncCallWithValist(fn, argc, ap); 4245 va_end(ap); 4246 4247 return result; 4248 } 4249 4250 4251 /*------------------------------------------------------------------------*/ 4252 /** 配列を引数にしてグローバル関数を実行 4253 * 4254 * @param sym [in] シンボル 4255 * @param args [in] 配列 4256 * 4257 * @return スタックのトップオブジェクト 4258 */ 4259 4260 newtRef NcCallGlobalFnWithArgArray(newtRefArg sym, newtRefArg args) 4261 { 4262 newtRefVar fn; 4263 4264 fn = NcGetGlobalFn(sym); 4265 if (NewtRefIsNIL(fn)) 4266 { 4267 return NewtThrow(kNErrUndefinedGlobalFunction, sym); 4268 } 4269 4270 return NcCallWithArgArray(fn, args); 4271 } 4272 4273 4274 /*------------------------------------------------------------------------*/ 4275 /** メソッドを可変引数で実行 4276 * 4277 * @param receiver [in] レシーバー 4278 * @param sym [in] シンボル 4279 * @param ignore [in] メソッド未定定義の例外を無視する 4280 * @param argc [in] 引数の数 4281 * 4282 * @return スタックのトップオブジェクト 4283 */ 4284 4285 newtRef NcSend(newtRefArg receiver, newtRefArg sym, bool ignore, int argc, ...) 4286 { 4287 newtRefVar result = kNewtRefUnbind; 4288 newtRefVar impl; 4289 newtRefVar fn; 4290 4291 if (! NewtRefIsSymbol(sym)) 4292 { 4293 return NewtThrow(kNErrNotASymbol, sym); 4294 } 4295 4296 if (! NewtRefIsFrame(receiver) && ! NewtRefIsNIL(receiver)) 4297 { 4298 return NewtThrow(kNErrNotAFrame, receiver); 4299 } 4300 4301 impl = NcFullLookupFrame(receiver, sym); 4302 4303 if (impl != kNewtRefUnbind) 4304 { 4305 va_list ap; 4306 4307 fn = NcGetSlot(impl, sym); 4308 4309 va_start(ap, argc); 4310 result = NVMMessageSendWithValist(impl, receiver, fn, argc, ap); 4311 va_end(ap); 4312 } 4313 else 4314 { 4315 if (! ignore) 4316 return NewtThrow(kNErrUndefinedMethod, sym); 4317 } 4318 4319 return result; 4320 } 4321 4322 4323 /*------------------------------------------------------------------------*/ 4324 /** 配列を引数にしてメソッドを実行 4325 * 4326 * @param receiver [in] レシーバー 4327 * @param sym [in] シンボル 4328 * @param ignore [in] メソッド未定定義の例外を無視する 4329 * @param args [in] 配列 4330 * 4331 * @return スタックのトップオブジェクト 4332 */ 4333 4334 newtRef NcSendWithArgArray(newtRefArg receiver, newtRefArg sym, bool ignore, newtRefArg args) 4335 { 4336 newtRefVar result = kNewtRefUnbind; 4337 newtRefVar impl; 4338 newtRefVar fn; 4339 4340 if (! NewtRefIsSymbol(sym)) 4341 { 4342 return NewtThrow(kNErrNotASymbol, sym); 4343 } 4344 4345 if (! NewtRefIsFrame(receiver) && ! NewtRefIsNIL(receiver)) 4346 { 4347 return NewtThrow(kNErrNotAFrame, receiver); 4348 } 4349 4350 impl = NcFullLookupFrame(receiver, sym); 4351 4352 if (impl != kNewtRefUnbind) 4353 { 4354 fn = NcGetSlot(impl, sym); 4355 result = NVMMessageSendWithArgArray(impl, receiver, fn, args); 4356 } 4357 else 4358 { 4359 if (! ignore) 4360 return NewtThrow(kNErrUndefinedMethod, sym); 4361 } 4362 4363 return result; 4364 } 4365 4366 4367 /*------------------------------------------------------------------------*/ 4368 /** メソッドを可変引数で実行(プロト呼出し) 4369 * 4370 * @param receiver [in] レシーバー 4371 * @param sym [in] シンボル 4372 * @param ignore [in] メソッド未定定義の例外を無視する 4373 * @param argc [in] 引数の数 4374 * 4375 * @return スタックのトップオブジェクト 4376 * 4377 * @note プロト継承のみ行う 4378 */ 4379 4380 newtRef NcSendProto(newtRefArg receiver, newtRefArg sym, bool ignore, int argc, ...) 4381 { 4382 newtRefVar result = kNewtRefUnbind; 4383 newtRefVar impl; 4384 newtRefVar fn; 4385 4386 if (! NewtRefIsSymbol(sym)) 4387 { 4388 return NewtThrow(kNErrNotASymbol, sym); 4389 } 4390 4391 if (! NewtRefIsFrame(receiver) && ! NewtRefIsNIL(receiver)) 4392 { 4393 return NewtThrow(kNErrNotAFrame, receiver); 4394 } 4395 4396 impl = NcProtoLookupFrame(receiver, sym); 4397 4398 if (impl != kNewtRefUnbind) 4399 { 4400 va_list ap; 4401 4402 fn = NcGetSlot(impl, sym); 4403 4404 va_start(ap, argc); 4405 result = NVMMessageSendWithValist(impl, receiver, fn, argc, ap); 4406 va_end(ap); 4407 } 4408 else 4409 { 4410 if (! ignore) 4411 return NewtThrow(kNErrUndefinedMethod, sym); 4412 } 4413 4414 return result; 4415 } 4416 4417 4418 /*------------------------------------------------------------------------*/ 4419 /** 配列を引数にしてメソッドを実行(プロト呼出し) 4420 * 4421 * @param receiver [in] レシーバー 4422 * @param sym [in] シンボル 4423 * @param ignore [in] メソッド未定定義の例外を無視する 4424 * @param args [in] 配列 4425 * 4426 * @return スタックのトップオブジェクト 4427 * 4428 * @note プロト継承のみ行う 4429 */ 4430 4431 newtRef NcSendProtoWithArgArray(newtRefArg receiver, newtRefArg sym, bool ignore, newtRefArg args) 4432 { 4433 newtRefVar result = kNewtRefUnbind; 4434 newtRefVar impl; 4435 newtRefVar fn; 4436 4437 if (! NewtRefIsSymbol(sym)) 4438 { 4439 return NewtThrow(kNErrNotASymbol, sym); 4440 } 4441 4442 if (! NewtRefIsFrame(receiver) && ! NewtRefIsNIL(receiver)) 4443 { 4444 return NewtThrow(kNErrNotAFrame, receiver); 4445 } 4446 4447 impl = NcProtoLookupFrame(receiver, sym); 4448 4449 if (impl != kNewtRefUnbind) 4450 { 4451 fn = NcGetSlot(impl, sym); 4452 result = NVMMessageSendWithArgArray(impl, receiver, fn, args); 4453 } 4454 else 4455 { 4456 if (! ignore) 4457 return NewtThrow(kNErrUndefinedMethod, sym); 4458 } 4459 4460 return result; 4461 } -
NEWT0/trunk/src/newt_core/incs/NewtEnv.h
r98 r112 41 41 42 42 #define NSNAMEDMP(name) (NewtMakeNamedMP(#name)) ///< 名前付マジックポインタの作成 43 #define NSNAMEDMP0(name) (NewtSymbolToMP(NSSYM0(name))) ///< 保管場所から名前付マジックポインタ の作成43 #define NSNAMEDMP0(name) (NewtSymbolToMP(NSSYM0(name))) ///< 保管場所から名前付マジックポインタを取得 44 44 #define NSMP(n) (NewtMakeMagicPointer(0, n)) ///< マジックポインタの作成 45 45 -
NEWT0/trunk/src/newt_core/incs/NewtVM.h
r68 r112 19 19 #include "NewtType.h" 20 20 #include "NewtMem.h" 21 22 23 /* マクロ */ 24 #define NcCall0(fn) NcCall(fn, 0) 25 #define NcCall1(fn, a1) NcCall(fn, 1, a1) 26 #define NcCall2(fn, a1, a2) NcCall(fn, 2, a1, a2) 27 #define NcCall3(fn, a1, a2, a3) NcCall(fn, 3, a1, a2, a3) 28 #define NcCall4(fn, a1, a2, a3, a4) NcCall(fn, 4, a1, a2, a3, a4) 29 #define NcCall5(fn, a1, a2, a3, a4, a5) NcCall(fn, 5, a1, a2, a3, a4, a5) 30 31 #define NcCallGlobalFn0(sym) NcCallGlobalFn(sym, 0) 32 #define NcCallGlobalFn1(sym, a1) NcCallGlobalFn(sym, 1, a1) 33 #define NcCallGlobalFn2(sym, a1, a2) NcCallGlobalFn(sym, 2, a1, a2) 34 #define NcCallGlobalFn3(sym, a1, a2, a3) NcCallGlobalFn(sym, 3, a1, a2, a3) 35 #define NcCallGlobalFn4(sym, a1, a2, a3, a4) NcCallGlobalFn(sym, 4, a1, a2, a3, a4) 36 #define NcCallGlobalFn5(sym, a1, a2, a3, a4, a5) NcCallGlobalFn(sym, 5, a1, a2, a3, a4, a5) 37 38 #define NcSend0(receiver, sym) NcSend(receiver, sym, false, 0) 39 #define NcSend1(receiver, sym, a1) NcSend(receiver, sym, false, 1, a1) 40 #define NcSend2(receiver, sym, a1, a2) NcSend(receiver, sym, false, 2, a1, a2) 41 #define NcSend3(receiver, sym, a1, a2, a3) NcSend(receiver, sym, false, 3, a1, a2, a3) 42 #define NcSend4(receiver, sym, a1, a2, a3, a4) NcSend(receiver, sym, false, 4, a1, a2, a3, a4) 43 #define NcSend5(receiver, sym, a1, a2, a3, a4, a5) NcSend(receiver, sym, false, 5, a1, a2, a3, a4, a5) 44 45 #define NcSendIfDefined0(receiver, sym) NcSend(receiver, sym, true, 0) 46 #define NcSendIfDefined1(receiver, sym, a1) NcSend(receiver, sym, true, 1, a1) 47 #define NcSendIfDefined2(receiver, sym, a1, a2) NcSend(receiver, sym, true, 2, a1, a2) 48 #define NcSendIfDefined3(receiver, sym, a1, a2, a3) NcSend(receiver, sym, true, 3, a1, a2, a3) 49 #define NcSendIfDefined4(receiver, sym, a1, a2, a3, a4) NcSend(receiver, sym, true, 4, a1, a2, a3, a4) 50 #define NcSendIfDefined5(receiver, sym, a1, a2, a3, a4, a5) NcSend(receiver, sym, true, 5, a1, a2, a3, a4, a5) 51 52 #define NcSendProto0(receiver, sym) NcSendProto(receiver, sym, false, 0) 53 #define NcSendProto1(receiver, sym, a1) NcSendProto(receiver, sym, false, 1, a1) 54 #define NcSendProto2(receiver, sym, a1, a2) NcSendProto(receiver, sym, false, 2, a1, a2) 55 #define NcSendProto3(receiver, sym, a1, a2, a3) NcSendProto(receiver, sym, false, 3, a1, a2, a3) 56 #define NcSendProto4(receiver, sym, a1, a2, a3, a4) NcSendProto(receiver, sym, false, 4, a1, a2, a3, a4) 57 #define NcSendProto5(receiver, sym, a1, a2, a3, a4, a5) NcSendProto(receiver, sym, false, 5, a1, a2, a3, a4, a5) 58 59 #define NcSendProtoIfDefined0(receiver, sym) NcSendProto(receiver, sym, true, 0) 60 #define NcSendProtoIfDefined1(receiver, sym, a1) NcSendProto(receiver, sym, true, 1, a1) 61 #define NcSendProtoIfDefined2(receiver, sym, a1, a2) NcSendProto(receiver, sym, true, 2, a1, a2) 62 #define NcSendProtoIfDefined3(receiver, sym, a1, a2, a3) NcSendProto(receiver, sym, true, 3, a1, a2, a3) 63 #define NcSendProtoIfDefined4(receiver, sym, a1, a2, a3, a4) NcSendProto(receiver, sym, true, 4, a1, a2, a3, a4) 64 #define NcSendProtoIfDefined5(receiver, sym, a1, a2, a3, a4, a5) NcSendProto(receiver, sym, true, 5, a1, a2, a3, a4, a5) 21 65 22 66 … … 60 104 61 105 /// VM 実行環境 62 typedef struct {106 typedef struct vm_env_t { 63 107 // バイトコード 64 uint8_t * bc; ///< バイトコード65 uint32_t bclen; ///< バイトコードの長さ108 uint8_t * bc; ///< バイトコード 109 uint32_t bclen; ///< バイトコードの長さ 66 110 67 111 // レジスタ 68 vm_reg_t reg; ///< レジスタ112 vm_reg_t reg; ///< レジスタ 69 113 70 114 // スタック 71 newtStack stack; ///< スタック72 newtStack callstack; ///< 関数呼出しスタック73 newtStack excpstack; ///< 例外ハンドラ・スタック115 newtStack stack; ///< スタック 116 newtStack callstack; ///< 関数呼出しスタック 117 newtStack excpstack; ///< 例外ハンドラ・スタック 74 118 75 119 // 例外 76 newtRefVar currexcp; ///< 現在の例外120 newtRefVar currexcp; ///< 現在の例外 77 121 78 122 // VM 管理 79 uint16_t level; ///< VM呼出しレベル 123 uint16_t level; ///< VM呼出しレベル 124 struct vm_env_t * next; ///< VM 実行環境のチェイン 80 125 } vm_env_t; 81 126 … … 121 166 newtRefArg inFunction, newtRefArg inArgs); 122 167 168 newtRef NcCall(newtRefArg fn, int argc, ...); 169 newtRef NcCallWithArgArray(newtRefArg fn, newtRefArg args); 170 newtRef NcCallGlobalFn(newtRefArg sym, int argc, ...); 171 newtRef NcCallGlobalFnWithArgArray(newtRefArg sym, newtRefArg args); 172 173 newtRef NcSend(newtRefArg receiver, newtRefArg sym, bool ignore, int argc, ...); 174 newtRef NcSendWithArgArray(newtRefArg receiver, newtRefArg sym, bool ignore, newtRefArg args); 175 newtRef NcSendProto(newtRefArg receiver, newtRefArg sym, bool ignore, int argc, ...); 176 newtRef NcSendProtoWithArgArray(newtRefArg receiver, newtRefArg sym, bool ignore, newtRefArg args); 177 178 123 179 #ifdef __cplusplus 124 180 }
