~jack/misc

ad3cab6c0780759455d9c97378d181e810f8a359 — Jack Kelly 1 year, 5 months ago 386e533
zlox: Closing upvalues
M zlox/src/chunk.h => zlox/src/chunk.h +1 -0
@@ 32,6 32,7 @@ typedef enum {
  OP_LOOP,
  OP_CALL,
  OP_CLOSURE,
  OP_CLOSE_UPVALUE,
  OP_RETURN,
} OpCode;


M zlox/src/compiler.c => zlox/src/compiler.c +9 -1
@@ 44,6 44,7 @@ typedef struct {
typedef struct {
  Token name;
  int depth;
  bool isCaptured;
} Local;

typedef struct {


@@ 201,6 202,7 @@ static void initCompiler(Compiler *compiler, FunctionType type) {

  Local *local = &current->locals[current->localCount++];
  local->depth = 0;
  local->isCaptured = false;
  local->name.start = "";
  local->name.length = 0;
}


@@ 229,7 231,11 @@ static void endScope() {

  while (current->localCount > 0 &&
         current->locals[current->localCount - 1].depth > current->scopeDepth) {
    emitByte(OP_POP);
    if (current->locals[current->localCount - 1].isCaptured) {
      emitByte(OP_CLOSE_UPVALUE);
    } else {
      emitByte(OP_POP);
    }
    current->localCount--;
  }
}


@@ 372,6 378,7 @@ static int resolveUpvalue(Compiler *compiler, Token *name) {

  int local = resolveLocal(compiler->enclosing, name);
  if (local != -1) {
    compiler->enclosing->locals[local].isCaptured = true;
    return addUpvalue(compiler, (uint8_t)local, true);
  }



@@ 392,6 399,7 @@ static void addLocal(Token name) {
  Local *local = &current->locals[current->localCount++];
  local->name = name;
  local->depth = -1;
  local->isCaptured = false;
}

static void declareVariable() {

M zlox/src/debug.c => zlox/src/debug.c +2 -0
@@ 123,6 123,8 @@ int disassembleInstruction(Chunk *chunk, int offset) {
      }
      return offset;
    }
  case OP_CLOSE_UPVALUE:
    return simpleInstruction("OP_CLOSE_UPVALUE", offset);
  case OP_RETURN:
    return simpleInstruction("OP_RETURN", offset);
  default:

M zlox/src/object.c => zlox/src/object.c +2 -0
@@ 93,6 93,8 @@ ObjString* copyString(const char *chars, int length) {
ObjUpvalue* newUpvalue(Value *slot) {
  ObjUpvalue *upvalue = ALLOCATE_OBJ(ObjUpvalue, OBJ_UPVALUE);
  upvalue->location = slot;
  upvalue->closed = NIL_VAL;
  upvalue->next = NULL;
  return upvalue;
}


M zlox/src/object.h => zlox/src/object.h +2 -0
@@ 57,6 57,8 @@ struct ObjString {
typedef struct ObjUpvalue {
  Obj obj;
  Value *location;
  Value closed;
  struct ObjUpvalue *next;
} ObjUpvalue;

typedef struct {

M zlox/src/vm.c => zlox/src/vm.c +35 -0
@@ 21,6 21,7 @@ static Value clockNative(int argCount, Value *args) {
static void resetStack() {
  vm.stackTop = vm.stack;
  vm.frameCount = 0;
  vm.openUpvalues = NULL;
}

static void runtimeError(const char *format, ...) {


@@ 114,10 115,39 @@ static bool callValue(Value callee, int argCount) {
}

static ObjUpvalue* captureUpvalue(Value *local) {
  ObjUpvalue *prevUpvalue = NULL;
  ObjUpvalue *upvalue = vm.openUpvalues;
  while (upvalue != NULL && upvalue->location > local) {
    prevUpvalue = upvalue;
    upvalue = upvalue->next;
  }

  if (upvalue != NULL && upvalue->location == local) {
    return upvalue;
  }

  ObjUpvalue *createdUpvalue = newUpvalue(local);
  createdUpvalue->next = upvalue;

  if (prevUpvalue == NULL) {
    vm.openUpvalues = createdUpvalue;
  } else {
    prevUpvalue->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;
  }
}

static bool isFalsey(Value value) {
  return IS_NIL(value) || (IS_BOOL(value) && !AS_BOOL(value));
}


@@ 318,9 348,14 @@ static InterpretResult run() {
        }
        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();

M zlox/src/vm.h => zlox/src/vm.h +1 -0
@@ 22,6 22,7 @@ typedef struct {
  Value *stackTop;
  Table globals;
  Table strings;
  ObjUpvalue *openUpvalues;
  Obj *objects;
} VM;