diff --git a/devtools/server/actors/webconsole/eager-ecma-allowlist.js b/devtools/server/actors/webconsole/eager-ecma-allowlist.js index 1b4a2705e0c4..cfe110c98e78 100644 --- a/devtools/server/actors/webconsole/eager-ecma-allowlist.js +++ b/devtools/server/actors/webconsole/eager-ecma-allowlist.js @@ -16,10 +16,6 @@ function allProperties(obj) { return matchingProperties(obj, /./); } -function getter(obj, name) { - return Object.getOwnPropertyDescriptor(obj, name).get; -} - const TypedArray = Reflect.getPrototypeOf(Int8Array); module.exports = [ @@ -162,34 +158,4 @@ module.exports = [ isFinite, isNaN, unescape, - getter(ArrayBuffer.prototype, "byteLength"), - getter(ArrayBuffer, Symbol.species), - getter(Array, Symbol.species), - getter(DataView.prototype, "buffer"), - getter(DataView.prototype, "byteLength"), - getter(DataView.prototype, "byteOffset"), - getter(Map.prototype, "size"), - getter(Map, Symbol.species), - // NOTE: Object.prototype.__proto__ is not safe, because it can internally - // invoke Proxy getPrototypeOf handler. - getter(Promise, Symbol.species), - getter(RegExp.prototype, "dotAll"), - getter(RegExp.prototype, "flags"), - getter(RegExp.prototype, "global"), - getter(RegExp.prototype, "hasIndices"), - getter(RegExp.prototype, "ignoreCase"), - getter(RegExp.prototype, "multiline"), - getter(RegExp.prototype, "source"), - getter(RegExp.prototype, "sticky"), - getter(RegExp.prototype, "unicode"), - getter(RegExp, Symbol.species), - getter(Set.prototype, "size"), - getter(Set, Symbol.species), - getter(Symbol.prototype, "description"), - getter(TypedArray.prototype, "buffer"), - getter(TypedArray.prototype, "byteLength"), - getter(TypedArray.prototype, "byteOffset"), - getter(TypedArray.prototype, "length"), - getter(TypedArray.prototype, Symbol.toStringTag), - getter(TypedArray, Symbol.species), ]; diff --git a/devtools/server/actors/webconsole/eager-function-allowlist.js b/devtools/server/actors/webconsole/eager-function-allowlist.js index 01728fdc884c..04153183fc10 100644 --- a/devtools/server/actors/webconsole/eager-function-allowlist.js +++ b/devtools/server/actors/webconsole/eager-function-allowlist.js @@ -6,64 +6,65 @@ const idlPureAllowlist = require("resource://devtools/server/actors/webconsole/webidl-pure-allowlist.js"); -// Exclude interfaces only with "instance" property, such as Location, -// which is not available in sandbox. -const props = []; -for (const [iface, ifaceData] of Object.entries(idlPureAllowlist)) { - if ("static" in ifaceData || "prototype" in ifaceData) { - props.push(iface); +// TODO: Bug 1616013 - Move more of these to be part of the pure list. +const customEagerFunctions = { + Document: [ + ["prototype", "getSelection"], + ["prototype", "hasStorageAccess"], + ], + Range: [ + ["prototype", "isPointInRange"], + ["prototype", "comparePoint"], + ["prototype", "intersectsNode"], + + // These two functions aren't pure because they do trigger layout when + // they are called, but in the context of eager evaluation, that should be + // a totally fine thing to do. + ["prototype", "getClientRects"], + ["prototype", "getBoundingClientRect"], + ], + Selection: [ + ["prototype", "getRangeAt"], + ["prototype", "containsNode"], + ], +}; + +const mergedFunctions = {}; +for (const [key, values] of Object.entries(idlPureAllowlist)) { + mergedFunctions[key] = [...values]; +} +for (const [key, values] of Object.entries(customEagerFunctions)) { + if (!mergedFunctions[key]) { + mergedFunctions[key] = []; } + mergedFunctions[key].push(...values); } const natives = []; - if (Components.Constructor && Cu) { const sandbox = Cu.Sandbox( Components.Constructor("@mozilla.org/systemprincipal;1", "nsIPrincipal")(), { invisibleToDebugger: true, - wantGlobalProperties: props, + wantGlobalProperties: Object.keys(mergedFunctions), } ); - function maybePush(maybeFunc) { - if (maybeFunc) { - natives.push(maybeFunc); - } - } - - function collectMethodsAndGetters(obj, methodsAndGetters) { - if ("methods" in methodsAndGetters) { - for (const name of methodsAndGetters.methods) { - maybePush(obj[name]); - } - } - if ("getters" in methodsAndGetters) { - for (const name of methodsAndGetters.getters) { - maybePush(Object.getOwnPropertyDescriptor(obj, name)?.get); - } - } - } - - for (const [iface, ifaceData] of Object.entries(idlPureAllowlist)) { - const ctor = sandbox[iface]; - if (!ctor) { - continue; - } - - if ("static" in ifaceData) { - collectMethodsAndGetters(ctor, ifaceData.static); - } - - if ("prototype" in ifaceData) { - const proto = ctor.prototype; - if (!proto) { - continue; + for (const iface of Object.keys(mergedFunctions)) { + for (const path of mergedFunctions[iface]) { + let value = sandbox; + for (const part of [iface, ...path]) { + value = value[part]; + if (!value) { + break; + } } - collectMethodsAndGetters(proto, ifaceData.prototype); + if (value) { + natives.push(value); + } } } } -module.exports = { natives, idlPureAllowlist }; +module.exports = natives; diff --git a/devtools/server/actors/webconsole/eval-with-debugger.js b/devtools/server/actors/webconsole/eval-with-debugger.js index c0996fb4fab6..a2d6021aefda 100644 --- a/devtools/server/actors/webconsole/eval-with-debugger.js +++ b/devtools/server/actors/webconsole/eval-with-debugger.js @@ -107,8 +107,6 @@ function isObject(value) { * - eager: Set to true if you want the evaluation to bail if it may have side effects. * - url: the url to evaluate the script as. Defaults to "debugger eval code", * or "debugger eager eval code" if eager is true. - * @param object webConsole - * * @return object * An object that holds the following properties: * - dbg: the debugger where the string was evaluated. @@ -128,11 +126,7 @@ exports.evalWithDebugger = function(string, options = {}, webConsole) { const evalString = getEvalInput(string); const { frame, dbg } = getFrameDbg(options, webConsole); - const { dbgGlobal, bindSelf, evalGlobal } = getDbgGlobal( - options, - dbg, - webConsole - ); + const { dbgGlobal, bindSelf } = getDbgGlobal(options, dbg, webConsole); const helpers = getHelpers(dbgGlobal, options, webConsole); let { bindings, helperCache } = bindCommands( isCommand(string), @@ -164,7 +158,7 @@ exports.evalWithDebugger = function(string, options = {}, webConsole) { let noSideEffectDebugger = null; if (options.eager) { - noSideEffectDebugger = makeSideeffectFreeDebugger(false, evalGlobal); + noSideEffectDebugger = makeSideeffectFreeDebugger(); } let result; @@ -363,15 +357,10 @@ function forceLexicalInitForVariableDeclarationsInThrowingExpression( * * @param boolean skipCheckingEffectfulOffsets * If true, effectful offsets are excluded from the checks for side effects. - * @param object maybeEvalGlobal - * If provided, raw debuggee global to get `window` accessors. * @return object * Side-effect-free debugger. */ -function makeSideeffectFreeDebugger( - skipCheckingEffectfulOffsets, - maybeEvalGlobal -) { +function makeSideeffectFreeDebugger(skipCheckingEffectfulOffsets) { // We ensure that the metadata for native functions is loaded before we // initialize sideeffect-prevention because the data is lazy-loaded, and this // logic can run inside of debuggee compartments because the @@ -380,7 +369,7 @@ function makeSideeffectFreeDebugger( // because building the list of valid native functions is itself a // side-effectful operation because it needs to populate a // module cache, among any number of other things. - ensureSideEffectFreeNatives(maybeEvalGlobal); + ensureSideEffectFreeNatives(); // Note: It is critical for debuggee performance that we implement all of // this debuggee tracking logic with a separate Debugger instance. @@ -436,11 +425,11 @@ function makeSideeffectFreeDebugger( // so we need to add this hook on "dbg" even though the rest of our hooks work via "newDbg". dbg.onNativeCall = (callee, reason) => { try { - // Setters are always effectful. Natives called normally or called via - // getters are handled with an allowlist. + // Getters are never considered effectful, and setters are always effectful. + // Natives called normally are handled with an allowlist. if ( - (reason == "get" || reason == "call") && - nativeHasNoSideEffects(callee) + reason == "get" || + (reason == "call" && nativeHasNoSideEffects(callee)) ) { // Returning undefined causes execution to continue normally. return undefined; @@ -463,77 +452,17 @@ exports.makeSideeffectFreeDebugger = makeSideeffectFreeDebugger; // Native functions which are considered to be side effect free. let gSideEffectFreeNatives; // string => Array(Function) -/** - * Generate gSideEffectFreeNatives map. - * - * @param object maybeEvalGlobal - * If provided, raw debuggee global to get `window` accessors. - */ -function ensureSideEffectFreeNatives(maybeEvalGlobal) { +function ensureSideEffectFreeNatives() { if (gSideEffectFreeNatives) { return; } - const { natives: domNatives, idlPureAllowlist } = eagerFunctionAllowlist; - - const instanceFunctionAllowlist = []; - - function collectMethodsAndGetters(obj, methodsAndGetters) { - // This can retrieve xray function if the obj comes from web content. - // Xray function has original native and JitInfo even if the property is - // modified by the web content. - - if ("methods" in methodsAndGetters) { - for (const name of methodsAndGetters.methods) { - const func = obj[name]; - if (func) { - instanceFunctionAllowlist.push(func); - } - } - } - if ("getters" in methodsAndGetters) { - for (const name of methodsAndGetters.getters) { - const func = Object.getOwnPropertyDescriptor(obj, name)?.get; - if (func) { - instanceFunctionAllowlist.push(func); - } - } - } - } - - // `Window` can be undefined if this is inside sandbox. - if ( - maybeEvalGlobal && - typeof Window === "function" && - Window.isInstance(maybeEvalGlobal) && - "Window" in idlPureAllowlist && - "instance" in idlPureAllowlist.Window - ) { - collectMethodsAndGetters(maybeEvalGlobal, idlPureAllowlist.Window.instance); - const maybeLocation = maybeEvalGlobal.location; - if (maybeLocation) { - collectMethodsAndGetters( - maybeLocation, - idlPureAllowlist.Location.instance - ); - } - const maybeDocument = maybeEvalGlobal.document; - if (maybeDocument) { - collectMethodsAndGetters( - maybeDocument, - idlPureAllowlist.Document.instance - ); - } - } - const natives = [ ...eagerEcmaAllowlist, // Pull in all of the non-ECMAScript native functions that we want to // allow as well. - ...domNatives, - - ...instanceFunctionAllowlist, + ...eagerFunctionAllowlist, ]; const map = new Map(); @@ -560,14 +489,8 @@ function nativeHasNoSideEffects(fn) { return true; } - // This needs to use isSameNativeWithJitInfo instead of isSameNative, given - // DOM getters share single native function with different JSJitInto, - // and isSameNative cannot distinguish between side-effect-free getters - // and others. - // - // See bug 1806598 for more info. const natives = gSideEffectFreeNatives.get(fn.name); - return natives && natives.some(n => fn.isSameNativeWithJitInfo(n)); + return natives && natives.some(n => fn.isSameNative(n)); } function updateConsoleInputEvaluation(dbg, webConsole) { @@ -629,22 +552,6 @@ function getFrameDbg(options, webConsole) { ); } -/** - * Get debugger object for given debugger and Web Console. - * - * @param object options - * See the `options` parameter of evalWithDebugger - * @param {Debugger} dbg - * Debugger object - * @param {WebConsoleActor} webConsole - * A reference to a webconsole actor which is used to get the target - * eval global and optionally the target actor - * @return object - * An object that holds the following properties: - * - bindSelf: (optional) the self object for the evaluation - * - dbgGlobal: the global object reference in the debugger - * - evalGlobal: the raw global object - */ function getDbgGlobal(options, dbg, webConsole) { let evalGlobal = webConsole.evalGlobal; @@ -663,7 +570,7 @@ function getDbgGlobal(options, dbg, webConsole) { // If we have an object to bind to |_self|, create a Debugger.Object // referring to that object, belonging to dbg. if (!options.selectedObjectActor) { - return { bindSelf: null, dbgGlobal, evalGlobal }; + return { bindSelf: null, dbgGlobal }; } // For objects related to console messages, they will be registered under the Target Actor @@ -674,12 +581,12 @@ function getDbgGlobal(options, dbg, webConsole) { webConsole.parentActor.getActorByID(options.selectedObjectActor); if (!actor) { - return { bindSelf: null, dbgGlobal, evalGlobal }; + return { bindSelf: null, dbgGlobal }; } const jsVal = actor instanceof LongStringActor ? actor.str : actor.rawValue(); if (!isObject(jsVal)) { - return { bindSelf: jsVal, dbgGlobal, evalGlobal }; + return { bindSelf: jsVal, dbgGlobal }; } // If we use the makeDebuggeeValue method of jsVal's own global, then @@ -687,7 +594,7 @@ function getDbgGlobal(options, dbg, webConsole) { // that is, without wrappers. The evalWithBindings call will then wrap // jsVal appropriately for the evaluation compartment. const bindSelf = dbgGlobal.makeDebuggeeValue(jsVal); - return { bindSelf, dbgGlobal, evalGlobal }; + return { bindSelf, dbgGlobal }; } function getHelpers(dbgGlobal, options, webConsole) { diff --git a/devtools/server/actors/webconsole/webidl-pure-allowlist.js b/devtools/server/actors/webconsole/webidl-pure-allowlist.js index 1bbe6110ece4..911dbfda8570 100644 --- a/devtools/server/actors/webconsole/webidl-pure-allowlist.js +++ b/devtools/server/actors/webconsole/webidl-pure-allowlist.js @@ -7,212 +7,66 @@ "use strict"; module.exports = { - DOMTokenList: { - prototype: { - getters: ["length", "value"], - methods: ["item", "contains"], - }, - }, - Document: { - instance: { - getters: ["location"], - }, - prototype: { - getters: [ - "URL", - "documentURI", - "compatMode", - "characterSet", - "charset", - "inputEncoding", - "contentType", - "doctype", - "documentElement", - "title", - "dir", - "body", - "head", - "images", - "embeds", - "plugins", - "links", - "forms", - "scripts", - "defaultView", - "currentScript", - "anchors", - "applets", - "all", - "styleSheetSets", - "featurePolicy", - "blockedNodeByClassifierCount", - "blockedNodesByClassifier", - "permDelegateHandler", - "children", - "firstElementChild", - "lastElementChild", - "childElementCount", - ], - methods: [ - "getSelection", - "hasStorageAccess", - "getElementsByTagName", - "getElementsByTagNameNS", - "getElementsByClassName", - "getElementById", - "getElementsByName", - "querySelector", - "querySelectorAll", - "createNSResolver", - ], - }, - }, - Element: { - prototype: { - getters: [ - "namespaceURI", - "prefix", - "localName", - "tagName", - "id", - "className", - "classList", - "part", - "attributes", - "innerHTML", - "outerHTML", - "previousElementSibling", - "nextElementSibling", - "children", - "firstElementChild", - "lastElementChild", - "childElementCount", - ], - methods: [ - "getAttributeNames", - "getAttribute", - "getAttributeNS", - "hasAttribute", - "hasAttributeNS", - "hasAttributes", - "closest", - "matches", - "webkitMatchesSelector", - "getElementsByTagName", - "getElementsByTagNameNS", - "getElementsByClassName", - "mozMatchesSelector", - "querySelector", - "querySelectorAll", - "getAsFlexContainer", - "getGridFragments", - "hasGridFragments", - "getElementsWithGrid", - ], - }, - }, - FormData: { - prototype: { - methods: ["entries", "keys", "values"], - }, - }, - Headers: { - prototype: { - methods: ["entries", "keys", "values"], - }, - }, - Location: { - instance: { - getters: [ - "href", - "origin", - "protocol", - "host", - "hostname", - "port", - "pathname", - "search", - "hash", - ], - }, - }, - Node: { - prototype: { - getters: [ - "nodeType", - "nodeName", - "baseURI", - "isConnected", - "ownerDocument", - "parentNode", - "parentElement", - "childNodes", - "firstChild", - "lastChild", - "previousSibling", - "nextSibling", - "nodeValue", - "textContent", - "flattenedTreeParentNode", - "isNativeAnonymous", - "containingShadowRoot", - "accessibleNode", - ], - methods: [ - "getRootNode", - "hasChildNodes", - "isSameNode", - "isEqualNode", - "compareDocumentPosition", - "contains", - "lookupPrefix", - "lookupNamespaceURI", - "isDefaultNamespace", - ], - }, - }, - Performance: { - prototype: { - getters: ["timeOrigin", "timing", "navigation", "eventCounts"], - methods: ["now"], - }, - }, - Range: { - prototype: { - methods: [ - "isPointInRange", - "comparePoint", - "intersectsNode", - "getClientRects", - "getBoundingClientRect", - ], - }, - }, - Selection: { - prototype: { - methods: ["getRangeAt", "containsNode"], - }, - }, - URLSearchParams: { - prototype: { - methods: ["entries", "keys", "values"], - }, - }, - Window: { - instance: { - getters: [ - "location", - "window", - "self", - "document", - "performance", - "browsingContext", - "windowUtils", - "windowGlobalChild", - "visualViewport", - "caches", - "scheduler", - ], - }, - }, + DOMTokenList: [ + ["prototype", "item"], + ["prototype", "contains"], + ], + Document: [ + ["prototype", "getElementsByTagName"], + ["prototype", "getElementsByTagNameNS"], + ["prototype", "getElementsByClassName"], + ["prototype", "getElementById"], + ["prototype", "getElementsByName"], + ["prototype", "querySelector"], + ["prototype", "querySelectorAll"], + ["prototype", "createNSResolver"], + ], + Element: [ + ["prototype", "getAttributeNames"], + ["prototype", "getAttribute"], + ["prototype", "getAttributeNS"], + ["prototype", "hasAttribute"], + ["prototype", "hasAttributeNS"], + ["prototype", "hasAttributes"], + ["prototype", "closest"], + ["prototype", "matches"], + ["prototype", "webkitMatchesSelector"], + ["prototype", "getElementsByTagName"], + ["prototype", "getElementsByTagNameNS"], + ["prototype", "getElementsByClassName"], + ["prototype", "mozMatchesSelector"], + ["prototype", "querySelector"], + ["prototype", "querySelectorAll"], + ["prototype", "getAsFlexContainer"], + ["prototype", "getGridFragments"], + ["prototype", "hasGridFragments"], + ["prototype", "getElementsWithGrid"], + ], + FormData: [ + ["prototype", "entries"], + ["prototype", "keys"], + ["prototype", "values"], + ], + Headers: [ + ["prototype", "entries"], + ["prototype", "keys"], + ["prototype", "values"], + ], + Node: [ + ["prototype", "getRootNode"], + ["prototype", "hasChildNodes"], + ["prototype", "isSameNode"], + ["prototype", "isEqualNode"], + ["prototype", "compareDocumentPosition"], + ["prototype", "contains"], + ["prototype", "lookupPrefix"], + ["prototype", "lookupNamespaceURI"], + ["prototype", "isDefaultNamespace"], + ], + Performance: [["prototype", "now"]], + URLSearchParams: [ + ["prototype", "entries"], + ["prototype", "keys"], + ["prototype", "values"], + ], }; diff --git a/devtools/shared/commands/script/tests/browser_script_command_execute_basic.js b/devtools/shared/commands/script/tests/browser_script_command_execute_basic.js index 6774686bcddc..5eff8c4520a4 100644 --- a/devtools/shared/commands/script/tests/browser_script_command_execute_basic.js +++ b/devtools/shared/commands/script/tests/browser_script_command_execute_basic.js @@ -14,9 +14,6 @@ const { add_task(async () => { const tab = await addTab(`data:text/html;charset=utf-8, - - - Testcase -

Body text

- `); + `); const commands = await CommandsFactory.forTab(tab); await commands.targetCommand.startListening(); @@ -77,8 +63,6 @@ add_task(async () => { await doEagerEvalWithSideEffect(commands); await doEagerEvalWithSideEffectIterator(commands); await doEagerEvalWithSideEffectMonkeyPatched(commands); - await doEagerEvalESGetters(commands); - await doEagerEvalDOMGetters(commands); await commands.destroy(); }); @@ -427,258 +411,3 @@ async function doEagerEvalWithSideEffectMonkeyPatched(commands) { result: "ab", }); } - -async function doEagerEvalESGetters(commands) { - // [code, expectedResult] - const testData = [ - // ArrayBuffer - ["testArrayBuffer.byteLength", 3], - - // DataView - ["testDataView.buffer === testArrayBuffer", true], - ["testDataView.byteLength", 1], - ["testDataView.byteOffset", 2], - - // Map - ["testMap.size", 4], - - // RegExp - ["/a/.dotAll", false], - ["/a/giy.flags", "giy"], - ["/a/g.global", true], - ["/a/g.hasIndices", false], - ["/a/g.ignoreCase", false], - ["/a/g.multiline", false], - ["/a/g.source", "a"], - ["/a/g.sticky", false], - ["/a/g.unicode", false], - - // Set - ["testSet.size", 5], - - // Symbol - ["Symbol.iterator.description", "Symbol.iterator"], - - // TypedArray - ["testInt8Array.buffer === testArrayBuffer", true], - ["testInt8Array.byteLength", 3], - ["testInt8Array.byteOffset", 0], - ["testInt8Array.length", 3], - ["testInt8Array[Symbol.toStringTag]", "Int8Array"], - ]; - - for (const [code, expectedResult] of testData) { - const response = await commands.scriptCommand.execute(code, { - eager: true, - }); - checkObject( - response, - { - input: code, - result: expectedResult, - }, - code - ); - - ok(!response.exception, "no eval exception"); - ok(!response.helperResult, "no helper result"); - } - - const testDataWithSideEffect = [ - // get Object.prototype.__proto__ - // - // This can invoke Proxy getPrototypeOf handler, which can be any native - // function, and debugger cannot hook the call. - `[].__proto__`, - `testProxy.__proto__`, - ]; - - for (const code of testDataWithSideEffect) { - const response = await commands.scriptCommand.execute(code, { - eager: true, - }); - checkObject( - response, - { - input: code, - result: { type: "undefined" }, - }, - code - ); - - ok(!response.exception, "no eval exception"); - ok(!response.helperResult, "no helper result"); - } -} - -async function doEagerEvalDOMGetters(commands) { - // [code, expectedResult] - const testData = [ - // DOMTokenList - ["document.documentElement.classList.length", 1], - ["document.documentElement.classList.value", "class1"], - - // Document - ["document.URL.startsWith('data:')", true], - ["document.documentURI.startsWith('data:')", true], - ["document.compatMode", "CSS1Compat"], - ["document.characterSet", "UTF-8"], - ["document.charset", "UTF-8"], - ["document.inputEncoding", "UTF-8"], - ["document.contentType", "text/html"], - ["document.doctype.constructor.name", "DocumentType"], - ["document.documentElement.constructor.name", "HTMLHtmlElement"], - ["document.title", "Testcase"], - ["document.dir", "ltr"], - ["document.body.constructor.name", "HTMLBodyElement"], - ["document.head.constructor.name", "HTMLHeadElement"], - ["document.images.constructor.name", "HTMLCollection"], - ["document.embeds.constructor.name", "HTMLCollection"], - ["document.plugins.constructor.name", "HTMLCollection"], - ["document.links.constructor.name", "HTMLCollection"], - ["document.forms.constructor.name", "HTMLCollection"], - ["document.scripts.constructor.name", "HTMLCollection"], - ["document.defaultView === window", true], - ["typeof document.currentScript", "object"], - ["document.anchors.constructor.name", "HTMLCollection"], - ["document.applets.constructor.name", "HTMLCollection"], - ["document.all.constructor.name", "HTMLAllCollection"], - ["document.styleSheetSets.constructor.name", "DOMStringList"], - ["typeof document.featurePolicy", "undefined"], - ["typeof document.blockedNodeByClassifierCount", "undefined"], - ["typeof document.blockedNodesByClassifier", "undefined"], - ["typeof document.permDelegateHandler", "undefined"], - ["document.children.constructor.name", "HTMLCollection"], - ["document.firstElementChild === document.documentElement", true], - ["document.lastElementChild === document.documentElement", true], - ["document.childElementCount", 1], - ["document.location.href.startsWith('data:')", true], - - // Element - ["document.body.namespaceURI", "http://www.w3.org/1999/xhtml"], - ["document.body.prefix === null", true], - ["document.body.localName", "body"], - ["document.body.tagName", "BODY"], - ["document.body.id", "body1"], - ["document.body.className", "class2"], - ["document.body.classList.constructor.name", "DOMTokenList"], - ["document.body.part.constructor.name", "DOMTokenList"], - ["document.body.attributes.constructor.name", "NamedNodeMap"], - ["document.body.innerHTML.includes('Body text')", true], - ["document.body.outerHTML.includes('Body text')", true], - ["document.body.previousElementSibling !== null", true], - ["document.body.nextElementSibling === null", true], - ["document.body.children.constructor.name", "HTMLCollection"], - ["document.body.firstElementChild !== null", true], - ["document.body.lastElementChild !== null", true], - ["document.body.childElementCount", 1], - - // Node - ["document.body.nodeType === Node.ELEMENT_NODE", true], - ["document.body.nodeName", "BODY"], - ["document.body.baseURI.startsWith('data:')", true], - ["document.body.isConnected", true], - ["document.body.ownerDocument === document", true], - ["document.body.parentNode === document.documentElement", true], - ["document.body.parentElement === document.documentElement", true], - ["document.body.childNodes.constructor.name", "NodeList"], - ["document.body.firstChild !== null", true], - ["document.body.lastChild !== null", true], - ["document.body.previousSibling !== null", true], - ["document.body.nextSibling === null", true], - ["document.body.nodeValue === null", true], - ["document.body.textContent.includes('Body text')", true], - ["typeof document.body.flattenedTreeParentNode", "undefined"], - ["typeof document.body.isNativeAnonymous", "undefined"], - ["typeof document.body.containingShadowRoot", "undefined"], - ["typeof document.body.accessibleNode", "undefined"], - - // Performance - ["performance.timeOrigin > 0", true], - ["performance.timing.constructor.name", "PerformanceTiming"], - ["performance.navigation.constructor.name", "PerformanceNavigation"], - ["performance.eventCounts.constructor.name", "EventCounts"], - - // window - ["window.window === window", true], - ["window.self === window", true], - ["window.document.constructor.name", "HTMLDocument"], - ["window.performance.constructor.name", "Performance"], - ["typeof window.browsingContext", "undefined"], - ["typeof window.windowUtils", "undefined"], - ["typeof window.windowGlobalChild", "undefined"], - ["window.visualViewport.constructor.name", "VisualViewport"], - ["typeof window.caches", "undefined"], - ["window.scheduler.constructor.name", "Scheduler"], - ["window.location.href.startsWith('data:')", true], - ]; - - for (const [code, expectedResult] of testData) { - const response = await commands.scriptCommand.execute(code, { - eager: true, - }); - checkObject( - response, - { - input: code, - result: expectedResult, - }, - code - ); - - ok(!response.exception, "no eval exception"); - ok(!response.helperResult, "no helper result"); - } - - const testDataWithSideEffect = [ - // NOTE: This is not an exhaustive list. - // Document - `document.implementation`, - `document.domain`, - `document.referrer`, - `document.cookie`, - `document.lastModified`, - `document.readyState`, - `document.designMode`, - `document.onbeforescriptexecute`, - `document.onafterscriptexecute`, - - // Element - `document.documentElement.scrollTop`, - `document.documentElement.scrollLeft`, - `document.documentElement.scrollWidth`, - `document.documentElement.scrollHeight`, - - // Performance - `performance.onresourcetimingbufferfull`, - - // window - `window.name`, - `window.history`, - `window.customElements`, - `window.locationbar`, - `window.menubar`, - `window.status`, - `window.closed`, - - // CanvasRenderingContext2D / CanvasCompositing - `testCanvasContext.globalAlpha`, - ]; - - for (const code of testDataWithSideEffect) { - const response = await commands.scriptCommand.execute(code, { - eager: true, - }); - checkObject( - response, - { - input: code, - result: { type: "undefined" }, - }, - code - ); - - ok(!response.exception, "no eval exception"); - ok(!response.helperResult, "no helper result"); - } -} diff --git a/devtools/shared/commands/script/tests/head.js b/devtools/shared/commands/script/tests/head.js index 50635e45022f..95472c7f71b2 100644 --- a/devtools/shared/commands/script/tests/head.js +++ b/devtools/shared/commands/script/tests/head.js @@ -9,7 +9,7 @@ Services.scriptloader.loadSubScript( this ); -function checkObject(object, expected, message) { +function checkObject(object, expected) { if (object && object.getGrip) { object = object.getGrip(); } @@ -17,35 +17,28 @@ function checkObject(object, expected, message) { for (const name of Object.keys(expected)) { const expectedValue = expected[name]; const value = object[name]; - checkValue(name, value, expectedValue, message); + checkValue(name, value, expectedValue); } } -function checkValue(name, value, expected, message) { - if (message) { - message = ` for '${message}'`; - } - +function checkValue(name, value, expected) { if (expected === null) { - is(value, null, `'${name}' is null${message}`); + is(value, null, `'${name}' is null`); } else if (expected === undefined) { - is(value, expected, `'${name}' is undefined${message}`); + is(value, expected, `'${name}' is undefined`); } else if ( typeof expected == "string" || typeof expected == "number" || typeof expected == "boolean" ) { - is(value, expected, "property '" + name + "'" + message); + is(value, expected, "property '" + name + "'"); } else if (expected instanceof RegExp) { - ok( - expected.test(value), - name + ": " + expected + " matched " + value + message - ); + ok(expected.test(value), name + ": " + expected + " matched " + value); } else if (Array.isArray(expected)) { - info("checking array for property '" + name + "'" + message); - checkObject(value, expected, message); + info("checking array for property '" + name + "'"); + checkObject(value, expected); } else if (typeof expected == "object") { - info("checking object for property '" + name + "'" + message); - checkObject(value, expected, message); + info("checking object for property '" + name + "'"); + checkObject(value, expected); } } diff --git a/devtools/shared/webconsole/GenerateDataFromWebIdls.py b/devtools/shared/webconsole/GenerateDataFromWebIdls.py index 59d9c135c034..77940cae74e5 100644 --- a/devtools/shared/webconsole/GenerateDataFromWebIdls.py +++ b/devtools/shared/webconsole/GenerateDataFromWebIdls.py @@ -21,7 +21,6 @@ import buildconfig # that we don't care about in the context of the devtools. PURE_INTERFACE_ALLOWLIST = set( [ - "Window", "Document", "Node", "DOMTokenList", @@ -78,101 +77,28 @@ for filepath in file_list["webidls"]: parser.parse(f.read(), filepath) results = parser.finish() -# TODO: Bug 1616013 - Move more of these to be part of the pure list. -pure_output = { - "Document": { - "instance": { - "getters": [ - "location", - ], - }, - "prototype": { - "methods": [ - "getSelection", - "hasStorageAccess", - ], - }, - }, - "Range": { - "prototype": { - "methods": [ - "isPointInRange", - "comparePoint", - "intersectsNode", - # These two functions aren't pure because they do trigger - # layout when they are called, but in the context of eager - # evaluation, that should be a totally fine thing to do. - "getClientRects", - "getBoundingClientRect", - ], - } - }, - "Selection": { - "prototype": { - "methods": ["getRangeAt", "containsNode"], - } - }, - "Window": { - "instance": { - "getters": [ - "location", - ], - }, - }, - "Location": { - "instance": { - "getters": [ - "href", - "origin", - "protocol", - "host", - "hostname", - "port", - "pathname", - "search", - "hash", - ], - }, - }, -} +pure_output = {} deprecated_output = {} for result in results: if isinstance(result, WebIDL.IDLInterface): iface = result.identifier.name - is_global = result.getExtendedAttribute("Global") - for member in result.members: name = member.identifier.name - if (member.isMethod() or member.isAttr()) and member.affects == "Nothing": + # We only care about methods because eager evaluation assumes that + # all getter functions are side-effect-free. + if member.isMethod() and member.affects == "Nothing": if ( PURE_INTERFACE_ALLOWLIST and not iface in PURE_INTERFACE_ALLOWLIST ) or name.startswith("_"): continue - - if iface not in pure_output: - pure_output[iface] = {} - - if is_global: - owner_type = "instance" - elif member.isStatic(): - owner_type = "static" + if not iface in pure_output: + pure_output[iface] = [] + if member.isStatic(): + pure_output[iface].append([name]) else: - owner_type = "prototype" - - if owner_type not in pure_output[iface]: - pure_output[iface][owner_type] = {} - - if member.isMethod(): - prop_type = "methods" - else: - prop_type = "getters" - - if prop_type not in pure_output[iface][owner_type]: - pure_output[iface][owner_type][prop_type] = [] - - pure_output[iface][owner_type][prop_type].append(name) + pure_output[iface].append(["prototype", name]) if ( not iface in DEPRECATED_INTERFACE__EXCLUDE_LIST and (member.isMethod() or member.isAttr()) diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index 7e605c770d99..f76e7f30834b 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -1530,11 +1530,6 @@ static bool XrayResolveAttribute( cacheOnHolder = true; - JS::Rooted getterId(cx); - if (!JS::ToGetterId(cx, id, &getterId)) { - return false; - } - // Because of centralization, we need to make sure we fault in the JitInfos as // well. At present, until the JSAPI changes, the easiest way to do this is // wrap them up as functions ourselves. @@ -1542,21 +1537,16 @@ static bool XrayResolveAttribute( // They all have getters, so we can just make it. JS::Rooted getter( cx, XrayCreateFunction(cx, wrapper, attrSpec.u.accessors.getter.native, 0, - getterId)); + id)); if (!getter) { return false; } JS::Rooted setter(cx); if (attrSpec.u.accessors.setter.native.op) { - JS::Rooted setterId(cx); - if (!JS::ToSetterId(cx, id, &setterId)) { - return false; - } - // We have a setter! Make it. setter = XrayCreateFunction(cx, wrapper, attrSpec.u.accessors.setter.native, - 1, setterId); + 1, id); if (!setter) { return false; } diff --git a/js/public/Id.h b/js/public/Id.h index e57c5266788a..6fb67ec2d184 100644 --- a/js/public/Id.h +++ b/js/public/Id.h @@ -255,16 +255,6 @@ MOZ_ALWAYS_INLINE void AssertIdIsNotGray(jsid id) { extern JS_PUBLIC_API PropertyKey GetWellKnownSymbolKey(JSContext* cx, SymbolCode which); -/** - * Generate getter/setter id for given id, by adding "get " or "set " prefix. - */ -extern JS_PUBLIC_API bool ToGetterId( - JSContext* cx, JS::Handle id, - JS::MutableHandle getterId); -extern JS_PUBLIC_API bool ToSetterId( - JSContext* cx, JS::Handle id, - JS::MutableHandle setterId); - } // namespace JS namespace js { diff --git a/js/src/debugger/Debugger.cpp b/js/src/debugger/Debugger.cpp index b456f54a9a09..293310305b6b 100644 --- a/js/src/debugger/Debugger.cpp +++ b/js/src/debugger/Debugger.cpp @@ -970,22 +970,19 @@ NativeResumeMode DebugAPI::slowPathOnNativeCall(JSContext* cx, // The onNativeCall hook is fired when self hosted functions are called, // and any other self hosted function or C++ native that is directly called // by the self hosted function is considered to be part of the same - // native call, except for the following 4 cases: + // native call, except for the following 2 cases: // // * callContentFunction and constructContentFunction, // which uses CallReason::CallContent // * Function.prototype.call and Function.prototype.apply, // which uses CallReason::FunCall - // * Getter call which uses CallReason::Getter - // * Setter call which uses CallReason::Setter // // We check this only after checking that debuggerList has items in order // to avoid unnecessary calls to cx->currentScript(), which can be expensive // when the top frame is in jitcode. JSScript* script = cx->currentScript(); if (script && script->selfHosted() && reason != CallReason::CallContent && - reason != CallReason::FunCall && reason != CallReason::Getter && - reason != CallReason::Setter) { + reason != CallReason::FunCall) { return NativeResumeMode::Continue; } diff --git a/js/src/debugger/Object.cpp b/js/src/debugger/Object.cpp index 56c846794236..b6d2c54e7a97 100644 --- a/js/src/debugger/Object.cpp +++ b/js/src/debugger/Object.cpp @@ -207,7 +207,6 @@ struct MOZ_STACK_CLASS DebuggerObject::CallData { bool makeDebuggeeValueMethod(); bool makeDebuggeeNativeFunctionMethod(); bool isSameNativeMethod(); - bool isSameNativeWithJitInfoMethod(); bool unsafeDereferenceMethod(); bool unwrapMethod(); bool getPromiseReactionsMethod(); @@ -1331,18 +1330,7 @@ bool DebuggerObject::CallData::isSameNativeMethod() { return false; } - return DebuggerObject::isSameNative(cx, object, args[0], CheckJitInfo::No, - args.rval()); -} - -bool DebuggerObject::CallData::isSameNativeWithJitInfoMethod() { - if (!args.requireAtLeast( - cx, "Debugger.Object.prototype.isSameNativeWithJitInfo", 1)) { - return false; - } - - return DebuggerObject::isSameNative(cx, object, args[0], CheckJitInfo::Yes, - args.rval()); + return DebuggerObject::isSameNative(cx, object, args[0], args.rval()); } bool DebuggerObject::CallData::unsafeDereferenceMethod() { @@ -1532,7 +1520,6 @@ const JSFunctionSpec DebuggerObject::methods_[] = { JS_DEBUG_FN("makeDebuggeeNativeFunction", makeDebuggeeNativeFunctionMethod, 1), JS_DEBUG_FN("isSameNative", isSameNativeMethod, 1), - JS_DEBUG_FN("isSameNativeWithJitInfo", isSameNativeWithJitInfoMethod, 1), JS_DEBUG_FN("unsafeDereference", unsafeDereferenceMethod, 0), JS_DEBUG_FN("unwrap", unwrapMethod, 0), JS_DEBUG_FN("getPromiseReactions", getPromiseReactionsMethod, 0), @@ -2553,36 +2540,9 @@ static JSAtom* MaybeGetSelfHostedFunctionName(const Value& v) { return GetClonedSelfHostedFunctionName(fun); } -static bool IsSameNative(JSFunction* a, JSFunction* b, - DebuggerObject::CheckJitInfo checkJitInfo) { - if (a->native() != b->native()) { - return false; - } - - if (checkJitInfo == DebuggerObject::CheckJitInfo::No) { - return true; - } - - // Both function should agree with the existence of JitInfo. - - if (a->hasJitInfo() != b->hasJitInfo()) { - return false; - } - - if (!a->hasJitInfo()) { - return true; - } - - if (a->jitInfo() == b->jitInfo()) { - return true; - } - - return false; -} - /* static */ bool DebuggerObject::isSameNative(JSContext* cx, Handle object, - HandleValue value, CheckJitInfo checkJitInfo, + HandleValue value, MutableHandleValue result) { RootedValue referentValue(cx, ObjectValue(*object->referent())); @@ -2605,9 +2565,7 @@ bool DebuggerObject::isSameNative(JSContext* cx, Handle object, } RootedFunction referentFun(cx, EnsureNativeFunction(referentValue)); - - result.setBoolean(referentFun && - IsSameNative(referentFun, fun, checkJitInfo)); + result.setBoolean(referentFun && referentFun->native() == fun->native()); return true; } diff --git a/js/src/debugger/Object.h b/js/src/debugger/Object.h index 69e4ad02c795..5a5ea149e0bb 100644 --- a/js/src/debugger/Object.h +++ b/js/src/debugger/Object.h @@ -148,11 +148,9 @@ class DebuggerObject : public NativeObject { [[nodiscard]] static bool makeDebuggeeNativeFunction( JSContext* cx, Handle object, HandleValue value, MutableHandleValue result); - enum class CheckJitInfo { No, Yes }; [[nodiscard]] static bool isSameNative(JSContext* cx, Handle object, HandleValue value, - CheckJitInfo checkJitInfo, MutableHandleValue result); [[nodiscard]] static bool unsafeDereference(JSContext* cx, Handle object, diff --git a/js/src/doc/Debugger/Debugger.Object.md b/js/src/doc/Debugger/Debugger.Object.md index 88e302aab61d..006c049181e4 100644 --- a/js/src/doc/Debugger/Debugger.Object.md +++ b/js/src/doc/Debugger/Debugger.Object.md @@ -476,15 +476,6 @@ compartment wrapper. If value is a native function in the debugger's compartment, return whether the referent is a native function for the same C++ native. -### `isSameNativeWithJitInfo(value)` -If value is a native function in the debugger's compartment, return -whether the referent is a native function for the same C++ native with the -same JSJitInfo pointer value. - -This can be used to distinguish functions with shared native function -implementation with different JSJitInfo pointer to define the underlying -functionality. - ### `decompile([pretty])` If the referent is a function that is debuggee code, return the JavaScript source code for a function definition equivalent to the diff --git a/js/src/jit-test/tests/debug/Debugger-onNativeCall-06.js b/js/src/jit-test/tests/debug/Debugger-onNativeCall-06.js index d28c8b6e94b9..abc779593fc7 100644 --- a/js/src/jit-test/tests/debug/Debugger-onNativeCall-06.js +++ b/js/src/jit-test/tests/debug/Debugger-onNativeCall-06.js @@ -7,7 +7,7 @@ var g = newGlobal({ newCompartment: true }); var dbg = new Debugger(); var gdbg = dbg.addDebuggee(g); -let rv = []; +const rv = []; dbg.onNativeCall = (callee, reason) => { rv.push(callee.name); }; @@ -26,43 +26,8 @@ gdbg.executeInGlobal(` "abc".match(/a./); `); assertEqArray(rv, [ - "map", "get [Symbol.species]", "push", "push", "push", - "map", "get [Symbol.species]", "padStart", "padStart", "padStart", - "map", "get [Symbol.species]", "dateNow", "dateNow", "dateNow", + "map", "push", "push", "push", + "map", "padStart", "padStart", "padStart", + "map", "dateNow", "dateNow", "dateNow", "match", "[Symbol.match]", ]); - -rv = []; -gdbg.executeInGlobal(` -// Nested getters called internally inside self-hosted. -const r = /a./; -r.foo = 10; -"abc".match(r); - -// Setter inside self-hosted JS. -// Hook "A.length = n" at the end of Array.prototype.concat. -var a = [1, 2, 3]; -Object.defineProperty(a, "constructor", { - get() { - return class { - constructor() { - let obj = {}; - Object.defineProperty(obj, "length", { set: Array.prototype.join }); - return obj; - } - static get [Symbol.species]() { - return this; - } - } - } -}); -void Array.prototype.concat.call(a, [10, 20, 30]); -`); -assertEqArray(rv, [ - "match", "[Symbol.match]", - "get flags", - "get hasIndices", "get global", "get ignoreCase", "get multiline", - "get dotAll", "get unicode", "get sticky", - - "defineProperty", "call", "concat", "defineProperty", "join", -]); diff --git a/js/src/jit-test/tests/debug/Object-isSameNativeWithJitInfo.js b/js/src/jit-test/tests/debug/Object-isSameNativeWithJitInfo.js deleted file mode 100644 index 648847ae491c..000000000000 --- a/js/src/jit-test/tests/debug/Object-isSameNativeWithJitInfo.js +++ /dev/null @@ -1,32 +0,0 @@ -var g = newGlobal({newCompartment: true}); -var dbg = Debugger(g); -var gdbg = dbg.addDebuggee(g); - -assertEq(gdbg.getProperty("print").return.isSameNativeWithJitInfo(print), true); -assertEq(gdbg.getProperty("print").return.isSameNativeWithJitInfo(newGlobal), false); - -// FakeDOMObject's accessor shares the single native functions, with -// different JSJitInfo for each. - -gdbg.executeInGlobal(` -var fun1 = Object.getOwnPropertyDescriptor(FakeDOMObject.prototype, "x").get; -var fun2 = Object.getOwnPropertyDescriptor(FakeDOMObject.prototype, "slot").get; -`); - -var g_fun1 = gdbg.executeInGlobal("fun1").return; -var g_fun2 = gdbg.executeInGlobal("fun2").return; - -var fun1 = Object.getOwnPropertyDescriptor(FakeDOMObject.prototype, "x").get; -var fun2 = Object.getOwnPropertyDescriptor(FakeDOMObject.prototype, "slot").get; - -// isSameNative doesn't distinguish between fun1 and fun2. -assertEq(g_fun1.isSameNative(fun1), true); -assertEq(g_fun1.isSameNative(fun2), true); -assertEq(g_fun2.isSameNative(fun1), true); -assertEq(g_fun2.isSameNative(fun2), true); - -// isSameNativeWithJitInfo can distinguish between fun1 and fun2. -assertEq(g_fun1.isSameNativeWithJitInfo(fun1), true); -assertEq(g_fun1.isSameNativeWithJitInfo(fun2), false); -assertEq(g_fun2.isSameNativeWithJitInfo(fun1), false); -assertEq(g_fun2.isSameNativeWithJitInfo(fun2), true); diff --git a/js/src/jsapi-tests/moz.build b/js/src/jsapi-tests/moz.build index f338506d797a..97011f0e4330 100644 --- a/js/src/jsapi-tests/moz.build +++ b/js/src/jsapi-tests/moz.build @@ -96,7 +96,6 @@ UNIFIED_SOURCES += [ "testProfileStrings.cpp", "testPromise.cpp", "testPropCache.cpp", - "testPropertyKey.cpp", "testRecordTupleToSource.cpp", "testRegExp.cpp", "testResolveRecursion.cpp", diff --git a/js/src/jsapi-tests/testPropertyKey.cpp b/js/src/jsapi-tests/testPropertyKey.cpp deleted file mode 100644 index aed210a658ae..000000000000 --- a/js/src/jsapi-tests/testPropertyKey.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "js/Id.h" // JS::PropertyKey, JS::GetWellKnownSymbolKey, JS::ToGetterId, JS::ToSetterId -#include "js/String.h" // JSString, JS_AtomizeString, JS_StringEqualsAscii -#include "js/Symbol.h" // JS::Symbol, JS::SymbolCode -#include "jsapi-tests/tests.h" - -BEGIN_TEST(testPropertyKeyGetterAndSetter) { - JS::Rooted str(cx, JS_AtomizeString(cx, "prop")); - CHECK(str); - - JS::Rooted strId(cx, JS::PropertyKey::NonIntAtom(str)); - MOZ_ASSERT(strId.isString()); - - JS::Rooted symId( - cx, JS::GetWellKnownSymbolKey(cx, JS::SymbolCode::iterator)); - MOZ_ASSERT(symId.isSymbol()); - - JS::Rooted numId(cx, JS::PropertyKey::Int(42)); - MOZ_ASSERT(numId.isInt()); - - bool match; - - JS::Rooted strGetterId(cx); - CHECK(JS::ToGetterId(cx, strId, &strGetterId)); - CHECK(strGetterId.isString()); - CHECK(JS_StringEqualsAscii(cx, strGetterId.toString(), "get prop", &match)); - CHECK(match); - - JS::Rooted strSetterId(cx); - CHECK(JS::ToSetterId(cx, strId, &strSetterId)); - CHECK(strSetterId.isString()); - CHECK(JS_StringEqualsAscii(cx, strSetterId.toString(), "set prop", &match)); - CHECK(match); - - JS::Rooted symGetterId(cx); - CHECK(JS::ToGetterId(cx, symId, &symGetterId)); - CHECK(symGetterId.isString()); - CHECK(JS_StringEqualsAscii(cx, symGetterId.toString(), - "get [Symbol.iterator]", &match)); - CHECK(match); - - JS::Rooted symSetterId(cx); - CHECK(JS::ToSetterId(cx, symId, &symSetterId)); - CHECK(symSetterId.isString()); - CHECK(JS_StringEqualsAscii(cx, symSetterId.toString(), - "set [Symbol.iterator]", &match)); - CHECK(match); - - JS::Rooted numGetterId(cx); - CHECK(JS::ToGetterId(cx, numId, &numGetterId)); - CHECK(numGetterId.isString()); - CHECK(JS_StringEqualsAscii(cx, numGetterId.toString(), "get 42", &match)); - CHECK(match); - - JS::Rooted numSetterId(cx); - CHECK(JS::ToSetterId(cx, numId, &numSetterId)); - CHECK(numSetterId.isString()); - CHECK(JS_StringEqualsAscii(cx, numSetterId.toString(), "set 42", &match)); - CHECK(match); - - return true; -} -END_TEST(testPropertyKeyGetterAndSetter) diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 1a81378dce63..1d48a6acace2 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -76,7 +76,6 @@ #include "vm/EnvironmentObject.h" #include "vm/ErrorObject.h" #include "vm/ErrorReporting.h" -#include "vm/FunctionPrefixKind.h" #include "vm/Interpreter.h" #include "vm/JSAtom.h" #include "vm/JSAtomState.h" @@ -3390,28 +3389,6 @@ JS_PUBLIC_API JS::PropertyKey JS::GetWellKnownSymbolKey(JSContext* cx, return PropertyKey::Symbol(cx->wellKnownSymbols().get(which)); } -static bool AddPrefix(JSContext* cx, JS::Handle id, - FunctionPrefixKind prefixKind, - JS::MutableHandle out) { - JS::Rooted atom(cx, js::IdToFunctionName(cx, id, prefixKind)); - if (!atom) { - return false; - } - - out.set(JS::PropertyKey::NonIntAtom(atom)); - return true; -} - -JS_PUBLIC_API bool JS::ToGetterId(JSContext* cx, JS::Handle id, - JS::MutableHandle getterId) { - return AddPrefix(cx, id, FunctionPrefixKind::Get, getterId); -} - -JS_PUBLIC_API bool JS::ToSetterId(JSContext* cx, JS::Handle id, - JS::MutableHandle setterId) { - return AddPrefix(cx, id, FunctionPrefixKind::Set, setterId); -} - #ifdef DEBUG static bool PropertySpecNameIsDigits(JSPropertySpec::Name name) { if (name.isSymbol()) {