mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-28 16:11:32 +00:00
Dynamically allocate internal fields.
This commit is contained in:
@ -2,8 +2,11 @@ use wasmer_runtime_core::{
|
||||
codegen::{Event, EventSink, FunctionMiddleware, InternalEvent},
|
||||
module::ModuleInfo,
|
||||
wasmparser::{Operator, Type as WpType},
|
||||
vm::InternalField,
|
||||
};
|
||||
|
||||
static INTERNAL_FIELD: InternalField = InternalField::allocate();
|
||||
|
||||
pub struct Metering {
|
||||
limit: u64,
|
||||
current_block: u64,
|
||||
@ -45,12 +48,12 @@ impl FunctionMiddleware for Metering {
|
||||
| Operator::Call { .. }
|
||||
| Operator::CallIndirect { .. }
|
||||
| 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 {
|
||||
value: self.current_block as i64,
|
||||
}));
|
||||
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;
|
||||
}
|
||||
_ => {}
|
||||
@ -61,7 +64,7 @@ impl FunctionMiddleware for Metering {
|
||||
| Operator::BrIf { .. }
|
||||
| Operator::Call { .. }
|
||||
| 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 {
|
||||
value: self.limit as i64,
|
||||
}));
|
||||
|
@ -6,7 +6,7 @@ use crate::{
|
||||
types::{LocalOrImport, MemoryIndex},
|
||||
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;
|
||||
|
||||
@ -96,6 +96,41 @@ pub struct InternalCtx {
|
||||
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)]
|
||||
pub struct Intrinsics {
|
||||
pub memory_grow: *const Func,
|
||||
|
Reference in New Issue
Block a user