|
|
@@ -33,7 +33,7 @@ static bool stack_format_object(VM* self, c11_sv spec);
|
|
|
} while(0)
|
|
|
#define DISPATCH_JUMP_ABSOLUTE(__target) \
|
|
|
do { \
|
|
|
- frame->ip = c11__at(Bytecode, &frame->co->codes, __target); \
|
|
|
+ frame->ip = __target; \
|
|
|
goto __NEXT_STEP; \
|
|
|
} while(0)
|
|
|
|
|
|
@@ -86,15 +86,18 @@ static bool unpack_dict_to_buffer(py_Ref key, py_Ref val, void* ctx) {
|
|
|
|
|
|
FrameResult VM__run_top_frame(VM* self) {
|
|
|
Frame* frame = self->top_frame;
|
|
|
+ Bytecode* codes;
|
|
|
+
|
|
|
const Frame* base_frame = frame;
|
|
|
|
|
|
while(true) {
|
|
|
Bytecode byte;
|
|
|
__NEXT_FRAME:
|
|
|
+ codes = frame->co->codes.data;
|
|
|
frame->ip++;
|
|
|
|
|
|
__NEXT_STEP:
|
|
|
- byte = *frame->ip;
|
|
|
+ byte = codes[frame->ip];
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
pk_print_stack(self, frame, byte);
|
|
|
@@ -176,7 +179,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
|
|
CHECK_STACK_OVERFLOW();
|
|
|
FuncDecl_ decl = c11__getitem(FuncDecl_, &frame->co->func_decls, byte.arg);
|
|
|
Function* ud = py_newobject(SP(), tp_function, 0, sizeof(Function));
|
|
|
- Function__ctor(ud, decl, frame->module);
|
|
|
+ Function__ctor(ud, decl, frame->module, frame->globals);
|
|
|
if(decl->nested) {
|
|
|
ud->closure = FastLocals__to_namedict(frame->locals, frame->co);
|
|
|
py_Name name = py_name(decl->code.name->data);
|
|
|
@@ -200,10 +203,10 @@ FrameResult VM__run_top_frame(VM* self) {
|
|
|
DISPATCH();
|
|
|
}
|
|
|
case OP_LOAD_NAME: {
|
|
|
- assert(frame->is_dynamic);
|
|
|
+ // assert(frame->is_dynamic);
|
|
|
py_Name name = byte.arg;
|
|
|
py_TValue* tmp;
|
|
|
- py_newstr(SP()++, py_name2str(name));
|
|
|
+ py_assign(SP()++, py_name2ref(name));
|
|
|
// locals
|
|
|
if(!py_isnone(&frame->p0[1])) {
|
|
|
if(py_getitem(&frame->p0[1], TOP())) {
|
|
|
@@ -217,6 +220,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ // `LOAD_
|
|
|
// globals
|
|
|
if(py_getitem(&frame->p0[0], TOP())) {
|
|
|
py_assign(TOP(), py_retval());
|
|
|
@@ -239,16 +243,18 @@ FrameResult VM__run_top_frame(VM* self) {
|
|
|
}
|
|
|
case OP_LOAD_NONLOCAL: {
|
|
|
py_Name name = byte.arg;
|
|
|
- py_Ref tmp = Frame__f_closure_try_get(frame, name);
|
|
|
+ py_Ref tmp = Frame__getclosure(frame, name);
|
|
|
if(tmp != NULL) {
|
|
|
PUSH(tmp);
|
|
|
DISPATCH();
|
|
|
}
|
|
|
- tmp = py_getdict(frame->module, name);
|
|
|
- if(tmp != NULL) {
|
|
|
- PUSH(tmp);
|
|
|
+ int res = Frame__getglobal(frame, name);
|
|
|
+ if(res == 1) {
|
|
|
+ PUSH(&self->last_retval);
|
|
|
DISPATCH();
|
|
|
}
|
|
|
+ if(res == -1) goto __ERROR;
|
|
|
+
|
|
|
tmp = py_getdict(&self->builtins, name);
|
|
|
if(tmp != NULL) {
|
|
|
PUSH(tmp);
|
|
|
@@ -259,12 +265,13 @@ FrameResult VM__run_top_frame(VM* self) {
|
|
|
}
|
|
|
case OP_LOAD_GLOBAL: {
|
|
|
py_Name name = byte.arg;
|
|
|
- py_Ref tmp = py_getdict(frame->module, name);
|
|
|
- if(tmp != NULL) {
|
|
|
- PUSH(tmp);
|
|
|
+ int res = Frame__getglobal(frame, name);
|
|
|
+ if(res == 1) {
|
|
|
+ PUSH(&self->last_retval);
|
|
|
DISPATCH();
|
|
|
}
|
|
|
- tmp = py_getdict(&self->builtins, name);
|
|
|
+ if(res == -1) goto __ERROR;
|
|
|
+ py_Ref tmp = py_getdict(&self->builtins, name);
|
|
|
if(tmp != NULL) {
|
|
|
PUSH(tmp);
|
|
|
DISPATCH();
|
|
|
@@ -289,11 +296,12 @@ FrameResult VM__run_top_frame(VM* self) {
|
|
|
DISPATCH();
|
|
|
}
|
|
|
// load global if attribute not found
|
|
|
- tmp = py_getdict(frame->module, name);
|
|
|
- if(tmp) {
|
|
|
- PUSH(tmp);
|
|
|
+ int res = Frame__getglobal(frame, name);
|
|
|
+ if(res == 1) {
|
|
|
+ PUSH(&self->last_retval);
|
|
|
DISPATCH();
|
|
|
}
|
|
|
+ if(res == -1) goto __ERROR;
|
|
|
tmp = py_getdict(&self->builtins, name);
|
|
|
if(tmp) {
|
|
|
PUSH(tmp);
|
|
|
@@ -337,9 +345,9 @@ FrameResult VM__run_top_frame(VM* self) {
|
|
|
}
|
|
|
case OP_STORE_FAST: frame->locals[byte.arg] = POPX(); DISPATCH();
|
|
|
case OP_STORE_NAME: {
|
|
|
- assert(frame->is_dynamic);
|
|
|
+ // assert(frame->is_dynamic);
|
|
|
py_Name name = byte.arg;
|
|
|
- py_newstr(SP()++, py_name2str(name));
|
|
|
+ py_assign(SP()++, py_name2ref(name));
|
|
|
// [value, name]
|
|
|
if(!py_isnone(&frame->p0[1])) {
|
|
|
// locals
|
|
|
@@ -369,7 +377,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
|
|
DISPATCH();
|
|
|
}
|
|
|
case OP_STORE_GLOBAL: {
|
|
|
- py_setdict(frame->module, byte.arg, TOP());
|
|
|
+ if(!Frame__setglobal(frame, byte.arg, TOP())) goto __ERROR;
|
|
|
POP();
|
|
|
DISPATCH();
|
|
|
}
|
|
|
@@ -407,9 +415,9 @@ FrameResult VM__run_top_frame(VM* self) {
|
|
|
DISPATCH();
|
|
|
}
|
|
|
case OP_DELETE_NAME: {
|
|
|
- assert(frame->is_dynamic);
|
|
|
+ // assert(frame->is_dynamic);
|
|
|
py_Name name = byte.arg;
|
|
|
- py_newstr(SP()++, py_name2str(name));
|
|
|
+ py_assign(SP()++, py_name2ref(name));
|
|
|
if(!py_isnone(&frame->p0[1])) {
|
|
|
// locals
|
|
|
if(py_delitem(&frame->p0[1], TOP())) {
|
|
|
@@ -439,12 +447,12 @@ FrameResult VM__run_top_frame(VM* self) {
|
|
|
}
|
|
|
case OP_DELETE_GLOBAL: {
|
|
|
py_Name name = byte.arg;
|
|
|
- bool ok = py_deldict(frame->module, name);
|
|
|
- if(!ok) {
|
|
|
- NameError(name);
|
|
|
- goto __ERROR;
|
|
|
- }
|
|
|
- DISPATCH();
|
|
|
+ int res = Frame__delglobal(frame, name);
|
|
|
+ if(res == 1) DISPATCH();
|
|
|
+ if(res == -1) goto __ERROR;
|
|
|
+ // res == 0
|
|
|
+ NameError(name);
|
|
|
+ goto __ERROR;
|
|
|
}
|
|
|
|
|
|
case OP_DELETE_ATTR: {
|
|
|
@@ -860,7 +868,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
|
|
ImportError("cannot import name '%n'", name);
|
|
|
goto __ERROR;
|
|
|
} else {
|
|
|
- py_setdict(frame->module, name, value);
|
|
|
+ if(!Frame__setglobal(frame, name, value)) goto __ERROR;
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
@@ -869,7 +877,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
|
|
if(!kv->key) continue;
|
|
|
c11_sv name = py_name2sv(kv->key);
|
|
|
if(name.size == 0 || name.data[0] == '_') continue;
|
|
|
- py_setdict(frame->module, kv->key, &kv->value);
|
|
|
+ if(!Frame__setglobal(frame, kv->key, &kv->value)) goto __ERROR;
|
|
|
}
|
|
|
}
|
|
|
POP();
|
|
|
@@ -998,8 +1006,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
|
|
case OP_END_CLASS: {
|
|
|
// [cls or decorated]
|
|
|
py_Name name = byte.arg;
|
|
|
- // set into f_globals
|
|
|
- py_setdict(frame->module, name, TOP());
|
|
|
+ if(!Frame__setglobal(frame, name, TOP())) goto __ERROR;
|
|
|
|
|
|
if(py_istype(TOP(), tp_type)) {
|
|
|
// call on_end_subclass
|
|
|
@@ -1166,7 +1173,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
|
|
py_BaseException__stpush(&self->curr_exception,
|
|
|
frame->co->src,
|
|
|
Frame__lineno(frame),
|
|
|
- frame->has_function ? frame->co->name->data : NULL);
|
|
|
+ frame->is_p0_function ? frame->co->name->data : NULL);
|
|
|
__ERROR_RE_RAISE:
|
|
|
do {
|
|
|
} while(0);
|
|
|
@@ -1183,6 +1190,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
|
|
return RES_ERROR;
|
|
|
}
|
|
|
frame = self->top_frame;
|
|
|
+ codes = frame->co->codes.data;
|
|
|
goto __ERROR;
|
|
|
}
|
|
|
}
|