summaryrefslogtreecommitdiff
path: root/core/bindings.rs
diff options
context:
space:
mode:
Diffstat (limited to 'core/bindings.rs')
-rw-r--r--core/bindings.rs158
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)
};