diff options
Diffstat (limited to 'core/bindings.rs')
-rw-r--r-- | core/bindings.rs | 158 |
1 files changed, 73 insertions, 85 deletions
diff --git a/core/bindings.rs b/core/bindings.rs index 52db40f0d..7970f9aab 100644 --- a/core/bindings.rs +++ b/core/bindings.rs @@ -19,22 +19,24 @@ use crate::snapshot_util::SnapshotOptions; use crate::JsRealm; use crate::JsRuntime; -pub(crate) fn external_references(ops: &[OpCtx]) -> v8::ExternalReferences { - // Overallocate a bit, it's better than having to resize the vector. - let mut references = Vec::with_capacity(4 + ops.len() * 4); - - references.push(v8::ExternalReference { - function: call_console.map_fn_to(), - }); - references.push(v8::ExternalReference { - function: import_meta_resolve.map_fn_to(), - }); - references.push(v8::ExternalReference { - function: catch_dynamic_import_promise_error.map_fn_to(), - }); - references.push(v8::ExternalReference { - function: empty_fn.map_fn_to(), - }); +pub(crate) fn external_references( + ops: &[OpCtx], + snapshot_options: SnapshotOptions, +) -> v8::ExternalReferences { + let mut references = vec![ + v8::ExternalReference { + function: call_console.map_fn_to(), + }, + v8::ExternalReference { + function: import_meta_resolve.map_fn_to(), + }, + v8::ExternalReference { + function: catch_dynamic_import_promise_error.map_fn_to(), + }, + v8::ExternalReference { + function: empty_fn.map_fn_to(), + }, + ]; for ctx in ops { let ctx_ptr = ctx as *const OpCtx as _; @@ -42,13 +44,12 @@ pub(crate) fn external_references(ops: &[OpCtx]) -> v8::ExternalReferences { references.push(v8::ExternalReference { function: ctx.decl.v8_fn_ptr, }); - if let Some(fast_fn) = &ctx.decl.fast_fn { - references.push(v8::ExternalReference { - pointer: fast_fn.function() as _, - }); - references.push(v8::ExternalReference { - pointer: ctx.fast_fn_c_info.unwrap().as_ptr() as _, - }); + if !snapshot_options.will_snapshot() { + if let Some(fast_fn) = &ctx.decl.fast_fn { + references.push(v8::ExternalReference { + pointer: fast_fn.function() as _, + }); + } } } @@ -113,9 +114,9 @@ pub(crate) fn initialize_context<'s>( v8::String::new_external_onebyte_static(scope, b"core").unwrap(); let ops_str = v8::String::new_external_onebyte_static(scope, b"ops").unwrap(); - let ops_obj = if snapshot_options.loaded() { - // Snapshot already registered `Deno.core.ops` but - // extensions may provide ops that aren't part of the snapshot. + // Snapshot already registered `Deno.core.ops` but + // extensions may provide ops that aren't part of the snapshot. + if snapshot_options.loaded() { // Grab the Deno.core.ops object & init it let deno_obj: v8::Local<v8::Object> = global .get(scope, deno_str.into()) @@ -132,58 +133,34 @@ pub(crate) fn initialize_context<'s>( .expect("Deno.core.ops to exist") .try_into() .unwrap(); - ops_obj - } else { - // globalThis.Deno = { core: { } }; - let deno_obj = v8::Object::new(scope); - global.set(scope, deno_str.into(), deno_obj.into()); - - let core_obj = v8::Object::new(scope); - deno_obj.set(scope, core_str.into(), core_obj.into()); - - // Bind functions to Deno.core.* - set_func(scope, core_obj, "callConsole", call_console); - - // Bind v8 console object to Deno.core.console - let extra_binding_obj = context.get_extras_binding_object(scope); - let console_str = - v8::String::new_external_onebyte_static(scope, b"console").unwrap(); - let console_obj = extra_binding_obj.get(scope, console_str.into()).unwrap(); - core_obj.set(scope, console_str.into(), console_obj); - - // Bind functions to Deno.core.ops.* - let ops_obj = v8::Object::new(scope); - core_obj.set(scope, ops_str.into(), ops_obj.into()); - ops_obj - }; - - if matches!(snapshot_options, SnapshotOptions::Load) { - // Only register ops that have `force_registration` flag set to true, - // the remaining ones should already be in the snapshot. - for op_ctx in op_ctxs - .iter() - .filter(|op_ctx| op_ctx.decl.force_registration) - { - add_op_to_deno_core_ops(scope, ops_obj, op_ctx); - } - } else if matches!(snapshot_options, SnapshotOptions::CreateFromExisting) { - // Register all ops, probing for which ones are already registered. - for op_ctx in op_ctxs { - let key = v8::String::new_external_onebyte_static( - scope, - op_ctx.decl.name.as_bytes(), - ) - .unwrap(); - if ops_obj.get(scope, key.into()).is_some() { - continue; - } - add_op_to_deno_core_ops(scope, ops_obj, op_ctx); - } - } else { - // In other cases register all ops unconditionally. - for op_ctx in op_ctxs { - add_op_to_deno_core_ops(scope, ops_obj, op_ctx); + for ctx in op_ctxs { + add_op_to_deno_core_ops(scope, ops_obj, ctx, snapshot_options); } + return context; + } + + // global.Deno = { core: { } }; + let deno_obj = v8::Object::new(scope); + global.set(scope, deno_str.into(), deno_obj.into()); + + let core_obj = v8::Object::new(scope); + deno_obj.set(scope, core_str.into(), core_obj.into()); + + // Bind functions to Deno.core.* + set_func(scope, core_obj, "callConsole", call_console); + + // Bind v8 console object to Deno.core.console + let extra_binding_obj = context.get_extras_binding_object(scope); + let console_str = + v8::String::new_external_onebyte_static(scope, b"console").unwrap(); + let console_obj = extra_binding_obj.get(scope, console_str.into()).unwrap(); + core_obj.set(scope, console_str.into(), console_obj); + + // Bind functions to Deno.core.ops.* + let ops_obj = v8::Object::new(scope); + core_obj.set(scope, ops_str.into(), ops_obj.into()); + for ctx in op_ctxs { + add_op_to_deno_core_ops(scope, ops_obj, ctx, snapshot_options); } context @@ -206,6 +183,7 @@ fn add_op_to_deno_core_ops( scope: &mut v8::HandleScope<'_>, obj: v8::Local<v8::Object>, op_ctx: &OpCtx, + snapshot_options: SnapshotOptions, ) { let op_ctx_ptr = op_ctx as *const OpCtx as *const c_void; let key = @@ -215,14 +193,24 @@ fn add_op_to_deno_core_ops( let builder = v8::FunctionTemplate::builder_raw(op_ctx.decl.v8_fn_ptr) .data(external.into()); - let templ = if let Some(fast_function) = &op_ctx.decl.fast_fn { - builder.build_fast( - scope, - &**fast_function, - Some(op_ctx.fast_fn_c_info.unwrap().as_ptr()), - None, - None, - ) + // TODO(bartlomieju): this should be cleaned up once we update Fast Calls API + // If this is a fast op, we don't want it to be in the snapshot. + // Only initialize once snapshot is loaded. + let maybe_fast_fn = + if op_ctx.decl.fast_fn.is_some() && snapshot_options.loaded() { + &op_ctx.decl.fast_fn + } else { + &None + }; + + let templ = if let Some(fast_function) = maybe_fast_fn { + // Don't initialize fast ops when snapshotting, the external references count mismatch. + if !snapshot_options.will_snapshot() { + // TODO(@littledivy): Support fast api overloads in ops. + builder.build_fast(scope, &**fast_function, None, None, None) + } else { + builder.build(scope) + } } else { builder.build(scope) }; |