@@ -805,30 +805,43 @@ static InterpretResult run(VM* vm) {
805805 case OP_BUILD_LIST : {
806806 int count = READ_BYTE ();
807807 struct ObjList * list = newList ();
808+ push (vm , OBJ_VAL (list )); // Root it!
808809 if (count > 0 ) {
809810 list -> items = ALLOCATE (Value , count );
810811 list -> capacity = count ;
811812 list -> count = count ;
812813 for (int i = count - 1 ; i >= 0 ; i -- ) {
813- list -> items [i ] = pop (vm );
814+ // Peek from below the rooted list
815+ list -> items [i ] = peek (vm , 1 + (count - 1 - i ));
814816 }
817+ // Clean stack: [item1, ..., itemN, list] -> [list]
818+ Value listVal = peek (vm , 0 );
819+ vm -> stackTop -= (count + 1 );
820+ push (vm , listVal );
815821 }
816- push (vm , OBJ_VAL (list ));
817822 break ;
818823 }
819824 case OP_BUILD_MAP : {
820825 int count = READ_BYTE ();
821826 struct ObjDictionary * dict = newDictionary ();
827+ push (vm , OBJ_VAL (dict )); // Root it!
822828 for (int i = 0 ; i < count ; i ++ ) {
823- Value val = pop (vm );
824- Value key = pop (vm );
829+ // Peek below the rooted dict
830+ Value val = peek (vm , 1 );
831+ Value key = peek (vm , 2 );
825832 if (!IS_STRING (key )) {
826833 runtimeError (vm , "Dictionary key must be a string." );
827834 return INTERPRET_RUNTIME_ERROR ;
828835 }
829836 tableSet (& dict -> items , AS_STRING (key ), val );
837+
838+ // Clean up key/val from stack, keep dict
839+ // Stack: [..., key, val, dict]
840+ pop (vm ); // dict
841+ pop (vm ); // val
842+ pop (vm ); // key
843+ push (vm , OBJ_VAL (dict ));
830844 }
831- push (vm , OBJ_VAL (dict ));
832845 break ;
833846 }
834847 case OP_GET_INDEX : {
0 commit comments