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

@ -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,