Skip to content

Commit c028175

Browse files
committed
feat: implement upvalues in runtime now
1 parent 16222d8 commit c028175

4 files changed

Lines changed: 54 additions & 0 deletions

File tree

src/memory.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ static void free_object(Obj* object)
2626
{
2727
case OBJ_CLOSURE:
2828
{
29+
ObjClosure* closure = (ObjClosure*)object;
30+
FREE_ARRAY(ObjUpvalue*, closure->upvalues, closure->upvalue_count);
2931
FREE(ObjClosure, object);
3032
break;
3133
}

src/object.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,16 @@ static Obj* allocate_object(size_t size, ObjType type)
2525

2626
ObjClosure* new_closure(ObjFunction* function)
2727
{
28+
ObjUpvalue** upvalues = ALLOCATE(ObjUpvalue*, function->upvalue_count);
29+
for (int i = 0; i < function->upvalue_count; i++)
30+
{
31+
upvalues[i] = NULL;
32+
}
33+
2834
ObjClosure* closure = ALLOCATE_OBJ(ObjClosure, OBJ_CLOSURE);
2935
closure->function = function;
36+
closure->upvalues = upvalues;
37+
closure->upvalue_count = function->upvalue_count;
3038
return closure;
3139
}
3240

@@ -101,6 +109,13 @@ ObjString* copy_string(const char* chars, int length)
101109
return allocate_string(heap_chars, length, hash);
102110
}
103111

112+
ObjUpvalue* new_upvalue(Value* slot)
113+
{
114+
ObjUpvalue* upvalue = ALLOCATE_OBJ(ObjUpvalue, OBJ_UPVALUE);
115+
upvalue->location = slot;
116+
return upvalue;
117+
}
118+
104119
static void print_function(ObjFunction* function)
105120
{
106121
if (function->name == NULL)

src/object.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,26 @@ struct ObjString
6161
u32 hash;
6262
};
6363

64+
typedef struct
65+
{
66+
Obj obj;
67+
Value* location;
68+
} ObjUpvalue;
69+
6470
typedef struct
6571
{
6672
Obj obj;
6773
ObjFunction* function;
74+
ObjUpvalue** upvalues;
75+
int upvalue_count;
6876
} ObjClosure;
6977

7078
ObjClosure* new_closure(ObjFunction* function);
7179
ObjFunction* new_function();
7280
ObjNative* new_native(NativeFn function);
7381
ObjString* take_string(char* chars, int length);
7482
ObjString* copy_string(const char* chars, int length);
83+
ObjUpvalue* new_upvalue(Value* slot);
7584
void print_object(Value value);
7685

7786
static inline bool is_obj_type(Value value, ObjType type)

src/vm.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,12 @@ static bool call_value(Value callee, int arg_count)
136136
return false;
137137
}
138138

139+
static ObjUpvalue* capture_upvalue(Value* local)
140+
{
141+
ObjUpvalue* created_upvalue = new_upvalue(local);
142+
return created_upvalue;
143+
}
144+
139145
static bool is_falsey(Value value)
140146
{
141147
return IS_NIL(value) || (IS_BOOL(value) && !AS_BOOL(value));
@@ -255,6 +261,18 @@ static InterpretResult run()
255261
}
256262
break;
257263
}
264+
case OP_GET_UPVALUE:
265+
{
266+
u8 slot = READ_BYTE();
267+
push(*frame->closure->upvalues[slot]->location);
268+
break;
269+
}
270+
case OP_SET_UPVALUE:
271+
{
272+
u8 slot = READ_BYTE();
273+
*frame->closure->upvalues[slot]->location = peek(0);
274+
break;
275+
}
258276
case OP_EQUAL:
259277
{
260278
Value v2 = pop();
@@ -347,6 +365,16 @@ static InterpretResult run()
347365
ObjFunction* function = AS_FUNCTION(READ_CONSTANT());
348366
ObjClosure* closure = new_closure(function);
349367
push(OBJ_VAL(closure));
368+
for (int i = 0; i < closure->upvalue_count; i++)
369+
{
370+
u8 islocal = READ_BYTE();
371+
u8 index = READ_BYTE();
372+
if (islocal)
373+
closure->upvalues[i] =
374+
capture_upvalue(frame->slots + index);
375+
else
376+
closure->upvalues[i] = frame->closure->upvalues[index];
377+
}
350378
break;
351379
}
352380
case OP_RETURN:

0 commit comments

Comments
 (0)