Skip to content

Commit b9d44e8

Browse files
authored
feat(perf_hooks): Improve performance interface compatibility (#1256)
1 parent 756fa82 commit b9d44e8

File tree

5 files changed

+90
-56
lines changed

5 files changed

+90
-56
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

modules/llrt_perf_hooks/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ name = "llrt_perf_hooks"
1212
path = "src/lib.rs"
1313

1414
[dependencies]
15+
llrt_events = { version = "0.7.0-beta", path = "../llrt_events" }
1516
llrt_utils = { version = "0.7.0-beta", path = "../../libs/llrt_utils", default-features = false }
1617
rquickjs = { git = "https://github.com/DelSkayn/rquickjs.git", version = "0.10.0", default-features = false }
1718

modules/llrt_perf_hooks/src/lib.rs

Lines changed: 15 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,15 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
3-
use llrt_utils::{
4-
module::{export_default, ModuleInfo},
5-
time,
6-
};
3+
use llrt_events::Emitter;
4+
use llrt_utils::module::{export_default, ModuleInfo};
75
use rquickjs::{
8-
atom::PredefinedAtom,
96
module::{Declarations, Exports, ModuleDef},
10-
prelude::Func,
11-
Ctx, JsLifetime, Object, Result,
7+
Class, Ctx, Object, Result,
128
};
139

14-
fn get_time_origin() -> f64 {
15-
let time_origin = time::origin_nanos() as f64;
16-
17-
time_origin / 1e6
18-
}
19-
20-
fn now() -> f64 {
21-
let now = time::now_nanos();
22-
let started = time::origin_nanos();
23-
let elapsed = now.checked_sub(started).unwrap_or_default();
24-
25-
(elapsed as f64) / 1e6
26-
}
27-
28-
fn to_json(ctx: Ctx<'_>) -> Result<Object<'_>> {
29-
let obj = Object::new(ctx.clone())?;
30-
31-
obj.set("timeOrigin", get_time_origin())?;
32-
33-
Ok(obj)
34-
}
10+
use crate::performance::Performance;
3511

36-
struct PerfInitedUserData;
37-
38-
unsafe impl JsLifetime<'_> for PerfInitedUserData {
39-
type Changed<'to> = PerfInitedUserData;
40-
}
41-
42-
fn new_performance(ctx: Ctx<'_>) -> Result<Object<'_>> {
43-
let global = ctx.globals();
44-
45-
let inited = ctx.userdata::<PerfInitedUserData>().is_some();
46-
if !inited {
47-
ctx.store_userdata(PerfInitedUserData)?;
48-
let performance = Object::new(ctx)?;
49-
performance.set("timeOrigin", get_time_origin())?;
50-
performance.set("now", Func::from(now))?;
51-
performance.set(PredefinedAtom::ToJSON, Func::from(to_json))?;
52-
global.set("performance", performance.clone())?;
53-
return Ok(performance);
54-
}
55-
global.get("performance")
56-
}
12+
mod performance;
5713

5814
pub struct PerfHooksModule;
5915

@@ -66,8 +22,11 @@ impl ModuleDef for PerfHooksModule {
6622

6723
fn evaluate<'js>(ctx: &Ctx<'js>, exports: &Exports<'js>) -> Result<()> {
6824
export_default(ctx, exports, |default| {
69-
let performance = new_performance(ctx.clone())?;
25+
let globals = ctx.globals();
26+
27+
let performance: Object = globals.get("performance")?;
7028
default.set("performance", performance)?;
29+
7130
Ok(())
7231
})
7332
}
@@ -83,7 +42,12 @@ impl From<PerfHooksModule> for ModuleInfo<PerfHooksModule> {
8342
}
8443

8544
pub fn init(ctx: &Ctx<'_>) -> Result<()> {
86-
new_performance(ctx.clone())?;
45+
let globals = ctx.globals();
46+
47+
let instance = Class::instance(ctx.clone(), Performance::new())?;
48+
Performance::add_event_target_prototype(ctx)?;
49+
50+
globals.set("performance", instance)?;
8751
Ok(())
8852
}
8953

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
use std::sync::{Arc, RwLock};
4+
5+
use llrt_events::{Emitter, EventList, Events};
6+
use llrt_utils::time;
7+
use rquickjs::{
8+
atom::PredefinedAtom,
9+
class::{Trace, Tracer},
10+
Ctx, JsLifetime, Object, Result,
11+
};
12+
13+
#[rquickjs::class]
14+
#[derive(Clone)]
15+
pub struct Performance<'js> {
16+
pub events: Events<'js>,
17+
}
18+
19+
unsafe impl<'js> JsLifetime<'js> for Performance<'js> {
20+
type Changed<'to> = Performance<'to>;
21+
}
22+
23+
impl<'js> Emitter<'js> for Performance<'js> {
24+
fn get_event_list(&self) -> Arc<RwLock<EventList<'js>>> {
25+
self.events.clone()
26+
}
27+
}
28+
29+
impl<'js> Trace<'js> for Performance<'js> {
30+
fn trace<'a>(&self, tracer: Tracer<'a, 'js>) {
31+
self.trace_event_emitter(tracer);
32+
}
33+
}
34+
35+
impl<'js> Default for Performance<'js> {
36+
fn default() -> Self {
37+
Self::new()
38+
}
39+
}
40+
41+
#[rquickjs::methods(rename_all = "camelCase")]
42+
impl<'js> Performance<'js> {
43+
#[qjs(constructor)]
44+
pub fn new() -> Self {
45+
Self {
46+
#[allow(clippy::arc_with_non_send_sync)]
47+
events: Arc::new(RwLock::new(Vec::new())),
48+
}
49+
}
50+
51+
#[qjs(get)]
52+
fn time_origin() -> f64 {
53+
let time_origin = time::origin_nanos() as f64;
54+
55+
time_origin / 1e6
56+
}
57+
58+
fn now() -> f64 {
59+
let now = time::now_nanos();
60+
let started = time::origin_nanos();
61+
let elapsed = now.checked_sub(started).unwrap_or_default();
62+
63+
(elapsed as f64) / 1e6
64+
}
65+
66+
#[qjs(rename = PredefinedAtom::ToJSON)]
67+
fn to_json(ctx: Ctx<'_>) -> Result<Object<'_>> {
68+
let obj = Object::new(ctx.clone())?;
69+
obj.set("timeOrigin", Self::time_origin())?;
70+
71+
Ok(obj)
72+
}
73+
}

wpt_errors.txt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -265,11 +265,6 @@ fetch/api/response > should pass response-stream-with-broken-then.any.js tests
265265
Error: [Attempt to inject {done: false, value: bye} via Object.prototype.then.] assert_equals: The value should be "hello". expected "hello" but got "[object Object]"
266266

267267

268-
🧪/wpt/hr-time.test.js
269-
hr-time > should pass basic.any.js tests
270-
Error: [Performance interface extends EventTarget.] not a function
271-
272-
273268
🧪/wpt/streams.readable-byte-streams.test.js
274269
streams/readable-byte-streams > should pass patched-global.any.js tests
275270
Error: [Patched then() sees byobRequest after filling all pending pull-into descriptors] Error borrowing class: can't borrow a value as it is already borrowed

0 commit comments

Comments
 (0)