diff --git a/mk/rt.mk b/mk/rt.mk index 7b50e579eef..c460e716e71 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -26,6 +26,7 @@ RUNTIME_CS := rt/sync/timer.cpp \ rt/rust_shape.cpp \ rt/rust_obstack.cpp \ rt/rust_gc.cpp \ + rt/rust_abi.cpp \ rt/memory_region.cpp \ rt/test/rust_test_harness.cpp \ rt/test/rust_test_runtime.cpp \ diff --git a/src/comp/back/abi.rs b/src/comp/back/abi.rs index 6a53767491f..0e1e05e8be8 100644 --- a/src/comp/back/abi.rs +++ b/src/comp/back/abi.rs @@ -112,6 +112,8 @@ const ivec_heap_elt_elems: uint = 1u; const worst_case_glue_call_args: int = 7; +const abi_version: uint = 1u; + fn memcpy_glue_name() -> str { ret "rust_memcpy_glue"; } fn bzero_glue_name() -> str { ret "rust_bzero_glue"; } diff --git a/src/comp/middle/shape.rs b/src/comp/middle/shape.rs index a3d0dbe0b6e..6c10ee4f357 100644 --- a/src/comp/middle/shape.rs +++ b/src/comp/middle/shape.rs @@ -84,15 +84,20 @@ fn eq_res_info(a: &res_info, b: &res_info) -> bool { ret a.did.crate == b.did.crate && a.did.node == b.did.node && a.t == b.t; } -fn mk_global(ccx: &@crate_ctxt, name: &str, llval: ValueRef) -> ValueRef { +fn mk_global(ccx: &@crate_ctxt, name: &str, llval: ValueRef, + internal: bool) -> ValueRef { let llglobal = lib::llvm::llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval), str::buf(name)); lib::llvm::llvm::LLVMSetInitializer(llglobal, llval); lib::llvm::llvm::LLVMSetGlobalConstant(llglobal, True); - lib::llvm::llvm::LLVMSetLinkage(llglobal, - lib::llvm::LLVMInternalLinkage as - lib::llvm::llvm::Linkage); + + if (internal) { + lib::llvm::llvm::LLVMSetLinkage(llglobal, + lib::llvm::LLVMInternalLinkage as + lib::llvm::llvm::Linkage); + } + ret llglobal; } @@ -510,7 +515,7 @@ fn gen_tag_shapes(ccx: &@crate_ctxt) -> ValueRef { header += data; header += lv_table; - ret mk_global(ccx, "tag_shapes", C_bytes(header)); + ret mk_global(ccx, "tag_shapes", C_bytes(header), true); } fn gen_resource_shapes(ccx: &@crate_ctxt) -> ValueRef { @@ -523,7 +528,7 @@ fn gen_resource_shapes(ccx: &@crate_ctxt) -> ValueRef { i += 1u; } - ret mk_global(ccx, "resource_shapes", C_struct(dtors)); + ret mk_global(ccx, "resource_shapes", C_struct(dtors), true); } fn gen_shape_tables(ccx: &@crate_ctxt) { diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 4c51c34d26a..6cfb9102db1 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -6926,6 +6926,12 @@ fn write_metadata(cx: &@crate_ctxt, crate: &@ast::crate) { llvm::LLVMSetInitializer(llvm_used, C_array(t_ptr_i8, [llglobal])); } +// Writes the current ABI version into the crate. +fn write_abi_version(ccx: &@crate_ctxt) { + shape::mk_global(ccx, "rust_abi_version", C_uint(abi::abi_version), + false); +} + fn trans_crate(sess: &session::session, crate: &@ast::crate, tcx: &ty::ctxt, output: &str, amap: &ast_map::map) -> ModuleRef { let llmod = @@ -7001,6 +7007,7 @@ fn trans_crate(sess: &session::session, crate: &@ast::crate, tcx: &ty::ctxt, create_crate_map(ccx); emit_tydescs(ccx); shape::gen_shape_tables(ccx); + write_abi_version(ccx); // Translate the metadata. write_metadata(cx.ccx, crate); diff --git a/src/rt/rust_abi.cpp b/src/rt/rust_abi.cpp new file mode 100644 index 00000000000..98b80fb41bd --- /dev/null +++ b/src/rt/rust_abi.cpp @@ -0,0 +1,10 @@ +#include +#include +#include "rust_abi.h" + +weak_symbol abi_version("rust_abi_version"); + +uint32_t get_abi_version() { + return (*abi_version == NULL) ? 0 : **abi_version; +} + diff --git a/src/rt/rust_abi.h b/src/rt/rust_abi.h index 1894a56f6a4..9c22ea3fe7e 100644 --- a/src/rt/rust_abi.h +++ b/src/rt/rust_abi.h @@ -1,6 +1,8 @@ #ifndef RUST_ABI_H #define RUST_ABI_H +#include + #ifdef __WIN32__ #include #else @@ -34,5 +36,7 @@ public: T *&operator*() { fill(); return data; } }; +uint32_t get_abi_version(); + #endif