Dynamically allocate internal fields.

This commit is contained in:
losfair
2019-05-23 20:10:17 +08:00
parent 6aec1c4b5f
commit cf58305889
2 changed files with 42 additions and 4 deletions

View File

@ -2,8 +2,11 @@ use wasmer_runtime_core::{
codegen::{Event, EventSink, FunctionMiddleware, InternalEvent}, codegen::{Event, EventSink, FunctionMiddleware, InternalEvent},
module::ModuleInfo, module::ModuleInfo,
wasmparser::{Operator, Type as WpType}, wasmparser::{Operator, Type as WpType},
vm::InternalField,
}; };
static INTERNAL_FIELD: InternalField = InternalField::allocate();
pub struct Metering { pub struct Metering {
limit: u64, limit: u64,
current_block: u64, current_block: u64,
@ -45,12 +48,12 @@ impl FunctionMiddleware for Metering {
| Operator::Call { .. } | Operator::Call { .. }
| Operator::CallIndirect { .. } | Operator::CallIndirect { .. }
| Operator::Return => { | Operator::Return => {
sink.push(Event::Internal(InternalEvent::GetInternal(0))); sink.push(Event::Internal(InternalEvent::GetInternal(INTERNAL_FIELD.index() as _)));
sink.push(Event::WasmOwned(Operator::I64Const { sink.push(Event::WasmOwned(Operator::I64Const {
value: self.current_block as i64, value: self.current_block as i64,
})); }));
sink.push(Event::WasmOwned(Operator::I64Add)); sink.push(Event::WasmOwned(Operator::I64Add));
sink.push(Event::Internal(InternalEvent::SetInternal(0))); sink.push(Event::Internal(InternalEvent::SetInternal(INTERNAL_FIELD.index() as _)));
self.current_block = 0; self.current_block = 0;
} }
_ => {} _ => {}
@ -61,7 +64,7 @@ impl FunctionMiddleware for Metering {
| Operator::BrIf { .. } | Operator::BrIf { .. }
| Operator::Call { .. } | Operator::Call { .. }
| Operator::CallIndirect { .. } => { | Operator::CallIndirect { .. } => {
sink.push(Event::Internal(InternalEvent::GetInternal(0))); sink.push(Event::Internal(InternalEvent::GetInternal(INTERNAL_FIELD.index() as _)));
sink.push(Event::WasmOwned(Operator::I64Const { sink.push(Event::WasmOwned(Operator::I64Const {
value: self.limit as i64, value: self.limit as i64,
})); }));

View File

@ -6,7 +6,7 @@ use crate::{
types::{LocalOrImport, MemoryIndex}, types::{LocalOrImport, MemoryIndex},
vmcalls, vmcalls,
}; };
use std::{ffi::c_void, mem, ptr}; use std::{ffi::c_void, mem, ptr, sync::atomic::{AtomicUsize, Ordering}, sync::Once, cell::UnsafeCell};
use hashbrown::HashMap; use hashbrown::HashMap;
@ -96,6 +96,41 @@ pub struct InternalCtx {
pub internals: *mut [u64; INTERNALS_SIZE], // TODO: Make this dynamic? pub internals: *mut [u64; INTERNALS_SIZE], // TODO: Make this dynamic?
} }
static INTERNAL_FIELDS: AtomicUsize = AtomicUsize::new(0);
pub struct InternalField {
init: Once,
inner: UnsafeCell<usize>,
}
unsafe impl Send for InternalField {}
unsafe impl Sync for InternalField {}
impl InternalField {
pub const fn allocate() -> InternalField {
InternalField {
init: Once::new(),
inner: UnsafeCell::new(::std::usize::MAX),
}
}
pub fn index(&self) -> usize {
let inner: *mut usize = self.inner.get();
self.init.call_once(|| {
let idx = INTERNAL_FIELDS.fetch_add(1, Ordering::SeqCst);
if idx >= INTERNALS_SIZE {
INTERNAL_FIELDS.fetch_sub(1, Ordering::SeqCst);
panic!("at most {} internal fields are supported", INTERNALS_SIZE);
} else {
unsafe {
*inner = idx;
}
}
});
unsafe { *inner }
}
}
#[repr(C)] #[repr(C)]
pub struct Intrinsics { pub struct Intrinsics {
pub memory_grow: *const Func, pub memory_grow: *const Func,