GitLab will continue to be upgraded from 11.4.5-ce.0 on November 25th 2019 at 4.00pm (AEDT) to 5.00pm (AEDT) due to Critical Security Patch Availability. During the update, GitLab and Mattermost services will not be available.

Commit dc7f409b authored by Isaac Oscar Gariano's avatar Isaac Oscar Gariano

Implemented native dumping and loading of rust objects

parent 0454a7fa
Pipeline #624 canceled with stages
# Copyright 2017 The Australian National University
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Copyright 2017 The Australian National University
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
[package]
name = "mu"
version = "0.0.1"
......@@ -28,26 +28,28 @@ aot = []
jit = []
[build-dependencies]
gcc = "0.3"
gcc = "*"
[dependencies]
ast = {path = "src/ast"}
utils = {path = "src/utils"}
gc = {path = "src/gc"}
field-offset = "0.1.1"
libloading = "0.3"
lazy_static = "0.1.15"
log = "0.3.5"
stderrlog = "0.2.2"
hprof = "0.1.3"
memmap = "0.4.0"
#rodal = {path = "rodal"}
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal" }
libc="*"
field-offset = "*"
libloading = "*"
lazy_static = "*"
log = "*"
stderrlog = "*"
hprof = "*"
memmap = "*"
memsec = "0.1.9"
rustc-serialize = "*"
time = "0.1.34"
maplit = "0.1.4"
docopt = "0.6"
petgraph = "0.4.1"
serde = "*"
serde_derive = "*"
time = "*"
maplit = "*"
docopt = "*"
petgraph = "*"
extprim = "*"
num-traits = "*"
......@@ -22,7 +22,8 @@ crate-type = ["rlib"]
[dependencies]
utils = {path = "../utils"}
lazy_static = "0.1.15"
log = "0.3.5"
simple_logger = "0.4.0"
rustc-serialize = "*"
\ No newline at end of file
lazy_static = "*"
log = "*"
simple_logger = "*"
#rodal = {path = "../../rodal"}
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal" }
......@@ -23,7 +23,7 @@ use utils::vec_utils;
use std::fmt;
#[derive(Debug)]
// this implements RustcEncodable, RustcDecodable, Clone and Display
// this implements Clone and Display
pub struct Instruction {
pub hdr: MuEntityHeader,
pub value : Option<Vec<P<Value>>>,
......@@ -33,43 +33,6 @@ pub struct Instruction {
impl_mu_entity!(Instruction);
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
impl Encodable for Instruction {
fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
s.emit_struct("Instruction", 4, |s| {
try!(s.emit_struct_field("hdr", 0, |s| self.hdr.encode(s)));
try!(s.emit_struct_field("value", 1, |s| self.value.encode(s)));
let ref ops = self.ops;
try!(s.emit_struct_field("ops", 2, |s| ops.encode(s)));
try!(s.emit_struct_field("v", 3, |s| self.v.encode(s)));
Ok(())
})
}
}
impl Decodable for Instruction {
fn decode<D: Decoder>(d: &mut D) -> Result<Instruction, D::Error> {
d.read_struct("Instruction", 4, |d| {
let hdr = try!(d.read_struct_field("hdr", 0, |d| Decodable::decode(d)));
let value = try!(d.read_struct_field("value", 1, |d| Decodable::decode(d)));
let ops = try!(d.read_struct_field("ops", 2, |d| Decodable::decode(d)));
let v = try!(d.read_struct_field("v", 3, |d| Decodable::decode(d)));
Ok(Instruction{
hdr: hdr,
value: value,
ops: ops,
v: v
})
})
}
}
impl Clone for Instruction {
fn clone(&self) -> Self {
Instruction {
......@@ -164,7 +127,7 @@ impl fmt::Display for Instruction {
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, RustcEncodable, RustcDecodable)]
#[derive(Debug, Clone)]
pub enum Instruction_ {
// non-terminal instruction
......@@ -494,7 +457,7 @@ impl Instruction_ {
}
}
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone)]
pub struct BinOpStatus {
pub flag_n: bool,
pub flag_z: bool,
......@@ -542,7 +505,7 @@ impl fmt::Debug for BinOpStatus {
}
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug)]
pub enum MemoryOrder {
NotAtomic,
Relaxed,
......@@ -553,18 +516,18 @@ pub enum MemoryOrder {
SeqCst
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug)]
pub enum CallConvention {
Mu,
Foreign(ForeignFFI)
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug)]
pub enum ForeignFFI {
C
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug)]
pub struct CallData {
pub func: OpIndex,
pub args: Vec<OpIndex>,
......@@ -581,7 +544,7 @@ impl CallData {
}
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug)]
pub struct ResumptionData {
pub normal_dest: Destination,
pub exn_dest: Destination
......@@ -593,7 +556,7 @@ impl ResumptionData {
}
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug)]
pub struct Destination {
pub target: MuID,
pub args: Vec<DestArg>
......@@ -636,7 +599,7 @@ impl Destination {
}
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug)]
pub enum DestArg {
Normal(OpIndex),
Freshbound(usize)
......
......@@ -21,6 +21,7 @@ use utils::vec_utils;
use utils::LinkedHashMap;
use utils::LinkedHashSet;
use std;
use std::fmt;
use std::default;
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
......@@ -77,7 +78,8 @@ pub fn new_internal_id() -> MuID {
ret
}
#[derive(Debug, RustcEncodable, RustcDecodable)]
rodal_struct!(MuFunction{hdr, sig, cur_ver, all_vers});
#[derive(Debug)]
pub struct MuFunction {
pub hdr: MuEntityHeader,
......@@ -112,7 +114,6 @@ impl fmt::Display for MuFunction {
}
}
#[derive(RustcEncodable, RustcDecodable)]
pub struct MuFunctionVersion {
pub hdr: MuEntityHeader,
......@@ -315,7 +316,7 @@ impl MuFunctionVersion {
}
}
#[derive(Clone, RustcEncodable, RustcDecodable)]
#[derive(Clone)]
pub struct FunctionContent {
pub entry: MuID,
pub blocks: LinkedHashMap<MuID, Block>,
......@@ -384,7 +385,7 @@ impl FunctionContent {
}
}
#[derive(Default, Debug, RustcEncodable, RustcDecodable)]
#[derive(Default, Debug)]
pub struct FunctionContext {
pub values: LinkedHashMap<MuID, SSAVarEntry>
}
......@@ -427,7 +428,7 @@ impl FunctionContext {
}
}
#[derive(RustcEncodable, RustcDecodable, Clone)]
#[derive(Clone)]
pub struct Block {
pub hdr: MuEntityHeader,
pub content: Option<BlockContent>,
......@@ -468,7 +469,7 @@ impl Block {
}
}
#[derive(Debug, RustcEncodable, RustcDecodable, Clone)]
#[derive(Debug, Clone)]
pub struct ControlFlow {
pub preds : Vec<MuID>,
pub succs : Vec<BlockEdge>
......@@ -507,7 +508,7 @@ impl default::Default for ControlFlow {
}
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug)]
pub struct BlockEdge {
pub target: MuID,
pub kind: EdgeKind,
......@@ -521,12 +522,12 @@ impl fmt::Display for BlockEdge {
}
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug)]
pub enum EdgeKind {
Forward, Backward
}
#[derive(RustcEncodable, RustcDecodable, Clone)]
#[derive(Clone)]
pub struct BlockContent {
pub args: Vec<P<Value>>,
pub exn_arg: Option<P<Value>>,
......@@ -622,7 +623,7 @@ impl BlockContent {
}
}
#[derive(Debug, RustcEncodable, RustcDecodable, Clone)]
#[derive(Debug, Clone)]
/// always use with P<TreeNode>
pub struct TreeNode {
pub op: OpCode,
......@@ -697,14 +698,15 @@ impl fmt::Display for TreeNode {
}
}
#[derive(Debug, RustcEncodable, RustcDecodable, Clone)]
#[derive(Debug, Clone)]
pub enum TreeNode_ {
Value(P<Value>),
Instruction(Instruction)
}
/// always use with P<Value>
#[derive(PartialEq, RustcEncodable, RustcDecodable)]
rodal_struct!(Value{hdr, ty, v});
#[derive(PartialEq)]
pub struct Value {
pub hdr: MuEntityHeader,
pub ty: P<MuType>,
......@@ -847,7 +849,8 @@ impl fmt::Display for Value {
}
}
#[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)]
rodal_enum!(Value_{(SSAVar: id), (Constant: val), (Global: ty), (Memory: location)});
#[derive(Debug, Clone, PartialEq)]
pub enum Value_ {
SSAVar(MuID),
Constant(Constant),
......@@ -870,41 +873,6 @@ pub struct SSAVarEntry {
split: Option<Vec<P<Value>>>
}
impl Encodable for SSAVarEntry {
fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
s.emit_struct("SSAVarEntry", 3, |s| {
try!(s.emit_struct_field("val", 0, |s| self.val.encode(s)));
let count = self.use_count.load(Ordering::SeqCst);
try!(s.emit_struct_field("use_count", 1, |s| s.emit_usize(count)));
try!(s.emit_struct_field("expr", 2, |s| self.expr.encode(s)));
try!(s.emit_struct_field("split", 3, |s| self.split.encode(s)));
Ok(())
})
}
}
impl Decodable for SSAVarEntry {
fn decode<D: Decoder>(d: &mut D) -> Result<SSAVarEntry, D::Error> {
d.read_struct("SSAVarEntry", 3, |d| {
let val = try!(d.read_struct_field("val", 0, |d| Decodable::decode(d)));
let count = try!(d.read_struct_field("use_count", 1, |d| d.read_usize()));
let expr = try!(d.read_struct_field("expr", 2, |d| Decodable::decode(d)));
let split = try!(d.read_struct_field("split", 3, |d| Decodable::decode(d)));
let ret = SSAVarEntry {
val: val,
use_count: ATOMIC_USIZE_INIT,
expr: expr,
split: split
};
ret.use_count.store(count, Ordering::SeqCst);
Ok(ret)
})
}
}
impl SSAVarEntry {
pub fn new(val: P<Value>) -> SSAVarEntry {
let ret = SSAVarEntry {
......@@ -965,7 +933,9 @@ impl fmt::Display for SSAVarEntry {
}
}
#[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)]
rodal_enum!(Constant{(Int: val), (IntEx: val), (Float: val), (Double: val), (FuncRef: val),
(Vector: val), NullRef, (ExternSym: val), (List: val)});
#[derive(Debug, Clone, PartialEq)]
pub enum Constant {
Int(u64),
IntEx(Vec<u64>),
......@@ -1015,10 +985,12 @@ impl fmt::Display for Constant {
}
#[cfg(target_arch = "x86_64")]
#[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)]
rodal_enum!(MemoryLocation{{Address: scale, base, offset, index}, {Symbolic: is_global, base, label}});
#[cfg(target_arch = "x86_64")]
#[derive(Debug, Clone, PartialEq)]
pub enum MemoryLocation {
Address{
base: P<Value>,
base: P<Value>, // +8
offset: Option<P<Value>>,
index: Option<P<Value>>,
scale: Option<u8>
......@@ -1059,17 +1031,19 @@ impl fmt::Display for MemoryLocation {
}
#[cfg(target_arch = "aarch64")]
#[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)]
rodal_enum!(MemoryLocation{{VirtualAddress: signed, base, offset, scale}, {Address: base, offset, shift, signed}, {Symbolic: label, is_global}});
#[cfg(target_arch = "aarch64")]
#[derive(Debug, Clone, PartialEq)]
pub enum MemoryLocation {
// Represents how an adress should be computed,
// will need to be converted to a real Address before being used
VirtualAddress{
// Represents base + offset*scale
// With offset being inerpreted as signed if 'signed' is true
base: P<Value>,
offset: Option<P<Value>>,
scale: u64,
signed: bool
base: P<Value>, //+8
offset: Option<P<Value>>, //+16
signed: bool, //+1
scale: u64 //+24
},
Address{
base: P<Value>, // Must be a normal 64-bit register or SP
......@@ -1119,6 +1093,7 @@ impl fmt::Display for MemoryLocation {
}
}
rodal_struct!(MuEntityHeader{id, name});
#[repr(C)]
#[derive(Debug)] // Display, PartialEq, Clone
pub struct MuEntityHeader {
......@@ -1135,34 +1110,6 @@ impl Clone for MuEntityHeader {
}
}
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
impl Encodable for MuEntityHeader {
fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
s.emit_struct("MuEntityHeader", 2, |s| {
try!(s.emit_struct_field("id", 0, |s| self.id.encode(s)));
let name = &self.name;
try!(s.emit_struct_field("name", 1, |s| name.encode(s)));
Ok(())
})
}
}
impl Decodable for MuEntityHeader {
fn decode<D: Decoder>(d: &mut D) -> Result<MuEntityHeader, D::Error> {
d.read_struct("MuEntityHeader", 2, |d| {
let id = try!(d.read_struct_field("id", 0, |d| {d.read_usize()}));
let name = try!(d.read_struct_field("name", 1, |d| Decodable::decode(d)));
Ok(MuEntityHeader{
id: id,
name: name
})
})
}
}
pub fn name_check(name: MuName) -> MuName {
let name = name.replace('.', "$");
......
......@@ -12,11 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
extern crate log;
#[macro_use]
extern crate rodal;
extern crate simple_logger;
#[macro_use]
extern crate lazy_static;
extern crate rustc_serialize;
extern crate utils;
#[macro_export]
......
......@@ -17,7 +17,7 @@ use types::*;
use inst::*;
use types::MuType_::*;
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, PartialEq)]
#[allow(non_camel_case_types)]
pub enum OpCode {
// SSA
......@@ -140,7 +140,7 @@ pub fn pick_op_code_for_value(ty: &P<MuType>) -> OpCode {
}
}
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum BinOp {
// Int(n) BinOp Int(n) -> Int(n)
Add,
......@@ -167,7 +167,7 @@ pub enum BinOp {
FRem
}
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum CmpOp {
// for Int comparison
EQ,
......@@ -300,7 +300,7 @@ impl CmpOp {
}
}
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum ConvOp {
TRUNC,
ZEXT,
......@@ -316,7 +316,7 @@ pub enum ConvOp {
PTRCAST
}
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum AtomicRMWOp {
XCHG,
ADD,
......
// Copyright 2017 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
......@@ -53,7 +39,6 @@
//use std::fmt::{self, Display, Debug};
//use std::hash::{Hash, Hasher};
//use std::ops::Deref;
//use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
use std::sync::Arc;
......@@ -112,10 +97,4 @@ pub fn P<T>(value: T) -> P<T> {
// fn hash<H: Hasher>(&self, state: &mut H) {
// (**self).hash(state);
// }
//}
//impl<T: MuEntity> Encodable for P<T> {
// fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
// s.emit_usize(self.id())
// }
//}
//}
\ No newline at end of file
......@@ -18,8 +18,10 @@ use ir::*;
use utils::POINTER_SIZE;
use utils::vec_utils;
use std;
use rodal;
use std::fmt;
use utils::LinkedHashMap;
use std::collections::HashMap;
use std::sync::RwLock;
lazy_static! {
......@@ -90,12 +92,14 @@ pub fn init_types() {
}
}
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
rodal_struct!(MuType{hdr, v});
#[derive(PartialEq, Debug)]
pub struct MuType {
pub hdr: MuEntityHeader,
pub v: MuType_
}
impl MuType {
pub fn new(id: MuID, v: MuType_) -> MuType {
MuType {
......@@ -346,7 +350,11 @@ impl MuType {
pub type StructTag = MuName;
pub type HybridTag = MuName;
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
rodal_enum!(MuType_{(Int: size), Float, Double, (Ref: ty), (IRef: ty), (WeakRef: ty), (UPtr: ty),
(Struct: tag), (Array: ty, size), (Hybrid: tag), Void, ThreadRef, StackRef, Tagref64,
(Vector: ty, size), (FuncRef: ty), (UFuncPtr: ty)});
#[derive(PartialEq, Debug)]
pub enum MuType_ {
/// int <length>
Int (usize),
......@@ -427,12 +435,15 @@ impl fmt::Display for MuType_ {
lazy_static! {
/// storing a map from MuName to StructType_
pub static ref STRUCT_TAG_MAP : RwLock<LinkedHashMap<StructTag, StructType_>> = RwLock::new(LinkedHashMap::new());
pub static ref STRUCT_TAG_MAP : RwLock<HashMap<StructTag, StructType_>> =
rodal::try_load_asm_name_move("STRUCT_TAG_MAP").unwrap_or(RwLock::new(HashMap::new()));
/// storing a map from MuName to HybridType_
pub static ref HYBRID_TAG_MAP : RwLock<LinkedHashMap<HybridTag, HybridType_>> = RwLock::new(LinkedHashMap::new());
pub static ref HYBRID_TAG_MAP : RwLock<HashMap<HybridTag, HybridType_>> =
rodal::try_load_asm_name_move("HYBRID_TAG_MAP").unwrap_or(RwLock::new(HashMap::new()));
}
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
rodal_struct!(StructType_{tys});
#[derive(PartialEq, Debug)]
pub struct StructType_ {
tys: Vec<P<MuType>>
}
......@@ -466,7 +477,8 @@ impl StructType_ {
}
}
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
rodal_struct!(HybridType_{fix_tys, var_ty});
#[derive(PartialEq, Debug)]
pub struct HybridType_ {
fix_tys: Vec<P<MuType>>,
var_ty : P<MuType>
......@@ -649,7 +661,8 @@ macro_rules! is_type (
pub type CFuncSig = MuFuncSig;
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
rodal_struct!(MuFuncSig{hdr, ret_tys, arg_tys});
#[derive(PartialEq, Debug)]
pub struct MuFuncSig {
pub hdr: MuEntityHeader,
pub ret_tys : Vec<P<MuType>>,
......
......@@ -30,11 +30,13 @@ use utils::LinkedHashMap;
use ast::ptr::P;
use ast::ir::*;
use ast::types;
use std::str;
use std::usize;
use std::ops;
use std::collections::HashSet;
use std::sync::RwLock;
struct ASMCode {
name: MuName,
......@@ -2759,7 +2761,7 @@ fn write_const_value(f: &mut File, constant: P<Value>) {
8 => f.write_fmt(format_args!(".byte {}\n", val as u8 )).unwrap(),
16 => f.write_fmt(format_args!(".word {}\n", val as u16)).unwrap(),
32 => f.write_fmt(format_args!(".long {}\n", val as u32)).unwrap(),
64 => f.write_fmt(format_args!(".quad {}\n", val as u64)).unwrap(),
64 => f.write_fmt(format_args!(".xword {}\n", val as u64)).unwrap(),
_ => panic!("unimplemented int length: {}", len)
}
}
......@@ -2771,15 +2773,15 @@ fn write_const_value(f: &mut File, constant: P<Value>) {
}
&Constant::Double(val) => {
let bytes: [u8; 8] = unsafe {mem::transmute(val)};
f.write(".quad ".as_bytes()).unwrap();
f.write(".xword ".as_bytes()).unwrap();
f.write(&bytes).unwrap();
f.write("\n".as_bytes()).unwrap();
}
&Constant::NullRef => {
f.write_fmt(format_args!(".quad 0\n")).unwrap()
f.write_fmt(format_args!(".xword 0\n")).unwrap()
}
&Constant::ExternSym(ref name) => {
f.write_fmt(format_args!(".quad {}\n", name)).unwrap()
f.write_fmt(format_args!(".xword {}\n", name)).unwrap()
}
&Constant::List(ref vals) => {
for val in vals {
......@@ -2797,7 +2799,6 @@ pub fn emit_context_with_reloc(vm: &VM,
fields : HashMap<Address, String>) {
use std::path;
use std::io::prelude::*;
use rustc_serialize::json;
debug!("---Emit VM Context---");
create_emit_directory(vm);
......@@ -2811,9 +2812,6 @@ pub fn emit_context_with_reloc(vm: &VM,
Ok(file) => file
};
// bss
file.write_fmt(format_args!(".bss\n")).unwrap();
// data
file.write(".data\n".as_bytes()).unwrap();
......@@ -2884,20 +2882,20 @@ pub fn emit_context_with_reloc(vm: &VM,
let load_ref = unsafe {cur_addr.load::<Address>()};
if load_ref.is_zero() {
// write 0
file.write(".quad 0\n".as_bytes()).unwrap();
file.write(".xword 0\n".as_bytes()).unwrap();
} else {
let label = match relocatable_refs.get(&load_ref) {
Some(label) => label,
None => panic!("cannot find label for address {}, it is not dumped by GC (why GC didn't trace to it)", load_ref)
};
file.write_fmt(format_args!(".quad {}\n", label.clone())).unwrap();
file.write_fmt(format_args!(".xword {}\n", label.clone())).unwrap();
}
} else if fields.contains_key(&cur_addr) {
// write uptr (or other relocatable value) with label
let label = fields.get(&cur_addr).unwrap();
file.write_fmt(format_args!(".quad {}\n", label.clone())).unwrap();
file.write_fmt(format_args!(".xword {}\n", label.clone())).unwrap();
} else {
// write plain word (as bytes)
let next_word_addr = cur_addr.plus(POINTER_SIZE);
......@@ -2916,15 +2914,21 @@ pub fn emit_context_with_reloc(vm: &VM,
// serialize vm