diff options
Diffstat (limited to 'extensions')
-rw-r--r-- | extensions/broadcast_channel/01_broadcast_channel.js | 167 | ||||
-rw-r--r-- | extensions/broadcast_channel/Cargo.toml | 20 | ||||
-rw-r--r-- | extensions/broadcast_channel/README.md | 5 | ||||
-rw-r--r-- | extensions/broadcast_channel/in_memory_broadcast_channel.rs | 97 | ||||
-rw-r--r-- | extensions/broadcast_channel/lib.deno_broadcast_channel.d.ts | 55 | ||||
-rw-r--r-- | extensions/broadcast_channel/lib.rs | 139 | ||||
-rw-r--r-- | extensions/fetch/21_formdata.js | 30 | ||||
-rw-r--r-- | extensions/file/02_filereader.js | 4 | ||||
-rw-r--r-- | extensions/timers/Cargo.toml | 7 | ||||
-rw-r--r-- | extensions/timers/benches/timers_ops.rs | 36 | ||||
-rw-r--r-- | extensions/url/00_url.js | 8 | ||||
-rw-r--r-- | extensions/url/Cargo.toml | 2 | ||||
-rw-r--r-- | extensions/url/benches/url_ops.rs | 45 | ||||
-rw-r--r-- | extensions/web/02_event.js | 5 | ||||
-rw-r--r-- | extensions/webstorage/lib.rs | 10 |
15 files changed, 576 insertions, 54 deletions
diff --git a/extensions/broadcast_channel/01_broadcast_channel.js b/extensions/broadcast_channel/01_broadcast_channel.js new file mode 100644 index 000000000..7670b0cfd --- /dev/null +++ b/extensions/broadcast_channel/01_broadcast_channel.js @@ -0,0 +1,167 @@ +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. +"use strict"; + +((window) => { + const core = window.Deno.core; + const webidl = window.__bootstrap.webidl; + const { setTarget } = window.__bootstrap.event; + + const handlerSymbol = Symbol("eventHandlers"); + function makeWrappedHandler(handler) { + function wrappedHandler(...args) { + if (typeof wrappedHandler.handler !== "function") { + return; + } + return wrappedHandler.handler.call(this, ...args); + } + wrappedHandler.handler = handler; + return wrappedHandler; + } + // TODO(lucacasonato) reuse when we can reuse code between web crates + function defineEventHandler(emitter, name) { + // HTML specification section 8.1.5.1 + Object.defineProperty(emitter, `on${name}`, { + get() { + // TODO(bnoordhuis) The "BroadcastChannel should have an onmessage + // event" WPT test expects that .onmessage !== undefined. Returning + // null makes it pass but is perhaps not exactly in the spirit. + return this[handlerSymbol]?.get(name)?.handler ?? null; + }, + set(value) { + if (!this[handlerSymbol]) { + this[handlerSymbol] = new Map(); + } + let handlerWrapper = this[handlerSymbol]?.get(name); + if (handlerWrapper) { + handlerWrapper.handler = value; + } else { + handlerWrapper = makeWrappedHandler(value); + this.addEventListener(name, handlerWrapper); + } + this[handlerSymbol].set(name, handlerWrapper); + }, + configurable: true, + enumerable: true, + }); + } + + const _name = Symbol("[[name]]"); + const _closed = Symbol("[[closed]]"); + + const channels = []; + let rid = null; + + async function recv() { + while (channels.length > 0) { + const message = await core.opAsync("op_broadcast_recv", rid); + + if (message === null) { + break; + } + + const [name, data] = message; + dispatch(null, name, new Uint8Array(data)); + } + + core.close(rid); + rid = null; + } + + function dispatch(source, name, data) { + for (const channel of channels) { + if (channel === source) continue; // Don't self-send. + if (channel[_name] !== name) continue; + if (channel[_closed]) continue; + + const go = () => { + if (channel[_closed]) return; + const event = new MessageEvent("message", { + data: core.deserialize(data), // TODO(bnoordhuis) Cache immutables. + origin: "http://127.0.0.1", + }); + setTarget(event, channel); + channel.dispatchEvent(event); + }; + + defer(go); + } + } + + // Defer to avoid starving the event loop. Not using queueMicrotask() + // for that reason: it lets promises make forward progress but can + // still starve other parts of the event loop. + function defer(go) { + setTimeout(go, 1); + } + + class BroadcastChannel extends EventTarget { + [_name]; + [_closed] = false; + + get name() { + return this[_name]; + } + + constructor(name) { + super(); + + const prefix = "Failed to construct 'broadcastChannel'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + + this[_name] = webidl.converters["DOMString"](name, { + prefix, + context: "Argument 1", + }); + + this[webidl.brand] = webidl.brand; + + channels.push(this); + + if (rid === null) { + // Create the rid immediately, otherwise there is a time window (and a + // race condition) where messages can get lost, because recv() is async. + rid = core.opSync("op_broadcast_subscribe"); + recv(); + } + } + + postMessage(message) { + webidl.assertBranded(this, BroadcastChannel); + + const prefix = "Failed to execute 'postMessage' on 'BroadcastChannel'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + + if (this[_closed]) { + throw new DOMException("Already closed", "InvalidStateError"); + } + + if (typeof message === "function" || typeof message === "symbol") { + throw new DOMException("Uncloneable value", "DataCloneError"); + } + + const data = core.serialize(message); + + // Send to other listeners in this VM. + dispatch(this, this[_name], new Uint8Array(data)); + + // Send to listeners in other VMs. + defer(() => core.opAsync("op_broadcast_send", [rid, this[_name]], data)); + } + + close() { + webidl.assertBranded(this, BroadcastChannel); + this[_closed] = true; + + const index = channels.indexOf(this); + if (index === -1) return; + + channels.splice(index, 1); + if (channels.length === 0) core.opSync("op_broadcast_unsubscribe", rid); + } + } + + defineEventHandler(BroadcastChannel.prototype, "message"); + defineEventHandler(BroadcastChannel.prototype, "messageerror"); + + window.__bootstrap.broadcastChannel = { BroadcastChannel }; +})(this); diff --git a/extensions/broadcast_channel/Cargo.toml b/extensions/broadcast_channel/Cargo.toml new file mode 100644 index 000000000..7bc65f3a0 --- /dev/null +++ b/extensions/broadcast_channel/Cargo.toml @@ -0,0 +1,20 @@ +# Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. + +[package] +name = "deno_broadcast_channel" +version = "0.1.0" +edition = "2018" +description = "Implementation of BroadcastChannel API for Deno" +authors = ["the Deno authors"] +license = "MIT" +readme = "README.md" +repository = "https://github.com/denoland/deno" + +[lib] +path = "lib.rs" + +[dependencies] +async-trait = "0.1" +deno_core = { version = "0.88.0", path = "../../core" } +tokio = { version = "1.4.0", features = ["full"] } +uuid = { version = "0.8.2", features = ["v4"] } diff --git a/extensions/broadcast_channel/README.md b/extensions/broadcast_channel/README.md new file mode 100644 index 000000000..5b5034ef7 --- /dev/null +++ b/extensions/broadcast_channel/README.md @@ -0,0 +1,5 @@ +# deno_broadcast_channel + +This crate implements the BroadcastChannel functions of Deno. + +Spec: https://html.spec.whatwg.org/multipage/web-messaging.html diff --git a/extensions/broadcast_channel/in_memory_broadcast_channel.rs b/extensions/broadcast_channel/in_memory_broadcast_channel.rs new file mode 100644 index 000000000..34498c830 --- /dev/null +++ b/extensions/broadcast_channel/in_memory_broadcast_channel.rs @@ -0,0 +1,97 @@ +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. + +use crate::BroadcastChannel; +use async_trait::async_trait; +use deno_core::error::AnyError; +use std::sync::Arc; +use std::sync::Mutex; +use tokio::sync::broadcast; +use tokio::sync::mpsc; +use uuid::Uuid; + +#[derive(Clone)] +pub struct InMemoryBroadcastChannel(Arc<Mutex<broadcast::Sender<Message>>>); + +pub struct InMemoryBroadcastChannelResource { + rx: tokio::sync::Mutex<( + broadcast::Receiver<Message>, + mpsc::UnboundedReceiver<()>, + )>, + cancel_tx: mpsc::UnboundedSender<()>, + uuid: Uuid, +} + +#[derive(Clone, Debug)] +struct Message { + name: Arc<String>, + data: Arc<Vec<u8>>, + uuid: Uuid, +} + +impl Default for InMemoryBroadcastChannel { + fn default() -> Self { + let (tx, _) = broadcast::channel(256); + Self(Arc::new(Mutex::new(tx))) + } +} + +#[async_trait] +impl BroadcastChannel for InMemoryBroadcastChannel { + type Resource = InMemoryBroadcastChannelResource; + + fn subscribe(&self) -> Result<Self::Resource, AnyError> { + let (cancel_tx, cancel_rx) = mpsc::unbounded_channel(); + let broadcast_rx = self.0.lock().unwrap().subscribe(); + let rx = tokio::sync::Mutex::new((broadcast_rx, cancel_rx)); + let uuid = Uuid::new_v4(); + Ok(Self::Resource { + rx, + cancel_tx, + uuid, + }) + } + + fn unsubscribe(&self, resource: &Self::Resource) -> Result<(), AnyError> { + Ok(resource.cancel_tx.send(())?) + } + + async fn send( + &self, + resource: &Self::Resource, + name: String, + data: Vec<u8>, + ) -> Result<(), AnyError> { + let name = Arc::new(name); + let data = Arc::new(data); + let uuid = resource.uuid; + self.0.lock().unwrap().send(Message { name, data, uuid })?; + Ok(()) + } + + async fn recv( + &self, + resource: &Self::Resource, + ) -> Result<Option<crate::Message>, AnyError> { + let mut g = resource.rx.lock().await; + let (broadcast_rx, cancel_rx) = &mut *g; + loop { + let result = tokio::select! { + r = broadcast_rx.recv() => r, + _ = cancel_rx.recv() => return Ok(None), + }; + use tokio::sync::broadcast::error::RecvError::*; + match result { + Err(Closed) => return Ok(None), + Err(Lagged(_)) => (), // Backlogged, messages dropped. + Ok(message) if message.uuid == resource.uuid => (), // Self-send. + Ok(message) => { + let name = String::clone(&message.name); + let data = Vec::clone(&message.data); + return Ok(Some((name, data))); + } + } + } + } +} + +impl deno_core::Resource for InMemoryBroadcastChannelResource {} diff --git a/extensions/broadcast_channel/lib.deno_broadcast_channel.d.ts b/extensions/broadcast_channel/lib.deno_broadcast_channel.d.ts new file mode 100644 index 000000000..c8efef778 --- /dev/null +++ b/extensions/broadcast_channel/lib.deno_broadcast_channel.d.ts @@ -0,0 +1,55 @@ +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. + +// deno-lint-ignore-file no-explicit-any + +/// <reference no-default-lib="true" /> +/// <reference lib="esnext" /> + +interface BroadcastChannelEventMap { + "message": MessageEvent; + "messageerror": MessageEvent; +} + +interface BroadcastChannel extends EventTarget { + /** + * Returns the channel name (as passed to the constructor). + */ + readonly name: string; + onmessage: ((this: BroadcastChannel, ev: MessageEvent) => any) | null; + onmessageerror: ((this: BroadcastChannel, ev: MessageEvent) => any) | null; + /** + * Closes the BroadcastChannel object, opening it up to garbage collection. + */ + close(): void; + /** + * Sends the given message to other BroadcastChannel objects set up for + * this channel. Messages can be structured objects, e.g. nested objects + * and arrays. + */ + postMessage(message: any): void; + addEventListener<K extends keyof BroadcastChannelEventMap>( + type: K, + listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, + options?: boolean | AddEventListenerOptions, + ): void; + addEventListener( + type: string, + listener: EventListenerOrEventListenerObject, + options?: boolean | AddEventListenerOptions, + ): void; + removeEventListener<K extends keyof BroadcastChannelEventMap>( + type: K, + listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, + options?: boolean | EventListenerOptions, + ): void; + removeEventListener( + type: string, + listener: EventListenerOrEventListenerObject, + options?: boolean | EventListenerOptions, + ): void; +} + +declare var BroadcastChannel: { + prototype: BroadcastChannel; + new (name: string): BroadcastChannel; +}; diff --git a/extensions/broadcast_channel/lib.rs b/extensions/broadcast_channel/lib.rs new file mode 100644 index 000000000..b2a79916c --- /dev/null +++ b/extensions/broadcast_channel/lib.rs @@ -0,0 +1,139 @@ +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. + +mod in_memory_broadcast_channel; + +pub use in_memory_broadcast_channel::InMemoryBroadcastChannel; + +use async_trait::async_trait; +use deno_core::error::bad_resource_id; +use deno_core::error::AnyError; +use deno_core::include_js_files; +use deno_core::op_async; +use deno_core::op_sync; +use deno_core::Extension; +use deno_core::OpState; +use deno_core::Resource; +use deno_core::ResourceId; +use deno_core::ZeroCopyBuf; +use std::cell::RefCell; +use std::path::PathBuf; +use std::rc::Rc; + +#[async_trait] +pub trait BroadcastChannel: Clone { + type Resource: Resource; + + fn subscribe(&self) -> Result<Self::Resource, AnyError>; + + fn unsubscribe(&self, resource: &Self::Resource) -> Result<(), AnyError>; + + async fn send( + &self, + resource: &Self::Resource, + name: String, + data: Vec<u8>, + ) -> Result<(), AnyError>; + + async fn recv( + &self, + resource: &Self::Resource, + ) -> Result<Option<Message>, AnyError>; +} + +pub type Message = (String, Vec<u8>); + +struct Unstable(bool); // --unstable + +pub fn op_broadcast_subscribe<BC: BroadcastChannel + 'static>( + state: &mut OpState, + _args: (), + _buf: (), +) -> Result<ResourceId, AnyError> { + let unstable = state.borrow::<Unstable>().0; + + if !unstable { + eprintln!( + "Unstable API 'BroadcastChannel'. The --unstable flag must be provided.", + ); + std::process::exit(70); + } + + let bc = state.borrow::<BC>(); + let resource = bc.subscribe()?; + Ok(state.resource_table.add(resource)) +} + +pub fn op_broadcast_unsubscribe<BC: BroadcastChannel + 'static>( + state: &mut OpState, + rid: ResourceId, + _buf: (), +) -> Result<(), AnyError> { + let resource = state + .resource_table + .get::<BC::Resource>(rid) + .ok_or_else(bad_resource_id)?; + let bc = state.borrow::<BC>(); + bc.unsubscribe(&resource) +} + +pub async fn op_broadcast_send<BC: BroadcastChannel + 'static>( + state: Rc<RefCell<OpState>>, + (rid, name): (ResourceId, String), + buf: ZeroCopyBuf, +) -> Result<(), AnyError> { + let resource = state + .borrow() + .resource_table + .get::<BC::Resource>(rid) + .ok_or_else(bad_resource_id)?; + let bc = state.borrow().borrow::<BC>().clone(); + bc.send(&resource, name, buf.to_vec()).await +} + +pub async fn op_broadcast_recv<BC: BroadcastChannel + 'static>( + state: Rc<RefCell<OpState>>, + rid: ResourceId, + _buf: (), +) -> Result<Option<Message>, AnyError> { + let resource = state + .borrow() + .resource_table + .get::<BC::Resource>(rid) + .ok_or_else(bad_resource_id)?; + let bc = state.borrow().borrow::<BC>().clone(); + bc.recv(&resource).await +} + +pub fn init<BC: BroadcastChannel + 'static>( + bc: BC, + unstable: bool, +) -> Extension { + Extension::builder() + .js(include_js_files!( + prefix "deno:extensions/broadcast_channel", + "01_broadcast_channel.js", + )) + .ops(vec![ + ( + "op_broadcast_subscribe", + op_sync(op_broadcast_subscribe::<BC>), + ), + ( + "op_broadcast_unsubscribe", + op_sync(op_broadcast_unsubscribe::<BC>), + ), + ("op_broadcast_send", op_async(op_broadcast_send::<BC>)), + ("op_broadcast_recv", op_async(op_broadcast_recv::<BC>)), + ]) + .state(move |state| { + state.put(bc.clone()); + state.put(Unstable(unstable)); + Ok(()) + }) + .build() +} + +pub fn get_declaration() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("lib.deno_broadcast_channel.d.ts") +} diff --git a/extensions/fetch/21_formdata.js b/extensions/fetch/21_formdata.js index 379d5eca1..db4cfafa3 100644 --- a/extensions/fetch/21_formdata.js +++ b/extensions/fetch/21_formdata.js @@ -287,20 +287,20 @@ return finalBuffer; } - #createBoundary = () => { + #createBoundary() { return ( "----------" + Array.from(Array(32)) .map(() => Math.random().toString(36)[2] || 0) .join("") ); - }; + } /** * @param {[string, string][]} headers * @returns {void} */ - #writeHeaders = (headers) => { + #writeHeaders(headers) { let buf = (this.chunks.length === 0) ? "" : "\r\n"; buf += `--${this.boundary}\r\n`; @@ -310,7 +310,7 @@ buf += `\r\n`; this.chunks.push(encoder.encode(buf)); - }; + } /** * @param {string} field @@ -318,11 +318,11 @@ * @param {string} [type] * @returns {void} */ - #writeFileHeaders = ( + #writeFileHeaders( field, filename, type, - ) => { + ) { /** @type {[string, string][]} */ const headers = [ [ @@ -332,37 +332,37 @@ ["Content-Type", type || "application/octet-stream"], ]; return this.#writeHeaders(headers); - }; + } /** * @param {string} field * @returns {void} */ - #writeFieldHeaders = (field) => { + #writeFieldHeaders(field) { /** @type {[string, string][]} */ const headers = [["Content-Disposition", `form-data; name="${field}"`]]; return this.#writeHeaders(headers); - }; + } /** * @param {string} field * @param {string} value * @returns {void} */ - #writeField = (field, value) => { + #writeField(field, value) { this.#writeFieldHeaders(field); this.chunks.push(encoder.encode(value)); - }; + } /** * @param {string} field * @param {File} value * @returns {void} */ - #writeFile = (field, value) => { + #writeFile(field, value) { this.#writeFileHeaders(field, value.name, value.type); this.chunks.push(value[_byteSequence]); - }; + } } /** @@ -418,7 +418,7 @@ * @param {string} headersText * @returns {{ headers: Headers, disposition: Map<string, string> }} */ - #parseHeaders = (headersText) => { + #parseHeaders(headersText) { const headers = new Headers(); const rawHeaders = headersText.split("\r\n"); for (const rawHeader of rawHeaders) { @@ -436,7 +436,7 @@ ); return { headers, disposition }; - }; + } /** * @returns {FormData} diff --git a/extensions/file/02_filereader.js b/extensions/file/02_filereader.js index 9575ab85a..428d8fd54 100644 --- a/extensions/file/02_filereader.js +++ b/extensions/file/02_filereader.js @@ -41,7 +41,7 @@ * @param {Blob} blob * @param {{kind: "ArrayBuffer" | "Text" | "DataUrl" | "BinaryString", encoding?: string}} readtype */ - #readOperation = (blob, readtype) => { + #readOperation(blob, readtype) { // 1. If fr’s state is "loading", throw an InvalidStateError DOMException. if (this[state] === "loading") { throw new DOMException( @@ -221,7 +221,7 @@ } } })(); - }; + } constructor() { super(); diff --git a/extensions/timers/Cargo.toml b/extensions/timers/Cargo.toml index afdbf2e4c..6b68a02e9 100644 --- a/extensions/timers/Cargo.toml +++ b/extensions/timers/Cargo.toml @@ -16,3 +16,10 @@ path = "lib.rs" [dependencies] deno_core = { version = "0.88.1", path = "../../core" } tokio = { version = "1.6.1", features = ["full"] } + +[dev-dependencies] +deno_bench_util = { version = "0.1.0", path = "../../bench_util" } + +[[bench]] +name = "timers_ops" +harness = false diff --git a/extensions/timers/benches/timers_ops.rs b/extensions/timers/benches/timers_ops.rs new file mode 100644 index 000000000..e31fe31ac --- /dev/null +++ b/extensions/timers/benches/timers_ops.rs @@ -0,0 +1,36 @@ +use deno_core::Extension; + +use deno_bench_util::bench_or_profile; +use deno_bench_util::bencher::{benchmark_group, Bencher}; +use deno_bench_util::{bench_js_async, bench_js_sync}; + +fn setup() -> Vec<Extension> { + vec![ + deno_timers::init::<deno_timers::NoTimersPermission>(), + Extension::builder() + .js(vec![ + ("setup", + Box::new(|| Ok(r#" + const { opNow, setTimeout, handleTimerMacrotask } = globalThis.__bootstrap.timers; + Deno.core.setMacrotaskCallback(handleTimerMacrotask); + "#.to_owned())), + ), + ]) + .state(|state| { + state.put(deno_timers::NoTimersPermission{}); + Ok(()) + }) + .build() + ] +} + +fn bench_op_now(b: &mut Bencher) { + bench_js_sync(b, r#"opNow();"#, setup); +} + +fn bench_set_timeout(b: &mut Bencher) { + bench_js_async(b, r#"setTimeout(() => {}, 0);"#, setup); +} + +benchmark_group!(benches, bench_op_now, bench_set_timeout,); +bench_or_profile!(benches); diff --git a/extensions/url/00_url.js b/extensions/url/00_url.js index 340937748..f6f3335dd 100644 --- a/extensions/url/00_url.js +++ b/extensions/url/00_url.js @@ -58,14 +58,14 @@ urls.set(this, null); } - #updateUrlSearch = () => { + #updateUrlSearch() { const url = urls.get(this); if (url == null) { return; } const parseArgs = { href: url.href, setSearch: this.toString() }; parts.set(url, core.opSync("op_url_parse", parseArgs)); - }; + } append(name, value) { requiredArguments("URLSearchParams.append", arguments.length, 2); @@ -227,7 +227,7 @@ return `${this.constructor.name} ${inspect(object)}`; } - #updateSearchParams = () => { + #updateSearchParams() { if (this.#searchParams != null) { const params = paramLists.get(this.#searchParams); const newParams = core.opSync( @@ -236,7 +236,7 @@ ); params.splice(0, params.length, ...newParams); } - }; + } get hash() { return parts.get(this).hash; diff --git a/extensions/url/Cargo.toml b/extensions/url/Cargo.toml index 57f82bba8..f87931ece 100644 --- a/extensions/url/Cargo.toml +++ b/extensions/url/Cargo.toml @@ -20,7 +20,7 @@ percent-encoding = "2.1.0" serde = { version = "1.0.125", features = ["derive"] } [dev-dependencies] -bencher = "0.1" +deno_bench_util = { version = "0.1.0", path = "../../bench_util" } [[bench]] name = "url_ops" diff --git a/extensions/url/benches/url_ops.rs b/extensions/url/benches/url_ops.rs index 8b3cf2705..c390af0d8 100644 --- a/extensions/url/benches/url_ops.rs +++ b/extensions/url/benches/url_ops.rs @@ -1,35 +1,26 @@ -use bencher::{benchmark_group, benchmark_main, Bencher}; +use deno_bench_util::bench_js_sync; +use deno_bench_util::bench_or_profile; +use deno_bench_util::bencher::{benchmark_group, Bencher}; -use deno_core::v8; -use deno_core::JsRuntime; -use deno_core::RuntimeOptions; +use deno_core::Extension; -fn create_js_runtime() -> JsRuntime { - let mut runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![deno_url::init()], - ..Default::default() - }); - - runtime - .execute("setup", "const { URL } = globalThis.__bootstrap.url;") - .unwrap(); - - runtime -} - -pub fn bench_runtime_js(b: &mut Bencher, src: &str) { - let mut runtime = create_js_runtime(); - let scope = &mut runtime.handle_scope(); - let code = v8::String::new(scope, src).unwrap(); - let script = v8::Script::compile(scope, code, None).unwrap(); - b.iter(|| { - script.run(scope).unwrap(); - }); +fn setup() -> Vec<Extension> { + vec![ + deno_url::init(), + Extension::builder() + .js(vec![( + "setup", + Box::new(|| { + Ok(r#"const { URL } = globalThis.__bootstrap.url;"#.to_owned()) + }), + )]) + .build(), + ] } fn bench_url_parse(b: &mut Bencher) { - bench_runtime_js(b, r#"new URL(`http://www.google.com/`);"#); + bench_js_sync(b, r#"new URL(`http://www.google.com/`);"#, setup); } benchmark_group!(benches, bench_url_parse,); -benchmark_main!(benches); +bench_or_profile!(benches); diff --git a/extensions/web/02_event.js b/extensions/web/02_event.js index b6b5609bc..8ee6acc61 100644 --- a/extensions/web/02_event.js +++ b/extensions/web/02_event.js @@ -1117,6 +1117,10 @@ } class MessageEvent extends Event { + get source() { + return null; + } + constructor(type, eventInitDict) { super(type, { bubbles: eventInitDict?.bubbles ?? false, @@ -1208,5 +1212,6 @@ }; window.__bootstrap.event = { setIsTrusted, + setTarget, }; })(this); diff --git a/extensions/webstorage/lib.rs b/extensions/webstorage/lib.rs index 8b3e206fb..d2170890e 100644 --- a/extensions/webstorage/lib.rs +++ b/extensions/webstorage/lib.rs @@ -13,9 +13,9 @@ use std::fmt; use std::path::PathBuf; #[derive(Clone)] -struct LocationDataDir(PathBuf); +struct OriginStorageDir(PathBuf); -pub fn init(location_data_dir: Option<PathBuf>) -> Extension { +pub fn init(origin_storage_dir: Option<PathBuf>) -> Extension { Extension::builder() .js(include_js_files!( prefix "deno:extensions/webstorage", @@ -34,8 +34,8 @@ pub fn init(location_data_dir: Option<PathBuf>) -> Extension { ), ]) .state(move |state| { - if let Some(location_data_dir) = location_data_dir.clone() { - state.put(LocationDataDir(location_data_dir)); + if let Some(origin_storage_dir) = origin_storage_dir.clone() { + state.put(OriginStorageDir(origin_storage_dir)); } Ok(()) }) @@ -55,7 +55,7 @@ fn get_webstorage( ) -> Result<&Connection, AnyError> { let conn = if persistent { if state.try_borrow::<LocalStorage>().is_none() { - let path = state.try_borrow::<LocationDataDir>().ok_or_else(|| { + let path = state.try_borrow::<OriginStorageDir>().ok_or_else(|| { DomExceptionNotSupportedError::new( "LocalStorage is not supported in this context.", ) |