@@ -119,25 +119,26 @@ impl Value {
119119
120120 /// Create a string value
121121 pub fn string ( s : & str ) -> Value {
122- let heap = Box :: new ( HeapObject :: String ( Rc :: from ( s) ) ) ;
122+ let heap = Rc :: new ( HeapObject :: String ( Rc :: from ( s) ) ) ;
123123 Value :: from_heap ( heap)
124124 }
125125
126126 /// Create a symbol value
127127 pub fn symbol ( s : & str ) -> Value {
128- let heap = Box :: new ( HeapObject :: Symbol ( Rc :: from ( s) ) ) ;
128+ let heap = Rc :: new ( HeapObject :: Symbol ( Rc :: from ( s) ) ) ;
129129 Value :: from_heap ( heap)
130130 }
131131
132132 /// Create a list value
133133 pub fn list ( items : Vec < Value > ) -> Value {
134- let heap = Box :: new ( HeapObject :: List ( Rc :: from ( items) ) ) ;
134+ let heap = Rc :: new ( HeapObject :: List ( Rc :: from ( items) ) ) ;
135135 Value :: from_heap ( heap)
136136 }
137137
138- /// Create a heap-allocated value from a Box<HeapObject>
139- fn from_heap ( heap : Box < HeapObject > ) -> Value {
140- let ptr = Box :: into_raw ( heap) as u64 ;
138+ /// Create a heap-allocated value from an Rc<HeapObject>
139+ /// Uses Rc::into_raw to store the pointer - refcount is NOT decremented
140+ fn from_heap ( heap : Rc < HeapObject > ) -> Value {
141+ let ptr = Rc :: into_raw ( heap) as u64 ;
141142 debug_assert ! ( ptr & TAG_MASK == 0 , "Pointer uses more than 48 bits" ) ;
142143 Value ( TAG_PTR | ptr)
143144 }
@@ -219,21 +220,10 @@ impl Value {
219220 return None ;
220221 }
221222 let ptr = ( self . 0 & PAYLOAD_MASK ) as * const HeapObject ;
222- // Safety: we only create these pointers from Box ::into_raw
223+ // Safety: we only create these pointers from Rc ::into_raw
223224 Some ( unsafe { & * ptr } )
224225 }
225226
226- /// Get the heap object mutably (for cloning the inner Rc)
227- #[ inline]
228- fn as_heap_mut ( & self ) -> Option < & mut HeapObject > {
229- if !self . is_ptr ( ) {
230- return None ;
231- }
232- let ptr = ( self . 0 & PAYLOAD_MASK ) as * mut HeapObject ;
233- // Safety: we only create these pointers from Box::into_raw
234- Some ( unsafe { & mut * ptr } )
235- }
236-
237227 /// Get as a symbol string, if this is a symbol
238228 pub fn as_symbol ( & self ) -> Option < & str > {
239229 match self . as_heap ( ) {
@@ -343,50 +333,50 @@ impl Value {
343333
344334 /// Create String (backwards compat) - from Rc<str>
345335 pub fn String ( s : Rc < str > ) -> Value {
346- let heap = Box :: new ( HeapObject :: String ( s) ) ;
336+ let heap = Rc :: new ( HeapObject :: String ( s) ) ;
347337 Value :: from_heap ( heap)
348338 }
349339
350340 /// Create Symbol (backwards compat) - from Rc<str>
351341 pub fn Symbol ( s : Rc < str > ) -> Value {
352- let heap = Box :: new ( HeapObject :: Symbol ( s) ) ;
342+ let heap = Rc :: new ( HeapObject :: Symbol ( s) ) ;
353343 Value :: from_heap ( heap)
354344 }
355345
356346 /// Create List (backwards compat) - from Rc<[Value]>
357347 pub fn List ( items : Rc < [ Value ] > ) -> Value {
358- let heap = Box :: new ( HeapObject :: List ( items) ) ;
348+ let heap = Rc :: new ( HeapObject :: List ( items) ) ;
359349 Value :: from_heap ( heap)
360350 }
361351
362352 /// Create Function (backwards compat)
363353 pub fn Function ( f : Rc < Function > ) -> Value {
364- let heap = Box :: new ( HeapObject :: Function ( f) ) ;
354+ let heap = Rc :: new ( HeapObject :: Function ( f) ) ;
365355 Value :: from_heap ( heap)
366356 }
367357
368358 /// Create NativeFunction (backwards compat)
369359 pub fn NativeFunction ( f : Rc < NativeFunction > ) -> Value {
370- let heap = Box :: new ( HeapObject :: NativeFunction ( f) ) ;
360+ let heap = Rc :: new ( HeapObject :: NativeFunction ( f) ) ;
371361 Value :: from_heap ( heap)
372362 }
373363
374364 /// Create CompiledFunction (backwards compat)
375365 pub fn CompiledFunction ( c : Rc < Chunk > ) -> Value {
376- let heap = Box :: new ( HeapObject :: CompiledFunction ( c) ) ;
366+ let heap = Rc :: new ( HeapObject :: CompiledFunction ( c) ) ;
377367 Value :: from_heap ( heap)
378368 }
379369}
380370
381371impl Drop for Value {
382372 fn drop ( & mut self ) {
383- // If this is a heap pointer, we need to drop the HeapObject
373+ // If this is a heap pointer, we need to decrement the Rc refcount
384374 if self . is_ptr ( ) {
385- let ptr = ( self . 0 & PAYLOAD_MASK ) as * mut HeapObject ;
386- // Safety: we only create these from Box ::into_raw, and we set
387- // the tag to something else after dropping
375+ let ptr = ( self . 0 & PAYLOAD_MASK ) as * const HeapObject ;
376+ // Safety: we only create these from Rc ::into_raw
377+ // Rc::from_raw will decrement the refcount and free if it hits 0
388378 unsafe {
389- drop ( Box :: from_raw ( ptr) ) ;
379+ drop ( Rc :: from_raw ( ptr) ) ;
390380 }
391381 // Mark as nil to prevent double-free
392382 self . 0 = TAG_NIL ;
@@ -397,13 +387,15 @@ impl Drop for Value {
397387impl Clone for Value {
398388 fn clone ( & self ) -> Self {
399389 if self . is_ptr ( ) {
400- // Clone the heap object (which clones the inner Rc)
401- if let Some ( heap ) = self . as_heap ( ) {
402- let cloned = Box :: new ( heap . clone ( ) ) ;
403- Value :: from_heap ( cloned )
404- } else {
405- Value :: nil ( )
390+ // Just increment the Rc reference count - no new allocation!
391+ let ptr = ( self . 0 & PAYLOAD_MASK ) as * const HeapObject ;
392+ // Safety: we only create these from Rc::into_raw
393+ // increment_strong_count increases refcount without creating an Rc
394+ unsafe {
395+ Rc :: increment_strong_count ( ptr ) ;
406396 }
397+ // Return a Value with the same pointer (both now own a reference)
398+ Value ( self . 0 )
407399 } else {
408400 // Primitives: just copy the bits
409401 Value ( self . 0 )
0 commit comments