mirror of
https://github.com/denoland/rusty_v8.git
synced 2025-01-11 08:34:01 -05:00
Add support for Platform::pump_message_loop and Platform::run_idle_tasks (#706)
Co-authored-by: Ben Noordhuis <info@bnoordhuis.nl>
This commit is contained in:
parent
89c8ae8af3
commit
14bcf04bef
14 changed files with 346 additions and 58 deletions
|
@ -2,7 +2,7 @@ use rusty_v8 as v8;
|
|||
|
||||
fn main() {
|
||||
// Initialize V8.
|
||||
let platform = v8::new_default_platform().unwrap();
|
||||
let platform = v8::new_default_platform(0, false).make_shared();
|
||||
v8::V8::initialize_platform(platform);
|
||||
v8::V8::initialize();
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ fn log_callback(
|
|||
|
||||
fn main() {
|
||||
// Initialize V8.
|
||||
let platform = v8::new_default_platform().unwrap();
|
||||
let platform = v8::new_default_platform(0, false).make_shared();
|
||||
v8::V8::initialize_platform(platform);
|
||||
v8::V8::initialize();
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ use rusty_v8 as v8;
|
|||
|
||||
fn main() {
|
||||
// Initialize V8.
|
||||
let platform = v8::new_default_platform().unwrap();
|
||||
let platform = v8::new_default_platform(0, false).make_shared();
|
||||
v8::V8::initialize_platform(platform);
|
||||
v8::V8::initialize();
|
||||
|
||||
|
@ -79,11 +79,15 @@ fn run_main(
|
|||
let script: &str = &args[i + 1];
|
||||
skip_next = true;
|
||||
|
||||
// TODO: pump event loop (not implemented on rusty_v8?)
|
||||
// while v8::Platform::pump_message_loop(&platform, isolate) {
|
||||
// // do nothing
|
||||
// }
|
||||
execute_string(scope, script, "unnamed", false, true);
|
||||
|
||||
while v8::Platform::pump_message_loop(
|
||||
&v8::V8::get_current_platform(),
|
||||
scope,
|
||||
false,
|
||||
) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
arg => {
|
||||
if arg.starts_with("--") {
|
||||
|
@ -94,6 +98,14 @@ fn run_main(
|
|||
// Use all other arguments as names of files to load and run.
|
||||
let script = std::fs::read_to_string(arg).expect("failed to read file");
|
||||
execute_string(scope, &script, arg, false, true);
|
||||
|
||||
while v8::Platform::pump_message_loop(
|
||||
&v8::V8::get_current_platform(),
|
||||
scope,
|
||||
false,
|
||||
) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
67
src/V8.rs
67
src/V8.rs
|
@ -7,7 +7,7 @@ use std::sync::Mutex;
|
|||
use std::vec::Vec;
|
||||
|
||||
use crate::platform::Platform;
|
||||
use crate::support::UniqueRef;
|
||||
use crate::support::SharedRef;
|
||||
use crate::support::UnitType;
|
||||
|
||||
extern "C" {
|
||||
|
@ -61,24 +61,26 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
#[derive(Debug)]
|
||||
enum GlobalState {
|
||||
Uninitialized,
|
||||
PlatformInitialized,
|
||||
Initialized,
|
||||
Disposed,
|
||||
PlatformInitialized(SharedRef<Platform>),
|
||||
Initialized(SharedRef<Platform>),
|
||||
Disposed(SharedRef<Platform>),
|
||||
PlatformShutdown,
|
||||
}
|
||||
use GlobalState::*;
|
||||
|
||||
lazy_static! {
|
||||
static ref GLOBAL_STATE: Mutex<GlobalState> =
|
||||
Mutex::new(GlobalState::Uninitialized);
|
||||
static ref GLOBAL_STATE: Mutex<GlobalState> = Mutex::new(Uninitialized);
|
||||
}
|
||||
|
||||
pub fn assert_initialized() {
|
||||
let global_state_guard = GLOBAL_STATE.lock().unwrap();
|
||||
assert_eq!(*global_state_guard, Initialized);
|
||||
match *global_state_guard {
|
||||
Initialized(_) => {}
|
||||
_ => panic!("Invalid global state"),
|
||||
};
|
||||
}
|
||||
|
||||
/// Pass the command line arguments to v8.
|
||||
|
@ -173,25 +175,41 @@ pub fn get_version() -> &'static str {
|
|||
c_str.to_str().unwrap()
|
||||
}
|
||||
|
||||
// TODO: V8::InitializePlatform does not actually take a UniquePtr but rather
|
||||
// a raw pointer. This means that the Platform object is not released when
|
||||
// V8::ShutdownPlatform is called.
|
||||
/// Sets the v8::Platform to use. This should be invoked before V8 is
|
||||
/// initialized.
|
||||
pub fn initialize_platform(platform: UniqueRef<Platform>) {
|
||||
pub fn initialize_platform(platform: SharedRef<Platform>) {
|
||||
let mut global_state_guard = GLOBAL_STATE.lock().unwrap();
|
||||
assert_eq!(*global_state_guard, Uninitialized);
|
||||
unsafe { v8__V8__InitializePlatform(platform.into_raw()) };
|
||||
*global_state_guard = PlatformInitialized;
|
||||
*global_state_guard = match *global_state_guard {
|
||||
Uninitialized => PlatformInitialized(platform.clone()),
|
||||
_ => panic!("Invalid global state"),
|
||||
};
|
||||
|
||||
{
|
||||
unsafe {
|
||||
v8__V8__InitializePlatform(&*platform as *const Platform as *mut _)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Initializes V8. This function needs to be called before the first Isolate
|
||||
/// is created. It always returns true.
|
||||
pub fn initialize() {
|
||||
let mut global_state_guard = GLOBAL_STATE.lock().unwrap();
|
||||
assert_eq!(*global_state_guard, PlatformInitialized);
|
||||
unsafe { v8__V8__Initialize() };
|
||||
*global_state_guard = Initialized;
|
||||
*global_state_guard = match *global_state_guard {
|
||||
PlatformInitialized(ref platform) => Initialized(platform.clone()),
|
||||
_ => panic!("Invalid global state"),
|
||||
};
|
||||
unsafe { v8__V8__Initialize() }
|
||||
}
|
||||
|
||||
/// Sets the v8::Platform to use. This should be invoked before V8 is
|
||||
/// initialized.
|
||||
pub fn get_current_platform() -> SharedRef<Platform> {
|
||||
let global_state_guard = GLOBAL_STATE.lock().unwrap();
|
||||
match *global_state_guard {
|
||||
Initialized(ref platform) => platform.clone(),
|
||||
_ => panic!("Invalid global state"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Releases any resources used by v8 and stops any utility threads
|
||||
|
@ -208,9 +226,11 @@ pub fn initialize() {
|
|||
/// to a crash.
|
||||
pub unsafe fn dispose() -> bool {
|
||||
let mut global_state_guard = GLOBAL_STATE.lock().unwrap();
|
||||
assert_eq!(*global_state_guard, Initialized);
|
||||
*global_state_guard = match *global_state_guard {
|
||||
Initialized(ref platform) => Disposed(platform.clone()),
|
||||
_ => panic!("Invalid global state"),
|
||||
};
|
||||
assert!(v8__V8__Dispose());
|
||||
*global_state_guard = Disposed;
|
||||
true
|
||||
}
|
||||
|
||||
|
@ -218,7 +238,10 @@ pub unsafe fn dispose() -> bool {
|
|||
/// V8 was disposed.
|
||||
pub fn shutdown_platform() {
|
||||
let mut global_state_guard = GLOBAL_STATE.lock().unwrap();
|
||||
assert_eq!(*global_state_guard, Disposed);
|
||||
// First shutdown platform, then drop platform
|
||||
unsafe { v8__V8__ShutdownPlatform() };
|
||||
*global_state_guard = PlatformShutdown;
|
||||
*global_state_guard = match *global_state_guard {
|
||||
Disposed(_) => PlatformShutdown,
|
||||
_ => panic!("Invalid global state"),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -2028,18 +2028,64 @@ v8::StartupData v8__SnapshotCreator__CreateBlob(
|
|||
return self->CreateBlob(function_code_handling);
|
||||
}
|
||||
|
||||
v8::Platform* v8__platform__NewDefaultPlatform() {
|
||||
// TODO(bnoordhuis) Support optional arguments.
|
||||
return v8::platform::NewDefaultPlatform().release();
|
||||
v8::Platform* v8__Platform__NewDefaultPlatform(int thread_pool_size,
|
||||
bool idle_task_support) {
|
||||
return v8::platform::NewDefaultPlatform(
|
||||
thread_pool_size,
|
||||
idle_task_support ? v8::platform::IdleTaskSupport::kEnabled
|
||||
: v8::platform::IdleTaskSupport::kDisabled,
|
||||
v8::platform::InProcessStackDumping::kDisabled, nullptr)
|
||||
.release();
|
||||
}
|
||||
|
||||
v8::Platform* v8__platform__NewSingleThreadedDefaultPlatform() {
|
||||
// TODO(bnoordhuis) Support optional arguments.
|
||||
return v8::platform::NewSingleThreadedDefaultPlatform().release();
|
||||
v8::Platform* v8__Platform__NewSingleThreadedDefaultPlatform(
|
||||
bool idle_task_support) {
|
||||
return v8::platform::NewSingleThreadedDefaultPlatform(
|
||||
idle_task_support ? v8::platform::IdleTaskSupport::kEnabled
|
||||
: v8::platform::IdleTaskSupport::kDisabled,
|
||||
v8::platform::InProcessStackDumping::kDisabled, nullptr)
|
||||
.release();
|
||||
}
|
||||
|
||||
bool v8__Platform__PumpMessageLoop(v8::Platform* platform, v8::Isolate* isolate,
|
||||
bool wait_for_work) {
|
||||
return v8::platform::PumpMessageLoop(
|
||||
platform, isolate,
|
||||
wait_for_work ? v8::platform::MessageLoopBehavior::kWaitForWork
|
||||
: v8::platform::MessageLoopBehavior::kDoNotWait);
|
||||
}
|
||||
|
||||
void v8__Platform__RunIdleTasks(v8::Platform* platform, v8::Isolate* isolate,
|
||||
double idle_time_in_seconds) {
|
||||
v8::platform::RunIdleTasks(platform, isolate, idle_time_in_seconds);
|
||||
}
|
||||
|
||||
void v8__Platform__DELETE(v8::Platform* self) { delete self; }
|
||||
|
||||
two_pointers_t std__shared_ptr__v8__Platform__CONVERT__std__unique_ptr(
|
||||
v8::Platform* unique_ptr) {
|
||||
return make_pod<two_pointers_t>(std::shared_ptr<v8::Platform>(unique_ptr));
|
||||
}
|
||||
|
||||
v8::Platform* std__shared_ptr__v8__Platform__get(
|
||||
const std::shared_ptr<v8::Platform>& ptr) {
|
||||
return ptr.get();
|
||||
}
|
||||
|
||||
two_pointers_t std__shared_ptr__v8__Platform__COPY(
|
||||
const std::shared_ptr<v8::Platform>& ptr) {
|
||||
return make_pod<two_pointers_t>(ptr);
|
||||
}
|
||||
|
||||
void std__shared_ptr__v8__Platform__reset(std::shared_ptr<v8::Platform>* ptr) {
|
||||
ptr->reset();
|
||||
}
|
||||
|
||||
long std__shared_ptr__v8__Platform__use_count(
|
||||
const std::shared_ptr<v8::Platform>& ptr) {
|
||||
return ptr.use_count();
|
||||
}
|
||||
|
||||
void v8_inspector__V8Inspector__Channel__BASE__sendResponse(
|
||||
v8_inspector::V8Inspector::Channel* self, int callId,
|
||||
v8_inspector::StringBuffer* message);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
//! ```rust
|
||||
//! use rusty_v8 as v8;
|
||||
//!
|
||||
//! let platform = v8::new_default_platform().unwrap();
|
||||
//! let platform = v8::new_default_platform(0, false).make_shared();
|
||||
//! v8::V8::initialize_platform(platform);
|
||||
//! v8::V8::initialize();
|
||||
//!
|
||||
|
|
182
src/platform.rs
182
src/platform.rs
|
@ -1,31 +1,181 @@
|
|||
use crate::support::int;
|
||||
use crate::Isolate;
|
||||
|
||||
use crate::support::long;
|
||||
use crate::support::Opaque;
|
||||
use crate::support::Shared;
|
||||
use crate::support::SharedPtrBase;
|
||||
use crate::support::SharedRef;
|
||||
use crate::support::UniquePtr;
|
||||
use crate::support::UniqueRef;
|
||||
|
||||
extern "C" {
|
||||
fn v8__platform__NewDefaultPlatform() -> *mut Platform;
|
||||
fn v8__platform__NewSingleThreadedDefaultPlatform() -> *mut Platform;
|
||||
fn v8__Platform__NewDefaultPlatform(
|
||||
thread_pool_size: int,
|
||||
idle_task_support: bool,
|
||||
) -> *mut Platform;
|
||||
fn v8__Platform__NewSingleThreadedDefaultPlatform(
|
||||
idle_task_support: bool,
|
||||
) -> *mut Platform;
|
||||
fn v8__Platform__DELETE(this: *mut Platform);
|
||||
}
|
||||
|
||||
/// Returns a new instance of the default v8::Platform implementation.
|
||||
pub fn new_default_platform() -> UniquePtr<Platform> {
|
||||
unsafe { UniquePtr::from_raw(v8__platform__NewDefaultPlatform()) }
|
||||
}
|
||||
fn v8__Platform__PumpMessageLoop(
|
||||
platform: *mut Platform,
|
||||
isolate: *mut Isolate,
|
||||
wait_for_work: bool,
|
||||
) -> bool;
|
||||
|
||||
/// The same as new_default_platform() but disables the worker thread pool.
|
||||
/// It must be used with the --single-threaded V8 flag.
|
||||
pub fn new_single_threaded_default_platform() -> UniquePtr<Platform> {
|
||||
unsafe {
|
||||
UniquePtr::from_raw(v8__platform__NewSingleThreadedDefaultPlatform())
|
||||
}
|
||||
fn v8__Platform__RunIdleTasks(
|
||||
platform: *mut Platform,
|
||||
isolate: *mut Isolate,
|
||||
idle_time_in_seconds: f64,
|
||||
);
|
||||
|
||||
fn std__shared_ptr__v8__Platform__CONVERT__std__unique_ptr(
|
||||
unique_ptr: UniquePtr<Platform>,
|
||||
) -> SharedPtrBase<Platform>;
|
||||
fn std__shared_ptr__v8__Platform__get(
|
||||
ptr: *const SharedPtrBase<Platform>,
|
||||
) -> *mut Platform;
|
||||
fn std__shared_ptr__v8__Platform__COPY(
|
||||
ptr: *const SharedPtrBase<Platform>,
|
||||
) -> SharedPtrBase<Platform>;
|
||||
fn std__shared_ptr__v8__Platform__reset(ptr: *mut SharedPtrBase<Platform>);
|
||||
fn std__shared_ptr__v8__Platform__use_count(
|
||||
ptr: *const SharedPtrBase<Platform>,
|
||||
) -> long;
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct Platform(Opaque);
|
||||
|
||||
impl Drop for Platform {
|
||||
fn drop(&mut self) {
|
||||
unsafe { v8__Platform__DELETE(self) }
|
||||
/// Returns a new instance of the default v8::Platform implementation.
|
||||
///
|
||||
/// |thread_pool_size| is the number of worker threads to allocate for
|
||||
/// background jobs. If a value of zero is passed, a suitable default
|
||||
/// based on the current number of processors online will be chosen.
|
||||
/// If |idle_task_support| is enabled then the platform will accept idle
|
||||
/// tasks (IdleTasksEnabled will return true) and will rely on the embedder
|
||||
/// calling v8::platform::RunIdleTasks to process the idle tasks.
|
||||
pub fn new_default_platform(
|
||||
thread_pool_size: u32,
|
||||
idle_task_support: bool,
|
||||
) -> UniqueRef<Platform> {
|
||||
Platform::new(thread_pool_size, idle_task_support)
|
||||
}
|
||||
|
||||
/// The same as new_default_platform() but disables the worker thread pool.
|
||||
/// It must be used with the --single-threaded V8 flag.
|
||||
///
|
||||
/// If |idle_task_support| is enabled then the platform will accept idle
|
||||
/// tasks (IdleTasksEnabled will return true) and will rely on the embedder
|
||||
/// calling v8::platform::RunIdleTasks to process the idle tasks.
|
||||
pub fn new_single_threaded_default_platform(
|
||||
idle_task_support: bool,
|
||||
) -> UniqueRef<Platform> {
|
||||
Platform::new_single_threaded(idle_task_support)
|
||||
}
|
||||
|
||||
impl Platform {
|
||||
/// Returns a new instance of the default v8::Platform implementation.
|
||||
///
|
||||
/// |thread_pool_size| is the number of worker threads to allocate for
|
||||
/// background jobs. If a value of zero is passed, a suitable default
|
||||
/// based on the current number of processors online will be chosen.
|
||||
/// If |idle_task_support| is enabled then the platform will accept idle
|
||||
/// tasks (IdleTasksEnabled will return true) and will rely on the embedder
|
||||
/// calling v8::platform::RunIdleTasks to process the idle tasks.
|
||||
pub fn new(
|
||||
thread_pool_size: u32,
|
||||
idle_task_support: bool,
|
||||
) -> UniqueRef<Self> {
|
||||
unsafe {
|
||||
UniqueRef::from_raw(v8__Platform__NewDefaultPlatform(
|
||||
thread_pool_size.min(16) as i32,
|
||||
idle_task_support,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// The same as new() but disables the worker thread pool.
|
||||
/// It must be used with the --single-threaded V8 flag.
|
||||
///
|
||||
/// If |idle_task_support| is enabled then the platform will accept idle
|
||||
/// tasks (IdleTasksEnabled will return true) and will rely on the embedder
|
||||
/// calling v8::platform::RunIdleTasks to process the idle tasks.
|
||||
pub fn new_single_threaded(idle_task_support: bool) -> UniqueRef<Self> {
|
||||
unsafe {
|
||||
UniqueRef::from_raw(v8__Platform__NewSingleThreadedDefaultPlatform(
|
||||
idle_task_support,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Platform {
|
||||
/// Pumps the message loop for the given isolate.
|
||||
///
|
||||
/// The caller has to make sure that this is called from the right thread.
|
||||
/// Returns true if a task was executed, and false otherwise. If the call to
|
||||
/// PumpMessageLoop is nested within another call to PumpMessageLoop, only
|
||||
/// nestable tasks may run. Otherwise, any task may run. Unless requested through
|
||||
/// the |wait_for_work| parameter, this call does not block if no task is pending.
|
||||
pub fn pump_message_loop(
|
||||
platform: &SharedRef<Self>,
|
||||
isolate: &mut Isolate,
|
||||
wait_for_work: bool,
|
||||
) -> bool {
|
||||
unsafe {
|
||||
v8__Platform__PumpMessageLoop(
|
||||
&**platform as *const Self as *mut _,
|
||||
isolate,
|
||||
wait_for_work,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Runs pending idle tasks for at most |idle_time_in_seconds| seconds.
|
||||
///
|
||||
/// The caller has to make sure that this is called from the right thread.
|
||||
/// This call does not block if no task is pending.
|
||||
pub fn run_idle_tasks(
|
||||
platform: &SharedRef<Self>,
|
||||
isolate: &mut Isolate,
|
||||
idle_time_in_seconds: f64,
|
||||
) {
|
||||
unsafe {
|
||||
v8__Platform__RunIdleTasks(
|
||||
&**platform as *const Self as *mut _,
|
||||
isolate,
|
||||
idle_time_in_seconds,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Shared for Platform {
|
||||
fn from_unique_ptr(unique_ptr: UniquePtr<Self>) -> SharedPtrBase<Self> {
|
||||
unsafe {
|
||||
std__shared_ptr__v8__Platform__CONVERT__std__unique_ptr(unique_ptr)
|
||||
}
|
||||
}
|
||||
fn get(ptr: &SharedPtrBase<Self>) -> *const Self {
|
||||
unsafe { std__shared_ptr__v8__Platform__get(ptr) }
|
||||
}
|
||||
fn clone(ptr: &SharedPtrBase<Self>) -> SharedPtrBase<Self> {
|
||||
unsafe { std__shared_ptr__v8__Platform__COPY(ptr) }
|
||||
}
|
||||
fn reset(ptr: &mut SharedPtrBase<Self>) {
|
||||
unsafe { std__shared_ptr__v8__Platform__reset(ptr) }
|
||||
}
|
||||
fn use_count(ptr: &SharedPtrBase<Self>) -> long {
|
||||
unsafe { std__shared_ptr__v8__Platform__use_count(ptr) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Platform {
|
||||
fn drop(&mut self) {
|
||||
unsafe { v8__Platform__DELETE(self) };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1727,7 +1727,7 @@ mod tests {
|
|||
fn initialize_v8() {
|
||||
static INIT: Once = Once::new();
|
||||
INIT.call_once(|| {
|
||||
V8::initialize_platform(new_default_platform().unwrap());
|
||||
V8::initialize_platform(new_default_platform(0, false).make_shared());
|
||||
V8::initialize();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -28,7 +28,9 @@ impl CoreIsolate {
|
|||
fn new(drop_count: Rc<AtomicUsize>) -> CoreIsolate {
|
||||
static START: Once = Once::new();
|
||||
START.call_once(|| {
|
||||
v8::V8::initialize_platform(v8::new_default_platform().unwrap());
|
||||
v8::V8::initialize_platform(
|
||||
v8::new_default_platform(0, false).make_shared(),
|
||||
);
|
||||
v8::V8::initialize();
|
||||
});
|
||||
let mut isolate = v8::Isolate::new(Default::default());
|
||||
|
|
|
@ -31,7 +31,9 @@ fn setup() -> SetupGuard {
|
|||
))
|
||||
.is_ok());
|
||||
v8::V8::set_flags_from_string("--expose_gc --harmony-import-assertions");
|
||||
v8::V8::initialize_platform(v8::new_default_platform().unwrap());
|
||||
v8::V8::initialize_platform(
|
||||
v8::new_default_platform(0, false).make_shared(),
|
||||
);
|
||||
v8::V8::initialize();
|
||||
});
|
||||
SetupGuard {}
|
||||
|
|
|
@ -19,7 +19,7 @@ fn set_entropy_source() {
|
|||
true
|
||||
});
|
||||
|
||||
v8::V8::initialize_platform(v8::new_default_platform().unwrap());
|
||||
v8::V8::initialize_platform(v8::new_default_platform(0, false).make_shared());
|
||||
v8::V8::initialize();
|
||||
|
||||
// Assumes that every isolate creates a PRNG from scratch, which is currently true.
|
||||
|
|
|
@ -5,7 +5,7 @@ use rusty_v8 as v8;
|
|||
#[test]
|
||||
fn set_flags_from_string() {
|
||||
v8::V8::set_flags_from_string("--use_strict");
|
||||
v8::V8::initialize_platform(v8::new_default_platform().unwrap());
|
||||
v8::V8::initialize_platform(v8::new_default_platform(0, false).make_shared());
|
||||
v8::V8::initialize();
|
||||
let isolate = &mut v8::Isolate::new(Default::default());
|
||||
let scope = &mut v8::HandleScope::new(isolate);
|
||||
|
|
53
tests/test_platform_atomics_pump_message_loop.rs
Normal file
53
tests/test_platform_atomics_pump_message_loop.rs
Normal file
|
@ -0,0 +1,53 @@
|
|||
use rusty_v8 as v8;
|
||||
|
||||
#[test]
|
||||
fn atomics_pump_message_loop() {
|
||||
v8::V8::set_flags_from_string("--harmony-top-level-await --allow-natives-syntax --harmony-sharedarraybuffer");
|
||||
v8::V8::initialize_platform(v8::new_default_platform(0, false).make_shared());
|
||||
v8::V8::initialize();
|
||||
let isolate = &mut v8::Isolate::new(Default::default());
|
||||
let scope = &mut v8::HandleScope::new(isolate);
|
||||
let context = v8::Context::new(scope);
|
||||
let scope = &mut v8::ContextScope::new(scope, context);
|
||||
let source = r#"
|
||||
function assertEquals(a, b) {
|
||||
if (a === b) return;
|
||||
throw a + " does not equal " + b;
|
||||
}
|
||||
|
||||
const sab = new SharedArrayBuffer(16);
|
||||
const i32a = new Int32Array(sab);
|
||||
|
||||
let resolved = false;
|
||||
(function() {
|
||||
const result = Atomics.waitAsync(i32a, 0, 0);
|
||||
result.value.then(
|
||||
(value) => { assertEquals("ok", value); resolved = true; },
|
||||
() => { assertUnreachable();
|
||||
});
|
||||
})();
|
||||
|
||||
const notify_return_value = Atomics.notify(i32a, 0, 1);
|
||||
assertEquals(1, notify_return_value);
|
||||
assertEquals(0, %AtomicsNumWaitersForTesting(i32a, 0));
|
||||
assertEquals(1, %AtomicsNumUnresolvedAsyncPromisesForTesting(i32a, 0));
|
||||
"#;
|
||||
let source = v8::String::new(scope, source).unwrap();
|
||||
let script = v8::Script::compile(scope, source, None).unwrap();
|
||||
script.run(scope).unwrap();
|
||||
|
||||
while v8::Platform::pump_message_loop(
|
||||
&v8::V8::get_current_platform(),
|
||||
scope,
|
||||
false,
|
||||
) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
let source2 = r#"
|
||||
assertEquals(0, %AtomicsNumUnresolvedAsyncPromisesForTesting(i32a, 0));
|
||||
"#;
|
||||
let source2 = v8::String::new(scope, source2).unwrap();
|
||||
let script2 = v8::Script::compile(scope, source2, None).unwrap();
|
||||
script2.run(scope).unwrap();
|
||||
}
|
|
@ -4,7 +4,7 @@ use rusty_v8 as v8;
|
|||
fn single_threaded_default_platform() {
|
||||
v8::V8::set_flags_from_string("--single_threaded");
|
||||
v8::V8::initialize_platform(
|
||||
v8::new_single_threaded_default_platform().unwrap(),
|
||||
v8::new_single_threaded_default_platform(false).make_shared(),
|
||||
);
|
||||
v8::V8::initialize();
|
||||
|
||||
|
|
Loading…
Reference in a new issue