Skip to content

Commit 449bab7

Browse files
committed
Migrate lfunc
1 parent fefc16b commit 449bab7

File tree

10 files changed

+687
-166
lines changed

10 files changed

+687
-166
lines changed

build/build.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ fn main() {
1313
.file("build/ldebug.c")
1414
.file("build/ldo.c")
1515
.file("build/ldump.c")
16-
.file("build/lfunc.c")
1716
.file("build/lgc.c")
1817
.file("build/linit.c")
1918
.file("build/liolib.c")

build/lfunc.c

Lines changed: 0 additions & 151 deletions
This file was deleted.

src/lfunc.rs

Lines changed: 191 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,40 @@
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};
218

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;
538

639
/*
740
** Upvalues for Lua closures
@@ -27,3 +60,158 @@ pub struct C2RustUnnamed_4 {
2760
pub next: *mut UpVal, /* linked list */
2861
pub touched: c_int, /* mark to avoid cycles with dead threads */
2962
}
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

Comments
 (0)