File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff 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 }
Original file line number Diff line number Diff line change @@ -25,8 +25,16 @@ static Obj* allocate_object(size_t size, ObjType type)
2525
2626ObjClosure * 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+
104119static void print_function (ObjFunction * function )
105120{
106121 if (function -> name == NULL )
Original file line number Diff line number Diff 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+
6470typedef struct
6571{
6672 Obj obj ;
6773 ObjFunction * function ;
74+ ObjUpvalue * * upvalues ;
75+ int upvalue_count ;
6876} ObjClosure ;
6977
7078ObjClosure * new_closure (ObjFunction * function );
7179ObjFunction * new_function ();
7280ObjNative * new_native (NativeFn function );
7381ObjString * take_string (char * chars , int length );
7482ObjString * copy_string (const char * chars , int length );
83+ ObjUpvalue * new_upvalue (Value * slot );
7584void print_object (Value value );
7685
7786static inline bool is_obj_type (Value value , ObjType type )
Original file line number Diff line number Diff 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+
139145static 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 :
You can’t perform that action at this time.
0 commit comments