mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-27 15:41:33 +00:00
Dynamically allocate internal fields.
This commit is contained in:
@ -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,
|
||||||
}));
|
}));
|
||||||
|
@ -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,
|
||||||
|
Reference in New Issue
Block a user