@@ -30,12 +30,7 @@ pub(crate) type LuaInnerValue = Value; // For internal use within LuaValue imple
3030
3131use crate :: Instruction ;
3232use crate :: gc:: { ProtoPtr , UpvaluePtr } ;
33- use crate :: lua_vm:: CFunction ;
34-
35- #[ derive( Clone , Copy , PartialEq , Eq , Hash , Debug ) ]
36- pub struct LuaValuePtr {
37- pub ptr : * mut LuaValue ,
38- }
33+ use crate :: lua_vm:: { CFunction , StkId } ;
3934
4035/// Runtime upvalue — pointer-based design matching C Lua's UpVal.
4136///
@@ -48,7 +43,7 @@ pub struct LuaValuePtr {
4843pub struct LuaUpvalue {
4944 /// Always-valid pointer to the upvalue's current value.
5045 /// Open → stack slot, Closed → &self.closed_value
51- v : * mut LuaValue ,
46+ v : StkId ,
5247 /// Storage for the closed value. When closed, `v` points here.
5348 closed_value : LuaValue ,
5449 /// Stack index (only meaningful when open)
@@ -59,9 +54,9 @@ impl LuaUpvalue {
5954 /// Create an open upvalue pointing to a stack location (absolute index).
6055 /// `stack_ptr` must remain valid until the upvalue is closed or the pointer is updated.
6156 #[ inline( always) ]
62- pub fn new_open ( stack_index : usize , stack_ptr : LuaValuePtr ) -> Self {
57+ pub fn new_open ( stack_index : usize , stk_id : StkId ) -> Self {
6358 LuaUpvalue {
64- v : stack_ptr . ptr ,
59+ v : stk_id ,
6560 closed_value : LuaValue :: nil ( ) ,
6661 stack_index,
6762 }
@@ -73,7 +68,7 @@ impl LuaUpvalue {
7368 #[ inline( always) ]
7469 pub fn new_closed ( value : LuaValue ) -> Self {
7570 LuaUpvalue {
76- v : std :: ptr :: null_mut ( ) ,
71+ v : StkId :: null ( ) ,
7772 closed_value : value,
7873 stack_index : 0 ,
7974 }
@@ -84,16 +79,16 @@ impl LuaUpvalue {
8479 /// No-op for open upvalues (where v is already a valid stack pointer).
8580 #[ inline( always) ]
8681 pub fn fix_closed_ptr ( & mut self ) {
87- if self . v . is_null ( ) {
88- self . v = & mut self . closed_value as * mut LuaValue ;
82+ if ! self . v . is_valid ( ) {
83+ self . v = StkId :: from_mut_ptr ( & mut self . closed_value as * mut LuaValue ) ;
8984 }
9085 }
9186
9287 /// Check if this upvalue is open (like C Lua's `upisopen` macro).
9388 /// Open ⟺ `v` does NOT point to our own `closed_value` field.
9489 #[ inline( always) ]
9590 pub fn is_open ( & self ) -> bool {
96- !std:: ptr:: eq ( self . v , & self . closed_value )
91+ !std:: ptr:: eq ( self . v . as_ptr ( ) , & self . closed_value )
9792 }
9893
9994 /// Get the stack index (only meaningful when open).
@@ -107,101 +102,43 @@ impl LuaUpvalue {
107102 #[ inline( always) ]
108103 pub fn close ( & mut self , stack_value : LuaValue ) {
109104 self . closed_value = stack_value;
110- self . v = & mut self . closed_value as * mut LuaValue ;
105+ self . v = StkId :: from_mut_ptr ( & mut self . closed_value as * mut LuaValue ) ;
111106 }
112107
113108 /// Update the cached stack pointer (called after stack reallocation).
114109 #[ inline( always) ]
115- pub fn update_stack_ptr ( & mut self , ptr : * mut LuaValue ) {
116- self . v = ptr ;
110+ pub fn update_stack_ptr ( & mut self , stk_id : StkId ) {
111+ self . v = stk_id ;
117112 }
118113
119114 /// Get the raw v pointer (for caching in the execute loop).
120115 #[ inline( always) ]
121- pub fn get_v_ptr ( & self ) -> * mut LuaValue {
116+ pub fn get_v_stk_id ( & self ) -> StkId {
122117 self . v
123118 }
124119
125120 /// Get the value with **zero branching** — single pointer dereference.
126121 #[ inline( always) ]
127122 pub fn get_value ( & self ) -> LuaValue {
128- debug_assert ! ( !self . v. is_null( ) , "upvalue get_value: null pointer" ) ;
129- debug_assert ! (
130- ( self . v as usize ) > 0x10000 ,
131- "upvalue get_value: suspiciously low pointer {:p} (stack_index={})" ,
132- self . v,
133- self . stack_index
134- ) ;
135- let val = unsafe { * self . v } ;
136- debug_assert ! (
137- Self :: is_valid_tt( val. tt( ) ) ,
138- "upvalue get_value: INVALID type tag 0x{:02X} read from {:p} (stack_index={}, is_open={}). Likely dangling pointer!" ,
139- val. tt( ) ,
140- self . v,
141- self . stack_index,
142- self . is_open( )
143- ) ;
144- val
123+ self . v . get ( )
145124 }
146125
147126 /// Get reference to the value with **zero branching**.
148127 #[ inline( always) ]
149128 pub fn get_value_ref ( & self ) -> & LuaValue {
150- debug_assert ! ( !self . v. is_null( ) , "upvalue get_value_ref: null pointer" ) ;
151- unsafe { & * self . v }
129+ self . v . get_ref ( )
152130 }
153131
154132 /// Set the value with **zero branching** — single pointer write.
155133 #[ inline( always) ]
156134 pub fn set_value ( & mut self , val : LuaValue ) {
157- debug_assert ! ( !self . v. is_null( ) , "upvalue set_value: null pointer" ) ;
158- debug_assert ! (
159- ( self . v as usize ) > 0x10000 ,
160- "upvalue set_value: suspiciously low pointer {:p} (stack_index={})" ,
161- self . v,
162- self . stack_index
163- ) ;
164- unsafe { * self . v = val }
135+ self . v . write ( & val) ;
165136 }
166137
167138 /// Set the value by raw parts to avoid constructing a temporary LuaValue.
168139 #[ inline( always) ]
169140 pub fn set_value_parts ( & mut self , value : Value , tt : u8 ) {
170- debug_assert ! ( !self . v. is_null( ) , "upvalue set_value_parts: null pointer" ) ;
171- debug_assert ! (
172- ( self . v as usize ) > 0x10000 ,
173- "upvalue set_value_parts: suspiciously low pointer {:p} (stack_index={})" ,
174- self . v,
175- self . stack_index
176- ) ;
177- unsafe {
178- ( * self . v ) . value = value;
179- ( * self . v ) . tt = tt;
180- }
181- }
182-
183- /// Check if a type tag is valid (used for dangling pointer detection)
184- fn is_valid_tt ( tt : u8 ) -> bool {
185- use crate :: lua_value:: lua_value:: * ;
186- matches ! (
187- tt,
188- LUA_VNIL
189- | LUA_VEMPTY
190- | LUA_VABSTKEY
191- | LUA_VFALSE
192- | LUA_VTRUE
193- | LUA_VNUMINT
194- | LUA_VNUMFLT
195- | LUA_VSHRSTR
196- | LUA_VLNGSTR
197- | LUA_VTABLE
198- | LUA_VFUNCTION
199- | LUA_CCLOSURE
200- | LUA_VLCF
201- | LUA_VLIGHTUSERDATA
202- | LUA_VUSERDATA
203- | LUA_VTHREAD
204- )
141+ self . v . write_parts ( tt, value) ;
205142 }
206143
207144 pub fn get_closed_value ( & self ) -> Option < & LuaValue > {
0 commit comments