mirror of
https://github.com/denoland/rusty_v8.git
synced 2025-02-15 10:05:55 -05:00
feat: Add support for source phase imports (#1701)
* feat: Add support for source phase imports * fmt * fix windows * undo * test --------- Co-authored-by: snek <snek@deno.com>
This commit is contained in:
parent
7b0ee753ff
commit
4a56d2d43b
3 changed files with 138 additions and 6 deletions
|
@ -3252,11 +3252,12 @@ int v8__Module__ScriptId(const v8::Module& self) {
|
|||
return const_cast<v8::Module&>(self).ScriptId();
|
||||
}
|
||||
|
||||
MaybeBool v8__Module__InstantiateModule(const v8::Module& self,
|
||||
const v8::Context& context,
|
||||
v8::Module::ResolveModuleCallback cb) {
|
||||
return maybe_to_maybe_bool(
|
||||
ptr_to_local(&self)->InstantiateModule(ptr_to_local(&context), cb));
|
||||
MaybeBool v8__Module__InstantiateModule(
|
||||
const v8::Module& self, const v8::Context& context,
|
||||
v8::Module::ResolveModuleCallback cb,
|
||||
v8::Module::ResolveSourceCallback source_callback) {
|
||||
return maybe_to_maybe_bool(ptr_to_local(&self)->InstantiateModule(
|
||||
ptr_to_local(&context), cb, source_callback));
|
||||
}
|
||||
|
||||
const v8::Value* v8__Module__Evaluate(const v8::Module& self,
|
||||
|
|
|
@ -16,6 +16,7 @@ use crate::Local;
|
|||
use crate::Message;
|
||||
use crate::Module;
|
||||
use crate::ModuleRequest;
|
||||
use crate::Object;
|
||||
use crate::String;
|
||||
use crate::UnboundModuleScript;
|
||||
use crate::Value;
|
||||
|
@ -146,6 +147,64 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
// System V ABI
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
#[repr(C)]
|
||||
pub struct ResolveSourceCallbackRet(*const Object);
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
pub type ResolveSourceCallback<'a> = extern "C" fn(
|
||||
Local<'a, Context>,
|
||||
Local<'a, String>,
|
||||
Local<'a, FixedArray>,
|
||||
Local<'a, Module>,
|
||||
) -> ResolveSourceCallbackRet;
|
||||
|
||||
// Windows x64 ABI: Local<Module> returned on the stack.
|
||||
#[cfg(target_os = "windows")]
|
||||
pub type ResolveSourceCallback<'a> = extern "C" fn(
|
||||
*mut *const Object,
|
||||
Local<'a, Context>,
|
||||
Local<'a, String>,
|
||||
Local<'a, FixedArray>,
|
||||
Local<'a, Module>,
|
||||
) -> *mut *const Object;
|
||||
|
||||
impl<'a, F> MapFnFrom<F> for ResolveSourceCallback<'a>
|
||||
where
|
||||
F: UnitType
|
||||
+ Fn(
|
||||
Local<'a, Context>,
|
||||
Local<'a, String>,
|
||||
Local<'a, FixedArray>,
|
||||
Local<'a, Module>,
|
||||
) -> Option<Local<'a, Object>>,
|
||||
{
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn mapping() -> Self {
|
||||
let f = |context, specifier, import_attributes, referrer| {
|
||||
ResolveSourceCallbackRet(
|
||||
(F::get())(context, specifier, import_attributes, referrer)
|
||||
.map(|r| -> *const Object { &*r })
|
||||
.unwrap_or(null()),
|
||||
)
|
||||
};
|
||||
f.to_c_fn()
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn mapping() -> Self {
|
||||
let f = |ret_ptr, context, specifier, import_attributes, referrer| {
|
||||
let r = (F::get())(context, specifier, import_attributes, referrer)
|
||||
.map(|r| -> *const Object { &*r })
|
||||
.unwrap_or(null());
|
||||
unsafe { std::ptr::write(ret_ptr, r) }; // Write result to stack.
|
||||
ret_ptr // Return stack pointer to the return value.
|
||||
};
|
||||
f.to_c_fn()
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn v8__Module__GetStatus(this: *const Module) -> ModuleStatus;
|
||||
fn v8__Module__GetException(this: *const Module) -> *const Value;
|
||||
|
@ -162,6 +221,7 @@ extern "C" {
|
|||
this: *const Module,
|
||||
context: *const Context,
|
||||
cb: ResolveModuleCallback,
|
||||
source_callback: Option<ResolveSourceCallback>,
|
||||
) -> MaybeBool;
|
||||
fn v8__Module__Evaluate(
|
||||
this: *const Module,
|
||||
|
@ -323,6 +383,31 @@ impl Module {
|
|||
self,
|
||||
&*scope.get_current_context(),
|
||||
callback.map_fn_to(),
|
||||
None,
|
||||
)
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Instantiates the module and its dependencies.
|
||||
///
|
||||
/// Returns an empty Maybe<bool> if an exception occurred during
|
||||
/// instantiation. (In the case where the callback throws an exception, that
|
||||
/// exception is propagated.)
|
||||
#[must_use]
|
||||
#[inline(always)]
|
||||
pub fn instantiate_module2<'a>(
|
||||
&self,
|
||||
scope: &mut HandleScope,
|
||||
callback: impl MapFnTo<ResolveModuleCallback<'a>>,
|
||||
source_callback: impl MapFnTo<ResolveSourceCallback<'a>>,
|
||||
) -> Option<bool> {
|
||||
unsafe {
|
||||
v8__Module__InstantiateModule(
|
||||
self,
|
||||
&*scope.get_current_context(),
|
||||
callback.map_fn_to(),
|
||||
Some(source_callback.map_fn_to()),
|
||||
)
|
||||
}
|
||||
.into()
|
||||
|
|
|
@ -51,7 +51,7 @@ mod setup {
|
|||
))
|
||||
.is_ok());
|
||||
v8::V8::set_flags_from_string(
|
||||
"--no_freeze_flags_after_init --expose_gc --harmony-shadow-realm --allow_natives_syntax --turbo_fast_api_calls",
|
||||
"--no_freeze_flags_after_init --expose_gc --harmony-shadow-realm --allow_natives_syntax --turbo_fast_api_calls --js-source-phase-imports",
|
||||
);
|
||||
v8::V8::initialize_platform(
|
||||
v8::new_unprotected_default_platform(0, false).make_shared(),
|
||||
|
@ -7755,6 +7755,52 @@ fn synthetic_module() {
|
|||
check("b", 2.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn static_source_phase_import() {
|
||||
let _setup_guard = setup::parallel_test();
|
||||
let isolate = &mut v8::Isolate::new(Default::default());
|
||||
|
||||
let scope = &mut v8::HandleScope::new(isolate);
|
||||
|
||||
let context = v8::Context::new(scope, Default::default());
|
||||
let scope = &mut v8::ContextScope::new(scope, context);
|
||||
|
||||
let module = create_module(
|
||||
scope,
|
||||
"import source mod from 'z'; export default mod;",
|
||||
None,
|
||||
v8::script_compiler::CompileOptions::NoCompileOptions,
|
||||
);
|
||||
|
||||
let obj = eval(scope, "new WebAssembly.Module(new Uint8Array([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]))").unwrap().cast::<v8::Object>();
|
||||
|
||||
context.set_slot(v8::Global::new(scope, obj));
|
||||
|
||||
fn resolve_source<'a>(
|
||||
context: v8::Local<'a, v8::Context>,
|
||||
_specifier: v8::Local<'a, v8::String>,
|
||||
_import_attributes: v8::Local<'a, v8::FixedArray>,
|
||||
_referrer: v8::Local<'a, v8::Module>,
|
||||
) -> Option<v8::Local<'a, v8::Object>> {
|
||||
let scope = unsafe { &mut v8::CallbackScope::new(context) };
|
||||
let global = context.get_slot::<v8::Global<v8::Object>>().unwrap();
|
||||
Some(v8::Local::new(scope, global))
|
||||
}
|
||||
|
||||
module
|
||||
.instantiate_module2(
|
||||
scope,
|
||||
unexpected_module_resolve_callback,
|
||||
resolve_source,
|
||||
)
|
||||
.unwrap();
|
||||
module.evaluate(scope).unwrap();
|
||||
|
||||
let ns = module.get_module_namespace().cast::<v8::Object>();
|
||||
let default = v8::String::new(scope, "default").unwrap();
|
||||
assert_eq!(obj, ns.get(scope, default.into()).unwrap());
|
||||
}
|
||||
|
||||
#[allow(clippy::float_cmp)]
|
||||
#[test]
|
||||
fn date() {
|
||||
|
|
Loading…
Add table
Reference in a new issue