mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-14 01:21:19 +00:00
Update singlepass backend to support metering.
This commit is contained in:
@ -23,7 +23,7 @@ use wasmer_runtime_core::{
|
||||
FuncIndex, FuncSig, GlobalIndex, LocalFuncIndex, LocalOrImport, MemoryIndex, SigIndex,
|
||||
TableIndex, Type,
|
||||
},
|
||||
vm::{self, LocalGlobal, LocalTable},
|
||||
vm::{self, LocalGlobal, LocalTable, INTERNALS_SIZE},
|
||||
};
|
||||
use wasmparser::{Operator, Type as WpType};
|
||||
|
||||
@ -1494,8 +1494,10 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
|
||||
|
||||
let a = self.assembler.as_mut().unwrap();
|
||||
|
||||
|
||||
let op = match ev {
|
||||
Event::Wasm(x) => x,
|
||||
Event::WasmOwned(ref x) => x,
|
||||
Event::Internal(x) => {
|
||||
match x {
|
||||
InternalEvent::Breakpoint(callback) => {
|
||||
@ -1505,8 +1507,71 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
|
||||
.unwrap()
|
||||
.insert(a.get_offset(), callback);
|
||||
}
|
||||
InternalEvent::FunctionBegin(_) | InternalEvent::FunctionEnd => {}
|
||||
_ => unimplemented!(),
|
||||
InternalEvent::FunctionBegin(_) | InternalEvent::FunctionEnd => {},
|
||||
InternalEvent::GetInternal(idx) => {
|
||||
let idx = idx as usize;
|
||||
assert!(idx < INTERNALS_SIZE);
|
||||
|
||||
let tmp = self.machine.acquire_temp_gpr().unwrap();
|
||||
|
||||
// Load `internals` pointer.
|
||||
a.emit_mov(
|
||||
Size::S64,
|
||||
Location::Memory(
|
||||
Machine::get_vmctx_reg(),
|
||||
vm::Ctx::offset_internals() as i32,
|
||||
),
|
||||
Location::GPR(tmp),
|
||||
);
|
||||
|
||||
let loc = self.machine.acquire_locations(
|
||||
a,
|
||||
&[WpType::I64],
|
||||
false,
|
||||
)[0];
|
||||
self.value_stack.push((loc, LocalOrTemp::Temp));
|
||||
|
||||
// Move internal into the result location.
|
||||
Self::emit_relaxed_binop(
|
||||
a,
|
||||
&mut self.machine,
|
||||
Assembler::emit_mov,
|
||||
Size::S64,
|
||||
Location::Memory(tmp, (idx * 8) as i32),
|
||||
loc,
|
||||
);
|
||||
|
||||
self.machine.release_temp_gpr(tmp);
|
||||
}
|
||||
InternalEvent::SetInternal(idx) => {
|
||||
let idx = idx as usize;
|
||||
assert!(idx < INTERNALS_SIZE);
|
||||
|
||||
let tmp = self.machine.acquire_temp_gpr().unwrap();
|
||||
|
||||
// Load `internals` pointer.
|
||||
a.emit_mov(
|
||||
Size::S64,
|
||||
Location::Memory(
|
||||
Machine::get_vmctx_reg(),
|
||||
vm::Ctx::offset_internals() as i32,
|
||||
),
|
||||
Location::GPR(tmp),
|
||||
);
|
||||
let loc = get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||
|
||||
// Move internal into storage.
|
||||
Self::emit_relaxed_binop(
|
||||
a,
|
||||
&mut self.machine,
|
||||
Assembler::emit_mov,
|
||||
Size::S64,
|
||||
loc,
|
||||
Location::Memory(tmp, (idx * 8) as i32),
|
||||
);
|
||||
self.machine.release_temp_gpr(tmp);
|
||||
}
|
||||
//_ => unimplemented!(),
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -35,7 +35,9 @@ extern "C" fn signal_trap_handler(
|
||||
let bkpt_map = BKPT_MAP.with(|x| x.borrow().last().map(|x| x.clone()));
|
||||
if let Some(bkpt_map) = bkpt_map {
|
||||
if let Some(ref x) = bkpt_map.get(&(ip as usize)) {
|
||||
(x)(BkptInfo {});
|
||||
(x)(BkptInfo {
|
||||
throw: throw,
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -128,6 +130,14 @@ pub fn call_protected<T>(f: impl FnOnce() -> T) -> Result<T, CallProtError> {
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe extern "C" fn throw() -> ! {
|
||||
let jmp_buf = SETJMP_BUFFER.with(|buf| buf.get());
|
||||
if *jmp_buf == [0; SETJMP_BUFFER_LEN] {
|
||||
::std::process::abort();
|
||||
}
|
||||
longjmp(jmp_buf as *mut ::nix::libc::c_void, 0xffff);
|
||||
}
|
||||
|
||||
/// Unwinds to last protected_call.
|
||||
pub unsafe fn do_unwind(signum: i32, siginfo: *const c_void, ucontext: *const c_void) -> ! {
|
||||
// Since do_unwind is only expected to get called from WebAssembly code which doesn't hold any host resources (locks etc.)
|
||||
|
Reference in New Issue
Block a user