mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-14 17:31:20 +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,
|
FuncIndex, FuncSig, GlobalIndex, LocalFuncIndex, LocalOrImport, MemoryIndex, SigIndex,
|
||||||
TableIndex, Type,
|
TableIndex, Type,
|
||||||
},
|
},
|
||||||
vm::{self, LocalGlobal, LocalTable},
|
vm::{self, LocalGlobal, LocalTable, INTERNALS_SIZE},
|
||||||
};
|
};
|
||||||
use wasmparser::{Operator, Type as WpType};
|
use wasmparser::{Operator, Type as WpType};
|
||||||
|
|
||||||
@ -1494,8 +1494,10 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
|
|||||||
|
|
||||||
let a = self.assembler.as_mut().unwrap();
|
let a = self.assembler.as_mut().unwrap();
|
||||||
|
|
||||||
|
|
||||||
let op = match ev {
|
let op = match ev {
|
||||||
Event::Wasm(x) => x,
|
Event::Wasm(x) => x,
|
||||||
|
Event::WasmOwned(ref x) => x,
|
||||||
Event::Internal(x) => {
|
Event::Internal(x) => {
|
||||||
match x {
|
match x {
|
||||||
InternalEvent::Breakpoint(callback) => {
|
InternalEvent::Breakpoint(callback) => {
|
||||||
@ -1505,8 +1507,71 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.insert(a.get_offset(), callback);
|
.insert(a.get_offset(), callback);
|
||||||
}
|
}
|
||||||
InternalEvent::FunctionBegin(_) | InternalEvent::FunctionEnd => {}
|
InternalEvent::FunctionBegin(_) | InternalEvent::FunctionEnd => {},
|
||||||
_ => unimplemented!(),
|
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(());
|
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()));
|
let bkpt_map = BKPT_MAP.with(|x| x.borrow().last().map(|x| x.clone()));
|
||||||
if let Some(bkpt_map) = bkpt_map {
|
if let Some(bkpt_map) = bkpt_map {
|
||||||
if let Some(ref x) = bkpt_map.get(&(ip as usize)) {
|
if let Some(ref x) = bkpt_map.get(&(ip as usize)) {
|
||||||
(x)(BkptInfo {});
|
(x)(BkptInfo {
|
||||||
|
throw: throw,
|
||||||
|
});
|
||||||
return;
|
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.
|
/// Unwinds to last protected_call.
|
||||||
pub unsafe fn do_unwind(signum: i32, siginfo: *const c_void, ucontext: *const c_void) -> ! {
|
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.)
|
// 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