fix(core): let V8 drive extension ESM loads (#18997)

This now allows circular imports across extensions.

Instead of load + eval of all ESM files in declaration order, all files
are only loaded. Eval is done recursively by V8, only evaluating
files that are listed in `Extension::esm_entry_point` fields.

---------

Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
This commit is contained in:
Luca Casonato 2023-05-09 12:37:13 +02:00 committed by GitHub
parent 723d4b0382
commit f34fcd16ea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 640 additions and 605 deletions

View file

@ -309,9 +309,11 @@ mod ts {
// deps = [runtime]
deno_core::extension!(
cli,
esm_entry_point = "ext:cli/99_main.js",
esm = [
dir "js",
"40_testing.js"
"40_testing.js",
"99_main.js"
],
customizer = |ext: &mut deno_core::ExtensionBuilder| {
ext.esm(vec![ExtensionFileSource {

3
cli/js/99_main.js Normal file
View file

@ -0,0 +1,3 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
import "ext:cli/40_testing.js";
import "ext:cli/runtime/js/99_main.js";

View file

@ -1093,6 +1093,28 @@ impl ModuleMap {
output
}
pub(crate) fn assert_all_modules_evaluated(
&self,
scope: &mut v8::HandleScope,
) {
let mut not_evaluated = vec![];
for (i, handle) in self.handles.iter().enumerate() {
let module = v8::Local::new(scope, handle);
if !matches!(module.get_status(), v8::ModuleStatus::Evaluated) {
not_evaluated.push(self.info[i].name.as_str().to_string());
}
}
if !not_evaluated.is_empty() {
let mut msg = "Following modules were not evaluated; make sure they are imported from other code:\n".to_string();
for m in not_evaluated {
msg.push_str(&format!(" - {}\n", m));
}
panic!("{}", msg);
}
}
pub fn serialize_for_snapshotting(
&self,
scope: &mut v8::HandleScope,
@ -1366,7 +1388,7 @@ impl ModuleMap {
/// Get module id, following all aliases in case of module specifier
/// that had been redirected.
fn get_id(
pub(crate) fn get_id(
&self,
name: impl AsRef<str>,
asserted_module_type: AssertedModuleType,

View file

@ -8,6 +8,7 @@ use crate::extensions::OpDecl;
use crate::extensions::OpEventLoopFn;
use crate::inspector::JsRuntimeInspector;
use crate::module_specifier::ModuleSpecifier;
use crate::modules::AssertedModuleType;
use crate::modules::ExtModuleLoaderCb;
use crate::modules::ModuleCode;
use crate::modules::ModuleError;
@ -23,7 +24,6 @@ use crate::snapshot_util;
use crate::source_map::SourceMapCache;
use crate::source_map::SourceMapGetter;
use crate::Extension;
use crate::ExtensionFileSource;
use crate::NoopModuleLoader;
use crate::OpMiddlewareFn;
use crate::OpResult;
@ -687,46 +687,49 @@ impl JsRuntime {
module_map
}
/// Initializes JS of provided Extensions in the given realm
/// Initializes JS of provided Extensions in the given realm.
fn init_extension_js(&mut self, realm: &JsRealm) -> Result<(), Error> {
fn load_and_evaluate_module(
runtime: &mut JsRuntime,
file_source: &ExtensionFileSource,
) -> Result<(), Error> {
futures::executor::block_on(async {
let id = runtime
.load_side_module(
&ModuleSpecifier::parse(file_source.specifier)?,
None,
)
.await?;
let receiver = runtime.mod_evaluate(id);
runtime.run_event_loop(false).await?;
receiver.await?
})
.with_context(|| format!("Couldn't execute '{}'", file_source.specifier))
}
// Initalization of JS happens in phases:
// 1. Iterate through all extensions:
// a. Execute all extension "script" JS files
// b. Load all extension "module" JS files (but do not execute them yet)
// 2. Iterate through all extensions:
// a. If an extension has a `esm_entry_point`, execute it.
let mut esm_entrypoints = vec![];
// Take extensions to avoid double-borrow
let extensions = std::mem::take(&mut self.extensions);
for ext in extensions.borrow().iter() {
{
if let Some(esm_files) = ext.get_esm_sources() {
if let Some(entry_point) = ext.get_esm_entry_point() {
let file_source = esm_files
.iter()
.find(|file| file.specifier == entry_point)
.unwrap();
load_and_evaluate_module(self, file_source)?;
} else {
for file_source in esm_files {
load_and_evaluate_module(self, file_source)?;
}
futures::executor::block_on(async {
let num_of_extensions = extensions.borrow().len();
for i in 0..num_of_extensions {
let (maybe_esm_files, maybe_esm_entry_point) = {
let exts = extensions.borrow();
(
exts[i].get_esm_sources().map(|e| e.to_owned()),
exts[i].get_esm_entry_point(),
)
};
if let Some(esm_files) = maybe_esm_files {
for file_source in esm_files {
self
.load_side_module(
&ModuleSpecifier::parse(file_source.specifier)?,
None,
)
.await?;
}
}
}
{
if let Some(entry_point) = maybe_esm_entry_point {
esm_entrypoints.push(entry_point);
}
let exts = extensions.borrow();
let ext = &exts[i];
if let Some(js_files) = ext.get_js_sources() {
for file_source in js_files {
realm.execute_script(
@ -736,14 +739,41 @@ impl JsRuntime {
)?;
}
}
if ext.is_core {
self.init_cbs(realm);
}
}
// TODO(bartlomieju): this not great that we need to have this conditional
// here, but I haven't found a better way to do it yet.
if ext.is_core {
self.init_cbs(realm);
for specifier in esm_entrypoints {
let mod_id = {
let module_map = self.module_map.as_ref().unwrap();
module_map
.borrow()
.get_id(specifier, AssertedModuleType::JavaScriptOrWasm)
.unwrap_or_else(|| {
panic!("{} not present in the module map", specifier)
})
};
let receiver = self.mod_evaluate(mod_id);
self.run_event_loop(false).await?;
receiver
.await?
.with_context(|| format!("Couldn't execute '{specifier}'"))?;
}
}
#[cfg(debug_assertions)]
{
let module_map_rc = self.module_map.clone().unwrap();
let mut scope = realm.handle_scope(self.v8_isolate());
let module_map = module_map_rc.borrow();
module_map.assert_all_modules_evaluated(&mut scope);
}
Ok::<_, anyhow::Error>(())
})?;
// Restore extensions
self.extensions = extensions;

View file

@ -4734,4 +4734,506 @@ webidl.configurePrototype(Crypto);
const CryptoPrototype = Crypto.prototype;
const crypto = webidl.createBranded(Crypto);
webidl.converters.AlgorithmIdentifier = (V, prefix, context, opts) => {
// Union for (object or DOMString)
if (webidl.type(V) == "Object") {
return webidl.converters.object(V, prefix, context, opts);
}
return webidl.converters.DOMString(V, prefix, context, opts);
};
webidl.converters["BufferSource or JsonWebKey"] = (
V,
prefix,
context,
opts,
) => {
// Union for (BufferSource or JsonWebKey)
if (
ArrayBufferIsView(V) ||
ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, V)
) {
return webidl.converters.BufferSource(V, prefix, context, opts);
}
return webidl.converters.JsonWebKey(V, prefix, context, opts);
};
webidl.converters.KeyType = webidl.createEnumConverter("KeyType", [
"public",
"private",
"secret",
]);
webidl.converters.KeyFormat = webidl.createEnumConverter("KeyFormat", [
"raw",
"pkcs8",
"spki",
"jwk",
]);
webidl.converters.KeyUsage = webidl.createEnumConverter("KeyUsage", [
"encrypt",
"decrypt",
"sign",
"verify",
"deriveKey",
"deriveBits",
"wrapKey",
"unwrapKey",
]);
webidl.converters["sequence<KeyUsage>"] = webidl.createSequenceConverter(
webidl.converters.KeyUsage,
);
webidl.converters.HashAlgorithmIdentifier =
webidl.converters.AlgorithmIdentifier;
/** @type {webidl.Dictionary} */
const dictAlgorithm = [{
key: "name",
converter: webidl.converters.DOMString,
required: true,
}];
webidl.converters.Algorithm = webidl
.createDictionaryConverter("Algorithm", dictAlgorithm);
webidl.converters.BigInteger = webidl.converters.Uint8Array;
/** @type {webidl.Dictionary} */
const dictRsaKeyGenParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "modulusLength",
converter: (V, prefix, context, opts) =>
webidl.converters["unsigned long"](V, prefix, context, {
...opts,
enforceRange: true,
}),
required: true,
},
{
key: "publicExponent",
converter: webidl.converters.BigInteger,
required: true,
},
];
webidl.converters.RsaKeyGenParams = webidl
.createDictionaryConverter("RsaKeyGenParams", dictRsaKeyGenParams);
const dictRsaHashedKeyGenParams = [
...new SafeArrayIterator(dictRsaKeyGenParams),
{
key: "hash",
converter: webidl.converters.HashAlgorithmIdentifier,
required: true,
},
];
webidl.converters.RsaHashedKeyGenParams = webidl.createDictionaryConverter(
"RsaHashedKeyGenParams",
dictRsaHashedKeyGenParams,
);
const dictRsaHashedImportParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "hash",
converter: webidl.converters.HashAlgorithmIdentifier,
required: true,
},
];
webidl.converters.RsaHashedImportParams = webidl.createDictionaryConverter(
"RsaHashedImportParams",
dictRsaHashedImportParams,
);
webidl.converters.NamedCurve = webidl.converters.DOMString;
const dictEcKeyImportParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "namedCurve",
converter: webidl.converters.NamedCurve,
required: true,
},
];
webidl.converters.EcKeyImportParams = webidl.createDictionaryConverter(
"EcKeyImportParams",
dictEcKeyImportParams,
);
const dictEcKeyGenParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "namedCurve",
converter: webidl.converters.NamedCurve,
required: true,
},
];
webidl.converters.EcKeyGenParams = webidl
.createDictionaryConverter("EcKeyGenParams", dictEcKeyGenParams);
const dictAesKeyGenParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "length",
converter: (V, prefix, context, opts) =>
webidl.converters["unsigned short"](V, prefix, context, {
...opts,
enforceRange: true,
}),
required: true,
},
];
webidl.converters.AesKeyGenParams = webidl
.createDictionaryConverter("AesKeyGenParams", dictAesKeyGenParams);
const dictHmacKeyGenParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "hash",
converter: webidl.converters.HashAlgorithmIdentifier,
required: true,
},
{
key: "length",
converter: (V, prefix, context, opts) =>
webidl.converters["unsigned long"](V, prefix, context, {
...opts,
enforceRange: true,
}),
},
];
webidl.converters.HmacKeyGenParams = webidl
.createDictionaryConverter("HmacKeyGenParams", dictHmacKeyGenParams);
const dictRsaPssParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "saltLength",
converter: (V, prefix, context, opts) =>
webidl.converters["unsigned long"](V, prefix, context, {
...opts,
enforceRange: true,
}),
required: true,
},
];
webidl.converters.RsaPssParams = webidl
.createDictionaryConverter("RsaPssParams", dictRsaPssParams);
const dictRsaOaepParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "label",
converter: webidl.converters["BufferSource"],
},
];
webidl.converters.RsaOaepParams = webidl
.createDictionaryConverter("RsaOaepParams", dictRsaOaepParams);
const dictEcdsaParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "hash",
converter: webidl.converters.HashAlgorithmIdentifier,
required: true,
},
];
webidl.converters["EcdsaParams"] = webidl
.createDictionaryConverter("EcdsaParams", dictEcdsaParams);
const dictHmacImportParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "hash",
converter: webidl.converters.HashAlgorithmIdentifier,
required: true,
},
{
key: "length",
converter: (V, prefix, context, opts) =>
webidl.converters["unsigned long"](V, prefix, context, {
...opts,
enforceRange: true,
}),
},
];
webidl.converters.HmacImportParams = webidl
.createDictionaryConverter("HmacImportParams", dictHmacImportParams);
const dictRsaOtherPrimesInfo = [
{
key: "r",
converter: webidl.converters["DOMString"],
},
{
key: "d",
converter: webidl.converters["DOMString"],
},
{
key: "t",
converter: webidl.converters["DOMString"],
},
];
webidl.converters.RsaOtherPrimesInfo = webidl.createDictionaryConverter(
"RsaOtherPrimesInfo",
dictRsaOtherPrimesInfo,
);
webidl.converters["sequence<RsaOtherPrimesInfo>"] = webidl
.createSequenceConverter(
webidl.converters.RsaOtherPrimesInfo,
);
const dictJsonWebKey = [
// Sections 4.2 and 4.3 of RFC7517.
// https://datatracker.ietf.org/doc/html/rfc7517#section-4
{
key: "kty",
converter: webidl.converters["DOMString"],
},
{
key: "use",
converter: webidl.converters["DOMString"],
},
{
key: "key_ops",
converter: webidl.converters["sequence<DOMString>"],
},
{
key: "alg",
converter: webidl.converters["DOMString"],
},
// JSON Web Key Parameters Registration
{
key: "ext",
converter: webidl.converters["boolean"],
},
// Section 6 of RFC7518 JSON Web Algorithms
// https://datatracker.ietf.org/doc/html/rfc7518#section-6
{
key: "crv",
converter: webidl.converters["DOMString"],
},
{
key: "x",
converter: webidl.converters["DOMString"],
},
{
key: "y",
converter: webidl.converters["DOMString"],
},
{
key: "d",
converter: webidl.converters["DOMString"],
},
{
key: "n",
converter: webidl.converters["DOMString"],
},
{
key: "e",
converter: webidl.converters["DOMString"],
},
{
key: "p",
converter: webidl.converters["DOMString"],
},
{
key: "q",
converter: webidl.converters["DOMString"],
},
{
key: "dp",
converter: webidl.converters["DOMString"],
},
{
key: "dq",
converter: webidl.converters["DOMString"],
},
{
key: "qi",
converter: webidl.converters["DOMString"],
},
{
key: "oth",
converter: webidl.converters["sequence<RsaOtherPrimesInfo>"],
},
{
key: "k",
converter: webidl.converters["DOMString"],
},
];
webidl.converters.JsonWebKey = webidl.createDictionaryConverter(
"JsonWebKey",
dictJsonWebKey,
);
const dictHkdfParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "hash",
converter: webidl.converters.HashAlgorithmIdentifier,
required: true,
},
{
key: "salt",
converter: webidl.converters["BufferSource"],
required: true,
},
{
key: "info",
converter: webidl.converters["BufferSource"],
required: true,
},
];
webidl.converters.HkdfParams = webidl
.createDictionaryConverter("HkdfParams", dictHkdfParams);
const dictPbkdf2Params = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "hash",
converter: webidl.converters.HashAlgorithmIdentifier,
required: true,
},
{
key: "iterations",
converter: (V, prefix, context, opts) =>
webidl.converters["unsigned long"](V, prefix, context, {
...opts,
enforceRange: true,
}),
required: true,
},
{
key: "salt",
converter: webidl.converters["BufferSource"],
required: true,
},
];
webidl.converters.Pbkdf2Params = webidl
.createDictionaryConverter("Pbkdf2Params", dictPbkdf2Params);
const dictAesDerivedKeyParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "length",
converter: (V, prefix, context, opts) =>
webidl.converters["unsigned long"](V, prefix, context, {
...opts,
enforceRange: true,
}),
required: true,
},
];
const dictAesCbcParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "iv",
converter: webidl.converters["BufferSource"],
required: true,
},
];
const dictAesGcmParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "iv",
converter: webidl.converters["BufferSource"],
required: true,
},
{
key: "tagLength",
converter: (V, prefix, context, opts) =>
webidl.converters["unsigned long"](V, prefix, context, {
...opts,
enforceRange: true,
}),
},
{
key: "additionalData",
converter: webidl.converters["BufferSource"],
},
];
const dictAesCtrParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "counter",
converter: webidl.converters["BufferSource"],
required: true,
},
{
key: "length",
converter: (V, prefix, context, opts) =>
webidl.converters["unsigned short"](V, prefix, context, {
...opts,
enforceRange: true,
}),
required: true,
},
];
webidl.converters.AesDerivedKeyParams = webidl
.createDictionaryConverter("AesDerivedKeyParams", dictAesDerivedKeyParams);
webidl.converters.AesCbcParams = webidl
.createDictionaryConverter("AesCbcParams", dictAesCbcParams);
webidl.converters.AesGcmParams = webidl
.createDictionaryConverter("AesGcmParams", dictAesGcmParams);
webidl.converters.AesCtrParams = webidl
.createDictionaryConverter("AesCtrParams", dictAesCtrParams);
webidl.converters.CryptoKey = webidl.createInterfaceConverter(
"CryptoKey",
CryptoKey.prototype,
);
const dictCryptoKeyPair = [
{
key: "publicKey",
converter: webidl.converters.CryptoKey,
},
{
key: "privateKey",
converter: webidl.converters.CryptoKey,
},
];
webidl.converters.CryptoKeyPair = webidl
.createDictionaryConverter("CryptoKeyPair", dictCryptoKeyPair);
const dictEcdhKeyDeriveParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "public",
converter: webidl.converters.CryptoKey,
required: true,
},
];
webidl.converters.EcdhKeyDeriveParams = webidl
.createDictionaryConverter("EcdhKeyDeriveParams", dictEcdhKeyDeriveParams);
export { Crypto, crypto, CryptoKey, SubtleCrypto };

View file

@ -1,516 +0,0 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
// @ts-check
/// <reference path="../../core/lib.deno_core.d.ts" />
/// <reference path="../webidl/internal.d.ts" />
const primordials = globalThis.__bootstrap.primordials;
import * as webidl from "ext:deno_webidl/00_webidl.js";
import { CryptoKey } from "ext:deno_crypto/00_crypto.js";
const {
ArrayBufferIsView,
ArrayBufferPrototype,
ObjectPrototypeIsPrototypeOf,
SafeArrayIterator,
} = primordials;
webidl.converters.AlgorithmIdentifier = (V, prefix, context, opts) => {
// Union for (object or DOMString)
if (webidl.type(V) == "Object") {
return webidl.converters.object(V, prefix, context, opts);
}
return webidl.converters.DOMString(V, prefix, context, opts);
};
webidl.converters["BufferSource or JsonWebKey"] = (
V,
prefix,
context,
opts,
) => {
// Union for (BufferSource or JsonWebKey)
if (
ArrayBufferIsView(V) ||
ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, V)
) {
return webidl.converters.BufferSource(V, prefix, context, opts);
}
return webidl.converters.JsonWebKey(V, prefix, context, opts);
};
webidl.converters.KeyType = webidl.createEnumConverter("KeyType", [
"public",
"private",
"secret",
]);
webidl.converters.KeyFormat = webidl.createEnumConverter("KeyFormat", [
"raw",
"pkcs8",
"spki",
"jwk",
]);
webidl.converters.KeyUsage = webidl.createEnumConverter("KeyUsage", [
"encrypt",
"decrypt",
"sign",
"verify",
"deriveKey",
"deriveBits",
"wrapKey",
"unwrapKey",
]);
webidl.converters["sequence<KeyUsage>"] = webidl.createSequenceConverter(
webidl.converters.KeyUsage,
);
webidl.converters.HashAlgorithmIdentifier =
webidl.converters.AlgorithmIdentifier;
/** @type {webidl.Dictionary} */
const dictAlgorithm = [{
key: "name",
converter: webidl.converters.DOMString,
required: true,
}];
webidl.converters.Algorithm = webidl
.createDictionaryConverter("Algorithm", dictAlgorithm);
webidl.converters.BigInteger = webidl.converters.Uint8Array;
/** @type {webidl.Dictionary} */
const dictRsaKeyGenParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "modulusLength",
converter: (V, prefix, context, opts) =>
webidl.converters["unsigned long"](V, prefix, context, {
...opts,
enforceRange: true,
}),
required: true,
},
{
key: "publicExponent",
converter: webidl.converters.BigInteger,
required: true,
},
];
webidl.converters.RsaKeyGenParams = webidl
.createDictionaryConverter("RsaKeyGenParams", dictRsaKeyGenParams);
const dictRsaHashedKeyGenParams = [
...new SafeArrayIterator(dictRsaKeyGenParams),
{
key: "hash",
converter: webidl.converters.HashAlgorithmIdentifier,
required: true,
},
];
webidl.converters.RsaHashedKeyGenParams = webidl.createDictionaryConverter(
"RsaHashedKeyGenParams",
dictRsaHashedKeyGenParams,
);
const dictRsaHashedImportParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "hash",
converter: webidl.converters.HashAlgorithmIdentifier,
required: true,
},
];
webidl.converters.RsaHashedImportParams = webidl.createDictionaryConverter(
"RsaHashedImportParams",
dictRsaHashedImportParams,
);
webidl.converters.NamedCurve = webidl.converters.DOMString;
const dictEcKeyImportParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "namedCurve",
converter: webidl.converters.NamedCurve,
required: true,
},
];
webidl.converters.EcKeyImportParams = webidl.createDictionaryConverter(
"EcKeyImportParams",
dictEcKeyImportParams,
);
const dictEcKeyGenParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "namedCurve",
converter: webidl.converters.NamedCurve,
required: true,
},
];
webidl.converters.EcKeyGenParams = webidl
.createDictionaryConverter("EcKeyGenParams", dictEcKeyGenParams);
const dictAesKeyGenParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "length",
converter: (V, prefix, context, opts) =>
webidl.converters["unsigned short"](V, prefix, context, {
...opts,
enforceRange: true,
}),
required: true,
},
];
webidl.converters.AesKeyGenParams = webidl
.createDictionaryConverter("AesKeyGenParams", dictAesKeyGenParams);
const dictHmacKeyGenParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "hash",
converter: webidl.converters.HashAlgorithmIdentifier,
required: true,
},
{
key: "length",
converter: (V, prefix, context, opts) =>
webidl.converters["unsigned long"](V, prefix, context, {
...opts,
enforceRange: true,
}),
},
];
webidl.converters.HmacKeyGenParams = webidl
.createDictionaryConverter("HmacKeyGenParams", dictHmacKeyGenParams);
const dictRsaPssParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "saltLength",
converter: (V, prefix, context, opts) =>
webidl.converters["unsigned long"](V, prefix, context, {
...opts,
enforceRange: true,
}),
required: true,
},
];
webidl.converters.RsaPssParams = webidl
.createDictionaryConverter("RsaPssParams", dictRsaPssParams);
const dictRsaOaepParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "label",
converter: webidl.converters["BufferSource"],
},
];
webidl.converters.RsaOaepParams = webidl
.createDictionaryConverter("RsaOaepParams", dictRsaOaepParams);
const dictEcdsaParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "hash",
converter: webidl.converters.HashAlgorithmIdentifier,
required: true,
},
];
webidl.converters["EcdsaParams"] = webidl
.createDictionaryConverter("EcdsaParams", dictEcdsaParams);
const dictHmacImportParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "hash",
converter: webidl.converters.HashAlgorithmIdentifier,
required: true,
},
{
key: "length",
converter: (V, prefix, context, opts) =>
webidl.converters["unsigned long"](V, prefix, context, {
...opts,
enforceRange: true,
}),
},
];
webidl.converters.HmacImportParams = webidl
.createDictionaryConverter("HmacImportParams", dictHmacImportParams);
const dictRsaOtherPrimesInfo = [
{
key: "r",
converter: webidl.converters["DOMString"],
},
{
key: "d",
converter: webidl.converters["DOMString"],
},
{
key: "t",
converter: webidl.converters["DOMString"],
},
];
webidl.converters.RsaOtherPrimesInfo = webidl.createDictionaryConverter(
"RsaOtherPrimesInfo",
dictRsaOtherPrimesInfo,
);
webidl.converters["sequence<RsaOtherPrimesInfo>"] = webidl
.createSequenceConverter(
webidl.converters.RsaOtherPrimesInfo,
);
const dictJsonWebKey = [
// Sections 4.2 and 4.3 of RFC7517.
// https://datatracker.ietf.org/doc/html/rfc7517#section-4
{
key: "kty",
converter: webidl.converters["DOMString"],
},
{
key: "use",
converter: webidl.converters["DOMString"],
},
{
key: "key_ops",
converter: webidl.converters["sequence<DOMString>"],
},
{
key: "alg",
converter: webidl.converters["DOMString"],
},
// JSON Web Key Parameters Registration
{
key: "ext",
converter: webidl.converters["boolean"],
},
// Section 6 of RFC7518 JSON Web Algorithms
// https://datatracker.ietf.org/doc/html/rfc7518#section-6
{
key: "crv",
converter: webidl.converters["DOMString"],
},
{
key: "x",
converter: webidl.converters["DOMString"],
},
{
key: "y",
converter: webidl.converters["DOMString"],
},
{
key: "d",
converter: webidl.converters["DOMString"],
},
{
key: "n",
converter: webidl.converters["DOMString"],
},
{
key: "e",
converter: webidl.converters["DOMString"],
},
{
key: "p",
converter: webidl.converters["DOMString"],
},
{
key: "q",
converter: webidl.converters["DOMString"],
},
{
key: "dp",
converter: webidl.converters["DOMString"],
},
{
key: "dq",
converter: webidl.converters["DOMString"],
},
{
key: "qi",
converter: webidl.converters["DOMString"],
},
{
key: "oth",
converter: webidl.converters["sequence<RsaOtherPrimesInfo>"],
},
{
key: "k",
converter: webidl.converters["DOMString"],
},
];
webidl.converters.JsonWebKey = webidl.createDictionaryConverter(
"JsonWebKey",
dictJsonWebKey,
);
const dictHkdfParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "hash",
converter: webidl.converters.HashAlgorithmIdentifier,
required: true,
},
{
key: "salt",
converter: webidl.converters["BufferSource"],
required: true,
},
{
key: "info",
converter: webidl.converters["BufferSource"],
required: true,
},
];
webidl.converters.HkdfParams = webidl
.createDictionaryConverter("HkdfParams", dictHkdfParams);
const dictPbkdf2Params = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "hash",
converter: webidl.converters.HashAlgorithmIdentifier,
required: true,
},
{
key: "iterations",
converter: (V, prefix, context, opts) =>
webidl.converters["unsigned long"](V, prefix, context, {
...opts,
enforceRange: true,
}),
required: true,
},
{
key: "salt",
converter: webidl.converters["BufferSource"],
required: true,
},
];
webidl.converters.Pbkdf2Params = webidl
.createDictionaryConverter("Pbkdf2Params", dictPbkdf2Params);
const dictAesDerivedKeyParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "length",
converter: (V, prefix, context, opts) =>
webidl.converters["unsigned long"](V, prefix, context, {
...opts,
enforceRange: true,
}),
required: true,
},
];
const dictAesCbcParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "iv",
converter: webidl.converters["BufferSource"],
required: true,
},
];
const dictAesGcmParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "iv",
converter: webidl.converters["BufferSource"],
required: true,
},
{
key: "tagLength",
converter: (V, prefix, context, opts) =>
webidl.converters["unsigned long"](V, prefix, context, {
...opts,
enforceRange: true,
}),
},
{
key: "additionalData",
converter: webidl.converters["BufferSource"],
},
];
const dictAesCtrParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "counter",
converter: webidl.converters["BufferSource"],
required: true,
},
{
key: "length",
converter: (V, prefix, context, opts) =>
webidl.converters["unsigned short"](V, prefix, context, {
...opts,
enforceRange: true,
}),
required: true,
},
];
webidl.converters.AesDerivedKeyParams = webidl
.createDictionaryConverter("AesDerivedKeyParams", dictAesDerivedKeyParams);
webidl.converters.AesCbcParams = webidl
.createDictionaryConverter("AesCbcParams", dictAesCbcParams);
webidl.converters.AesGcmParams = webidl
.createDictionaryConverter("AesGcmParams", dictAesGcmParams);
webidl.converters.AesCtrParams = webidl
.createDictionaryConverter("AesCtrParams", dictAesCtrParams);
webidl.converters.CryptoKey = webidl.createInterfaceConverter(
"CryptoKey",
CryptoKey.prototype,
);
const dictCryptoKeyPair = [
{
key: "publicKey",
converter: webidl.converters.CryptoKey,
},
{
key: "privateKey",
converter: webidl.converters.CryptoKey,
},
];
webidl.converters.CryptoKeyPair = webidl
.createDictionaryConverter("CryptoKeyPair", dictCryptoKeyPair);
const dictEcdhKeyDeriveParams = [
...new SafeArrayIterator(dictAlgorithm),
{
key: "public",
converter: webidl.converters.CryptoKey,
required: true,
},
];
webidl.converters.EcdhKeyDeriveParams = webidl
.createDictionaryConverter("EcdhKeyDeriveParams", dictEcdhKeyDeriveParams);

View file

@ -103,7 +103,7 @@ deno_core::extension!(deno_crypto,
x25519::op_crypto_export_spki_x25519,
x25519::op_crypto_export_pkcs8_x25519,
],
esm = [ "00_crypto.js", "01_webidl.js" ],
esm = [ "00_crypto.js" ],
options = {
maybe_seed: Option<u64>,
},

View file

@ -14,6 +14,7 @@ const core = globalThis.Deno.core;
const ops = core.ops;
import * as webidl from "ext:deno_webidl/00_webidl.js";
import { ReadableStream } from "ext:deno_web/06_streams.js";
import { URL } from "ext:deno_url/00_url.js";
const primordials = globalThis.__bootstrap.primordials;
const {
ArrayBufferPrototype,
@ -653,6 +654,33 @@ function blobFromObjectUrl(url) {
return blob;
}
/**
* @param {Blob} blob
* @returns {string}
*/
function createObjectURL(blob) {
const prefix = "Failed to execute 'createObjectURL' on 'URL'";
webidl.requiredArguments(arguments.length, 1, prefix);
blob = webidl.converters["Blob"](blob, prefix, "Argument 1");
return ops.op_blob_create_object_url(blob.type, getParts(blob));
}
/**
* @param {string} url
* @returns {void}
*/
function revokeObjectURL(url) {
const prefix = "Failed to execute 'revokeObjectURL' on 'URL'";
webidl.requiredArguments(arguments.length, 1, prefix);
url = webidl.converters["DOMString"](url, prefix, "Argument 1");
ops.op_blob_revoke_object_url(url);
}
URL.createObjectURL = createObjectURL;
URL.revokeObjectURL = revokeObjectURL;
export {
Blob,
blobFromObjectUrl,

View file

@ -1,45 +0,0 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
// @ts-check
/// <reference no-default-lib="true" />
/// <reference path="../../core/lib.deno_core.d.ts" />
/// <reference path="../webidl/internal.d.ts" />
/// <reference path="../web/internal.d.ts" />
/// <reference path="../web/lib.deno_web.d.ts" />
/// <reference path="../url/internal.d.ts" />
/// <reference path="../url/lib.deno_url.d.ts" />
/// <reference path="./internal.d.ts" />
/// <reference lib="esnext" />
const core = globalThis.Deno.core;
const ops = core.ops;
import * as webidl from "ext:deno_webidl/00_webidl.js";
import { getParts } from "ext:deno_web/09_file.js";
import { URL } from "ext:deno_url/00_url.js";
/**
* @param {Blob} blob
* @returns {string}
*/
function createObjectURL(blob) {
const prefix = "Failed to execute 'createObjectURL' on 'URL'";
webidl.requiredArguments(arguments.length, 1, prefix);
blob = webidl.converters["Blob"](blob, prefix, "Argument 1");
return ops.op_blob_create_object_url(blob.type, getParts(blob));
}
/**
* @param {string} url
* @returns {void}
*/
function revokeObjectURL(url) {
const prefix = "Failed to execute 'revokeObjectURL' on 'URL'";
webidl.requiredArguments(arguments.length, 1, prefix);
url = webidl.converters["DOMString"](url, prefix, "Argument 1");
ops.op_blob_revoke_object_url(url);
}
URL.createObjectURL = createObjectURL;
URL.revokeObjectURL = revokeObjectURL;

View file

@ -103,7 +103,6 @@ deno_core::extension!(deno_web,
"08_text_encoding.js",
"09_file.js",
"10_filereader.js",
"11_blob_url.js",
"12_location.js",
"13_message_port.js",
"14_compression.js",

View file

@ -267,6 +267,17 @@ mod startup_snapshot {
include_str!("js/99_main.js"),
),
}]);
ext.esm_entry_point("ext:runtime_main/js/99_main.js");
}
);
#[cfg(feature = "snapshot_from_snapshot")]
deno_core::extension!(
runtime_main,
deps = [runtime],
customizer = |ext: &mut deno_core::ExtensionBuilder| {
eprintln!("I am here!!!");
ext.esm_entry_point("ext:runtime/90_deno_ns.js");
}
);
@ -315,7 +326,6 @@ mod startup_snapshot {
// FIXME(bartlomieju): these extensions are specified last, because they
// depend on `runtime`, even though it should be other way around
deno_node::deno_node::init_ops_and_esm::<Permissions>(None, fs),
#[cfg(not(feature = "snapshot_from_snapshot"))]
runtime_main::init_ops_and_esm(),
];