1
- use libc:: c_int;
1
+ /*
2
+ ** Auxiliary functions to manipulate prototypes and closures
3
+ */
4
+
5
+ use std:: mem:: size_of;
6
+ use std:: ptr;
7
+
8
+ use libc:: { c_char, c_int, size_t} ;
9
+
10
+ use crate :: lgc:: luaC_upvalbarrier;
11
+ use crate :: llimits:: { lu_byte, lu_mem} ;
12
+ use crate :: lmem:: { luaM_free, luaM_freearray, luaM_new} ;
13
+ use crate :: lobject:: {
14
+ getstr, setnilvalue, setobj, CClosure , GCObject , LClosure , Proto , StkId , TValue , LUA_TCCL ,
15
+ LUA_TLCL , LUA_TPROTO ,
16
+ } ;
17
+ use crate :: lstate:: { gco2ccl, gco2lcl, gco2p, lua_State} ;
2
18
3
- use crate :: llimits:: lu_mem;
4
- use crate :: lobject:: TValue ;
19
+ pub const fn sizeCclosure ( n : c_int ) -> size_t {
20
+ ( size_of :: < CClosure > ( ) as c_int + size_of :: < TValue > ( ) as c_int * ( n - 1 ) ) as size_t
21
+ }
22
+
23
+ pub const fn sizeLclosure ( n : c_int ) -> size_t {
24
+ ( size_of :: < LClosure > ( ) as c_int + size_of :: < * const TValue > ( ) as c_int * ( n - 1 ) ) as size_t
25
+ }
26
+
27
+ /* test whether thread is in 'twups' list */
28
+ #[ inline( always) ]
29
+ pub unsafe fn isintwups ( L : * mut lua_State ) -> bool {
30
+ ( * L ) . twups != L
31
+ }
32
+
33
+ /*
34
+ ** maximum number of upvalues in a closure (both C and Lua). (Value
35
+ ** must fit in a VM register.)
36
+ */
37
+ pub const MAXUPVAL : usize = 255 ;
5
38
6
39
/*
7
40
** Upvalues for Lua closures
@@ -27,3 +60,158 @@ pub struct C2RustUnnamed_4 {
27
60
pub next : * mut UpVal , /* linked list */
28
61
pub touched : c_int , /* mark to avoid cycles with dead threads */
29
62
}
63
+
64
+ #[ inline( always) ]
65
+ pub unsafe fn upisopen ( up : * mut UpVal ) -> bool {
66
+ ( * up) . v != & mut ( * up) . u . value as * mut _
67
+ }
68
+
69
+ extern "C" {
70
+ pub fn luaC_newobj ( L : * mut lua_State , tt : c_int , sz : size_t ) -> * mut GCObject ;
71
+ }
72
+
73
+ #[ no_mangle]
74
+ pub unsafe extern "C" fn luaF_newCclosure ( L : * mut lua_State , n : c_int ) -> * mut CClosure {
75
+ let o = luaC_newobj ( L , LUA_TCCL , sizeCclosure ( n) ) ;
76
+ let mut c: * mut CClosure = gco2ccl ( o) ;
77
+ ( * c) . nupvalues = n as lu_byte ;
78
+ return c;
79
+ }
80
+
81
+ #[ no_mangle]
82
+ pub unsafe extern "C" fn luaF_newLclosure ( L : * mut lua_State , mut n : c_int ) -> * mut LClosure {
83
+ let o = luaC_newobj ( L , LUA_TLCL , sizeLclosure ( n) ) ;
84
+ let mut c: * mut LClosure = gco2lcl ( o) ;
85
+ ( * c) . p = ptr:: null_mut ( ) ;
86
+ ( * c) . nupvalues = n as lu_byte ;
87
+ while n != 0 {
88
+ n -= 1 ;
89
+ * ( ( * c) . upvals ) . as_mut_ptr ( ) . offset ( n as isize ) = ptr:: null_mut ( ) ;
90
+ }
91
+ return c;
92
+ }
93
+
94
+ /*
95
+ ** fill a closure with new closed upvalues
96
+ */
97
+ #[ no_mangle]
98
+ pub unsafe extern "C" fn luaF_initupvals ( L : * mut lua_State , cl : * mut LClosure ) {
99
+ let mut i = 0 ;
100
+ while i < ( * cl) . nupvalues {
101
+ let uv = luaM_new :: < UpVal > ( L ) ;
102
+ ( * uv) . refcount = 1 ;
103
+ ( * uv) . v = & mut ( * uv) . u . value ; /* make it closed */
104
+ setnilvalue ( ( * uv) . v ) ;
105
+ * ( ( * cl) . upvals ) . as_mut_ptr ( ) . offset ( i as isize ) = uv;
106
+ i += 1 ;
107
+ }
108
+ }
109
+
110
+ #[ no_mangle]
111
+ pub unsafe extern "C" fn luaF_findupval ( L : * mut lua_State , level : StkId ) -> * mut UpVal {
112
+ let mut pp: * mut * mut UpVal = & mut ( * L ) . openupval ;
113
+ let mut p: * mut UpVal ;
114
+ debug_assert ! ( isintwups( L ) || ( * L ) . openupval. is_null( ) ) ;
115
+ while !( * pp) . is_null ( ) && ( * * pp) . v >= level {
116
+ p = * pp;
117
+ debug_assert ! ( upisopen( p) ) ;
118
+ if ( * p) . v == level {
119
+ /* found a corresponding upvalue? */
120
+ return p;
121
+ }
122
+ pp = & mut ( * p) . u . open . next ;
123
+ }
124
+ /* not found: create a new upvalue */
125
+ let uv = luaM_new :: < UpVal > ( L ) ;
126
+ ( * uv) . refcount = 0 ;
127
+ ( * uv) . u . open . next = * pp; /* link it to list of open upvalues */
128
+ ( * uv) . u . open . touched = 1 ;
129
+ * pp = uv;
130
+ ( * uv) . v = level; /* current value lives in the stack */
131
+ if !isintwups ( L ) {
132
+ /* thread not in list of threads with upvalues? */
133
+ ( * L ) . twups = ( * ( * L ) . l_G ) . twups ; /* link it to the list */
134
+ ( * ( * L ) . l_G ) . twups = L ;
135
+ }
136
+ return uv;
137
+ }
138
+
139
+ #[ no_mangle]
140
+ pub unsafe extern "C" fn luaF_close ( L : * mut lua_State , level : StkId ) {
141
+ let mut uv;
142
+ while !( ( * L ) . openupval ) . is_null ( ) && ( * ( * L ) . openupval ) . v >= level {
143
+ uv = ( * L ) . openupval ;
144
+ debug_assert ! ( upisopen( uv) ) ;
145
+ ( * L ) . openupval = ( * uv) . u . open . next ; /* remove from 'open' list */
146
+ if ( * uv) . refcount == 0 {
147
+ /* no references? */
148
+ luaM_free ( L , uv) ; /* free upvalue */
149
+ } else {
150
+ setobj ( L , & mut ( * uv) . u . value , ( * uv) . v ) ; /* move value to upvalue slot */
151
+ ( * uv) . v = & mut ( * uv) . u . value ; /* now current value lives here */
152
+ luaC_upvalbarrier ( L , uv) ;
153
+ }
154
+ }
155
+ }
156
+
157
+ #[ no_mangle]
158
+ pub unsafe extern "C" fn luaF_newproto ( L : * mut lua_State ) -> * mut Proto {
159
+ let o = luaC_newobj ( L , LUA_TPROTO , size_of :: < Proto > ( ) ) ;
160
+ let f: * mut Proto = gco2p ( o) ;
161
+ ( * f) . k = ptr:: null_mut ( ) ;
162
+ ( * f) . sizek = 0 ;
163
+ ( * f) . p = ptr:: null_mut ( ) ;
164
+ ( * f) . sizep = 0 ;
165
+ ( * f) . code = ptr:: null_mut ( ) ;
166
+ ( * f) . cache = ptr:: null_mut ( ) ;
167
+ ( * f) . sizecode = 0 ;
168
+ ( * f) . lineinfo = ptr:: null_mut ( ) ;
169
+ ( * f) . sizelineinfo = 0 ;
170
+ ( * f) . upvalues = ptr:: null_mut ( ) ;
171
+ ( * f) . sizeupvalues = 0 ;
172
+ ( * f) . numparams = 0 ;
173
+ ( * f) . is_vararg = 0 ;
174
+ ( * f) . maxstacksize = 0 ;
175
+ ( * f) . locvars = ptr:: null_mut ( ) ;
176
+ ( * f) . sizelocvars = 0 ;
177
+ ( * f) . linedefined = 0 ;
178
+ ( * f) . lastlinedefined = 0 ;
179
+ ( * f) . source = ptr:: null_mut ( ) ;
180
+ return f;
181
+ }
182
+
183
+ #[ no_mangle]
184
+ pub unsafe extern "C" fn luaF_freeproto ( L : * mut lua_State , f : * mut Proto ) {
185
+ luaM_freearray ( L , ( * f) . code , ( * f) . sizecode as usize ) ;
186
+ luaM_freearray ( L , ( * f) . p , ( * f) . sizep as usize ) ;
187
+ luaM_freearray ( L , ( * f) . k , ( * f) . sizek as usize ) ;
188
+ luaM_freearray ( L , ( * f) . lineinfo , ( * f) . sizelineinfo as usize ) ;
189
+ luaM_freearray ( L , ( * f) . locvars , ( * f) . sizelocvars as usize ) ;
190
+ luaM_freearray ( L , ( * f) . upvalues , ( * f) . sizeupvalues as usize ) ;
191
+ luaM_free ( L , f) ;
192
+ }
193
+
194
+ /*
195
+ ** Look for n-th local variable at line 'line' in function 'func'.
196
+ ** Returns NULL if not found.
197
+ */
198
+
199
+ #[ no_mangle]
200
+ pub unsafe extern "C" fn luaF_getlocalname (
201
+ f : * const Proto ,
202
+ mut local_number : c_int ,
203
+ pc : c_int ,
204
+ ) -> * const c_char {
205
+ let mut i = 0 ;
206
+ while i < ( * f) . sizelocvars && ( * ( ( * f) . locvars ) . offset ( i as isize ) ) . startpc <= pc {
207
+ if pc < ( * ( ( * f) . locvars ) . offset ( i as isize ) ) . endpc {
208
+ /* is variable active? */
209
+ local_number -= 1 ;
210
+ if local_number == 0 {
211
+ return getstr ( ( * ( * f) . locvars . offset ( i as isize ) ) . varname ) ;
212
+ }
213
+ }
214
+ i += 1 ;
215
+ }
216
+ return ptr:: null ( ) ; /* not found */
217
+ }
0 commit comments