summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xtest_smiri.sh4
-rw-r--r--tools/standalone_miri/hir_sim.cpp14
-rw-r--r--tools/standalone_miri/hir_sim.hpp7
-rw-r--r--tools/standalone_miri/main.cpp18
-rw-r--r--tools/standalone_miri/miri.cpp104
-rw-r--r--tools/standalone_miri/value.cpp41
-rw-r--r--tools/standalone_miri/value.hpp14
7 files changed, 117 insertions, 85 deletions
diff --git a/test_smiri.sh b/test_smiri.sh
index 5a7de4e4..0dbad3fa 100755
--- a/test_smiri.sh
+++ b/test_smiri.sh
@@ -2,5 +2,7 @@
set -e
cd $(dirname $0)
make -f minicargo.mk MMIR=1 LIBS
+echo "--- mrustc -o output-mmir/hello"
./bin/mrustc rustc-1.19.0-src/src/test/run-pass/hello.rs -O -C codegen-type=monomir -o output-mmir/hello -L output-mmir/ > output-mmir/hello_dbg.txt
-./tools/bin/standalone_miri output-mmir/hello.mir --logfile smiri_hello.log
+echo "--- standalone_miri output-mmir/hello.mir"
+time ./tools/bin/standalone_miri output-mmir/hello.mir --logfile smiri_hello.log
diff --git a/tools/standalone_miri/hir_sim.cpp b/tools/standalone_miri/hir_sim.cpp
index f3b4d400..94f0d0e1 100644
--- a/tools/standalone_miri/hir_sim.cpp
+++ b/tools/standalone_miri/hir_sim.cpp
@@ -20,6 +20,7 @@ size_t HIR::TypeRef::get_size(size_t ofs) const
case RawType::Unit:
return 0;
case RawType::Composite:
+ // NOTE: Don't care if the type has metadata
return this->composite_type->size;
case RawType::Unreachable:
LOG_BUG("Attempting to get size of an unreachable type, " << *this);
@@ -53,7 +54,7 @@ size_t HIR::TypeRef::get_size(size_t ofs) const
}
throw "";
}
-
+
switch(this->wrappers[ofs].type)
{
case TypeWrapper::Ty::Array:
@@ -100,22 +101,25 @@ size_t HIR::TypeRef::get_size(size_t ofs) const
}
throw "";
}
-bool HIR::TypeRef::has_slice_meta() const
+bool HIR::TypeRef::has_slice_meta(size_t& out_inner_size) const
{
if( this->wrappers.size() == 0 )
{
if(this->inner_type == RawType::Composite)
{
- // TODO: Handle metadata better
+ // TODO: This type could be wrapping a slice, needs to return the inner type size.
+ // - Also need to know which field is the unsized one
return false;
}
else
{
+ out_inner_size = 1;
return (this->inner_type == RawType::Str);
}
}
else
{
+ out_inner_size = this->get_size(1);
return (this->wrappers[0].type == TypeWrapper::Ty::Slice);
}
}
@@ -130,9 +134,9 @@ HIR::TypeRef HIR::TypeRef::get_inner() const
ity.wrappers.erase(ity.wrappers.begin());
return ity;
}
-HIR::TypeRef HIR::TypeRef::wrap(TypeWrapper::Ty ty, size_t size) const
+HIR::TypeRef HIR::TypeRef::wrap(TypeWrapper::Ty ty, size_t size)&&
{
- auto rv = *this;
+ auto rv = ::std::move(*this);
rv.wrappers.insert(rv.wrappers.begin(), { ty, size });
return rv;
}
diff --git a/tools/standalone_miri/hir_sim.hpp b/tools/standalone_miri/hir_sim.hpp
index 1dc9bcc4..9f5ba59c 100644
--- a/tools/standalone_miri/hir_sim.hpp
+++ b/tools/standalone_miri/hir_sim.hpp
@@ -118,11 +118,14 @@ namespace HIR {
}
size_t get_size(size_t ofs=0) const;
- bool has_slice_meta() const; // The attached metadata is a count
+ bool has_slice_meta(size_t& out_inner_size) const; // The attached metadata is a count of elements
const TypeRef* get_usized_type(size_t& running_inner_size) const;
TypeRef get_meta_type() const;
TypeRef get_inner() const;
- TypeRef wrap(TypeWrapper::Ty ty, size_t size) const;
+ TypeRef wrap(TypeWrapper::Ty ty, size_t size)&&;
+ TypeRef wrapped(TypeWrapper::Ty ty, size_t size) const {
+ return TypeRef(*this).wrap(ty, size);
+ }
TypeRef get_field(size_t idx, size_t& ofs) const;
bool operator==(const RawType& x) const {
diff --git a/tools/standalone_miri/main.cpp b/tools/standalone_miri/main.cpp
index c214676a..e3a8d22e 100644
--- a/tools/standalone_miri/main.cpp
+++ b/tools/standalone_miri/main.cpp
@@ -50,15 +50,7 @@ int main(int argc, const char* argv[])
auto tree = ModuleTree {};
tree.load_file(opts.infile);
- // Construct argc/argv values
- auto val_argc = Value( ::HIR::TypeRef{RawType::ISize} );
- ::HIR::TypeRef argv_ty { RawType::I8 };
- argv_ty.wrappers.push_back(TypeWrapper { TypeWrapper::Ty::Pointer, 0 });
- argv_ty.wrappers.push_back(TypeWrapper { TypeWrapper::Ty::Pointer, 0 });
- auto val_argv = Value(argv_ty);
-
// Create argc/argv based on input arguments
- val_argc.write_isize(0, 1 + opts.args.size());
auto argv_alloc = Allocation::new_alloc((1 + opts.args.size()) * POINTER_SIZE);
argv_alloc->write_usize(0 * POINTER_SIZE, 0);
argv_alloc->relocations.push_back({ 0 * POINTER_SIZE, RelocationPtr::new_ffi(FFIPointer { "", (void*)(opts.infile.c_str()), opts.infile.size() + 1 }) });
@@ -67,9 +59,13 @@ int main(int argc, const char* argv[])
argv_alloc->write_usize((1 + i) * POINTER_SIZE, 0);
argv_alloc->relocations.push_back({ (1 + i) * POINTER_SIZE, RelocationPtr::new_ffi({ "", (void*)(opts.args[0]), ::std::strlen(opts.args[0]) + 1 }) });
}
- //val_argv.write_ptr(0, 0, RelocationPtr::new_alloc(argv_alloc));
- val_argv.write_usize(0, 0);
- val_argv.allocation->relocations.push_back({ 0 * POINTER_SIZE, RelocationPtr::new_alloc(argv_alloc) });
+
+ // Construct argc/argv values
+ auto val_argc = Value::new_isize(1 + opts.args.size());
+ ::HIR::TypeRef argv_ty { RawType::I8 };
+ argv_ty.wrappers.push_back(TypeWrapper { TypeWrapper::Ty::Pointer, 0 });
+ argv_ty.wrappers.push_back(TypeWrapper { TypeWrapper::Ty::Pointer, 0 });
+ auto val_argv = Value::new_pointer(argv_ty, 0, RelocationPtr::new_alloc(argv_alloc));
// Catch various exceptions from the interpreter
try
diff --git a/tools/standalone_miri/miri.cpp b/tools/standalone_miri/miri.cpp
index 733aa8a3..c0e7d15c 100644
--- a/tools/standalone_miri/miri.cpp
+++ b/tools/standalone_miri/miri.cpp
@@ -352,16 +352,18 @@ struct MirHelpers
LOG_ASSERT(val.m_size == POINTER_SIZE + meta_size, "Deref of " << ty << ", but pointer isn't correct size");
meta_val = ::std::make_shared<Value>( val.read_value(POINTER_SIZE, meta_size) );
- // TODO: Get a more sane size from the metadata
- if( alloc )
- {
+ size_t slice_inner_size;
+ if( ty.has_slice_meta(slice_inner_size) ) {
+ size = (ty.wrappers.empty() ? ty.get_size() : 0) + meta_val->read_usize(0) * slice_inner_size;
+ }
+ //else if( ty == RawType::TraitObject) {
+ // // NOTE: Getting the size from the allocation is semi-valid, as you can't sub-slice trait objects
+ // size = alloc.get_size() - ofs;
+ //}
+ else {
LOG_DEBUG("> Meta " << *meta_val << ", size = " << alloc.get_size() << " - " << ofs);
size = alloc.get_size() - ofs;
}
- else
- {
- size = 0;
- }
}
else
{
@@ -406,6 +408,7 @@ struct MirHelpers
}
void write_lvalue(const ::MIR::LValue& lv, Value val)
{
+ // TODO: Ensure that target is writable? Or should write_value do that?
//LOG_DEBUG(lv << " = " << val);
::HIR::TypeRef ty;
auto base_value = get_value_and_type(lv, ty);
@@ -428,12 +431,14 @@ struct MirHelpers
Value val = Value(ty);
val.write_bytes(0, &ce.v, ::std::min(ty.get_size(), sizeof(ce.v))); // TODO: Endian
// TODO: If the write was clipped, sign-extend
+ // TODO: i128/u128 need the upper bytes cleared+valid
return val;
} break;
TU_ARM(c, Uint, ce) {
ty = ::HIR::TypeRef(ce.t);
Value val = Value(ty);
val.write_bytes(0, &ce.v, ::std::min(ty.get_size(), sizeof(ce.v))); // TODO: Endian
+ // TODO: i128/u128 need the upper bytes cleared+valid
return val;
} break;
TU_ARM(c, Bool, ce) {
@@ -466,11 +471,9 @@ struct MirHelpers
ty = ::HIR::TypeRef(RawType::Str);
ty.wrappers.push_back(TypeWrapper { TypeWrapper::Ty::Borrow, 0 });
Value val = Value(ty);
- val.write_usize(0, 0);
+ val.write_ptr(0, 0, RelocationPtr::new_string(&ce));
val.write_usize(POINTER_SIZE, ce.size());
- val.allocation->relocations.push_back(Relocation { 0, RelocationPtr::new_string(&ce) });
LOG_DEBUG(c << " = " << val);
- //return Value::new_dataptr(ce.data());
return val;
} break;
// --> Accessor
@@ -482,11 +485,8 @@ struct MirHelpers
}
if( const auto* s = this->thread.m_modtree.get_static_opt(ce) ) {
ty = s->ty;
- ty.wrappers.push_back(TypeWrapper { TypeWrapper::Ty::Borrow, 0 });
- Value val = Value(ty);
- val.write_usize(0, 0);
- val.allocation->relocations.push_back(Relocation { 0, RelocationPtr::new_alloc(s->val.allocation) });
- return val;
+ ty.wrappers.insert(ty.wrappers.begin(), TypeWrapper { TypeWrapper::Ty::Borrow, 0 });
+ return Value::new_pointer(ty, 0, RelocationPtr::new_alloc(s->val.allocation));
}
LOG_ERROR("Constant::ItemAddr - " << ce << " - not found");
} break;
@@ -602,19 +602,17 @@ bool InterpreterThread::step_one(Value& out_thread_result)
LOG_DEBUG("- alloc=" << alloc);
size_t ofs = src_base_value.m_offset;
const auto meta = src_ty.get_meta_type();
- //bool is_slice_like = src_ty.has_slice_meta();
src_ty.wrappers.insert(src_ty.wrappers.begin(), TypeWrapper { TypeWrapper::Ty::Borrow, static_cast<size_t>(re.type) });
+ // Create the pointer
new_val = Value(src_ty);
- // ^ Pointer value
- new_val.write_usize(0, ofs);
+ new_val.write_ptr(0, ofs, ::std::move(alloc));
+ // - Add metadata if required
if( meta != RawType::Unreachable )
{
LOG_ASSERT(src_base_value.m_metadata, "Borrow of an unsized value, but no metadata avaliable");
new_val.write_value(POINTER_SIZE, *src_base_value.m_metadata);
}
- // - Add the relocation after writing the value (writing clears the relocations)
- new_val.allocation->relocations.push_back(Relocation { 0, ::std::move(alloc) });
} break;
TU_ARM(se.src, Cast, re) {
// Determine the type of cast, is it a reinterpret or is it a value transform?
@@ -1306,11 +1304,9 @@ bool InterpreterThread::step_one(Value& out_thread_result)
size_t ofs = v.m_offset;
assert(ty.get_meta_type() == RawType::Unreachable);
- auto ptr_ty = ty.wrap(TypeWrapper::Ty::Borrow, 2);
+ auto ptr_ty = ty.wrapped(TypeWrapper::Ty::Borrow, 2);
- auto ptr_val = Value(ptr_ty);
- ptr_val.write_usize(0, ofs);
- ptr_val.allocation->relocations.push_back(Relocation { 0, ::std::move(alloc) });
+ auto ptr_val = Value::new_pointer(ptr_ty, ofs, ::std::move(alloc));
if( !drop_value(ptr_val, ty, /*shallow=*/se.kind == ::MIR::eDropKind::SHALLOW) )
{
@@ -1327,7 +1323,7 @@ bool InterpreterThread::step_one(Value& out_thread_result)
LOG_TODO(stmt);
break;
}
-
+
cur_frame.stmt_idx += 1;
}
else
@@ -1456,7 +1452,7 @@ bool InterpreterThread::step_one(Value& out_thread_result)
}
cur_frame.stmt_idx = 0;
}
-
+
return false;
}
bool InterpreterThread::pop_stack(Value& out_thread_result)
@@ -1465,7 +1461,7 @@ bool InterpreterThread::pop_stack(Value& out_thread_result)
auto res_v = ::std::move(this->m_stack.back().ret);
this->m_stack.pop_back();
-
+
if( this->m_stack.empty() )
{
LOG_DEBUG("Thread complete, result " << res_v);
@@ -1539,8 +1535,7 @@ bool InterpreterThread::call_path(Value& ret, const ::HIR::Path& path, ::std::ve
{
if( path == ::HIR::SimplePath { "std", { "sys", "imp", "c", "SetThreadStackGuarantee" } } )
{
- ret = Value(::HIR::TypeRef{RawType::I32});
- ret.write_i32(0, 120); // ERROR_CALL_NOT_IMPLEMENTED
+ ret = Value::new_i32(120); //ERROR_CALL_NOT_IMPLEMENTED
return true;
}
@@ -1552,7 +1547,7 @@ bool InterpreterThread::call_path(Value& ret, const ::HIR::Path& path, ::std::ve
ret.write_u64(8, 0);
return true;
}
-
+
// - No stack overflow handling needed
if( path == ::HIR::SimplePath { "std", { "sys", "imp", "stack_overflow", "imp", "init" } } )
{
@@ -1567,7 +1562,7 @@ bool InterpreterThread::call_path(Value& ret, const ::HIR::Path& path, ::std::ve
// External function!
return this->call_extern(ret, fcn.external.link_name, fcn.external.link_abi, ::std::move(args));
}
-
+
this->m_stack.push_back(StackFrame(fcn, ::std::move(args)));
return false;
}
@@ -1586,10 +1581,8 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c
::HIR::TypeRef rty { RawType::Unit };
rty.wrappers.push_back({ TypeWrapper::Ty::Pointer, 0 });
- rv = Value(rty);
- rv.write_usize(0, 0);
// TODO: Use the alignment when making an allocation?
- rv.allocation->relocations.push_back({ 0, RelocationPtr::new_alloc(Allocation::new_alloc(size)) });
+ rv = Value::new_pointer(rty, 0, RelocationPtr::new_alloc(Allocation::new_alloc(size)));
}
else if( link_name == "__rust_reallocate" )
{
@@ -1632,13 +1625,12 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c
auto arg = args.at(1);
auto data_ptr = args.at(2).read_pointer_valref_mut(0, POINTER_SIZE);
auto vtable_ptr = args.at(3).read_pointer_valref_mut(0, POINTER_SIZE);
-
+
::std::vector<Value> sub_args;
sub_args.push_back( ::std::move(arg) );
this->m_stack.push_back(StackFrame::make_wrapper([=](Value& out_rv, Value /*rv*/)->bool{
- out_rv = Value(::HIR::TypeRef(RawType::U32));
- out_rv.write_u32(0, 0);
+ out_rv = Value::new_u32(0);
return true;
}));
@@ -1667,8 +1659,7 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c
else if( link_name == "AddVectoredExceptionHandler" )
{
LOG_DEBUG("Call `AddVectoredExceptionHandler` - Ignoring and returning non-null");
- rv = Value(::HIR::TypeRef(RawType::USize));
- rv.write_usize(0, 1);
+ rv = Value::new_usize(1);
}
else if( link_name == "GetModuleHandleW" )
{
@@ -1732,8 +1723,7 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c
ssize_t val = write(fd, buf, count);
- rv = Value(::HIR::TypeRef(RawType::ISize));
- rv.write_isize(0, val);
+ rv = Value::new_isize(val);
}
else if( link_name == "sysconf" )
{
@@ -1742,33 +1732,27 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c
long val = sysconf(name);
- rv = Value(::HIR::TypeRef(RawType::USize));
- rv.write_usize(0, val);
+ rv = Value::new_usize(val);
}
else if( link_name == "pthread_mutex_init" || link_name == "pthread_mutex_lock" || link_name == "pthread_mutex_unlock" || link_name == "pthread_mutex_destroy" )
{
- rv = Value(::HIR::TypeRef(RawType::I32));
- rv.write_i32(0, 0);
+ rv = Value::new_i32(0);
}
else if( link_name == "pthread_rwlock_rdlock" )
{
- rv = Value(::HIR::TypeRef(RawType::I32));
- rv.write_i32(0, 0);
+ rv = Value::new_i32(0);
}
else if( link_name == "pthread_mutexattr_init" || link_name == "pthread_mutexattr_settype" || link_name == "pthread_mutexattr_destroy" )
{
- rv = Value(::HIR::TypeRef(RawType::I32));
- rv.write_i32(0, 0);
+ rv = Value::new_i32(0);
}
else if( link_name == "pthread_condattr_init" || link_name == "pthread_condattr_destroy" || link_name == "pthread_condattr_setclock" )
{
- rv = Value(::HIR::TypeRef(RawType::I32));
- rv.write_i32(0, 0);
+ rv = Value::new_i32(0);
}
else if( link_name == "pthread_cond_init" || link_name == "pthread_cond_destroy" )
{
- rv = Value(::HIR::TypeRef(RawType::I32));
- rv.write_i32(0, 0);
+ rv = Value::new_i32(0);
}
else if( link_name == "pthread_key_create" )
{
@@ -1776,9 +1760,8 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c
auto key = ThreadState::s_next_tls_key ++;
key_ref.m_alloc.alloc().write_u32( key_ref.m_offset, key );
-
- rv = Value(::HIR::TypeRef(RawType::I32));
- rv.write_i32(0, 0);
+
+ rv = Value::new_i32(0);
}
else if( link_name == "pthread_getspecific" )
{
@@ -1787,8 +1770,7 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c
// Get a pointer-sized value from storage
uint64_t v = key < m_thread.tls_values.size() ? m_thread.tls_values[key] : 0;
- rv = Value(::HIR::TypeRef(RawType::USize));
- rv.write_usize(0, v);
+ rv = Value::new_usize(v);
}
else if( link_name == "pthread_setspecific" )
{
@@ -1801,13 +1783,11 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c
}
m_thread.tls_values[key] = v;
- rv = Value(::HIR::TypeRef(RawType::I32));
- rv.write_i32(0, 0);
+ rv = Value::new_i32(0);
}
else if( link_name == "pthread_key_delete" )
{
- rv = Value(::HIR::TypeRef(RawType::I32));
- rv.write_i32(0, 0);
+ rv = Value::new_i32(0);
}
#endif
// std C
diff --git a/tools/standalone_miri/value.cpp b/tools/standalone_miri/value.cpp
index c3db284a..c1098d1d 100644
--- a/tools/standalone_miri/value.cpp
+++ b/tools/standalone_miri/value.cpp
@@ -499,6 +499,11 @@ void Allocation::write_bytes(size_t ofs, const void* src, size_t count)
::std::memcpy(this->data_ptr() + ofs, src, count);
mark_bytes_valid(ofs, count);
}
+void Allocation::write_ptr(size_t ofs, size_t ptr_ofs, RelocationPtr reloc)
+{
+ this->write_usize(ofs, ptr_ofs);
+ this->relocations.push_back(Relocation { ofs, /*POINTER_SIZE,*/ ::std::move(reloc) });
+}
::std::ostream& operator<<(::std::ostream& os, const Allocation& x)
{
auto flags = os.flags();
@@ -620,6 +625,34 @@ Value Value::new_ffiptr(FFIPointer ffi)
rv.allocation->mask.at(0) = 0xFF; // TODO: Get pointer size and make that much valid instead of 8 bytes
return rv;
}
+Value Value::new_pointer(::HIR::TypeRef ty, uint64_t v, RelocationPtr r) {
+ assert(!ty.wrappers.empty());
+ assert(ty.wrappers[0].type == TypeWrapper::Ty::Borrow || ty.wrappers[0].type == TypeWrapper::Ty::Pointer);
+ Value rv(ty);
+ rv.write_usize(0, v);
+ rv.allocation->relocations.push_back(Relocation { 0, /*POINTER_SIZE,*/ ::std::move(r) });
+ return rv;
+}
+Value Value::new_usize(uint64_t v) {
+ Value rv( ::HIR::TypeRef(RawType::USize) );
+ rv.write_usize(0, v);
+ return rv;
+}
+Value Value::new_isize(int64_t v) {
+ Value rv( ::HIR::TypeRef(RawType::ISize) );
+ rv.write_isize(0, v);
+ return rv;
+}
+Value Value::new_u32(uint32_t v) {
+ Value rv( ::HIR::TypeRef(RawType::U32) );
+ rv.write_u32(0, v);
+ return rv;
+}
+Value Value::new_i32(int32_t v) {
+ Value rv( ::HIR::TypeRef(RawType::I32) );
+ rv.write_i32(0, v);
+ return rv;
+}
void Value::create_allocation()
{
@@ -775,6 +808,14 @@ void Value::write_value(size_t ofs, Value v)
}
}
}
+void Value::write_ptr(size_t ofs, size_t ptr_ofs, RelocationPtr reloc)
+{
+ if( !this->allocation )
+ {
+ LOG_ERROR("Writing a pointer with no allocation");
+ }
+ this->allocation->write_ptr(ofs, ptr_ofs, ::std::move(reloc));
+}
::std::ostream& operator<<(::std::ostream& os, const Value& v)
{
diff --git a/tools/standalone_miri/value.hpp b/tools/standalone_miri/value.hpp
index 81302e67..b057b3c4 100644
--- a/tools/standalone_miri/value.hpp
+++ b/tools/standalone_miri/value.hpp
@@ -201,6 +201,7 @@ struct ValueCommonWrite:
void write_f64(size_t ofs, double v) { write_bytes(ofs, &v, 8); }
void write_usize(size_t ofs, uint64_t v);
void write_isize(size_t ofs, int64_t v) { write_usize(ofs, static_cast<uint64_t>(v)); }
+ virtual void write_ptr(size_t ofs, size_t ptr_ofs, RelocationPtr reloc) = 0;
};
class Allocation:
@@ -245,6 +246,7 @@ public:
void write_value(size_t ofs, Value v);
void write_bytes(size_t ofs, const void* src, size_t count) override;
+ void write_ptr(size_t ofs, size_t ptr_ofs, RelocationPtr reloc) override;
};
extern ::std::ostream& operator<<(::std::ostream& os, const Allocation& x);
@@ -254,7 +256,8 @@ struct Value:
// If NULL, data is direct
AllocationHandle allocation;
struct {
- uint8_t data[2*sizeof(size_t)-3]; // 16-3 = 13, fits in 16 bits of mask
+ // NOTE: Can't pack the mask+size tighter, need 4 bits of size (8-15) leaving 12 bits of mask
+ uint8_t data[2*8-3]; // 13 data bytes, plus 16bit mask, plus size = 16 bytes
uint8_t mask[2];
uint8_t size;
} direct_data;
@@ -265,8 +268,11 @@ struct Value:
static Value with_size(size_t size, bool have_allocation);
static Value new_fnptr(const ::HIR::Path& fn_path);
static Value new_ffiptr(FFIPointer ffi);
- //static Value new_usize(uint64_t v);
- //static Value new_isize(int64_t v);
+ static Value new_pointer(::HIR::TypeRef ty, uint64_t v, RelocationPtr r);
+ static Value new_usize(uint64_t v);
+ static Value new_isize(int64_t v);
+ static Value new_u32(uint32_t v);
+ static Value new_i32(int32_t v);
void create_allocation();
size_t size() const { return allocation ? allocation->size() : direct_data.size; }
@@ -289,7 +295,7 @@ struct Value:
void write_value(size_t ofs, Value v);
void write_bytes(size_t ofs, const void* src, size_t count) override;
- //void write_ptr(size_t ofs, size_t ptr_ofs, RelocationPtr reloc);
+ void write_ptr(size_t ofs, size_t ptr_ofs, RelocationPtr reloc) override;
};
extern ::std::ostream& operator<<(::std::ostream& os, const Value& v);