@@ -321,6 +321,8 @@ DEF_PRIMITIVE(list_new)
321321
322322DEF_PRIMITIVE (list_add )
323323{
324+ VALIDATE_VALUE_IS_NOT_FROZEN (args [0 ]);
325+
324326 wrenValueBufferWrite (vm , & AS_LIST (args [0 ])-> elements , args [1 ]);
325327 RETURN_VAL (args [1 ]);
326328}
@@ -330,6 +332,8 @@ DEF_PRIMITIVE(list_add)
330332// minimize stack churn.
331333DEF_PRIMITIVE (list_addCore )
332334{
335+ VALIDATE_VALUE_IS_NOT_FROZEN (args [0 ]);
336+
333337 wrenValueBufferWrite (vm , & AS_LIST (args [0 ])-> elements , args [1 ]);
334338
335339 // Return the list.
@@ -338,6 +342,8 @@ DEF_PRIMITIVE(list_addCore)
338342
339343DEF_PRIMITIVE (list_clear )
340344{
345+ VALIDATE_VALUE_IS_NOT_FROZEN (args [0 ]);
346+
341347 wrenValueBufferClear (vm , & AS_LIST (args [0 ])-> elements );
342348 RETURN_NULL ;
343349}
@@ -349,6 +355,8 @@ DEF_PRIMITIVE(list_count)
349355
350356DEF_PRIMITIVE (list_insert )
351357{
358+ VALIDATE_VALUE_IS_NOT_FROZEN (args [0 ]);
359+
352360 ObjList * list = AS_LIST (args [0 ]);
353361
354362 // count + 1 here so you can "insert" at the very end.
@@ -392,6 +400,8 @@ DEF_PRIMITIVE(list_iteratorValue)
392400
393401DEF_PRIMITIVE (list_removeAt )
394402{
403+ VALIDATE_VALUE_IS_NOT_FROZEN (args [0 ]);
404+
395405 ObjList * list = AS_LIST (args [0 ]);
396406 uint32_t index = validateIndex (vm , args [1 ], list -> elements .count , "Index" );
397407 if (index == UINT32_MAX ) return false;
@@ -400,6 +410,8 @@ DEF_PRIMITIVE(list_removeAt)
400410}
401411
402412DEF_PRIMITIVE (list_removeValue ) {
413+ VALIDATE_VALUE_IS_NOT_FROZEN (args [0 ]);
414+
403415 ObjList * list = AS_LIST (args [0 ]);
404416 int index = wrenListIndexOf (vm , list , args [1 ]);
405417 if (index == -1 ) RETURN_NULL ;
@@ -414,6 +426,8 @@ DEF_PRIMITIVE(list_indexOf)
414426
415427DEF_PRIMITIVE (list_swap )
416428{
429+ VALIDATE_VALUE_IS_NOT_FROZEN (args [0 ]);
430+
417431 ObjList * list = AS_LIST (args [0 ]);
418432 uint32_t indexA = validateIndex (vm , args [1 ], list -> elements .count , "Index 0" );
419433 if (indexA == UINT32_MAX ) return false;
@@ -461,6 +475,8 @@ DEF_PRIMITIVE(list_subscript)
461475
462476DEF_PRIMITIVE (list_subscriptSetter )
463477{
478+ VALIDATE_VALUE_IS_NOT_FROZEN (args [0 ]);
479+
464480 ObjList * list = AS_LIST (args [0 ]);
465481 uint32_t index = validateIndex (vm , args [1 ], list -> elements .count ,
466482 "Subscript" );
@@ -488,6 +504,8 @@ DEF_PRIMITIVE(map_subscript)
488504
489505DEF_PRIMITIVE (map_subscriptSetter )
490506{
507+ VALIDATE_VALUE_IS_NOT_FROZEN (args [0 ]);
508+
491509 if (!validateKey (vm , args [1 ])) return false;
492510
493511 wrenMapSet (vm , AS_MAP (args [0 ]), args [1 ], args [2 ]);
@@ -499,6 +517,8 @@ DEF_PRIMITIVE(map_subscriptSetter)
499517// minimize stack churn.
500518DEF_PRIMITIVE (map_addCore )
501519{
520+ VALIDATE_VALUE_IS_NOT_FROZEN (args [0 ]);
521+
502522 if (!validateKey (vm , args [1 ])) return false;
503523
504524 wrenMapSet (vm , AS_MAP (args [0 ]), args [1 ], args [2 ]);
@@ -509,6 +529,8 @@ DEF_PRIMITIVE(map_addCore)
509529
510530DEF_PRIMITIVE (map_clear )
511531{
532+ VALIDATE_VALUE_IS_NOT_FROZEN (args [0 ]);
533+
512534 wrenMapClear (vm , AS_MAP (args [0 ]));
513535 RETURN_NULL ;
514536}
@@ -560,6 +582,8 @@ DEF_PRIMITIVE(map_iterate)
560582
561583DEF_PRIMITIVE (map_remove )
562584{
585+ VALIDATE_VALUE_IS_NOT_FROZEN (args [0 ]);
586+
563587 if (!validateKey (vm , args [1 ])) return false;
564588
565589 RETURN_VAL (wrenMapRemoveKey (vm , AS_MAP (args [0 ]), args [1 ]));
@@ -863,6 +887,11 @@ DEF_PRIMITIVE(object_bangeq)
863887 RETURN_BOOL (!wrenValuesEqual (args [0 ], args [1 ]));
864888}
865889
890+ DEF_PRIMITIVE (object_freeze )
891+ {
892+ RETURN_VAL (wrenFreeze (args [0 ], true));
893+ }
894+
866895DEF_PRIMITIVE (object_is )
867896{
868897 if (!IS_CLASS (args [1 ]))
@@ -885,6 +914,11 @@ DEF_PRIMITIVE(object_is)
885914 RETURN_BOOL (false);
886915}
887916
917+ DEF_PRIMITIVE (object_isFrozen )
918+ {
919+ RETURN_BOOL (wrenIsFrozen (args [0 ]));
920+ }
921+
888922DEF_PRIMITIVE (object_toString )
889923{
890924 Obj * obj = AS_OBJ (args [0 ]);
@@ -897,6 +931,12 @@ DEF_PRIMITIVE(object_type)
897931 RETURN_OBJ (wrenGetClass (vm , args [0 ]));
898932}
899933
934+ DEF_PRIMITIVE (object_validateIsNotFrozen )
935+ {
936+ VALIDATE_VALUE_IS_NOT_FROZEN (args [0 ]);
937+ RETURN_VAL (args [0 ]);
938+ }
939+
900940DEF_PRIMITIVE (range_from )
901941{
902942 RETURN_NUM (AS_RANGE (args [0 ])-> from );
@@ -1247,9 +1287,12 @@ void wrenInitializeCore(WrenVM* vm)
12471287 PRIMITIVE (vm -> objectClass , "!" , object_not );
12481288 PRIMITIVE (vm -> objectClass , "==(_)" , object_eqeq );
12491289 PRIMITIVE (vm -> objectClass , "!=(_)" , object_bangeq );
1290+ PRIMITIVE (vm -> objectClass , "freeze()" , object_freeze );
12501291 PRIMITIVE (vm -> objectClass , "is(_)" , object_is );
1292+ PRIMITIVE (vm -> objectClass , "isFrozen" , object_isFrozen );
12511293 PRIMITIVE (vm -> objectClass , "toString" , object_toString );
12521294 PRIMITIVE (vm -> objectClass , "type" , object_type );
1295+ PRIMITIVE (vm -> objectClass , "validateIsNotFrozen()" , object_validateIsNotFrozen );
12531296
12541297 // Now we can define Class, which is a subclass of Object.
12551298 vm -> classClass = defineClass (vm , coreModule , "Class" );
0 commit comments