Skip to content

Commit 7f62fed

Browse files
committed
Implement basic statics (rust-lang#9)
1 parent c7ed1ce commit 7f62fed

File tree

2 files changed

+66
-35
lines changed

2 files changed

+66
-35
lines changed

examples/mini_core_hello_world.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,14 @@ extern "C" {
1616
fn puts(s: *const u8);
1717
}
1818

19+
static NUM: u8 = 6 * 7;
20+
1921
#[lang = "start"]
2022
fn start(_main: *const u8, i: isize, _: *const *const u8) -> isize {
2123
unsafe {
2224
let (ptr, _): (*const u8, usize) = intrinsics::transmute("Hello!\0");
2325
puts(ptr);
2426
}
25-
42
27+
28+
NUM as isize
2629
}

src/constant.rs

Lines changed: 62 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,23 @@ use rustc_mir::interpret::{CompileTimeEvaluator, Memory};
66

77
#[derive(Default)]
88
pub struct ConstantCx {
9-
todo_allocs: HashSet<AllocId>,
9+
todo: HashSet<TodoItem>,
1010
done: HashSet<DataId>,
1111
}
1212

13+
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
14+
enum TodoItem {
15+
Alloc(AllocId),
16+
Static(DefId),
17+
}
18+
1319
impl ConstantCx {
1420
pub fn finalize<'a, 'tcx: 'a, B: Backend>(
1521
mut self,
1622
tcx: TyCtxt<'a, 'tcx, 'tcx>,
1723
module: &mut Module<B>,
1824
) {
19-
println!("todo allocs: {:?}", self.todo_allocs);
25+
println!("todo {:?}", self.todo);
2026
define_all_allocs(tcx, module, &mut self);
2127
println!("done {:?}", self.done);
2228
for data_id in self.done.drain() {
@@ -26,14 +32,15 @@ impl ConstantCx {
2632
}
2733

2834
pub fn codegen_static<'a, 'tcx: 'a, B: Backend>(cx: &mut CodegenCx<'a, 'tcx, B>, def_id: DefId) {
29-
unimpl!("static mono item {:?}", def_id);
35+
cx.constants.todo.insert(TodoItem::Static(def_id));
3036
}
3137

3238
pub fn codegen_static_ref<'a, 'tcx: 'a>(
3339
fx: &mut FunctionCx<'a, 'tcx>,
3440
static_: &Static<'tcx>,
3541
) -> CPlace<'tcx> {
36-
unimpl!("static place {:?} ty {:?}", static_.def_id, static_.ty);
42+
let data_id = data_id_for_static(fx.tcx, fx.module, static_.def_id);
43+
cplace_for_dataid(fx, static_.ty, data_id)
3744
}
3845

3946
pub fn trans_promoted<'a, 'tcx: 'a>(
@@ -109,38 +116,36 @@ fn trans_const_place<'a, 'tcx: 'a>(
109116
fx: &mut FunctionCx<'a, 'tcx>,
110117
const_: &'tcx Const<'tcx>,
111118
) -> CPlace<'tcx> {
112-
let ty = fx.monomorphize(&const_.ty);
113-
let layout = fx.layout_of(ty);
114-
115119
let alloc = fx.tcx.const_value_to_allocation(const_);
116120
//println!("const value: {:?} allocation: {:?}", value, alloc);
117121
let alloc_id = fx.tcx.alloc_map.lock().allocate(alloc);
118-
let data_id = get_global_for_alloc_id(fx.module, fx.constants, alloc_id);
119-
let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
120-
// TODO: does global_value return a ptr of a val?
121-
let global_ptr = fx.bcx.ins().global_value(types::I64, local_data_id);
122-
CPlace::Addr(global_ptr, layout)
122+
fx.constants.todo.insert(TodoItem::Alloc(alloc_id));
123+
let data_id = data_id_for_alloc_id(fx.module, alloc_id);
124+
cplace_for_dataid(fx, const_.ty, data_id)
123125
}
124126

125-
// If ret.1 is true, then the global didn't exist before
126-
fn define_global_for_alloc_id<'a, 'tcx: 'a, B: Backend>(
127-
module: &mut Module<B>,
128-
cx: &mut ConstantCx,
129-
alloc_id: AllocId,
130-
) -> DataId {
127+
fn data_id_for_alloc_id<B: Backend>(module: &mut Module<B>, alloc_id: AllocId) -> DataId {
131128
module
132129
.declare_data(&alloc_id.0.to_string(), Linkage::Local, false)
133130
.unwrap()
134131
}
135132

136-
fn get_global_for_alloc_id<'a, 'tcx: 'a, B: Backend + 'a>(
137-
module: &mut Module<B>,
138-
cx: &mut ConstantCx,
139-
alloc_id: AllocId,
140-
) -> DataId {
141-
cx.todo_allocs.insert(alloc_id);
142-
let data_id = define_global_for_alloc_id(module, cx, alloc_id);
143-
data_id
133+
fn data_id_for_static<B: Backend>(tcx: TyCtxt, module: &mut Module<B>, def_id: DefId) -> DataId {
134+
let symbol_name = tcx.symbol_name(Instance::mono(tcx, def_id)).as_str();
135+
module
136+
.declare_data(&*symbol_name, Linkage::Export, false)
137+
.unwrap()
138+
}
139+
140+
fn cplace_for_dataid<'a, 'tcx: 'a>(
141+
fx: &mut FunctionCx<'a, 'tcx>,
142+
ty: Ty<'tcx>,
143+
data_id: DataId,
144+
) -> CPlace<'tcx> {
145+
let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
146+
let global_ptr = fx.bcx.ins().global_value(types::I64, local_data_id);
147+
let layout = fx.layout_of(fx.monomorphize(&ty));
148+
CPlace::Addr(global_ptr, layout)
144149
}
145150

146151
fn define_all_allocs<'a, 'tcx: 'a, B: Backend + 'a>(
@@ -150,15 +155,38 @@ fn define_all_allocs<'a, 'tcx: 'a, B: Backend + 'a>(
150155
) {
151156
let memory = Memory::<CompileTimeEvaluator>::new(tcx.at(DUMMY_SP), ());
152157

153-
while let Some(alloc_id) = pop_set(&mut cx.todo_allocs) {
154-
let data_id = define_global_for_alloc_id(module, cx, alloc_id);
155-
println!("alloc_id {} data_id {}", alloc_id, data_id);
158+
while let Some(todo_item) = pop_set(&mut cx.todo) {
159+
let (data_id, alloc) = match todo_item {
160+
TodoItem::Alloc(alloc_id) => {
161+
println!("alloc_id {}", alloc_id);
162+
let data_id = data_id_for_alloc_id(module, alloc_id);
163+
let alloc = memory.get(alloc_id).unwrap();
164+
(data_id, alloc)
165+
}
166+
TodoItem::Static(def_id) => {
167+
println!("static {:?}", def_id);
168+
let instance = ty::Instance::mono(tcx, def_id);
169+
let cid = GlobalId {
170+
instance,
171+
promoted: None,
172+
};
173+
let const_ = tcx.const_eval(ParamEnv::reveal_all().and(cid)).unwrap();
174+
175+
let alloc = match const_.val {
176+
ConstValue::ByRef(alloc, n) if n.bytes() == 0 => alloc,
177+
_ => bug!("static const eval returned {:#?}", const_),
178+
};
179+
180+
let data_id = data_id_for_static(tcx, module, def_id);
181+
(data_id, alloc)
182+
}
183+
};
184+
185+
println!("data_id {}", data_id);
156186
if cx.done.contains(&data_id) {
157187
continue;
158188
}
159189

160-
let alloc = memory.get(alloc_id).unwrap();
161-
//let alloc = tcx.alloc_map.lock().get(alloc_id).unwrap();
162190
let mut data_ctx = DataContext::new();
163191

164192
data_ctx.define(
@@ -167,8 +195,8 @@ fn define_all_allocs<'a, 'tcx: 'a, B: Backend + 'a>(
167195
);
168196

169197
for &(offset, reloc) in alloc.relocations.iter() {
170-
cx.todo_allocs.insert(reloc);
171-
let data_id = define_global_for_alloc_id(module, cx, reloc);
198+
cx.todo.insert(TodoItem::Alloc(reloc));
199+
let data_id = data_id_for_alloc_id(module, reloc);
172200

173201
let reloc_offset = {
174202
let endianness = memory.endianness();
@@ -186,7 +214,7 @@ fn define_all_allocs<'a, 'tcx: 'a, B: Backend + 'a>(
186214
cx.done.insert(data_id);
187215
}
188216

189-
assert!(cx.todo_allocs.is_empty(), "{:?}", cx.todo_allocs);
217+
assert!(cx.todo.is_empty(), "{:?}", cx.todo);
190218
}
191219

192220
fn pop_set<T: Copy + Eq + ::std::hash::Hash>(set: &mut HashSet<T>) -> Option<T> {

0 commit comments

Comments
 (0)