From 5295b8025f2d98fd65257de1b764580fbad1a814 Mon Sep 17 00:00:00 2001 From: crowlkats Date: Mon, 7 Jun 2021 23:16:36 +0200 Subject: [PATCH 1/7] work --- extensions/timers/02_performance.js | 130 +++++++++++++++++----------- tools/wpt/expectation.json | 5 +- 2 files changed, 82 insertions(+), 53 deletions(-) diff --git a/extensions/timers/02_performance.js b/extensions/timers/02_performance.js index bca98fdbd1bc19..204b3eaeb9f269 100644 --- a/extensions/timers/02_performance.js +++ b/extensions/timers/02_performance.js @@ -48,26 +48,34 @@ const now = opNow; + const _name = Symbol("[[name]]"); + const _entryType = Symbol("[[entryType]]"); + const _startTime = Symbol("[[startTime]]"); + const _duration = Symbol("[[duration]]"); class PerformanceEntry { - #name = ""; - #entryType = ""; - #startTime = 0; - #duration = 0; + [_name] = ""; + [_entryType] = ""; + [_startTime] = 0; + [_duration] = 0; get name() { - return this.#name; + webidl.assertBranded(this, PerformanceEntry); + return this[_name]; } get entryType() { - return this.#entryType; + webidl.assertBranded(this, PerformanceEntry); + return this[_entryType]; } get startTime() { - return this.#startTime; + webidl.assertBranded(this, PerformanceEntry); + return this[_startTime]; } get duration() { - return this.#duration; + webidl.assertBranded(this, PerformanceEntry); + return this[_duration]; } constructor( @@ -75,41 +83,47 @@ entryType = null, startTime = null, duration = null, - key = null, + key = undefined, ) { - if (key != illegalConstructorKey) { - throw new TypeError("Illegal constructor."); + if (key !== illegalConstructorKey) { + webidl.illegalConstructor(); } - this.#name = name; - this.#entryType = entryType; - this.#startTime = startTime; - this.#duration = duration; + this[webidl.brand] = webidl.brand; + + this[_name] = name; + this[_entryType] = entryType; + this[_startTime] = startTime; + this[_duration] = duration; } toJSON() { + webidl.assertBranded(this, PerformanceEntry); return { - name: this.#name, - entryType: this.#entryType, - startTime: this.#startTime, - duration: this.#duration, + name: this[_name], + entryType: this[_entryType], + startTime: this[_startTime], + duration: this[_duration], }; } - [customInspect]() { - return `${this.constructor.name} { name: "${this.name}", entryType: "${this.entryType}", startTime: ${this.startTime}, duration: ${this.duration} }`; + [customInspect](inspect) { + return `${this.constructor.name} ${inspect(this.toJSON())}`; } } + const _detail = Symbol("[[detail]]"); class PerformanceMark extends PerformanceEntry { [Symbol.toStringTag] = "PerformanceMark"; - #detail = null; + [_detail] = null; get detail() { - return this.#detail; + webidl.assertBranded(this, PerformanceMark); + return this[_detail]; } get entryType() { + webidl.assertBranded(this, PerformanceMark); return "mark"; } @@ -135,13 +149,15 @@ const { detail = null, startTime = now() } = options ?? {}; super(name, "mark", startTime, 0, illegalConstructorKey); + this[webidl.brand] = webidl.brand; if (startTime < 0) { throw new TypeError("startTime cannot be negative"); } - this.#detail = structuredClone(detail); + this[_detail] = structuredClone(detail); } toJSON() { + webidl.assertBranded(this, PerformanceMark); return { name: this.name, entryType: this.entryType, @@ -151,25 +167,23 @@ }; } - [customInspect]() { - return this.detail - ? `${this.constructor.name} {\n detail: ${ - JSON.stringify(this.detail, null, 2) - },\n name: "${this.name}",\n entryType: "${this.entryType}",\n startTime: ${this.startTime},\n duration: ${this.duration}\n}` - : `${this.constructor.name} { detail: ${this.detail}, name: "${this.name}", entryType: "${this.entryType}", startTime: ${this.startTime}, duration: ${this.duration} }`; + [customInspect](inspect) { + return `${this.constructor.name} ${inspect(this.toJSON())}`; } } class PerformanceMeasure extends PerformanceEntry { [Symbol.toStringTag] = "PerformanceMeasure"; - #detail = null; + [_detail] = null; get detail() { - return this.#detail; + webidl.assertBranded(this, PerformanceMeasure); + return this[_detail]; } get entryType() { + webidl.assertBranded(this, PerformanceMeasure); return "measure"; } @@ -178,16 +192,19 @@ startTime, duration, detail = null, - key, + key = undefined, ) { - if (key != illegalConstructorKey) { - throw new TypeError("Illegal constructor."); + if (key !== illegalConstructorKey) { + webidl.illegalConstructor(); } - super(name, "measure", startTime, duration, illegalConstructorKey); - this.#detail = structuredClone(detail); + + super(name, "measure", startTime, duration, key); + this[webidl.brand] = webidl.brand; + this[_detail] = structuredClone(detail); } toJSON() { + webidl.assertBranded(this, PerformanceMeasure); return { name: this.name, entryType: this.entryType, @@ -197,23 +214,18 @@ }; } - [customInspect]() { - return this.detail - ? `${this.constructor.name} {\n detail: ${ - JSON.stringify(this.detail, null, 2) - },\n name: "${this.name}",\n entryType: "${this.entryType}",\n startTime: ${this.startTime},\n duration: ${this.duration}\n}` - : `${this.constructor.name} { detail: ${this.detail}, name: "${this.name}", entryType: "${this.entryType}", startTime: ${this.startTime}, duration: ${this.duration} }`; + [customInspect](inspect) { + return `${this.constructor.name} ${inspect(this.toJSON())}`; } } class Performance { - constructor(key = null) { - if (key != illegalConstructorKey) { - throw new TypeError("Illegal constructor."); - } + constructor() { + webidl.illegalConstructor(); } clearMarks(markName) { + webidl.assertBranded(this, Performance); if (markName == null) { performanceEntries = performanceEntries.filter( (entry) => entry.entryType !== "mark", @@ -226,6 +238,7 @@ } clearMeasures(measureName) { + webidl.assertBranded(this, Performance); if (measureName == null) { performanceEntries = performanceEntries.filter( (entry) => entry.entryType !== "measure", @@ -239,6 +252,7 @@ } getEntries() { + webidl.assertBranded(this, Performance); return filterByNameType(); } @@ -246,10 +260,12 @@ name, type, ) { + webidl.assertBranded(this, Performance); return filterByNameType(name, type); } getEntriesByType(type) { + webidl.assertBranded(this, Performance); return filterByNameType(undefined, type); } @@ -257,6 +273,7 @@ markName, options = {}, ) { + webidl.assertBranded(this, Performance); // 3.1.1.1 If the global object is a Window object and markName uses the // same name as a read only attribute in the PerformanceTiming interface, // throw a SyntaxError. - not implemented @@ -271,6 +288,7 @@ startOrMeasureOptions = {}, endMark, ) { + webidl.assertBranded(this, Performance); if ( startOrMeasureOptions && typeof startOrMeasureOptions === "object" && Object.keys(startOrMeasureOptions).length > 0 @@ -348,17 +366,29 @@ } now() { + webidl.assertBranded(this, Performance); return now(); } - } - const performance = new Performance(illegalConstructorKey); + toJSON() { + webidl.assertBranded(this, Performance); + return {}; + } + + [customInspect](inspect) { + return `${this.constructor.name} ${inspect(this.toJSON())}`; + } + + get [Symbol.toStringTag]() { + return "Performance"; + } + } window.__bootstrap.performance = { PerformanceEntry, PerformanceMark, PerformanceMeasure, Performance, - performance, + performance: webidl.createBranded(Performance), }; })(this); diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index 933fc57d6f14fd..8949119f450d2a 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -246,12 +246,11 @@ "Performance interface: operation now()", "Performance interface: attribute timeOrigin", "Performance interface: operation toJSON()", - "Stringification of performance", "Performance interface: performance must inherit property \"timeOrigin\" with the proper type", - "Performance interface: performance must inherit property \"toJSON()\" with the proper type", "Performance interface: default toJSON operation on performance", "Window interface: attribute performance" - ] + ], + "window-worker-timeOrigin.window.html": false }, "streams": { "idlharness.any.html": [ From 0363114e048cd1a3a417542a1df989452dcdf4f6 Mon Sep 17 00:00:00 2001 From: crowlkats Date: Mon, 7 Jun 2021 23:18:11 +0200 Subject: [PATCH 2/7] fix --- tools/wpt/expectation.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index 8949119f450d2a..085f3ed86e38e7 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -249,8 +249,7 @@ "Performance interface: performance must inherit property \"timeOrigin\" with the proper type", "Performance interface: default toJSON operation on performance", "Window interface: attribute performance" - ], - "window-worker-timeOrigin.window.html": false + ] }, "streams": { "idlharness.any.html": [ @@ -1202,4 +1201,4 @@ "set.any.html": true } } -} \ No newline at end of file +} From db88c4e81f3846ba7d1654884ddd9873d0b01760 Mon Sep 17 00:00:00 2001 From: crowlkats Date: Mon, 7 Jun 2021 23:52:02 +0200 Subject: [PATCH 3/7] fix --- cli/tests/unit/performance_test.ts | 6 +++--- tools/wpt/expectation.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/tests/unit/performance_test.ts b/cli/tests/unit/performance_test.ts index 229b38bb8ca5f5..156841165befa0 100644 --- a/cli/tests/unit/performance_test.ts +++ b/cli/tests/unit/performance_test.ts @@ -82,12 +82,12 @@ unitTest(function performanceMeasure() { }); unitTest(function performanceIllegalConstructor() { - assertThrows(() => new Performance(), TypeError, "Illegal constructor."); + assertThrows(() => new Performance(), TypeError, "Illegal constructor"); assertEquals(Performance.length, 0); }); unitTest(function performanceEntryIllegalConstructor() { - assertThrows(() => new PerformanceEntry(), TypeError, "Illegal constructor."); + assertThrows(() => new PerformanceEntry(), TypeError, "Illegal constructor"); assertEquals(PerformanceEntry.length, 0); }); @@ -95,6 +95,6 @@ unitTest(function performanceMeasureIllegalConstructor() { assertThrows( () => new PerformanceMeasure(), TypeError, - "Illegal constructor.", + "Illegal constructor", ); }); diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index 085f3ed86e38e7..d429ffbd8583fd 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -1201,4 +1201,4 @@ "set.any.html": true } } -} +} \ No newline at end of file From 2b544f37819b9040d29713cf17ee17daa6db1303 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Sat, 3 Jul 2021 22:47:55 +0200 Subject: [PATCH 4/7] fix some more things --- extensions/timers/02_performance.js | 4 ++++ tools/wpt/expectation.json | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/extensions/timers/02_performance.js b/extensions/timers/02_performance.js index 2d0769252ce656..c35e7be3c67752 100644 --- a/extensions/timers/02_performance.js +++ b/extensions/timers/02_performance.js @@ -112,6 +112,7 @@ return `${this.constructor.name} ${inspect(this.toJSON())}`; } } + webidl.configurePrototype(PerformanceEntry); const _detail = Symbol("[[detail]]"); class PerformanceMark extends PerformanceEntry { @@ -173,6 +174,7 @@ return `${this.constructor.name} ${inspect(this.toJSON())}`; } } + webidl.configurePrototype(PerformanceMark); class PerformanceMeasure extends PerformanceEntry { [Symbol.toStringTag] = "PerformanceMeasure"; @@ -220,6 +222,7 @@ return `${this.constructor.name} ${inspect(this.toJSON())}`; } } + webidl.configurePrototype(PerformanceMeasure); class Performance { constructor() { @@ -385,6 +388,7 @@ return "Performance"; } } + webidl.configurePrototype(Performance); window.__bootstrap.performance = { PerformanceEntry, diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index 3654049f288c13..87e5b98c1bd261 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -497,12 +497,8 @@ "clear_one_measure.any.html": true, "entry_type.any.html": true, "idlharness.any.html": [ - "PerformanceMark interface: attribute detail", "PerformanceMeasure interface object length", - "PerformanceMeasure interface: attribute detail", - "Performance interface: operation mark(DOMString, optional PerformanceMarkOptions)", "Performance interface: operation clearMarks(optional DOMString)", - "Performance interface: operation measure(DOMString, optional (DOMString or PerformanceMeasureOptions), optional DOMString)", "Performance interface: operation clearMeasures(optional DOMString)", "Performance interface: calling mark(DOMString, optional PerformanceMarkOptions) on performance with too few arguments must throw TypeError", "Performance interface: calling measure(DOMString, optional (DOMString or PerformanceMeasureOptions), optional DOMString) on performance with too few arguments must throw TypeError" From d9af29746b4134bf983f38989963e9ab1c67ae09 Mon Sep 17 00:00:00 2001 From: crowlkats Date: Sun, 4 Jul 2021 18:48:53 +0200 Subject: [PATCH 5/7] work --- extensions/timers/02_performance.js | 168 +++++++++++++++++++++++----- extensions/webidl/00_webidl.js | 1 + tools/wpt/expectation.json | 10 +- 3 files changed, 146 insertions(+), 33 deletions(-) diff --git a/extensions/timers/02_performance.js b/extensions/timers/02_performance.js index c35e7be3c67752..d3570ce97715c5 100644 --- a/extensions/timers/02_performance.js +++ b/extensions/timers/02_performance.js @@ -10,6 +10,58 @@ const customInspect = Symbol.for("Deno.customInspect"); let performanceEntries = []; + webidl.converters["PerformanceMarkOptions"] = webidl + .createDictionaryConverter( + "PerformanceMarkOptions", + [ + { + key: "detail", + converter: webidl.converters.any, + }, + { + key: "startTime", + converter: webidl.converters.DOMHighResTimeStamp, + }, + ], + ); + + webidl.converters["DOMString or DOMHighResTimeStamp"] = (V, opts) => { + if (webidl.type(V) === "Number" && V !== null) { + return webidl.converters.DOMHighResTimeStamp(V, opts); + } + return webidl.converters.DOMString(V, opts); + }; + + webidl.converters["PerformanceMeasureOptions"] = webidl + .createDictionaryConverter( + "PerformanceMeasureOptions", + [ + { + key: "detail", + converter: webidl.converters.any, + }, + { + key: "start", + converter: webidl.converters["DOMString or DOMHighResTimeStamp"], + }, + { + key: "duration", + converter: webidl.converters.DOMHighResTimeStamp, + }, + { + key: "end", + converter: webidl.converters["DOMString or DOMHighResTimeStamp"], + }, + ], + ); + + webidl.converters["DOMString or PerformanceMeasureOptions"] = (V, opts) => { + if (webidl.type(V) === "Object" && V !== null) { + return webidl.converters["PerformanceMeasureOptions"](V, opts); + } + return webidl.converters.DOMString(V, opts); + }; + function findMostRecent( name, type, @@ -137,19 +189,17 @@ const prefix = "Failed to construct 'PerformanceMark'"; webidl.requiredArguments(arguments.length, 1, { prefix }); - // ensure options is object-ish, or null-ish - switch (typeof options) { - case "object": // includes null - case "function": - case "undefined": { - break; - } - default: { - throw new TypeError("Invalid options"); - } - } + name = webidl.converters.DOMString(name, { + prefix, + context: "Argument 1", + }); + + options = webidl.converters.PerformanceMarkOptions(options, { + prefix, + context: "Argument 2", + }); - const { detail = null, startTime = now() } = options ?? {}; + const { detail = null, startTime = now() } = options; super(name, "mark", startTime, 0, illegalConstructorKey); this[webidl.brand] = webidl.brand; @@ -229,29 +279,39 @@ webidl.illegalConstructor(); } - clearMarks(markName) { + clearMarks(markName = undefined) { webidl.assertBranded(this, Performance); - if (markName == null) { + if (markName !== undefined) { + markName = webidl.converters.DOMString(markName, { + prefix: "Failed to execute 'clearMarks' on 'Performance'", + context: "Argument 1", + }); + performanceEntries = performanceEntries.filter( - (entry) => entry.entryType !== "mark", + (entry) => !(entry.name === markName && entry.entryType === "mark"), ); } else { performanceEntries = performanceEntries.filter( - (entry) => !(entry.name === markName && entry.entryType === "mark"), + (entry) => entry.entryType !== "mark", ); } } - clearMeasures(measureName) { + clearMeasures(measureName = undefined) { webidl.assertBranded(this, Performance); - if (measureName == null) { + if (measureName !== undefined) { + measureName = webidl.converters.DOMString(measureName, { + prefix: "Failed to execute 'clearMeasures' on 'Performance'", + context: "Argument 1", + }); + performanceEntries = performanceEntries.filter( - (entry) => entry.entryType !== "measure", + (entry) => + !(entry.name === measureName && entry.entryType === "measure"), ); } else { performanceEntries = performanceEntries.filter( - (entry) => - !(entry.name === measureName && entry.entryType === "measure"), + (entry) => entry.entryType !== "measure", ); } } @@ -263,26 +323,62 @@ getEntriesByName( name, - type, + type = undefined, ) { webidl.assertBranded(this, Performance); + const prefix = "Failed to execute 'getEntriesByName' on 'Performance'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + + name = webidl.converters.DOMString(name, { + prefix, + context: "Argument 1", + }); + + if (type !== undefined) { + type = webidl.converters.DOMString(type, { + prefix, + context: "Argument 2", + }); + } + return filterByNameType(name, type); } getEntriesByType(type) { webidl.assertBranded(this, Performance); + const prefix = "Failed to execute 'getEntriesByName' on 'Performance'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + + type = webidl.converters.DOMString(type, { + prefix, + context: "Argument 1", + }); + return filterByNameType(undefined, type); } mark( markName, - options = {}, + markOptions = {}, ) { webidl.assertBranded(this, Performance); + const prefix = "Failed to execute 'mark' on 'Performance'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + + markName = webidl.converters.DOMString(markName, { + prefix, + context: "Argument 1", + }); + + markOptions = webidl.converters.PerformanceMarkOptions(markOptions, { + prefix, + context: "Argument 2", + }); + // 3.1.1.1 If the global object is a Window object and markName uses the // same name as a read only attribute in the PerformanceTiming interface, // throw a SyntaxError. - not implemented - const entry = new PerformanceMark(markName, options); + const entry = new PerformanceMark(markName, markOptions); // 3.1.1.7 Queue entry - not implemented performanceEntries.push(entry); return entry; @@ -291,9 +387,31 @@ measure( measureName, startOrMeasureOptions = {}, - endMark, + endMark = undefined, ) { webidl.assertBranded(this, Performance); + const prefix = "Failed to execute 'measure' on 'Performance'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + + measureName = webidl.converters.DOMString(measureName, { + prefix, + context: "Argument 1", + }); + + startOrMeasureOptions = webidl.converters + ["DOMString or PerformanceMeasureOptions"](startOrMeasureOptions, { + prefix, + context: "Argument 2", + }); + console.log("foooobarrrrrr", startOrMeasureOptions); + + if (endMark !== undefined) { + endMark = webidl.converters.DOMString(endMark, { + prefix, + context: "Argument 3", + }); + } + if ( startOrMeasureOptions && typeof startOrMeasureOptions === "object" && Object.keys(startOrMeasureOptions).length > 0 diff --git a/extensions/webidl/00_webidl.js b/extensions/webidl/00_webidl.js index c43a39ee9225c1..6bd323f17df422 100644 --- a/extensions/webidl/00_webidl.js +++ b/extensions/webidl/00_webidl.js @@ -612,6 +612,7 @@ }; converters.DOMTimeStamp = converters["unsigned long long"]; + converters.DOMHighResTimeStamp = converters["double"]; converters.Function = convertCallbackFunction; diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index 87e5b98c1bd261..625cb21b05faa4 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -282,9 +282,7 @@ "idlharness.any.html": [ "Performance interface: existence and properties of interface object", "Performance interface: existence and properties of interface prototype object", - "Performance interface: operation now()", "Performance interface: attribute timeOrigin", - "Performance interface: operation toJSON()", "Performance interface: performance must inherit property \"timeOrigin\" with the proper type", "Performance interface: default toJSON operation on performance", "Window interface: attribute performance" @@ -497,11 +495,7 @@ "clear_one_measure.any.html": true, "entry_type.any.html": true, "idlharness.any.html": [ - "PerformanceMeasure interface object length", - "Performance interface: operation clearMarks(optional DOMString)", - "Performance interface: operation clearMeasures(optional DOMString)", - "Performance interface: calling mark(DOMString, optional PerformanceMarkOptions) on performance with too few arguments must throw TypeError", - "Performance interface: calling measure(DOMString, optional (DOMString or PerformanceMeasureOptions), optional DOMString) on performance with too few arguments must throw TypeError" + "PerformanceMeasure interface object length" ], "mark-entry-constructor.any.html": true, "mark-errors.any.html": true, @@ -1265,4 +1259,4 @@ "eventhandlers.any.html?wss": false, "referrer.any.html": true } -} \ No newline at end of file +} From f9676af5f2876edeef596ccf86a232d06b157972 Mon Sep 17 00:00:00 2001 From: Leo K Date: Mon, 5 Jul 2021 04:57:39 +0200 Subject: [PATCH 6/7] Update extensions/timers/02_performance.js Co-authored-by: Luca Casonato --- extensions/timers/02_performance.js | 1 - 1 file changed, 1 deletion(-) diff --git a/extensions/timers/02_performance.js b/extensions/timers/02_performance.js index d3570ce97715c5..3c36294a6fb5e3 100644 --- a/extensions/timers/02_performance.js +++ b/extensions/timers/02_performance.js @@ -403,7 +403,6 @@ prefix, context: "Argument 2", }); - console.log("foooobarrrrrr", startOrMeasureOptions); if (endMark !== undefined) { endMark = webidl.converters.DOMString(endMark, { From 2525c66142e69038e07cc7943ffbcf7fb45a8b3c Mon Sep 17 00:00:00 2001 From: crowlkats Date: Mon, 5 Jul 2021 06:33:25 +0200 Subject: [PATCH 7/7] fix constructor --- extensions/timers/02_performance.js | 6 +++--- tools/wpt/expectation.json | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/extensions/timers/02_performance.js b/extensions/timers/02_performance.js index 3c36294a6fb5e3..56f82b42ec5e0f 100644 --- a/extensions/timers/02_performance.js +++ b/extensions/timers/02_performance.js @@ -242,9 +242,9 @@ } constructor( - name, - startTime, - duration, + name = null, + startTime = null, + duration = null, detail = null, key = undefined, ) { diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index 625cb21b05faa4..f695cefe65f96d 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -494,9 +494,7 @@ "clear_one_mark.any.html": true, "clear_one_measure.any.html": true, "entry_type.any.html": true, - "idlharness.any.html": [ - "PerformanceMeasure interface object length" - ], + "idlharness.any.html": true, "mark-entry-constructor.any.html": true, "mark-errors.any.html": true, "mark-l3.any.html": false,