support super(), test ok

support `super()`
This commit is contained in:
pikastech 2022-09-08 18:48:58 +08:00
parent 22d4c2137e
commit 87a084b4d8
5 changed files with 248 additions and 96 deletions

View File

@ -11,7 +11,7 @@
"program": "${workspaceFolder}/build/test/pikascript_test", "program": "${workspaceFolder}/build/test/pikascript_test",
// "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain", // "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain",
"args": [ "args": [
// "--gtest_filter=str.split" // "--gtest_filter=vm.super_"
], ],
"stopAtEntry": false, "stopAtEntry": false,
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",

View File

@ -1444,3 +1444,59 @@ TEST(vm, none) {
obj_deinit(pikaMain); obj_deinit(pikaMain);
EXPECT_EQ(pikaMemNow(), 0); EXPECT_EQ(pikaMemNow(), 0);
} }
TEST(vm, super_) {
/* init */
pikaMemInfo.heapUsedMax = 0;
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
extern unsigned char pikaModules_py_a[];
obj_linkLibrary(pikaMain, pikaModules_py_a);
/* run */
__platform_printf("BEGIN\r\n");
obj_run(pikaMain,
"class test:\n"
" def __init__(self):\n"
" print('in test init')\n"
"class test2(test):\n"
" def __init__(self):\n"
" super().__init__()\n"
" print('in test2 init')\n"
"t = test2()");
/* collect */
/* assert */
EXPECT_STREQ(log_buff[0], "in test2 init\r\n");
EXPECT_STREQ(log_buff[1], "in test init\r\n");
EXPECT_STREQ(log_buff[2], "BEGIN\r\n");
/* deinit */
obj_deinit(pikaMain);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(vm, super_val) {
/* init */
pikaMemInfo.heapUsedMax = 0;
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
extern unsigned char pikaModules_py_a[];
obj_linkLibrary(pikaMain, pikaModules_py_a);
/* run */
__platform_printf("BEGIN\r\n");
obj_run(pikaMain,
"class test:\n"
" def __init__(self):\n"
" self.a = 1\n"
" self.b = 2\n"
"class test2(test):\n"
" def __init__(self):\n"
" super().__init__()\n"
" self.c = 3\n"
" self.d = 4\n"
"t = test2()\n"
"print(t.a, t.b, t.c, t.d)\n");
/* collect */
/* assert */
EXPECT_STREQ(log_buff[1], "BEGIN\r\n");
EXPECT_STREQ(log_buff[0], "1 2 3 4\r\n");
/* deinit */
obj_deinit(pikaMain);
EXPECT_EQ(pikaMemNow(), 0);
}

View File

@ -1003,6 +1003,7 @@ Arg* arg_setObj(Arg* self, char* name, PikaObj* obj) {
} }
Arg* arg_setRef(Arg* self, char* name, PikaObj* obj) { Arg* arg_setRef(Arg* self, char* name, PikaObj* obj) {
pika_assert(NULL!= obj);
obj_refcntInc(obj); obj_refcntInc(obj);
return arg_setObj(self, name, obj); return arg_setObj(self, name, obj);
} }

View File

@ -44,7 +44,7 @@ static VMParameters* __pikaVM_runByteCodeFrameWithState(
VMParameters* globals, VMParameters* globals,
ByteCodeFrame* bytecode_frame, ByteCodeFrame* bytecode_frame,
uint16_t pc, uint16_t pc,
TryInfo* try_info); RunState* run_state);
/* head declare end */ /* head declare end */
@ -57,12 +57,18 @@ static void VMState_setErrorCode(VMState* vm, uint8_t error_code) {
vm->error_code = error_code; vm->error_code = error_code;
} }
static InstructUnit* VMState_getInstructWithOffset(VMState* vm, static InstructUnit* VMState_getInstructUnitWithOffset(VMState* vm,
int32_t offset) { int32_t offset) {
return instructArray_getByOffset(&(vm->bytecode_frame->instruct_array), return instructArray_getByOffset(&(vm->bytecode_frame->instruct_array),
vm->pc + offset); vm->pc + offset);
} }
static enum Instruct VMstate_getInstructWithOffset(VMState* vm,
int32_t offset) {
return instructUnit_getInstruct(
VMState_getInstructUnitWithOffset(vm, offset));
}
static int VMState_getBlockDeepthNow(VMState* vm) { static int VMState_getBlockDeepthNow(VMState* vm) {
/* support run byteCode */ /* support run byteCode */
InstructUnit* ins_unit = VMState_getInstructNow(vm); InstructUnit* ins_unit = VMState_getInstructNow(vm);
@ -75,6 +81,11 @@ static char* VMState_getConstWithInstructUnit(VMState* vm,
instructUnit_getConstPoolIndex(ins_unit)); instructUnit_getConstPoolIndex(ins_unit));
} }
static char* VMState_getConstWithOffset(VMState* vm, int32_t offset) {
return VMState_getConstWithInstructUnit(
vm, VMState_getInstructUnitWithOffset(vm, offset));
}
static int VMState_getInvokeDeepthNow(VMState* vm) { static int VMState_getInvokeDeepthNow(VMState* vm) {
/* support run byteCode */ /* support run byteCode */
InstructUnit* ins_unit = VMState_getInstructNow(vm); InstructUnit* ins_unit = VMState_getInstructNow(vm);
@ -88,7 +99,8 @@ static int32_t VMState_getAddrOffsetOfJmpBack(VMState* vm) {
/* find loop deepth */ /* find loop deepth */
while (1) { while (1) {
offset -= instructUnit_getSize(ins_unit_now); offset -= instructUnit_getSize(ins_unit_now);
InstructUnit* ins_unit_now = VMState_getInstructWithOffset(vm, offset); InstructUnit* ins_unit_now =
VMState_getInstructUnitWithOffset(vm, offset);
uint16_t invoke_deepth = instructUnit_getInvokeDeepth(ins_unit_now); uint16_t invoke_deepth = instructUnit_getInvokeDeepth(ins_unit_now);
enum Instruct ins = instructUnit_getInstruct(ins_unit_now); enum Instruct ins = instructUnit_getInstruct(ins_unit_now);
char* data = VMState_getConstWithInstructUnit(vm, ins_unit_now); char* data = VMState_getConstWithInstructUnit(vm, ins_unit_now);
@ -101,7 +113,8 @@ static int32_t VMState_getAddrOffsetOfJmpBack(VMState* vm) {
offset = 0; offset = 0;
while (1) { while (1) {
offset += instructUnit_getSize(ins_unit_now); offset += instructUnit_getSize(ins_unit_now);
InstructUnit* ins_unit_now = VMState_getInstructWithOffset(vm, offset); InstructUnit* ins_unit_now =
VMState_getInstructUnitWithOffset(vm, offset);
enum Instruct ins = instructUnit_getInstruct(ins_unit_now); enum Instruct ins = instructUnit_getInstruct(ins_unit_now);
char* data = VMState_getConstWithInstructUnit(vm, ins_unit_now); char* data = VMState_getConstWithInstructUnit(vm, ins_unit_now);
int block_deepth_now = instructUnit_getBlockDeepth(ins_unit_now); int block_deepth_now = instructUnit_getBlockDeepth(ins_unit_now);
@ -131,7 +144,7 @@ static int32_t VMState_getAddrOffsetFromJmp(VMState* vm) {
if (vm->pc + offset >= (int)VMState_getInstructArraySize(vm)) { if (vm->pc + offset >= (int)VMState_getInstructArraySize(vm)) {
break; break;
} }
this_ins_unit = VMState_getInstructWithOffset(vm, offset); this_ins_unit = VMState_getInstructUnitWithOffset(vm, offset);
if (instructUnit_getIsNewLine(this_ins_unit)) { if (instructUnit_getIsNewLine(this_ins_unit)) {
uint8_t blockDeepth = uint8_t blockDeepth =
instructUnit_getBlockDeepth(this_ins_unit); instructUnit_getBlockDeepth(this_ins_unit);
@ -147,7 +160,7 @@ static int32_t VMState_getAddrOffsetFromJmp(VMState* vm) {
if (vm->jmp < 0) { if (vm->jmp < 0) {
while (1) { while (1) {
offset -= instructUnit_getSize(); offset -= instructUnit_getSize();
this_ins_unit = VMState_getInstructWithOffset(vm, offset); this_ins_unit = VMState_getInstructUnitWithOffset(vm, offset);
if (instructUnit_getIsNewLine(this_ins_unit)) { if (instructUnit_getIsNewLine(this_ins_unit)) {
uint8_t blockDeepth = uint8_t blockDeepth =
instructUnit_getBlockDeepth(this_ins_unit); instructUnit_getBlockDeepth(this_ins_unit);
@ -178,7 +191,7 @@ static int32_t VMState_getAddrOffsetOfRaise(VMState* vm) {
if (vm->pc + offset >= (int)VMState_getInstructArraySize(vm)) { if (vm->pc + offset >= (int)VMState_getInstructArraySize(vm)) {
return 0; return 0;
} }
ins_unit_now = VMState_getInstructWithOffset(vm, offset); ins_unit_now = VMState_getInstructUnitWithOffset(vm, offset);
enum Instruct ins = instructUnit_getInstruct(ins_unit_now); enum Instruct ins = instructUnit_getInstruct(ins_unit_now);
if ((NTR == ins)) { if ((NTR == ins)) {
return offset; return offset;
@ -423,8 +436,8 @@ static Arg* VM_instruction_handler_TRY(PikaObj* self,
VMState* vm, VMState* vm,
char* data, char* data,
Arg* arg_ret_reg) { Arg* arg_ret_reg) {
pika_assert(NULL != vm->try_info); pika_assert(NULL != vm->run_state);
vm->try_info->try_state = TRY_STATE_INNER; vm->run_state->try_state = TRY_STATE_INNER;
return NULL; return NULL;
} }
@ -439,7 +452,7 @@ static Arg* VM_instruction_handler_NTR(PikaObj* self,
VMState* vm, VMState* vm,
char* data, char* data,
Arg* arg_ret_reg) { Arg* arg_ret_reg) {
vm->try_info->try_state = TRY_STATE_NONE; vm->run_state->try_state = TRY_STATE_NONE;
return NULL; return NULL;
} }
@ -508,11 +521,11 @@ static Arg* VM_instruction_handler_GER(PikaObj* self,
} }
Arg* _obj_runMethodArgWithState(PikaObj* self, Arg* _obj_runMethodArgWithState(PikaObj* self,
PikaObj* method_args_obj, PikaObj* locals,
Arg* method_arg, Arg* method_arg,
TryInfo* try_state, RunState* run_state,
Arg* ret_arg_reg) { Arg* ret_arg_reg) {
pika_assert(NULL != try_state); pika_assert(NULL != run_state);
Arg* return_arg = NULL; Arg* return_arg = NULL;
/* get method Ptr */ /* get method Ptr */
Method method_ptr = methodArg_getPtr(method_arg); Method method_ptr = methodArg_getPtr(method_arg);
@ -533,28 +546,28 @@ Arg* _obj_runMethodArgWithState(PikaObj* self,
/* run method */ /* run method */
if (method_type == ARG_TYPE_METHOD_NATIVE) { if (method_type == ARG_TYPE_METHOD_NATIVE) {
/* native method */ /* native method */
method_ptr(self, method_args_obj->list); method_ptr(self, locals->list);
/* get method return */ /* get method return */
return_arg = arg_copy_noalloc( return_arg = arg_copy_noalloc(
args_getArg(method_args_obj->list, (char*)"return"), ret_arg_reg); args_getArg(locals->list, (char*)"return"), ret_arg_reg);
} else if (method_type == ARG_TYPE_METHOD_NATIVE_CONSTRUCTOR) { } else if (method_type == ARG_TYPE_METHOD_NATIVE_CONSTRUCTOR) {
/* native method */ /* native method */
method_ptr(self, method_args_obj->list); method_ptr(self, locals->list);
/* get method return */ /* get method return */
return_arg = arg_copy_noalloc( return_arg = arg_copy_noalloc(
args_getArg(method_args_obj->list, (char*)"return"), ret_arg_reg); args_getArg(locals->list, (char*)"return"), ret_arg_reg);
} else { } else {
/* static method and object method */ /* static method and object method */
/* byteCode */ /* byteCode */
uintptr_t insturctArray_start = (uintptr_t)instructArray_getByOffset( uintptr_t insturctArray_start = (uintptr_t)instructArray_getByOffset(
&(method_bytecodeFrame->instruct_array), 0); &(method_bytecodeFrame->instruct_array), 0);
uint16_t pc = (uintptr_t)method_ptr - insturctArray_start; uint16_t pc = (uintptr_t)method_ptr - insturctArray_start;
method_args_obj = __pikaVM_runByteCodeFrameWithState( locals = __pikaVM_runByteCodeFrameWithState(
self, method_args_obj, self, method_bytecodeFrame, pc, try_state); self, locals, self, method_bytecodeFrame, pc, run_state);
/* get method return */ /* get method return */
return_arg = arg_copy_noalloc( return_arg = arg_copy_noalloc(
args_getArg(method_args_obj->list, (char*)"return"), ret_arg_reg); args_getArg(locals->list, (char*)"return"), ret_arg_reg);
} }
return return_arg; return return_arg;
} }
@ -562,27 +575,27 @@ Arg* _obj_runMethodArgWithState(PikaObj* self,
Arg* obj_runMethodArgWithState(PikaObj* self, Arg* obj_runMethodArgWithState(PikaObj* self,
PikaObj* method_args_obj, PikaObj* method_args_obj,
Arg* method_arg, Arg* method_arg,
TryInfo* try_state) { RunState* try_state) {
return _obj_runMethodArgWithState(self, method_args_obj, method_arg, return _obj_runMethodArgWithState(self, method_args_obj, method_arg,
try_state, NULL); try_state, NULL);
} }
Arg* obj_runMethodArgWithState_noalloc(PikaObj* self, Arg* obj_runMethodArgWithState_noalloc(PikaObj* self,
PikaObj* method_args_obj, PikaObj* locals,
Arg* method_arg, Arg* method_arg,
TryInfo* try_state, RunState* run_state,
Arg* ret_arg_reg) { Arg* ret_arg_reg) {
return _obj_runMethodArgWithState(self, method_args_obj, method_arg, return _obj_runMethodArgWithState(self, locals, method_arg, run_state,
try_state, ret_arg_reg); ret_arg_reg);
} }
Arg* obj_runMethodArg(PikaObj* self, Arg* obj_runMethodArg(PikaObj* self,
PikaObj* method_args_obj, PikaObj* method_args_obj,
Arg* method_arg) { Arg* method_arg) {
TryInfo try_info = {.try_state = TRY_STATE_NONE, RunState run_state = {.try_state = TRY_STATE_NONE,
.try_result = TRY_RESULT_NONE}; .try_result = TRY_RESULT_NONE};
return obj_runMethodArgWithState(self, method_args_obj, method_arg, return obj_runMethodArgWithState(self, method_args_obj, method_arg,
&try_info); &run_state);
} }
char* _loadDefaultArgs(char* type_list, char* _loadDefaultArgs(char* type_list,
@ -889,29 +902,88 @@ static Arg* VM_instruction_handler_RET(PikaObj* self,
return NULL; return NULL;
} }
static char* _find_super_class_name(VMState* vm) {
/* find super class */
int offset = 0;
char* super_class_name = NULL;
while (1) {
offset -= instructUnit_getSize();
if (vm->pc + offset >= (int)VMState_getInstructArraySize(vm)) {
return 0;
}
if ((CLS == VMstate_getInstructWithOffset(vm, offset))) {
break;
}
}
while (1) {
offset += instructUnit_getSize();
if (vm->pc + offset >= (int)VMState_getInstructArraySize(vm)) {
return 0;
}
if ((RUN == instructUnit_getInstruct(
VMState_getInstructUnitWithOffset(vm, offset)))) {
super_class_name = VMState_getConstWithOffset(vm, offset);
return super_class_name;
}
}
}
static char* _find_self_name(VMState* vm) {
/* find super class */
int offset = 0;
char* self_name = NULL;
while (1) {
offset -= instructUnit_getSize();
if (vm->pc + offset >= (int)VMState_getInstructArraySize(vm)) {
return 0;
}
if ((CLS == VMstate_getInstructWithOffset(vm, offset))) {
break;
}
}
while (1) {
offset += instructUnit_getSize();
if (vm->pc + offset >= (int)VMState_getInstructArraySize(vm)) {
return 0;
}
if ((OUT == instructUnit_getInstruct(
VMState_getInstructUnitWithOffset(vm, offset)))) {
self_name = VMState_getConstWithOffset(vm, offset);
return self_name;
}
}
}
static Arg* VM_instruction_handler_RUN(PikaObj* self, static Arg* VM_instruction_handler_RUN(PikaObj* self,
VMState* vm, VMState* vm,
char* data, char* data,
Arg* arg_ret_reg) { Arg* arg_ret_reg) {
Arg* return_arg = NULL; Arg* return_arg = NULL;
VMParameters* sub_locals = NULL; VMParameters* sub_locals = NULL;
char* methodPath = data; char* run_path = data;
PikaObj* method_host_obj = NULL; PikaObj* method_host = NULL;
Arg* method_arg = NULL; PikaObj* obj_this = NULL;
Arg* method = NULL;
Arg* host_arg = NULL; Arg* host_arg = NULL;
PIKA_BOOL is_temp = PIKA_FALSE; PIKA_BOOL is_temp = PIKA_FALSE;
PIKA_BOOL skip_init = PIKA_FALSE;
char* sys_out; char* sys_out;
int arg_num_used = 0; int arg_num_used = 0;
arg_newReg(arg_reg1, 64); arg_newReg(arg_reg1, 64);
TryInfo sub_try_info = {.try_state = TRY_STATE_NONE, RunState sub_run_state = {.try_state = vm->run_state->try_state,
.try_result = TRY_RESULT_NONE}; .try_result = TRY_RESULT_NONE};
pika_assert(NULL != vm->try_info); pika_assert(NULL != vm->run_state);
/* transfer try_state */ /* inhert */
sub_try_info.try_state = vm->try_info->try_state; if (CLS ==
VMstate_getInstructWithOffset(vm, -2 * (int)instructUnit_getSize())) {
skip_init = PIKA_TRUE;
}
/* tuple or single arg */ /* tuple or single arg */
if (data[0] == 0) { if (run_path[0] == 0) {
if (VMState_getInputArgNum(vm) < 2) { if (VMState_getInputArgNum(vm) < 2) {
/* return arg directly */ /* return arg directly */
Arg* arg1 = stack_popArg(&(vm->stack), &arg_reg1); Arg* arg1 = stack_popArg(&(vm->stack), &arg_reg1);
@ -924,20 +996,32 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self,
goto exit; goto exit;
} }
/* support for super() */
if (strEqu(run_path, "super")) {
run_path = _find_super_class_name(vm);
vm->in_super = 1;
skip_init = 1;
}
/* return tiny obj */ /* return tiny obj */
if (strEqu(data, "TinyObj")) { if (strEqu(run_path, "TinyObj")) {
return_arg = arg_newMetaObj(New_TinyObj); return_arg = arg_newMetaObj(New_TinyObj);
goto exit; goto exit;
} }
if (!skip_init && vm->in_super) {
vm->in_super = PIKA_FALSE;
obj_this = obj_getPtr(vm->locals, _find_self_name(vm));
}
/* get method host obj from reg */ /* get method host obj from reg */
if (NULL == method_host_obj && _checkLReg(data)) { if (NULL == method_host && _checkLReg(run_path)) {
uint8_t reg_index = _getLRegIndex(data); uint8_t reg_index = _getLRegIndex(run_path);
method_host_obj = vm->lreg[reg_index]; method_host = vm->lreg[reg_index];
} }
/* get method host obj from stack */ /* get method host obj from stack */
if (NULL == method_host_obj && methodPath[0] == '.') { if (NULL == method_host && run_path[0] == '.') {
/* get method host obj from stack */ /* get method host obj from stack */
Arg* stack_tmp[PIKA_ARG_NUM_MAX] = {0}; Arg* stack_tmp[PIKA_ARG_NUM_MAX] = {0};
int arg_num = VMState_getInputArgNum(vm); int arg_num = VMState_getInputArgNum(vm);
@ -952,8 +1036,8 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self,
stack_tmp[i] = stack_popArg_alloc(&(vm->stack)); stack_tmp[i] = stack_popArg_alloc(&(vm->stack));
} }
host_arg = stack_tmp[arg_num - 1]; host_arg = stack_tmp[arg_num - 1];
method_host_obj = _arg_to_obj(host_arg, &is_temp); method_host = _arg_to_obj(host_arg, &is_temp);
if (NULL != method_host_obj) { if (NULL != method_host) {
arg_num_used++; arg_num_used++;
} }
/* push back other args to stack */ /* push back other args to stack */
@ -963,45 +1047,48 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self,
} }
/* get method host obj from self */ /* get method host obj from self */
if (NULL == method_host_obj) { if (NULL == method_host) {
method_host_obj = obj_getHostObjWithIsTemp(self, methodPath, &is_temp); method_host = obj_getHostObjWithIsTemp(self, run_path, &is_temp);
} }
/* get method host obj from local scope */ /* get method host obj from local scope */
if (NULL == method_host_obj) { if (NULL == method_host) {
method_host_obj = method_host = obj_getHostObjWithIsTemp(vm->locals, run_path, &is_temp);
obj_getHostObjWithIsTemp(vm->locals, methodPath, &is_temp);
} }
/* method host obj is not found */ /* method host obj is not found */
if (NULL == method_host_obj) { if (NULL == method_host) {
/* error, not found object */ /* error, not found object */
VMState_setErrorCode(vm, PIKA_RES_ERR_ARG_NO_FOUND); VMState_setErrorCode(vm, PIKA_RES_ERR_ARG_NO_FOUND);
__platform_printf("Error: method '%s' no found.\r\n", data); __platform_printf("Error: method '%s' no found.\r\n", run_path);
goto exit; goto exit;
} }
/* get method in local */ /* get object this */
method_arg = if (NULL == obj_this) {
obj_getMethodArg_noalloc(method_host_obj, methodPath, &arg_reg1); obj_this = method_host;
if (NULL == method_arg) {
/* get method in locals */
method_arg =
obj_getMethodArg_noalloc(vm->locals, methodPath, &arg_reg1);
} }
if (NULL == method_arg) { /* get method in object */
/* get method in global */ if (NULL == method) {
method_arg = method = obj_getMethodArg_noalloc(method_host, run_path, &arg_reg1);
obj_getMethodArg_noalloc(vm->globals, methodPath, &arg_reg1); }
/* get method in locals */
if (NULL == method) {
method = obj_getMethodArg_noalloc(vm->locals, run_path, &arg_reg1);
}
/* get method in global */
if (NULL == method) {
method = obj_getMethodArg_noalloc(vm->globals, run_path, &arg_reg1);
} }
/* assert method type */ /* assert method type */
if (NULL == method_arg || ARG_TYPE_NONE == arg_getType(method_arg)) { if (NULL == method || ARG_TYPE_NONE == arg_getType(method)) {
/* error, method no found */ /* error, method no found */
VMState_setErrorCode(vm, PIKA_RES_ERR_ARG_NO_FOUND); VMState_setErrorCode(vm, PIKA_RES_ERR_ARG_NO_FOUND);
__platform_printf("NameError: name '%s' is not defined\r\n", data); __platform_printf("NameError: name '%s' is not defined\r\n", run_path);
goto exit; goto exit;
} }
@ -1010,7 +1097,7 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self,
/* load args from vmState to sub_local->list */ /* load args from vmState to sub_local->list */
arg_num_used += VMState_loadArgsFromMethodArg( arg_num_used += VMState_loadArgsFromMethodArg(
vm, method_host_obj, sub_locals->list, method_arg, data, arg_num_used); vm, obj_this, sub_locals->list, method, run_path, arg_num_used);
/* load args faild */ /* load args faild */
if (vm->error_code != 0) { if (vm->error_code != 0) {
@ -1018,12 +1105,17 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self,
} }
/* run method arg */ /* run method arg */
return_arg = obj_runMethodArgWithState_noalloc( return_arg = obj_runMethodArgWithState_noalloc(obj_this, sub_locals, method,
method_host_obj, sub_locals, method_arg, &sub_try_info, arg_ret_reg); &sub_run_state, arg_ret_reg);
if (skip_init) {
if (arg_getType(return_arg) == ARG_TYPE_OBJECT_NEW) {
arg_setType(return_arg, ARG_TYPE_OBJECT);
}
}
if (sub_try_info.try_result != TRY_RESULT_NONE) { if (sub_run_state.try_result != TRY_RESULT_NONE) {
/* try result */ /* try result */
vm->error_code = sub_try_info.try_result; vm->error_code = sub_run_state.try_result;
} }
/* __init__() */ /* __init__() */
@ -1045,7 +1137,7 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self,
goto init_exit; goto init_exit;
} }
return_arg_init = obj_runMethodArgWithState(new_obj, sub_locals, return_arg_init = obj_runMethodArgWithState(new_obj, sub_locals,
method_arg, &sub_try_info); method_arg, &sub_run_state);
init_exit: init_exit:
if (NULL != return_arg_init) { if (NULL != return_arg_init) {
arg_deinit(return_arg_init); arg_deinit(return_arg_init);
@ -1055,21 +1147,21 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self,
} }
/* transfer sysOut */ /* transfer sysOut */
sys_out = obj_getSysOut(method_host_obj); sys_out = obj_getSysOut(obj_this);
if (NULL != sys_out) { if (NULL != sys_out) {
args_setSysOut(vm->locals->list, sys_out); args_setSysOut(vm->locals->list, sys_out);
} }
/* transfer errCode */ /* transfer errCode */
if (0 != obj_getErrorCode(method_host_obj)) { if (0 != obj_getErrorCode(obj_this)) {
/* method error */ /* method error */
VMState_setErrorCode(vm, PIKA_RES_ERR_RUNTIME_ERROR); VMState_setErrorCode(vm, PIKA_RES_ERR_RUNTIME_ERROR);
} }
goto exit; goto exit;
exit: exit:
if (NULL != method_arg) { if (NULL != method) {
arg_deinit(method_arg); arg_deinit(method);
} }
if (NULL != sub_locals) { if (NULL != sub_locals) {
obj_deinit(sub_locals); obj_deinit(sub_locals);
@ -1077,9 +1169,9 @@ exit:
if (NULL != host_arg) { if (NULL != host_arg) {
arg_deinit(host_arg); arg_deinit(host_arg);
} }
if (NULL != method_host_obj && is_temp) { if (NULL != method_host && is_temp) {
/* class method */ /* class method */
obj_deinit(method_host_obj); obj_deinit(method_host);
} }
return return_arg; return return_arg;
@ -1820,7 +1912,8 @@ static Arg* __VM_instruction_handler_DEF(PikaObj* self,
int offset = 0; int offset = 0;
/* byteCode */ /* byteCode */
while (1) { while (1) {
InstructUnit* ins_unit_now = VMState_getInstructWithOffset(vm, offset); InstructUnit* ins_unit_now =
VMState_getInstructUnitWithOffset(vm, offset);
if (!instructUnit_getIsNewLine(ins_unit_now)) { if (!instructUnit_getIsNewLine(ins_unit_now)) {
offset += instructUnit_getSize(); offset += instructUnit_getSize();
continue; continue;
@ -1894,7 +1987,7 @@ static Arg* VM_instruction_handler_ASS(PikaObj* self,
if (arg_getType(arg1) == ARG_TYPE_INT && arg_getInt(arg1) == 0) { if (arg_getType(arg1) == ARG_TYPE_INT && arg_getInt(arg1) == 0) {
stack_pushArg(&vm->stack, arg_newInt(PIKA_RES_ERR_ASSERT)); stack_pushArg(&vm->stack, arg_newInt(PIKA_RES_ERR_ASSERT));
res = VM_instruction_handler_RIS(self, vm, data, arg_ret_reg); res = VM_instruction_handler_RIS(self, vm, data, arg_ret_reg);
if (vm->try_info->try_state == TRY_STATE_NONE) { if (vm->run_state->try_state == TRY_STATE_NONE) {
if (arg_num == 1) { if (arg_num == 1) {
__platform_printf("AssertionError\n", data); __platform_printf("AssertionError\n", data);
} }
@ -2044,12 +2137,12 @@ static int pikaVM_runInstructUnit(PikaObj* self,
int32_t pc_next = vm->pc + instructUnit_getSize(); int32_t pc_next = vm->pc + instructUnit_getSize();
char* data = VMState_getConstWithInstructUnit(vm, ins_unit); char* data = VMState_getConstWithInstructUnit(vm, ins_unit);
/* run instruct */ /* run instruct */
pika_assert(NULL != vm->try_info); pika_assert(NULL != vm->run_state);
return_arg = VM_instruct_handler_table[instruct](self, vm, data, &ret_reg); return_arg = VM_instruct_handler_table[instruct](self, vm, data, &ret_reg);
if (vm->error_code != PIKA_RES_OK) { if (vm->error_code != PIKA_RES_OK) {
/* raise jmp */ /* raise jmp */
if (vm->try_info->try_state == TRY_STATE_INNER) { if (vm->run_state->try_state == TRY_STATE_INNER) {
vm->jmp = VM_JMP_RAISE; vm->jmp = VM_JMP_RAISE;
}; };
} }
@ -2080,7 +2173,7 @@ nextLine:
if (0 == offset) { if (0 == offset) {
/* can not found end of try, return */ /* can not found end of try, return */
pc_next = VM_PC_EXIT; pc_next = VM_PC_EXIT;
vm->try_info->try_result = TRY_RESULT_RAISE; vm->run_state->try_result = TRY_RESULT_RAISE;
goto exit; goto exit;
} }
pc_next = vm->pc + offset; pc_next = vm->pc + offset;
@ -2525,8 +2618,8 @@ static VMParameters* __pikaVM_runByteCodeFrameWithState(
VMParameters* globals, VMParameters* globals,
ByteCodeFrame* bytecode_frame, ByteCodeFrame* bytecode_frame,
uint16_t pc, uint16_t pc,
TryInfo* try_info) { RunState* run_state) {
pika_assert(NULL != try_info); pika_assert(NULL != run_state);
int size = bytecode_frame->instruct_array.size; int size = bytecode_frame->instruct_array.size;
/* locals is the local scope */ /* locals is the local scope */
VMState vm = { VMState vm = {
@ -2539,8 +2632,9 @@ static VMParameters* __pikaVM_runByteCodeFrameWithState(
.error_code = PIKA_RES_OK, .error_code = PIKA_RES_OK,
.line_error_code = PIKA_RES_OK, .line_error_code = PIKA_RES_OK,
.try_error_code = PIKA_RES_OK, .try_error_code = PIKA_RES_OK,
.try_info = try_info, .run_state = run_state,
.ins_cnt = 0, .ins_cnt = 0,
.in_super = PIKA_FALSE,
}; };
stack_init(&(vm.stack)); stack_init(&(vm.stack));
VMState_initReg(&vm); VMState_initReg(&vm);
@ -2572,11 +2666,11 @@ static VMParameters* __pikaVM_runByteCodeFrameWithState(
} }
head_ins_unit--; head_ins_unit--;
} }
if (vm.try_info->try_state) { if (vm.run_state->try_state) {
vm.try_error_code = vm.error_code; vm.try_error_code = vm.error_code;
} }
/* print inses of a line */ /* print inses of a line */
if (!vm.try_info->try_state) { if (!vm.run_state->try_state) {
while (1) { while (1) {
if (head_ins_unit != this_ins_unit) { if (head_ins_unit != this_ins_unit) {
__platform_printf(" "); __platform_printf(" ");
@ -2602,11 +2696,11 @@ static VMParameters* __pikaVM_runByteCodeFrameWithState(
VMParameters* pikaVM_runByteCodeFrame(PikaObj* self, VMParameters* pikaVM_runByteCodeFrame(PikaObj* self,
ByteCodeFrame* byteCode_frame) { ByteCodeFrame* byteCode_frame) {
TryInfo try_info = {.try_state = TRY_STATE_NONE, RunState run_state = {.try_state = TRY_STATE_NONE,
.try_result = TRY_RESULT_NONE}; .try_result = TRY_RESULT_NONE};
try_info.try_state = TRY_STATE_NONE; run_state.try_state = TRY_STATE_NONE;
return __pikaVM_runByteCodeFrameWithState(self, self, self, byteCode_frame, return __pikaVM_runByteCodeFrameWithState(self, self, self, byteCode_frame,
0, &try_info); 0, &run_state);
} }
InstructUnit* instructArray_getByOffset(InstructArray* self, int32_t offset) { InstructUnit* instructArray_getByOffset(InstructArray* self, int32_t offset) {

View File

@ -57,8 +57,8 @@ typedef enum {
TRY_RESULT_RAISE, TRY_RESULT_RAISE,
} TRY_RESULT; } TRY_RESULT;
typedef struct TryInfo TryInfo; typedef struct RunState RunState;
struct TryInfo { struct RunState {
TRY_STATE try_state; TRY_STATE try_state;
TRY_RESULT try_result; TRY_RESULT try_result;
}; };
@ -76,9 +76,10 @@ struct VMState {
uint8_t line_error_code; uint8_t line_error_code;
uint8_t try_error_code; uint8_t try_error_code;
uint32_t ins_cnt; uint32_t ins_cnt;
PIKA_BOOL in_super;
PikaObj* lreg[PIKA_REGIST_SIZE]; PikaObj* lreg[PIKA_REGIST_SIZE];
PIKA_BOOL ireg[PIKA_REGIST_SIZE]; PIKA_BOOL ireg[PIKA_REGIST_SIZE];
TryInfo* try_info; RunState* run_state;
}; };
typedef struct OperatorInfo OperatorInfo; typedef struct OperatorInfo OperatorInfo;