|
|
@@ -21,6 +21,7 @@ VM vm;
|
|
|
static void resetStack() {
|
|
|
vm.stackTop = vm.stack;// 指针指向栈底
|
|
|
vm.frameCount = 0;
|
|
|
+ vm.openUpvalues = NULL;
|
|
|
}
|
|
|
|
|
|
static void runtimeError(const char *format, ...) {
|
|
|
@@ -125,9 +126,34 @@ static void concatenate() {
|
|
|
push(OBJ_VAL(result));
|
|
|
}
|
|
|
static ObjUpvalue *captureUpvalue(Value *local) {
|
|
|
+ ObjUpvalue *preUpvalue = NULL;
|
|
|
+ ObjUpvalue *upvalue = vm.openUpvalues;
|
|
|
+ while (upvalue != NULL && upvalue->location > local) {
|
|
|
+ preUpvalue = upvalue;
|
|
|
+ upvalue = upvalue->next;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (upvalue != NULL && upvalue->location == local) {
|
|
|
+ return upvalue;
|
|
|
+ }
|
|
|
+
|
|
|
ObjUpvalue *createdUpvalue = newUpvalue(local);
|
|
|
+ if (preUpvalue == NULL) {
|
|
|
+ vm.openUpvalues = createdUpvalue;
|
|
|
+ } else {
|
|
|
+ preUpvalue->next = createdUpvalue;
|
|
|
+ }
|
|
|
return createdUpvalue;
|
|
|
}
|
|
|
+static void closeUpvalues(Value *last) {
|
|
|
+ while (vm.openUpvalues != NULL && vm.openUpvalues->location >= last) {
|
|
|
+ ObjUpvalue *upvalue = vm.openUpvalues;
|
|
|
+ upvalue->closed = *upvalue->location;
|
|
|
+ upvalue->location = &upvalue->closed;
|
|
|
+ vm.openUpvalues = upvalue->next;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/// VM run function - exec opcode
|
|
|
/// \return
|
|
|
static InterpretResult run() {
|
|
|
@@ -157,6 +183,7 @@ static InterpretResult run() {
|
|
|
|
|
|
for (;;) {
|
|
|
#ifdef DEBUG_TRACE_EXECUTION
|
|
|
+#ifdef DEBUG_STACK_INFO
|
|
|
//! <Stack tracing> start
|
|
|
printf("\n!!! <Stack tracing now>:\n");
|
|
|
printf("------------------------\n|");
|
|
|
@@ -170,7 +197,7 @@ static InterpretResult run() {
|
|
|
printf("\n");
|
|
|
printf("\n");
|
|
|
//! <Stack tracing> end
|
|
|
-
|
|
|
+#endif
|
|
|
printf("The Instruction: \n");
|
|
|
disassembleInstruction(&frame->closure->function->chunk, (int) (frame->ip - frame->closure->function->chunk.code));
|
|
|
#endif
|
|
|
@@ -326,8 +353,13 @@ static InterpretResult run() {
|
|
|
*frame->closure->upvalues[slot]->location = peek(0);
|
|
|
break;
|
|
|
}
|
|
|
+ case OP_CLOSE_UPVALUE:
|
|
|
+ closeUpvalues(vm.stackTop - 1);
|
|
|
+ pop();
|
|
|
+ break;
|
|
|
case OP_RETURN: {
|
|
|
Value result = pop();
|
|
|
+ closeUpvalues(frame->slots);
|
|
|
vm.frameCount--;
|
|
|
if (vm.frameCount == 0) {
|
|
|
pop();
|
|
|
@@ -378,6 +410,11 @@ InterpretResult interpret(const char *source) {
|
|
|
void push(Value value) {
|
|
|
*vm.stackTop = value;
|
|
|
vm.stackTop++;
|
|
|
+#ifdef DEBUG_TRACE_EXECUTION
|
|
|
+ printf("push stack: ");
|
|
|
+ printValue(value);
|
|
|
+ printf("\n");
|
|
|
+#endif
|
|
|
}
|
|
|
|
|
|
Value pop() {
|