author | Noemi Erli <nerli@mozilla.com> |
Sat, 14 Apr 2018 12:49:03 +0300 | |
changeset 413357 | 37b8862d354e0014a72715462dd2102dd5b599cc |
parent 413311 | 26bee50f8c274bdc0a38b5a77f9991f5159bc399 (current diff) |
parent 413356 | a434fac58370fc14bceb525e1ca8b7125638b6cd (diff) |
child 413358 | 2e635314b75f06c5652cd1a60e46bd116bc5c270 |
child 413363 | b8c5eb9fb1e6b4979d566ca78a1aab85e558bfb0 |
push id | 33843 |
push user | nerli@mozilla.com |
push date | Sat, 14 Apr 2018 09:49:25 +0000 |
treeherder | mozilla-central@37b8862d354e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
milestone | 61.0a1 |
first release with | nightly linux32
37b8862d354e
/
61.0a1
/
20180414100503
/
files
nightly linux64
37b8862d354e
/
61.0a1
/
20180414100503
/
files
nightly mac
37b8862d354e
/
61.0a1
/
20180414100503
/
files
nightly win32
37b8862d354e
/
61.0a1
/
20180414100503
/
files
nightly win64
37b8862d354e
/
61.0a1
/
20180414100503
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
61.0a1
/
20180414100503
/
pushlog to previous
nightly linux64
61.0a1
/
20180414100503
/
pushlog to previous
nightly mac
61.0a1
/
20180414100503
/
pushlog to previous
nightly win32
61.0a1
/
20180414100503
/
pushlog to previous
nightly win64
61.0a1
/
20180414100503
/
pushlog to previous
|
dom/base/nsContentUtils.cpp | file | annotate | diff | comparison | revisions | |
dom/payments/test/Bug1443914ChromeScript.js | file | annotate | diff | comparison | revisions | |
dom/payments/test/test_bug1443914.html | file | annotate | diff | comparison | revisions | |
js/src/gc/ZoneGroup.cpp | file | annotate | diff | comparison | revisions | |
js/src/gc/ZoneGroup.h | file | annotate | diff | comparison | revisions | |
js/src/jsapi-tests/testToIntWidth.cpp | file | annotate | diff | comparison | revisions |
--- a/browser/base/content/test/static/browser_parsable_css.js +++ b/browser/base/content/test/static/browser_parsable_css.js @@ -20,17 +20,17 @@ let whitelist = [ {sourceName: /devtools-client-shared\/components\/reps\/reps.css/i, isFromDevTools: true}, // PDFjs is futureproofing its pseudoselectors, and those rules are dropped. {sourceName: /web\/viewer\.css$/i, errorMessage: /Unknown pseudo-class.*(fullscreen|selection)/i, isFromDevTools: false}, // PDFjs rules needed for compat with other UAs. {sourceName: /web\/viewer\.css$/i, - errorMessage: /Unknown property.*appearance/i, + errorMessage: /Unknown property.*(appearance|user-select)/i, isFromDevTools: false}, // Highlighter CSS uses a UA-only pseudo-class, see bug 985597. {sourceName: /highlighters\.css$/i, errorMessage: /Unknown pseudo-class.*moz-native-anonymous/i, isFromDevTools: true}, // Responsive Design Mode CSS uses a UA-only pseudo-class, see Bug 1241714. {sourceName: /responsive-ua\.css$/i, errorMessage: /Unknown pseudo-class.*moz-dropdown-list/i,
--- a/browser/extensions/pdfjs/README.mozilla +++ b/browser/extensions/pdfjs/README.mozilla @@ -1,5 +1,5 @@ This is the PDF.js project output, https://github.com/mozilla/pdf.js -Current extension version is: 2.0.480 +Current extension version is: 2.0.491 -Taken from upstream commit: a7a034d8 +Taken from upstream commit: 2dc4af52
--- a/browser/extensions/pdfjs/content/PdfStreamConverter.jsm +++ b/browser/extensions/pdfjs/content/PdfStreamConverter.jsm @@ -14,16 +14,17 @@ */ "use strict"; var EXPORTED_SYMBOLS = ["PdfStreamConverter"]; const PDFJS_EVENT_ID = "pdf.js.message"; const PREF_PREFIX = "pdfjs"; +const PDF_VIEWER_ORIGIN = "resource://pdf.js"; const PDF_VIEWER_WEB_PAGE = "resource://pdf.js/web/viewer.html"; const MAX_NUMBER_OF_PREFS = 50; const MAX_STRING_PREF_LENGTH = 128; ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.defineModuleGetter(this, "NetUtil", @@ -76,21 +77,25 @@ function log(aMsg) { if (!getBoolPref(PREF_PREFIX + ".pdfBugEnabled", false)) { return; } var msg = "PdfStreamConverter.js: " + (aMsg.join ? aMsg.join("") : aMsg); Services.console.logStringMessage(msg); dump(msg + "\n"); } -function getDOMWindow(aChannel) { +function getDOMWindow(aChannel, aPrincipal) { var requestor = aChannel.notificationCallbacks ? aChannel.notificationCallbacks : aChannel.loadGroup.notificationCallbacks; var win = requestor.getInterface(Ci.nsIDOMWindow); + // Ensure the window wasn't navigated to something that is not PDF.js. + if (!win.document.nodePrincipal.equals(aPrincipal)) { + return null; + } return win; } function getLocalizedStrings(path) { var stringBundle = Services.strings.createBundle("chrome://pdf.js/locale/" + path); var map = {}; @@ -590,31 +595,31 @@ class RangedChromeActions extends Chrome data = this.dataListener.readData(); this.dataListener.onprogress = (loaded, total) => { this.domWindow.postMessage({ pdfjsLoadAction: "progressiveRead", loaded, total, chunk: this.dataListener.readData(), - }, "*"); + }, PDF_VIEWER_ORIGIN); }; this.dataListener.oncomplete = () => { this.dataListener = null; }; } this.domWindow.postMessage({ pdfjsLoadAction: "supportsRangedLoading", rangeEnabled: this.rangeEnabled, streamingEnabled: this.streamingEnabled, pdfUrl: this.pdfUrl, length: this.contentLength, data, - }, "*"); + }, PDF_VIEWER_ORIGIN); return true; } requestDataRange(args) { if (!this.rangeEnabled) { return; } @@ -626,23 +631,23 @@ class RangedChromeActions extends Chrome // errors from chrome code for non-range requests, so this doesn't // seem high-pri this.networkManager.requestRange(begin, end, { onDone: function RangedChromeActions_onDone(aArgs) { domWindow.postMessage({ pdfjsLoadAction: "range", begin: aArgs.begin, chunk: aArgs.chunk, - }, "*"); + }, PDF_VIEWER_ORIGIN); }, onProgress: function RangedChromeActions_onProgress(evt) { domWindow.postMessage({ pdfjsLoadAction: "rangeProgress", loaded: evt.loaded, - }, "*"); + }, PDF_VIEWER_ORIGIN); }, }); } abortLoading() { this.networkManager.abortAllRequests(); if (this.originalRequest) { this.originalRequest.cancel(Cr.NS_BINDING_ABORTED); @@ -668,25 +673,25 @@ class StandardChromeActions extends Chro return false; } this.dataListener.onprogress = (loaded, total) => { this.domWindow.postMessage({ pdfjsLoadAction: "progress", loaded, total, - }, "*"); + }, PDF_VIEWER_ORIGIN); }; this.dataListener.oncomplete = (data, errorCode) => { this.domWindow.postMessage({ pdfjsLoadAction: "complete", data, errorCode, - }, "*"); + }, PDF_VIEWER_ORIGIN); this.dataListener = null; this.originalRequest = null; }; return true; } @@ -934,30 +939,34 @@ PdfStreamConverter.prototype = { onStartRequest(request, context) { listener.onStartRequest(aRequest, aContext); }, onDataAvailable(request, context, inputStream, offset, count) { listener.onDataAvailable(aRequest, aContext, inputStream, offset, count); }, onStopRequest(request, context, statusCode) { - // We get the DOM window here instead of before the request since it - // may have changed during a redirect. - var domWindow = getDOMWindow(channel); + var domWindow = getDOMWindow(channel, resourcePrincipal); + if (!Components.isSuccessCode(statusCode) || !domWindow) { + // The request may have been aborted and the document may have been + // replaced with something that is not PDF.js, abort attaching. + listener.onStopRequest(aRequest, context, statusCode); + return; + } var actions; if (rangeRequest || streamRequest) { actions = new RangedChromeActions( domWindow, contentDispositionFilename, aRequest, rangeRequest, streamRequest, dataListener); } else { actions = new StandardChromeActions( domWindow, contentDispositionFilename, aRequest, dataListener); } var requestListener = new RequestListener(actions); - domWindow.addEventListener(PDFJS_EVENT_ID, function(event) { + domWindow.document.addEventListener(PDFJS_EVENT_ID, function(event) { requestListener.receive(event); }, false, true); if (actions.supportsIntegratedFind()) { var findEventManager = new FindEventManager(domWindow); findEventManager.bind(); } listener.onStopRequest(aRequest, aContext, statusCode);
--- a/browser/extensions/pdfjs/content/build/pdf.js +++ b/browser/extensions/pdfjs/content/build/pdf.js @@ -1645,18 +1645,18 @@ exports.GlobalWorkerOptions = GlobalWork /***/ }), /* 5 */ /***/ (function(module, exports, __w_pdfjs_require__) { "use strict"; -var pdfjsVersion = '2.0.480'; -var pdfjsBuild = 'a7a034d8'; +var pdfjsVersion = '2.0.491'; +var pdfjsBuild = '2dc4af52'; var pdfjsSharedUtil = __w_pdfjs_require__(0); var pdfjsDisplayAPI = __w_pdfjs_require__(9); var pdfjsDisplayTextLayer = __w_pdfjs_require__(17); var pdfjsDisplayAnnotationLayer = __w_pdfjs_require__(18); var pdfjsDisplayDOMUtils = __w_pdfjs_require__(1); var pdfjsDisplaySVG = __w_pdfjs_require__(19); let pdfjsDisplayWorkerOptions = __w_pdfjs_require__(4); let pdfjsDisplayAPICompatibility = __w_pdfjs_require__(3); @@ -4924,17 +4924,17 @@ function _fetchDocument(worker, source, return Promise.reject(new Error('Worker was destroyed')); } if (pdfDataRangeTransport) { source.length = pdfDataRangeTransport.length; source.initialData = pdfDataRangeTransport.initialData; } return worker.messageHandler.sendWithPromise('GetDocRequest', { docId, - apiVersion: '2.0.480', + apiVersion: '2.0.491', source: { data: source.data, url: source.url, password: source.password, disableAutoFetch: source.disableAutoFetch, rangeChunkSize: source.rangeChunkSize, length: source.length }, @@ -6247,18 +6247,18 @@ var InternalRenderTask = function Intern } } } }; return InternalRenderTask; }(); var version, build; { - exports.version = version = '2.0.480'; - exports.build = build = 'a7a034d8'; + exports.version = version = '2.0.491'; + exports.build = build = '2dc4af52'; } exports.getDocument = getDocument; exports.LoopbackPort = LoopbackPort; exports.PDFDataRangeTransport = PDFDataRangeTransport; exports.PDFWorker = PDFWorker; exports.PDFDocumentProxy = PDFDocumentProxy; exports.PDFPageProxy = PDFPageProxy; exports.setPDFNetworkStreamFactory = setPDFNetworkStreamFactory;
--- a/browser/extensions/pdfjs/content/build/pdf.worker.js +++ b/browser/extensions/pdfjs/content/build/pdf.worker.js @@ -2753,19 +2753,19 @@ var ColorSpace = function ColorSpaceClos } } } }, usesZeroToOneRange: true }; ColorSpace.parse = function (cs, xref, res, pdfFunctionFactory) { let IR = ColorSpace.parseToIR(cs, xref, res, pdfFunctionFactory); - return ColorSpace.fromIR(IR, pdfFunctionFactory); - }; - ColorSpace.fromIR = function (IR, pdfFunctionFactory) { + return ColorSpace.fromIR(IR); + }; + ColorSpace.fromIR = function (IR) { var name = Array.isArray(IR) ? IR[0] : IR; var whitePoint, blackPoint, gamma; switch (name) { case 'DeviceGrayCS': return this.singletons.gray; case 'DeviceRgbCS': return this.singletons.rgb; case 'DeviceCmykCS': @@ -2779,29 +2779,29 @@ var ColorSpace = function ColorSpaceClos whitePoint = IR[1]; blackPoint = IR[2]; gamma = IR[3]; var matrix = IR[4]; return new CalRGBCS(whitePoint, blackPoint, gamma, matrix); case 'PatternCS': var basePatternCS = IR[1]; if (basePatternCS) { - basePatternCS = ColorSpace.fromIR(basePatternCS, pdfFunctionFactory); + basePatternCS = ColorSpace.fromIR(basePatternCS); } return new PatternCS(basePatternCS); case 'IndexedCS': var baseIndexedCS = IR[1]; var hiVal = IR[2]; var lookup = IR[3]; - return new IndexedCS(ColorSpace.fromIR(baseIndexedCS, pdfFunctionFactory), hiVal, lookup); + return new IndexedCS(ColorSpace.fromIR(baseIndexedCS), hiVal, lookup); case 'AlternateCS': var numComps = IR[1]; var alt = IR[2]; - var tintFnIR = IR[3]; - return new AlternateCS(numComps, ColorSpace.fromIR(alt, pdfFunctionFactory), pdfFunctionFactory.createFromIR(tintFnIR)); + var tintFn = IR[3]; + return new AlternateCS(numComps, ColorSpace.fromIR(alt), tintFn); case 'LabCS': whitePoint = IR[1]; blackPoint = IR[2]; var range = IR[3]; return new LabCS(whitePoint, blackPoint, range); default: throw new _util.FormatError(`Unknown colorspace name: ${name}`); } @@ -2900,18 +2900,18 @@ var ColorSpace = function ColorSpaceClos lookup = lookup.getBytes(); } return ['IndexedCS', baseIndexedCS, hiVal, lookup]; case 'Separation': case 'DeviceN': var name = xref.fetchIfRef(cs[1]); numComps = Array.isArray(name) ? name.length : 1; alt = ColorSpace.parseToIR(cs[2], xref, res, pdfFunctionFactory); - let tintFnIR = pdfFunctionFactory.createIR(xref.fetchIfRef(cs[3])); - return ['AlternateCS', numComps, alt, tintFnIR]; + let tintFn = pdfFunctionFactory.create(xref.fetchIfRef(cs[3])); + return ['AlternateCS', numComps, alt, tintFn]; case 'Lab': params = xref.fetchIfRef(cs[1]); whitePoint = params.getArray('WhitePoint'); blackPoint = params.getArray('BlackPoint'); var range = params.getArray('Range'); return ['LabCS', whitePoint, blackPoint, range]; default: throw new _util.FormatError(`unimplemented color space object "${mode}"`); @@ -20086,30 +20086,32 @@ class PDFFunctionFactory { } createFromArray(fnObj) { return PDFFunction.parseArray({ xref: this.xref, isEvalSupported: this.isEvalSupported, fnObj }); } - createFromIR(IR) { - return PDFFunction.fromIR({ - xref: this.xref, - isEvalSupported: this.isEvalSupported, - IR - }); - } - createIR(fn) { - return PDFFunction.getIR({ - xref: this.xref, - isEvalSupported: this.isEvalSupported, - fn - }); - } +} +function toNumberArray(arr) { + if (!Array.isArray(arr)) { + return null; + } + const length = arr.length; + for (let i = 0; i < length; i++) { + if (typeof arr[i] !== 'number') { + const result = new Array(length); + for (let i = 0; i < length; i++) { + result[i] = +arr[i]; + } + return result; + } + } + return arr; } var PDFFunction = function PDFFunctionClosure() { const CONSTRUCT_SAMPLED = 0; const CONSTRUCT_INTERPOLATED = 2; const CONSTRUCT_STICHED = 3; const CONSTRUCT_POSTSCRIPT = 4; return { getSampleArray(size, outputSize, bps, stream) { @@ -20224,41 +20226,41 @@ var PDFFunction = function PDFFunctionCl var out = []; var index = 0; for (var i = 0; i < inputLength; i += 2) { out[index] = [arr[i], arr[i + 1]]; ++index; } return out; } - var domain = dict.getArray('Domain'); - var range = dict.getArray('Range'); + var domain = toNumberArray(dict.getArray('Domain')); + var range = toNumberArray(dict.getArray('Range')); if (!domain || !range) { throw new _util.FormatError('No domain or range'); } var inputSize = domain.length / 2; var outputSize = range.length / 2; domain = toMultiArray(domain); range = toMultiArray(range); - var size = dict.get('Size'); + var size = toNumberArray(dict.get('Size')); var bps = dict.get('BitsPerSample'); var order = dict.get('Order') || 1; if (order !== 1) { (0, _util.info)('No support for cubic spline interpolation: ' + order); } - var encode = dict.getArray('Encode'); + var encode = toNumberArray(dict.getArray('Encode')); if (!encode) { encode = []; for (var i = 0; i < inputSize; ++i) { - encode.push(0); - encode.push(size[i] - 1); - } - } - encode = toMultiArray(encode); - var decode = dict.getArray('Decode'); + encode.push([0, size[i] - 1]); + } + } else { + encode = toMultiArray(encode); + } + var decode = toNumberArray(dict.getArray('Decode')); if (!decode) { decode = range; } else { decode = toMultiArray(decode); } var samples = this.getSampleArray(size, outputSize, bps, fn); return [CONSTRUCT_SAMPLED, inputSize, domain, encode, decode, samples, size, outputSize, Math.pow(2, bps) - 1, range]; }, @@ -20314,22 +20316,19 @@ var PDFFunction = function PDFFunctionCl rj += samples[cubeVertex[i] + j] * cubeN[i]; } rj = interpolate(rj, 0, 1, decode[j][0], decode[j][1]); dest[destOffset + j] = Math.min(Math.max(rj, range[j][0]), range[j][1]); } }; }, constructInterpolated({ xref, isEvalSupported, fn, dict }) { - var c0 = dict.getArray('C0') || [0]; - var c1 = dict.getArray('C1') || [1]; + var c0 = toNumberArray(dict.getArray('C0')) || [0]; + var c1 = toNumberArray(dict.getArray('C1')) || [1]; var n = dict.get('N'); - if (!Array.isArray(c0) || !Array.isArray(c1)) { - throw new _util.FormatError('Illegal dictionary for interpolated function'); - } var length = c0.length; var diff = []; for (var i = 0; i < length; ++i) { diff.push(c1[i] - c0[i]); } return [CONSTRUCT_INTERPOLATED, c0, diff, n]; }, constructInterpolatedFromIR({ xref, isEvalSupported, IR }) { @@ -20340,51 +20339,43 @@ var PDFFunction = function PDFFunctionCl return function constructInterpolatedFromIRResult(src, srcOffset, dest, destOffset) { var x = n === 1 ? src[srcOffset] : Math.pow(src[srcOffset], n); for (var j = 0; j < length; ++j) { dest[destOffset + j] = c0[j] + x * diff[j]; } }; }, constructStiched({ xref, isEvalSupported, fn, dict }) { - var domain = dict.getArray('Domain'); + var domain = toNumberArray(dict.getArray('Domain')); if (!domain) { throw new _util.FormatError('No domain'); } var inputSize = domain.length / 2; if (inputSize !== 1) { throw new _util.FormatError('Bad domain for stiched function'); } var fnRefs = dict.get('Functions'); var fns = []; for (var i = 0, ii = fnRefs.length; i < ii; ++i) { - fns.push(this.getIR({ + fns.push(this.parse({ xref, isEvalSupported, fn: xref.fetchIfRef(fnRefs[i]) })); } - var bounds = dict.getArray('Bounds'); - var encode = dict.getArray('Encode'); + var bounds = toNumberArray(dict.getArray('Bounds')); + var encode = toNumberArray(dict.getArray('Encode')); return [CONSTRUCT_STICHED, domain, bounds, encode, fns]; }, constructStichedFromIR({ xref, isEvalSupported, IR }) { var domain = IR[1]; var bounds = IR[2]; var encode = IR[3]; - var fnsIR = IR[4]; - var fns = []; + var fns = IR[4]; var tmpBuf = new Float32Array(1); - for (var i = 0, ii = fnsIR.length; i < ii; i++) { - fns.push(this.fromIR({ - xref, - isEvalSupported, - IR: fnsIR[i] - })); - } return function constructStichedFromIRResult(src, srcOffset, dest, destOffset) { var clip = function constructStichedFromIRClip(v, min, max) { if (v > max) { v = max; } else if (v < min) { v = min; } return v; @@ -20405,18 +20396,18 @@ var PDFFunction = function PDFFunctionCl } var rmin = encode[2 * i]; var rmax = encode[2 * i + 1]; tmpBuf[0] = dmin === dmax ? rmin : rmin + (v - dmin) * (rmax - rmin) / (dmax - dmin); fns[i](tmpBuf, 0, dest, destOffset); }; }, constructPostScript({ xref, isEvalSupported, fn, dict }) { - var domain = dict.getArray('Domain'); - var range = dict.getArray('Range'); + var domain = toNumberArray(dict.getArray('Domain')); + var range = toNumberArray(dict.getArray('Range')); if (!domain) { throw new _util.FormatError('No domain.'); } if (!range) { throw new _util.FormatError('No range.'); } var lexer = new _ps_parser.PostScriptLexer(fn); var parser = new _ps_parser.PostScriptParser(lexer); @@ -21107,18 +21098,18 @@ exports.PostScriptCompiler = PostScriptC /***/ }), /* 19 */ /***/ (function(module, exports, __w_pdfjs_require__) { "use strict"; -var pdfjsVersion = '2.0.480'; -var pdfjsBuild = 'a7a034d8'; +var pdfjsVersion = '2.0.491'; +var pdfjsBuild = '2dc4af52'; var pdfjsCoreWorker = __w_pdfjs_require__(20); exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler; /***/ }), /* 20 */ /***/ (function(module, exports, __w_pdfjs_require__) { "use strict"; @@ -21309,17 +21300,17 @@ var WorkerMessageHandler = { }); }, createDocumentHandler(docParams, port) { var pdfManager; var terminated = false; var cancelXHRs = null; var WorkerTasks = []; let apiVersion = docParams.apiVersion; - let workerVersion = '2.0.480'; + let workerVersion = '2.0.491'; if (apiVersion !== null && apiVersion !== workerVersion) { throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`); } var docId = docParams.docId; var docBaseUrl = docParams.docBaseUrl; var workerHandlerName = docParams.docId + '_worker'; var handler = new _util.MessageHandler(workerHandlerName, docId, port); handler.postMessageTransfers = docParams.postMessageTransfers; @@ -35126,17 +35117,20 @@ var FontRendererFactory = function FontR } function parseCff(data, start, end, seacAnalysisEnabled) { var properties = {}; var parser = new _cff_parser.CFFParser(new _stream.Stream(data, start, end - start), properties, seacAnalysisEnabled); var cff = parser.parse(); return { glyphs: cff.charStrings.objects, subrs: cff.topDict.privateDict && cff.topDict.privateDict.subrsIndex && cff.topDict.privateDict.subrsIndex.objects, - gsubrs: cff.globalSubrIndex && cff.globalSubrIndex.objects + gsubrs: cff.globalSubrIndex && cff.globalSubrIndex.objects, + isCFFCIDFont: cff.isCIDFont, + fdSelect: cff.fdSelect, + fdArray: cff.fdArray }; } function parseGlyfTable(glyf, loca, isGlyphLocationsLong) { var itemSize, itemDecode; if (isGlyphLocationsLong) { itemSize = 4; itemDecode = function fontItemDecodeLong(data, offset) { return data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3]; @@ -35330,17 +35324,17 @@ var FontRendererFactory = function FontR } else { quadraticCurveTo(contour[j].x, contour[j].y, (contour[j].x + contour[j + 1].x) / 2, (contour[j].y + contour[j + 1].y) / 2); } } startPoint = endPoint + 1; } } } - function compileCharString(code, cmds, font) { + function compileCharString(code, cmds, font, glyphId) { var stack = []; var x = 0, y = 0; var stems = 0; function moveTo(x, y) { cmds.push({ cmd: 'moveTo', args: [x, y] @@ -35414,18 +35408,37 @@ var FontRendererFactory = function FontR xb = xa + stack.shift(); yb = ya + stack.shift(); x = xb + stack.shift(); y = yb + stack.shift(); bezierCurveTo(xa, ya, xb, yb, x, y); } break; case 10: - n = stack.pop() + font.subrsBias; - subrCode = font.subrs[n]; + n = stack.pop(); + subrCode = null; + if (font.isCFFCIDFont) { + let fdIndex = font.fdSelect.getFDIndex(glyphId); + if (fdIndex >= 0 && fdIndex < font.fdArray.length) { + let fontDict = font.fdArray[fdIndex], + subrs; + if (fontDict.privateDict && fontDict.privateDict.subrsIndex) { + subrs = fontDict.privateDict.subrsIndex.objects; + } + if (subrs) { + let numSubrs = subrs.length; + n += numSubrs < 1240 ? 107 : numSubrs < 33900 ? 1131 : 32768; + subrCode = subrs[n]; + } + } else { + (0, _util.warn)('Invalid fd index for glyph index.'); + } + } else { + subrCode = font.subrs[n + font.subrsBias]; + } if (subrCode) { parse(subrCode); } break; case 11: return; case 12: v = code[i++]; @@ -35505,20 +35518,20 @@ var FontRendererFactory = function FontR y = stack.pop(); x = stack.pop(); cmds.push({ cmd: 'save' }); cmds.push({ cmd: 'translate', args: [x, y] }); var cmap = lookupCmap(font.cmap, String.fromCharCode(font.glyphNameMap[_encodings.StandardEncoding[achar]])); - compileCharString(font.glyphs[cmap.glyphId], cmds, font); + compileCharString(font.glyphs[cmap.glyphId], cmds, font, cmap.glyphId); cmds.push({ cmd: 'restore' }); cmap = lookupCmap(font.cmap, String.fromCharCode(font.glyphNameMap[_encodings.StandardEncoding[bchar]])); - compileCharString(font.glyphs[cmap.glyphId], cmds, font); + compileCharString(font.glyphs[cmap.glyphId], cmds, font, cmap.glyphId); } return; case 18: stems += stack.length >> 1; stackClean = true; break; case 19: stems += stack.length >> 1; @@ -35683,39 +35696,49 @@ var FontRendererFactory = function FontR this.compiledCharCodeToGlyphId = Object.create(null); this.fontMatrix = fontMatrix; } CompiledFont.prototype = { getPathJs(unicode) { var cmap = lookupCmap(this.cmap, unicode); var fn = this.compiledGlyphs[cmap.glyphId]; if (!fn) { - fn = this.compileGlyph(this.glyphs[cmap.glyphId]); + fn = this.compileGlyph(this.glyphs[cmap.glyphId], cmap.glyphId); this.compiledGlyphs[cmap.glyphId] = fn; } if (this.compiledCharCodeToGlyphId[cmap.charCode] === undefined) { this.compiledCharCodeToGlyphId[cmap.charCode] = cmap.glyphId; } return fn; }, - compileGlyph(code) { + compileGlyph(code, glyphId) { if (!code || code.length === 0 || code[0] === 14) { return noop; } + let fontMatrix = this.fontMatrix; + if (this.isCFFCIDFont) { + let fdIndex = this.fdSelect.getFDIndex(glyphId); + if (fdIndex >= 0 && fdIndex < this.fdArray.length) { + let fontDict = this.fdArray[fdIndex]; + fontMatrix = fontDict.getByName('FontMatrix') || _util.FONT_IDENTITY_MATRIX; + } else { + (0, _util.warn)('Invalid fd index for glyph index.'); + } + } var cmds = []; cmds.push({ cmd: 'save' }); cmds.push({ cmd: 'transform', - args: this.fontMatrix.slice() + args: fontMatrix.slice() }); cmds.push({ cmd: 'scale', args: ['size', '-size'] }); - this.compileGlyphImpl(code, cmds); + this.compileGlyphImpl(code, cmds, glyphId); cmds.push({ cmd: 'restore' }); return cmds; }, compileGlyphImpl() { (0, _util.unreachable)('Children classes should implement this.'); }, hasBuiltPath(unicode) { var cmap = lookupCmap(this.cmap, unicode); @@ -35738,20 +35761,23 @@ var FontRendererFactory = function FontR CompiledFont.call(this, fontMatrix); this.glyphs = cffInfo.glyphs; this.gsubrs = cffInfo.gsubrs || []; this.subrs = cffInfo.subrs || []; this.cmap = cmap; this.glyphNameMap = glyphNameMap || (0, _glyphlist.getGlyphsUnicode)(); this.gsubrsBias = this.gsubrs.length < 1240 ? 107 : this.gsubrs.length < 33900 ? 1131 : 32768; this.subrsBias = this.subrs.length < 1240 ? 107 : this.subrs.length < 33900 ? 1131 : 32768; + this.isCFFCIDFont = cffInfo.isCFFCIDFont; + this.fdSelect = cffInfo.fdSelect; + this.fdArray = cffInfo.fdArray; } _util.Util.inherit(Type2Compiled, CompiledFont, { - compileGlyphImpl(code, cmds) { - compileCharString(code, cmds, this); + compileGlyphImpl(code, cmds, glyphId) { + compileCharString(code, cmds, this, glyphId); } }); return { create: function FontRendererFactory_create(font, seacAnalysisEnabled) { var data = new Uint8Array(font.data); var cmap, glyf, loca, cff, indexToLocFormat, unitsPerEm; var numTables = getUshort(data, 4); for (var i = 0, p = 12; i < numTables; i++, p += 16) {
--- a/browser/extensions/pdfjs/content/web/viewer.css +++ b/browser/extensions/pdfjs/content/web/viewer.css @@ -24,17 +24,16 @@ line-height: 1.0; } .textLayer > div { color: transparent; position: absolute; white-space: pre; cursor: text; - -moz-transform-origin: 0% 0%; transform-origin: 0% 0%; } .textLayer .highlight { margin: -1px; padding: 1px; background-color: rgb(180, 0, 170); @@ -52,29 +51,31 @@ .textLayer .highlight.middle { border-radius: 0px; } .textLayer .highlight.selected { background-color: rgb(0, 100, 0); } +.textLayer ::-moz-selection { background: rgb(0,0,255); } + .textLayer ::selection { background: rgb(0,0,255); } -.textLayer ::-moz-selection { background: rgb(0,0,255); } .textLayer .endOfContent { display: block; position: absolute; left: 0px; top: 100%; right: 0px; bottom: 0px; z-index: -1; cursor: default; -moz-user-select: none; + user-select: none; } .textLayer .endOfContent.active { top: 0px; } .annotationLayer section { @@ -204,17 +205,17 @@ * when the element has focus and revert this when it loses focus. */ width: 115%; } .annotationLayer .buttonWidgetAnnotation.checkBox input, .annotationLayer .buttonWidgetAnnotation.radioButton input { -moz-appearance: none; - appearance: none; + appearance: none; padding: 0; } .annotationLayer .popupWrapper { position: absolute; width: 20em; } @@ -360,27 +361,29 @@ select { top: 0px; border-top: 2px solid transparent; background-color: #000; width: 100%; height: 100%; overflow: hidden; cursor: none; -moz-user-select: none; + user-select: none; } #viewerContainer.pdfPresentationMode:fullscreen { top: 0px; border-top: 2px solid transparent; background-color: #000; width: 100%; height: 100%; overflow: hidden; cursor: none; -moz-user-select: none; + user-select: none; } .pdfPresentationMode:-moz-full-screen a:not(.internalLink) { display: none; } .pdfPresentationMode:fullscreen a:not(.internalLink) { display: none; @@ -434,16 +437,17 @@ html[dir='rtl'] #sidebarContainer { top: 36px; } #outerContainer.sidebarResizing #sidebarContainer { /* Improve responsiveness and avoid visual glitches when the sidebar is resized. */ transition-duration: 0s; /* Prevent e.g. the thumbnails being selected when the sidebar is resized. */ -moz-user-select: none; + user-select: none; } #outerContainer.sidebarMoving #sidebarContainer, #outerContainer.sidebarOpen #sidebarContainer { visibility: visible; } html[dir='ltr'] #outerContainer.sidebarOpen #sidebarContainer { left: 0px; @@ -659,24 +663,22 @@ html[dir='ltr'] .findbar { left: 68px; } html[dir='rtl'] .findbar { right: 68px; } .findbar label { -moz-user-select: none; + user-select: none; } #findInput { width: 200px; } -#findInput::-moz-placeholder { - font-style: italic; -} #findInput::placeholder { font-style: italic; } #findInput[data-status="pending"] { background-image: url(images/loading-small.png); background-repeat: no-repeat; background-position: right; } @@ -928,16 +930,17 @@ html[dir='rtl'] .splitToolbarButtonSepar min-width: 16px; padding: 2px 6px 0; border: 1px solid transparent; border-radius: 2px; color: hsla(0,0%,100%,.8); font-size: 12px; line-height: 14px; -moz-user-select: none; + user-select: none; /* Opera does not support user-select, use <... unselectable="on"> instead */ cursor: default; transition-property: background-color, border-color, box-shadow; transition-duration: 150ms; transition-timing-function: ease; } html[dir='ltr'] .toolbarButton, @@ -1359,16 +1362,17 @@ html[dir='rtl'] .verticalToolbarSeparato margin: 4px 2px 4px 0; border: 1px solid transparent; border-radius: 2px; color: hsl(0,0%,85%); font-size: 12px; line-height: 14px; text-align: left; -moz-user-select: none; + user-select: none; cursor: default; } #thumbnailView { position: absolute; width: calc(100% - 60px); top: 0; bottom: 0; @@ -1447,16 +1451,17 @@ a:focus > .thumbnail > .thumbnailSelecti #outlineView, #attachmentsView { position: absolute; width: calc(100% - 8px); top: 0; bottom: 0; overflow: auto; -moz-user-select: none; + user-select: none; } #outlineView { padding: 4px 4px 0; } #attachmentsView { padding: 3px 4px 0; } @@ -1480,16 +1485,17 @@ html[dir='rtl'] .outlineItem > .outlineI of the container. */ height: auto; margin-bottom: 1px; border-radius: 2px; color: hsla(0,0%,100%,.8); font-size: 13px; line-height: 15px; -moz-user-select: none; + user-select: none; white-space: normal; } .attachmentsItem > button { border: 0 none; background: none; cursor: pointer; width: 100%; @@ -1574,18 +1580,18 @@ html[dir='rtl'] .outlineItemToggler::bef color: hsla(0,0%,100%,.8); font-style: italic; cursor: default; } /* TODO: file FF bug to support ::-moz-selection:window-inactive so we can override the opaque grey background when the window is inactive; see https://bugzilla.mozilla.org/show_bug.cgi?id=706209 */ +::-moz-selection { background: rgba(0,0,255,0.3); } ::selection { background: rgba(0,0,255,0.3); } -::-moz-selection { background: rgba(0,0,255,0.3); } #errorWrapper { background: none repeat scroll 0 0 #FF5555; color: white; left: 0; position: absolute; right: 0; z-index: 1000;
--- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -6421,60 +6421,43 @@ nsContentUtils::GetUTFOrigin(nsIPrincipa } /* static */ nsresult nsContentUtils::GetUTFOrigin(nsIURI* aURI, nsAString& aOrigin) { NS_PRECONDITION(aURI, "missing uri"); - // For Blob URI we have to return the origin of page using its principal. - nsCOMPtr<nsIURIWithPrincipal> uriWithPrincipal = do_QueryInterface(aURI); - if (uriWithPrincipal) { - nsCOMPtr<nsIPrincipal> principal; - uriWithPrincipal->GetPrincipal(getter_AddRefs(principal)); - - if (principal) { - nsCOMPtr<nsIURI> uri; - nsresult rv = principal->GetURI(getter_AddRefs(uri)); - NS_ENSURE_SUCCESS(rv, rv); - - if (uri && uri != aURI) { - return GetUTFOrigin(uri, aOrigin); - } - } else { - // We are probably dealing with an unknown blob URL. - bool isBlobURL = false; - nsresult rv = aURI->SchemeIs(BLOBURI_SCHEME, &isBlobURL); - NS_ENSURE_SUCCESS(rv, rv); - - if (isBlobURL) { - nsAutoCString path; - rv = aURI->GetPathQueryRef(path); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr<nsIURI> uri; - nsresult rv = NS_NewURI(getter_AddRefs(uri), path); - if (NS_FAILED(rv)) { - aOrigin.AssignLiteral("null"); - return NS_OK; - } - - return GetUTFOrigin(uri, aOrigin); - } - } + bool isBlobURL = false; + nsresult rv = aURI->SchemeIs(BLOBURI_SCHEME, &isBlobURL); + NS_ENSURE_SUCCESS(rv, rv); + + // For Blob URI, the path is the URL of the owning page. + if (isBlobURL) { + nsAutoCString path; + rv = aURI->GetPathQueryRef(path); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr<nsIURI> uri; + nsresult rv = NS_NewURI(getter_AddRefs(uri), path); + if (NS_FAILED(rv)) { + aOrigin.AssignLiteral("null"); + return NS_OK; + } + + return GetUTFOrigin(uri, aOrigin); } aOrigin.Truncate(); nsCOMPtr<nsIURI> uri = NS_GetInnermostURI(aURI); NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED); nsCString host; - nsresult rv = uri->GetHost(host); + rv = uri->GetHost(host); if (NS_SUCCEEDED(rv) && !host.IsEmpty()) { nsCString scheme; rv = uri->GetScheme(scheme); NS_ENSURE_SUCCESS(rv, rv); int32_t port = -1; uri->GetPort(&port);
--- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -5374,24 +5374,27 @@ def getJSToNativeConversionInfo(type, de getPromiseGlobal = dedent( """ // We basically want our entry global here. Play it safe // and use GetEntryGlobal() to get it, with whatever // principal-clamping it ends up doing. globalObj = GetEntryGlobal()->GetGlobalJSObject(); """) else: - getPromiseGlobal = "" + getPromiseGlobal = dedent( + """ + globalObj = JS::CurrentGlobalOrNull(cx); + """) templateBody = fill( """ { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment, // etc. - JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx)); + JS::Rooted<JSObject*> globalObj(cx); $*{getPromiseGlobal} JSAutoCompartment ac(cx, globalObj); GlobalObject promiseGlobal(cx, globalObj); if (promiseGlobal.Failed()) { $*{exceptionCode} } JS::Rooted<JS::Value> valueToResolve(cx, $${val});
--- a/dom/broadcastchannel/BroadcastChannel.cpp +++ b/dom/broadcastchannel/BroadcastChannel.cpp @@ -120,58 +120,16 @@ public: private: RefPtr<ThreadSafeWorkerRef> mWorkerRef; nsACString& mOrigin; PrincipalInfo& mPrincipalInfo; ErrorResult& mRv; }; -class BCPostMessageRunnable final : public nsIRunnable, - public nsICancelableRunnable -{ -public: - NS_DECL_ISUPPORTS - - BCPostMessageRunnable(BroadcastChannelChild* aActor, - BroadcastChannelMessage* aData) - : mActor(aActor) - , mData(aData) - { - MOZ_ASSERT(mActor); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(mActor); - if (mActor->IsActorDestroyed()) { - return NS_OK; - } - - ClonedMessageData message; - mData->BuildClonedMessageDataForBackgroundChild(mActor->Manager(), message); - mActor->SendPostMessage(message); - return NS_OK; - } - - nsresult Cancel() override - { - mActor = nullptr; - return NS_OK; - } - -private: - ~BCPostMessageRunnable() {} - - RefPtr<BroadcastChannelChild> mActor; - RefPtr<BroadcastChannelMessage> mData; -}; - -NS_IMPL_ISUPPORTS(BCPostMessageRunnable, nsICancelableRunnable, nsIRunnable) - class CloseRunnable final : public nsIRunnable, public nsICancelableRunnable { public: NS_DECL_ISUPPORTS explicit CloseRunnable(BroadcastChannel* aBC) : mBC(aBC) @@ -393,45 +351,28 @@ void BroadcastChannel::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage, ErrorResult& aRv) { if (mState != StateActive) { aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return; } - PostMessageInternal(aCx, aMessage, aRv); -} - -void -BroadcastChannel::PostMessageInternal(JSContext* aCx, - JS::Handle<JS::Value> aMessage, - ErrorResult& aRv) -{ RefPtr<BroadcastChannelMessage> data = new BroadcastChannelMessage(); data->Write(aCx, aMessage, aRv); if (NS_WARN_IF(aRv.Failed())) { return; } - PostMessageData(data); -} - -void -BroadcastChannel::PostMessageData(BroadcastChannelMessage* aData) -{ RemoveDocFromBFCache(); - RefPtr<BCPostMessageRunnable> runnable = - new BCPostMessageRunnable(mActor, aData); - - if (NS_FAILED(NS_DispatchToCurrentThread(runnable))) { - NS_WARNING("Failed to dispatch to the current thread!"); - } + ClonedMessageData message; + data->BuildClonedMessageDataForBackgroundChild(mActor->Manager(), message); + mActor->SendPostMessage(message); } void BroadcastChannel::Close() { if (mState != StateActive) { return; }
--- a/dom/broadcastchannel/tests/test_event_listener_leaks.html +++ b/dom/broadcastchannel/tests/test_event_listener_leaks.html @@ -18,20 +18,20 @@ // exercise the leak condition. let count = 0; async function useBroadcastChannel(contentWindow) { contentWindow.messageCount = 0; count += 1; const name = `test_event_listener_leaks-${count}`; + let bc = new contentWindow.BroadcastChannel(name); let outer = new BroadcastChannel(name); outer.postMessage('foo'); - let bc = new contentWindow.BroadcastChannel(name); await new Promise(resolve => { bc.onmessage = e => { contentWindow.messageCount += 1; resolve(); }; }); is(contentWindow.messageCount, 1, "message should be received");
--- a/dom/encoding/FallbackEncoding.cpp +++ b/dom/encoding/FallbackEncoding.cpp @@ -1,16 +1,17 @@ /* -*- 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 "mozilla/dom/FallbackEncoding.h" +#include "mozilla/ArrayUtils.h" #include "mozilla/Encoding.h" #include "mozilla/intl/LocaleService.h" #include "mozilla/Preferences.h" #include "mozilla/Services.h" #include "nsIObserverService.h" #include "nsUConvPropertySearch.h" using mozilla::intl::LocaleService;
--- a/dom/fetch/Request.cpp +++ b/dom/fetch/Request.cpp @@ -204,51 +204,38 @@ GetRequestURLFromWorker(const GlobalObje nsAString& aRequestURL, nsACString& aURLfragment, ErrorResult& aRv) { RefPtr<URL> url = ParseURLFromWorker(aGlobal, aInput, aRv); if (aRv.Failed()) { return; } nsString username; - url->GetUsername(username, aRv); - if (NS_WARN_IF(aRv.Failed())) { - return; - } + url->GetUsername(username); nsString password; - url->GetPassword(password, aRv); - if (NS_WARN_IF(aRv.Failed())) { - return; - } + url->GetPassword(password); + if (!username.IsEmpty() || !password.IsEmpty()) { aRv.ThrowTypeError<MSG_URL_HAS_CREDENTIALS>(aInput); return; } + // Get the fragment from URL. nsAutoString fragment; - url->GetHash(fragment, aRv); - if (NS_WARN_IF(aRv.Failed())) { - return; - } + url->GetHash(fragment); // Note: URL::GetHash() includes the "#" and we want the fragment with out // the hash symbol. if (!fragment.IsEmpty()) { CopyUTF16toUTF8(Substring(fragment, 1), aURLfragment); } - url->SetHash(EmptyString(), aRv); - if (NS_WARN_IF(aRv.Failed())) { - return; - } - url->Stringify(aRequestURL, aRv); - if (NS_WARN_IF(aRv.Failed())) { - return; - } + url->SetHash(EmptyString()); + url->Stringify(aRequestURL); } class ReferrerSameOriginChecker final : public WorkerMainThreadRunnable { public: ReferrerSameOriginChecker(WorkerPrivate* aWorkerPrivate, const nsAString& aReferrerURL, nsresult& aResult) @@ -394,21 +381,17 @@ Request::Constructor(const GlobalObject& } } } else { RefPtr<URL> url = ParseURLFromWorker(aGlobal, referrer, aRv); if (NS_WARN_IF(aRv.Failed())) { aRv.ThrowTypeError<MSG_INVALID_REFERRER_URL>(referrer); return nullptr; } - url->Stringify(referrerURL, aRv); - if (NS_WARN_IF(aRv.Failed())) { - aRv.ThrowTypeError<MSG_INVALID_REFERRER_URL>(referrer); - return nullptr; - } + url->Stringify(referrerURL); if (!referrerURL.EqualsLiteral(kFETCH_CLIENT_REFERRER_STR)) { WorkerPrivate* worker = GetCurrentThreadWorkerPrivate(); nsresult rv = NS_OK; // ReferrerSameOriginChecker uses a sync loop to get the main thread // to perform the same-origin check. Overall, on Workers this method // can create 3 sync loops (two for constructing URLs and one here) so // in the future we may want to optimize it all by off-loading all of // this work in a single sync loop.
--- a/dom/fetch/Response.cpp +++ b/dom/fetch/Response.cpp @@ -124,21 +124,17 @@ Response::Redirect(const GlobalObject& a worker->AssertIsOnWorkerThread(); NS_ConvertUTF8toUTF16 baseURL(worker->GetLocationInfo().mHref); RefPtr<URL> url = URL::WorkerConstructor(aGlobal, aUrl, baseURL, aRv); if (aRv.Failed()) { return nullptr; } - url->Stringify(parsedURL, aRv); - } - - if (aRv.Failed()) { - return nullptr; + url->Stringify(parsedURL); } if (aStatus != 301 && aStatus != 302 && aStatus != 303 && aStatus != 307 && aStatus != 308) { aRv.ThrowRangeError<MSG_INVALID_REDIRECT_STATUSCODE_ERROR>(); return nullptr; } Optional<Nullable<fetch::ResponseBodyInit>> body;
--- a/dom/interfaces/payments/nsIPaymentActionRequest.idl +++ b/dom/interfaces/payments/nsIPaymentActionRequest.idl @@ -77,25 +77,31 @@ interface nsIPaymentCreateActionRequest readonly attribute nsIPaymentDetails details; /* * The Options information of the payment request. */ readonly attribute nsIPaymentOptions options; /* + * The selected shipping option of the payment request; + */ + readonly attribute AString shippingOption; + + /* * Initialize function the this request. */ void initRequest(in AString aRequestId, in nsIPaymentActionCallback aCallback, in uint64_t aTabId, in nsIPrincipal aPrincipal, in nsIArray aMethodData, in nsIPaymentDetails aDetails, - in nsIPaymentOptions aOptions); + in nsIPaymentOptions aOptions, + in AString aShippingOption); }; [builtinclass, uuid(4429697d-1135-47de-a46e-5196d399ec55)] interface nsIPaymentCompleteActionRequest : nsIPaymentActionRequest { /* * The complete status from merchant side. */ @@ -113,21 +119,27 @@ interface nsIPaymentCompleteActionReques interface nsIPaymentUpdateActionRequest : nsIPaymentActionRequest { /* * The details information for updating the specified payment request. */ readonly attribute nsIPaymentDetails details; /* + * The selected shipping option information + */ + readonly attribute AString shippingOption; + + /* * Initialize function for this request. */ void initRequest(in AString aRequestId, in nsIPaymentActionCallback aCallback, - in nsIPaymentDetails aDetails); + in nsIPaymentDetails aDetails, + in AString aShippingOption); }; %{C++ #define NS_PAYMENT_ACTION_REQUEST_CID \ { 0x7ddbe8be, 0xbeac, 0x4952, { 0x96, 0xf6, 0x61, 0x99, 0x81, 0xdf, 0xf7, 0xa6 } } #define NS_PAYMENT_ACTION_REQUEST_CONTRACT_ID \ "@mozilla.org/dom/payments/payment-action-request;1"
--- a/dom/interfaces/payments/nsIPaymentRequest.idl +++ b/dom/interfaces/payments/nsIPaymentRequest.idl @@ -80,12 +80,14 @@ interface nsIPaymentRequest : nsISupport { readonly attribute uint64_t tabId; readonly attribute nsIPrincipal topLevelPrincipal; readonly attribute AString requestId; readonly attribute AString completeStatus; readonly attribute nsIArray paymentMethods; readonly attribute nsIPaymentDetails paymentDetails; readonly attribute nsIPaymentOptions paymentOptions; + readonly attribute AString shippingOption; [noscript] void setCompleteStatus(in AString aCompleteStatus); - void updatePaymentDetails(in nsIPaymentDetails aDetails); + void updatePaymentDetails(in nsIPaymentDetails aDetails, + in AString aShippingOption); };
--- a/dom/payments/PaymentActionRequest.cpp +++ b/dom/payments/PaymentActionRequest.cpp @@ -73,32 +73,34 @@ PaymentCreateActionRequest::PaymentCreat NS_IMETHODIMP PaymentCreateActionRequest::InitRequest(const nsAString& aRequestId, nsIPaymentActionCallback* aCallback, const uint64_t aTabId, nsIPrincipal* aTopLevelPrincipal, nsIArray* aMethodData, nsIPaymentDetails* aDetails, - nsIPaymentOptions* aOptions) + nsIPaymentOptions* aOptions, + const nsAString& aShippingOption) { NS_ENSURE_ARG_POINTER(aCallback); NS_ENSURE_ARG_POINTER(aTopLevelPrincipal); NS_ENSURE_ARG_POINTER(aMethodData); NS_ENSURE_ARG_POINTER(aDetails); NS_ENSURE_ARG_POINTER(aOptions); nsresult rv = Init(aRequestId, nsIPaymentActionRequest::CREATE_ACTION, aCallback); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } mTabId = aTabId; mTopLevelPrincipal = aTopLevelPrincipal; mMethodData = aMethodData; mDetails = aDetails; mOptions = aOptions; + mShippingOption = aShippingOption; return NS_OK; } NS_IMETHODIMP PaymentCreateActionRequest::GetTabId(uint64_t* aTabId) { NS_ENSURE_ARG_POINTER(aTabId); *aTabId = mTabId; @@ -140,16 +142,23 @@ PaymentCreateActionRequest::GetOptions(n { NS_ENSURE_ARG_POINTER(aOptions); MOZ_ASSERT(mOptions); nsCOMPtr<nsIPaymentOptions> options = mOptions; options.forget(aOptions); return NS_OK; } +NS_IMETHODIMP +PaymentCreateActionRequest::GetShippingOption(nsAString& aShippingOption) +{ + aShippingOption = mShippingOption; + return NS_OK; +} + /* PaymentCompleteActionRequest */ NS_IMPL_ISUPPORTS_INHERITED(PaymentCompleteActionRequest, PaymentActionRequest, nsIPaymentCompleteActionRequest) PaymentCompleteActionRequest::PaymentCompleteActionRequest() : mCompleteStatus(EmptyString()) @@ -189,24 +198,33 @@ PaymentUpdateActionRequest::GetDetails(n NS_ENSURE_ARG_POINTER(aDetails); MOZ_ASSERT(mDetails); nsCOMPtr<nsIPaymentDetails> details = mDetails; details.forget(aDetails); return NS_OK; } NS_IMETHODIMP +PaymentUpdateActionRequest::GetShippingOption(nsAString& aShippingOption) +{ + aShippingOption = mShippingOption; + return NS_OK; +} + +NS_IMETHODIMP PaymentUpdateActionRequest::InitRequest(const nsAString& aRequestId, nsIPaymentActionCallback* aCallback, - nsIPaymentDetails* aDetails) + nsIPaymentDetails* aDetails, + const nsAString& aShippingOption) { NS_ENSURE_ARG_POINTER(aCallback); NS_ENSURE_ARG_POINTER(aDetails); nsresult rv = Init(aRequestId, nsIPaymentActionRequest::UPDATE_ACTION, aCallback); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } mDetails = aDetails; + mShippingOption = aShippingOption; return NS_OK; } } // end of namespace dom } // end of namespace mozilla
--- a/dom/payments/PaymentActionRequest.h +++ b/dom/payments/PaymentActionRequest.h @@ -44,16 +44,17 @@ public: private: ~PaymentCreateActionRequest() = default; uint64_t mTabId; nsCOMPtr<nsIPrincipal> mTopLevelPrincipal; nsCOMPtr<nsIArray> mMethodData; nsCOMPtr<nsIPaymentDetails> mDetails; nsCOMPtr<nsIPaymentOptions> mOptions; + nsString mShippingOption; }; class PaymentCompleteActionRequest final : public nsIPaymentCompleteActionRequest , public PaymentActionRequest { public: NS_DECL_ISUPPORTS_INHERITED NS_FORWARD_NSIPAYMENTACTIONREQUEST(PaymentActionRequest::) @@ -75,14 +76,15 @@ public: NS_FORWARD_NSIPAYMENTACTIONREQUEST(PaymentActionRequest::) NS_DECL_NSIPAYMENTUPDATEACTIONREQUEST PaymentUpdateActionRequest() = default; private: ~PaymentUpdateActionRequest() = default; nsCOMPtr<nsIPaymentDetails> mDetails; + nsString mShippingOption; }; } // end of namespace dom } // end of namespace mozilla #endif
--- a/dom/payments/PaymentRequestData.cpp +++ b/dom/payments/PaymentRequestData.cpp @@ -604,23 +604,25 @@ PaymentOptions::GetShippingType(nsAStrin NS_IMPL_ISUPPORTS(PaymentRequest, nsIPaymentRequest) PaymentRequest::PaymentRequest(const uint64_t aTabId, const nsAString& aRequestId, nsIPrincipal* aTopLevelPrincipal, nsIArray* aPaymentMethods, nsIPaymentDetails* aPaymentDetails, - nsIPaymentOptions* aPaymentOptions) + nsIPaymentOptions* aPaymentOptions, + const nsAString& aShippingOption) : mTabId(aTabId) , mRequestId(aRequestId) , mTopLevelPrincipal(aTopLevelPrincipal) , mPaymentMethods(aPaymentMethods) , mPaymentDetails(aPaymentDetails) , mPaymentOptions(aPaymentOptions) + , mShippingOption(aShippingOption) { } NS_IMETHODIMP PaymentRequest::GetTabId(uint64_t* aTabId) { NS_ENSURE_ARG_POINTER(aTabId); *aTabId = mTabId; @@ -670,24 +672,33 @@ PaymentRequest::GetPaymentOptions(nsIPay NS_ENSURE_ARG_POINTER(aPaymentOptions); MOZ_ASSERT(mPaymentOptions); nsCOMPtr<nsIPaymentOptions> options = mPaymentOptions; options.forget(aPaymentOptions); return NS_OK; } NS_IMETHODIMP -PaymentRequest::UpdatePaymentDetails(nsIPaymentDetails* aPaymentDetails) +PaymentRequest::GetShippingOption(nsAString& aShippingOption) +{ + aShippingOption = mShippingOption; + return NS_OK; +} + +NS_IMETHODIMP +PaymentRequest::UpdatePaymentDetails(nsIPaymentDetails* aPaymentDetails, + const nsAString& aShippingOption) { MOZ_ASSERT(aPaymentDetails); bool requestShipping; nsresult rv = mPaymentOptions->GetRequestShipping(&requestShipping); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } + mShippingOption = aShippingOption; return mPaymentDetails->Update(aPaymentDetails, requestShipping); } NS_IMETHODIMP PaymentRequest::SetCompleteStatus(const nsAString& aCompleteStatus) { mCompleteStatus = aCompleteStatus; return NS_OK;
--- a/dom/payments/PaymentRequestData.h +++ b/dom/payments/PaymentRequestData.h @@ -179,28 +179,30 @@ public: NS_DECL_ISUPPORTS NS_DECL_NSIPAYMENTREQUEST PaymentRequest(const uint64_t aTabId, const nsAString& aRequestId, nsIPrincipal* aPrincipal, nsIArray* aPaymentMethods, nsIPaymentDetails* aPaymentDetails, - nsIPaymentOptions* aPaymentOptions); + nsIPaymentOptions* aPaymentOptions, + const nsAString& aShippingOption); private: ~PaymentRequest() = default; uint64_t mTabId; nsString mRequestId; nsString mCompleteStatus; nsCOMPtr<nsIPrincipal> mTopLevelPrincipal; nsCOMPtr<nsIArray> mPaymentMethods; nsCOMPtr<nsIPaymentDetails> mPaymentDetails; nsCOMPtr<nsIPaymentOptions> mPaymentOptions; + nsString mShippingOption; }; class PaymentAddress final : public nsIPaymentAddress { public: NS_DECL_ISUPPORTS NS_DECL_NSIPAYMENTADDRESS
--- a/dom/payments/PaymentRequestManager.cpp +++ b/dom/payments/PaymentRequestManager.cpp @@ -462,17 +462,18 @@ PaymentRequestManager::CreatePayment(JSC IPCPaymentOptions options; ConvertOptions(aOptions, options); IPCPaymentCreateActionRequest action(internalId, IPC::Principal(aTopLevelPrincipal), methodData, details, - options); + options, + shippingOption); rv = SendRequestPayment(request, action, true); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } mRequestQueue.AppendElement(request); request.forget(aRequest); return NS_OK; @@ -568,17 +569,17 @@ PaymentRequestManager::UpdatePayment(JSC nsAutoString shippingOption; SetDOMStringToNull(shippingOption); if (aRequestShipping) { GetSelectedShippingOption(aDetails, shippingOption); request->SetShippingOption(shippingOption); } nsAutoString requestId(aRequestId); - IPCPaymentUpdateActionRequest action(requestId, details); + IPCPaymentUpdateActionRequest action(requestId, details, shippingOption); return SendRequestPayment(request, action); } nsresult PaymentRequestManager::RespondPayment(const IPCPaymentActionResponse& aResponse) { switch (aResponse.type()) { case IPCPaymentActionResponse::TIPCPaymentCanMakeActionResponse: {
--- a/dom/payments/PaymentRequestService.cpp +++ b/dom/payments/PaymentRequestService.cpp @@ -248,19 +248,23 @@ PaymentRequestService::RequestPayment(ns nsCOMPtr<nsIPaymentDetails> details; rv = request->GetDetails(getter_AddRefs(details)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIPaymentOptions> options; rv = request->GetOptions(getter_AddRefs(options)); NS_ENSURE_SUCCESS(rv, rv); + nsAutoString shippingOption; + rv = request->GetShippingOption(shippingOption); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr<nsIPaymentRequest> payment = new payments::PaymentRequest(tabId, requestId, topLevelPrincipal, - methodData, details, options); + methodData, details, options, shippingOption); if (!mRequestQueue.AppendElement(payment, mozilla::fallible)) { return NS_ERROR_OUT_OF_MEMORY; } break; } case nsIPaymentActionRequest::CANMAKE_ACTION: { nsCOMPtr<nsIPaymentCanMakeActionResponse> canMakeResponse = @@ -352,24 +356,28 @@ PaymentRequestService::RequestPayment(ns case nsIPaymentActionRequest::UPDATE_ACTION: { nsCOMPtr<nsIPaymentUpdateActionRequest> request = do_QueryInterface(aRequest); MOZ_ASSERT(request); nsCOMPtr<nsIPaymentDetails> details; rv = request->GetDetails(getter_AddRefs(details)); NS_ENSURE_SUCCESS(rv, rv); + nsAutoString shippingOption; + rv = request->GetShippingOption(shippingOption); + NS_ENSURE_SUCCESS(rv, rv); + rv = request->GetRequestId(requestId); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIPaymentRequest> payment; rv = GetPaymentRequestById(requestId, getter_AddRefs(payment)); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } - rv = payment->UpdatePaymentDetails(details); + rv = payment->UpdatePaymentDetails(details, shippingOption); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } if (mShowingRequest) { MOZ_ASSERT(mShowingRequest == payment); rv = LaunchUIAction(requestId, type); } else { mShowingRequest = payment;
--- a/dom/payments/ipc/PPaymentRequest.ipdl +++ b/dom/payments/ipc/PPaymentRequest.ipdl @@ -71,16 +71,17 @@ struct IPCPaymentOptions struct IPCPaymentCreateActionRequest { nsString requestId; Principal topLevelPrincipal; IPCPaymentMethodData[] methodData; IPCPaymentDetails details; IPCPaymentOptions options; + nsString shippingOption; }; struct IPCPaymentCanMakeActionRequest { nsString requestId; }; struct IPCPaymentShowActionRequest @@ -98,16 +99,17 @@ struct IPCPaymentCompleteActionRequest nsString requestId; nsString completeStatus; }; struct IPCPaymentUpdateActionRequest { nsString requestId; IPCPaymentDetails details; + nsString shippingOption; }; union IPCPaymentActionRequest { IPCPaymentCreateActionRequest; IPCPaymentCanMakeActionRequest; IPCPaymentShowActionRequest; IPCPaymentAbortActionRequest;
--- a/dom/payments/ipc/PaymentRequestParent.cpp +++ b/dom/payments/ipc/PaymentRequestParent.cpp @@ -71,17 +71,18 @@ PaymentRequestParent::RecvRequestPayment return IPC_FAIL_NO_REASON(this); } rv = createAction->InitRequest(request.requestId(), callback, mTabId, request.topLevelPrincipal(), methodData, details, - options); + options, + request.shippingOption()); if (NS_WARN_IF(NS_FAILED(rv))) { return IPC_FAIL_NO_REASON(this); } action = do_QueryInterface(createAction); MOZ_ASSERT(action); break; } @@ -137,17 +138,18 @@ PaymentRequestParent::RecvRequestPayment if (NS_WARN_IF(NS_FAILED(rv))) { return IPC_FAIL_NO_REASON(this); } nsCOMPtr<nsIPaymentUpdateActionRequest> updateAction = do_CreateInstance(NS_PAYMENT_UPDATE_ACTION_REQUEST_CONTRACT_ID); rv = updateAction->InitRequest(request.requestId(), callback, - details); + details, + request.shippingOption()); action = do_QueryInterface(updateAction); MOZ_ASSERT(action); break; } default: { return IPC_FAIL(this, "Unexpected request type"); } }
new file mode 100644 --- /dev/null +++ b/dom/payments/test/DefaultData.js @@ -0,0 +1,50 @@ +// testing data declation +const defaultMethods = [{ + supportedMethods: "basic-card", + data: { + supportedNetworks: ['unionpay', 'visa', 'mastercard', 'amex', 'discover', + 'diners', 'jcb', 'mir', + ], + supportedTypes: ['prepaid', 'debit', 'credit'], + }, +}, { + supportedMethods: "testing-payment-method", +}]; + +const defaultDetails = { + total: { + label: "Total", + amount: { + currency: "USD", + value: "1.00", + } + }, + shippingOptions: [ + { + id: "NormalShipping", + label: "NormalShipping", + amount: { + currency: "USD", + value: "10.00", + }, + selected: false, + }, + { + id: "FastShipping", + label: "FastShipping", + amount: { + currency: "USD", + value: "5.00", + }, + selected: false, + }, + ], +}; + +const defaultOptions = { + requestPayerName: true, + requestPayerEmail: false, + reqeustPayerPhone: false, + requestShipping: true, + shippingType: "shipping" +};
rename from dom/payments/test/Bug1443914ChromeScript.js rename to dom/payments/test/ShippingOptionsChromeScript.js --- a/dom/payments/test/Bug1443914ChromeScript.js +++ b/dom/payments/test/ShippingOptionsChromeScript.js @@ -9,72 +9,84 @@ const paymentSrv = Cc["@mozilla.org/dom/ function emitTestFail(message) { sendAsyncMessage("test-fail", message); } function emitTestPass(message) { sendAsyncMessage("test-pass", message); } -const shippingAddress = Cc["@mozilla.org/dom/payments/payment-address;1"]. - createInstance(Ci.nsIPaymentAddress); -const addressLine = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray); -const address = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString); -address.data = "Easton Ave"; -addressLine.appendElement(address); -shippingAddress.init("USA", // country - addressLine, // address line - "CA", // region - "San Bruno", // city - "Test locality", // dependent locality - "94066", // postal code - "123456", // sorting code - "en", // language code - "Testing Org", // organization - "Bill A. Pacheco", // recipient - "+1-434-441-3879"); // phone +let expectedRequestOption = null; +let expectedUpdatedOption = null; +let changeShippingOption = null; + +function showResponse(requestId) { + const showResponseData = Cc["@mozilla.org/dom/payments/general-response-data;1"]. + createInstance(Ci.nsIGeneralResponseData); + showResponseData.initData({}); + const showResponse = Cc["@mozilla.org/dom/payments/payment-show-action-response;1"]. + createInstance(Ci.nsIPaymentShowActionResponse); + showResponse.init(requestId, + Ci.nsIPaymentActionResponse.PAYMENT_ACCEPTED, + "testing-payment-method", // payment method + showResponseData, // payment method data + "Bill A. Pacheco", // payer name + "", // payer email + ""); // payer phone + paymentSrv.respondPayment(showResponse.QueryInterface(Ci.nsIPaymentActionResponse)); +} + +function showRequest(requestId) { + let request = paymentSrv.getPaymentRequestById(requestId); + const message = "request.shippingOption should be " + expectedRequestOption + + " when calling show(), but got " + request.shippingOption + "."; + if (request.shippingOption != expectedRequestOption) { + emitTestFail(message); + } else { + emitTestPass(message); + } + if (changeShippingOption) { + paymentSrv.changeShippingOption(requestId, changeShippingOption); + } else { + showResponse(requestId); + } +} + +function updateRequest(requestId) { + let request = paymentSrv.getPaymentRequestById(requestId); + const message = "request.shippingOption should be " + expectedUpdatedOption + + " when calling updateWith(), but got " + request.shippingOption + "."; + if (request.shippingOption != expectedUpdatedOption) { + emitTestFail(message); + } else { + emitTestPass(message); + } + showResponse(requestId); +} const TestingUIService = { - showPayment: function(requestId) { - paymentSrv.changeShippingAddress(requestId, shippingAddress); - }, + showPayment: showRequest, abortPayment: function(requestId) { }, completePayment: function(requestId) { let request = paymentSrv.getPaymentRequestById(requestId); let completeResponse = Cc["@mozilla.org/dom/payments/payment-complete-action-response;1"]. createInstance(Ci.nsIPaymentCompleteActionResponse); completeResponse.init(requestId, Ci.nsIPaymentActionResponse.COMPLETE_SUCCEEDED); paymentSrv.respondPayment(completeResponse.QueryInterface(Ci.nsIPaymentActionResponse)); }, - updatePayment: function(requestId) { - let request = paymentSrv.getPaymentRequestById(requestId); - if (request.shippingOptions != null) { - emitTestFail("request.shippingOptions should be null"); - } else { - emitTestPass("request.shippingOptions should be null"); - } - const showResponseData = Cc["@mozilla.org/dom/payments/general-response-data;1"]. - createInstance(Ci.nsIGeneralResponseData); - showResponseData.initData({}); - const showResponse = Cc["@mozilla.org/dom/payments/payment-show-action-response;1"]. - createInstance(Ci.nsIPaymentShowActionResponse); - showResponse.init(requestId, - Ci.nsIPaymentActionResponse.PAYMENT_ACCEPTED, - "testing-payment-method", // payment method - showResponseData, // payment method data - "Bill A. Pacheco", // payer name - "", // payer email - ""); // payer phone - paymentSrv.respondPayment(showResponse.QueryInterface(Ci.nsIPaymentActionResponse)); - }, + updatePayment: updateRequest, QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentUIService]), }; -addMessageListener("set-checking-shipping-options-ui-service", function() { - paymentSrv.setTestingUIService(TestingUIService.QueryInterface(Ci.nsIPaymentUIService)); +paymentSrv.setTestingUIService(TestingUIService.QueryInterface(Ci.nsIPaymentUIService)); + +addMessageListener("set-expected-results", function(results) { + expectedRequestOption = results.requestResult; + expectedUpdatedOption = results.responseResult; + changeShippingOption = results.changeOptionResult; }); addMessageListener("teardown", function() { paymentSrv.cleanup(); paymentSrv.setTestingUIService(null); sendAsyncMessage('teardown-complete'); });
--- a/dom/payments/test/mochitest.ini +++ b/dom/payments/test/mochitest.ini @@ -1,30 +1,31 @@ [DEFAULT] # skip-if !e10s will be removed once non-e10s is supported skip-if = !e10s scheme = https support-files = simple_payment_request.html echo_payment_request.html BasiccardChromeScript.js - Bug1443914ChromeScript.js ConstructorChromeScript.js CurrencyAmountValidationChromeScript.js + DefaultData.js GeneralChromeScript.js PMIValidationChromeScript.js + ShippingOptionsChromeScript.js ShowPaymentChromeScript.js RequestShippingChromeScript.js [test_abortPayment.html] run-if = nightly_build # Bug 1390018: Depends on the Nightly-only UI service [test_basiccard.html] [test_block_none10s.html] skip-if = e10s # Bug 1408250: Don't expose PaymentRequest Constructor in non-e10s -[test_bug1443914.html] [test_canMakePayment.html] run-if = nightly_build # Bug 1390737: Depends on the Nightly-only UI service [test_constructor.html] [test_currency_amount_validation.html] [test_payment-request-in-iframe.html] [test_pmi_validation.html] [test_requestShipping.html] +[test_shippingOptions.html] [test_showPayment.html]
rename from dom/payments/test/test_bug1443914.html rename to dom/payments/test/test_shippingOptions.html --- a/dom/payments/test/test_bug1443914.html +++ b/dom/payments/test/test_shippingOptions.html @@ -1,127 +1,194 @@ <!DOCTYPE HTML> <html> <!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1440041 https://bugzilla.mozilla.org/show_bug.cgi?id=1443914 --> <head> <meta charset="utf-8"> - <title>Test for Bug 1443914</title> + <title>Test for shippingOptions related bugs</title> <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="./DefaultData.js"></script> <script type="application/javascript"> "use strict"; SimpleTest.waitForExplicitFinish(); - var gUrl = SimpleTest.getTestFileURL('Bug1443914ChromeScript.js'); + var gUrl = SimpleTest.getTestFileURL('ShippingOptionsChromeScript.js'); var gScript = SpecialPowers.loadChromeScript(gUrl); function testFailHandler(message) { ok(false, message); } function testPassHandler(message) { ok(true, message); } gScript.addMessageListener("test-fail", testFailHandler); gScript.addMessageListener("test-pass", testPassHandler); - // testing data declation - const defaultMethods = [{ - supportedMethods: "basic-card", - data: { - supportedNetworks: ['unionpay', 'visa', 'mastercard', 'amex', 'discover', - 'diners', 'jcb', 'mir', - ], - supportedTypes: ['prepaid', 'debit', 'credit'], + let shippingOptions = [{ + id: "NormalShipping", + label: "NormalShipping", + amount: { + currency: "USD", + value: "10.00", }, - }, { - supportedMethods: "testing-payment-method", - }]; - - const defaultDetails = { - id: "test payment", - total: { - label: "Total", - amount: { - currency: "USD", - value: "1.00" - } + selected: true, + },{ + id: "FastShipping", + label: "FastShipping", + amount: { + currency: "USD", + value: "5.00", }, - shippingOptions: [ - { - id: "NormalShipping", - label: "NormalShipping", - amount: { - currency: "USD", - value: "10.00" - }, - selected: false, - }, - ], - }; - - const defaultOptions = { - requestPayerName: true, - requestPayerEmail: false, - reqeustPayerPhone: false, - requestShipping: true, - shippingType: "shipping" - }; + selected: false, + }] - const updateDetails = { - total: { - label: "Total", - amount: { - currency: "USD", - value: "1.00" + // testing function main body + function testShippingOptionsTemplate(initDetails, + optionUpdateDetails, + expectedRequestOption, + expectedOptionChangeOption, + expectedResponseOption) { + const expectedResults = {requestResult: expectedRequestOption, + changeOptionResult: expectedOptionChangeOption, + responseResult: expectedResponseOption,}; + gScript.sendAsyncMessage("set-expected-results", expectedResults); + return new Promise((resolve, reject) => { + const request = new PaymentRequest(defaultMethods, initDetails, defaultOptions); + const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true); + is(request.shippingOption, expectedRequestOption, + "request.shippingOption should be " + expectedRequestOption + + " after created, but got " + request.shippingOption + "."); + if (optionUpdateDetails) { + request.addEventListener("shippingoptionchange", event => { + is(request.shippingOption, expectedOptionChangeOption, + "request.shippingOption should be " + expectedOptionChangeOption + + " in shippingoptionchange event, but got " + request.shippingOption + "."); + event.updateWith(optionUpdateDetails); + }); } - }, - error: "", - }; - // testing function main body - function test_bug1443914() { - gScript.sendAsyncMessage("set-checking-shipping-options-ui-service"); - return new Promise((resolve, reject) => { - const request = new PaymentRequest(defaultMethods, defaultDetails, defaultOptions); - const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true); - request.addEventListener("shippingaddresschange", (event) => { - event.updateWith(updateDetails); - }); - request.addEventListener("shippingoptionchange", (event) => { - event.updateWith(updateDetails); - }); request.show().then(response => { - response.complete("success").then(() => { + is(response.shippingOption, expectedResponseOption, + "response.shippingOption should be " + expectedResponseOption + + ", but got " + response.shippingOption + "."); + response.complete("success").then(() => { resolve(); }).catch(error => { ok(false, "Unexpected error: " + error.name); resolve(); - }); + }) + }, response => { }).catch(error => { ok(false, "Unexpected error: " + error.name); resolve(); }).finally(handler.destruct); }); } + // test no selected shipping option in default + function testNoSelectedShippingOptions() { + return testShippingOptionsTemplate(defaultDetails, // initial details + null, // update details for optionchange + null, // expected request.shippintOption after create + null, // expected request.shippingOption after optionchange + null); // expected response.shippingOption + } + + // test select one shipping option in default + function testSelectedOneShippingOption() { + let details = Object.assign({}, defaultDetails); + details.shippingOptions = shippingOptions; + details.shippingOptions[0].selected = true; + details.shippingOptions[1].selected = false; + const expectedOption = details.shippingOptions[0].id; + return testShippingOptionsTemplate(details, // initial details + null, // update details for optionchange + expectedOption, // expected request.shippintOption after create + null, // expected request.shippingOption after optionchange + expectedOption); // expected response.shippingOption + } + + // test select multiple shipping options in default + function testMultiSelectedShippingOptions() { + let details = Object.assign({}, defaultDetails); + details.shippingOptions = shippingOptions; + details.shippingOptions[0].selected = true; + details.shippingOptions[1].selected = true; + const expectedOption = details.shippingOptions[1].id; + return testShippingOptionsTemplate(details, // initial details + null, // update details for optionchange + expectedOption, // expected request.shippintOption after create + null, // expected request.shippingOption after optionchange + expectedOption); // expected response.shippingOption + } + + // test no selected shipping option in default, but selected by user + function testSelectedByUser() { + let updateDetails = Object.assign({}, defaultDetails); + updateDetails.shippingOptions = shippingOptions; + updateDetails.shippingOptions[0].selected = true; + updateDetails.shippingOptions[1].selected = false; + const expectedOption = updateDetails.shippingOptions[0].id; + return testShippingOptionsTemplate(defaultDetails, // initial details + updateDetails, // update details for optionchange + null, // expected request.shippintOption after create + expectedOption, // expected request.shippingOption after optionchange + expectedOption); // expected response.shippingOption + } + + // test no selected shipping option in default, but selected by user then updated + // by merchant to the other. + function testUpdateSelectedByMerchant() { + let updateDetails = Object.assign({}, defaultDetails); + updateDetails.shippingOptions = shippingOptions; + updateDetails.shippingOptions[0].selected = false; + updateDetails.shippingOptions[1].selected = true; + const expectedOption = updateDetails.shippingOptions[0].id; + const expectedResponse = updateDetails.shippingOptions[1].id; + return testShippingOptionsTemplate(defaultDetails, // initial details + updateDetails, // update details for optionchange + null, // expected request.shippintOption after create + expectedOption, // expected request.shippingOption after optionchange + expectedResponse);// expected response.shippingOption + } + + // test update shipping options to null + function testUpdateShippingOptionsToNull() { + let updateDetails = Object.assign({}, defaultDetails); + delete updateDetails.shippingOptions; + const expectedOption = defaultDetails.shippingOptions[0].id; + return testShippingOptionsTemplate(defaultDetails, // initial details + updateDetails, // update details for optionchange + null, // expected request.shippintOption after create + expectedOption, // expected request.shippingOption after optionchange + null); // expected response.shippingOption + } + function teardown() { gScript.addMessageListener("teardown-complete", function teardownCompleteHandler() { gScript.removeMessageListener("teardown-complete", teardownCompleteHandler); gScript.removeMessageListener("test-fail", testFailHandler); gScript.removeMessageListener("test-pass", testPassHandler); gScript.destroy(); SimpleTest.finish(); }); gScript.sendAsyncMessage("teardown"); } function runTests() { - test_bug1443914() + testNoSelectedShippingOptions() + .then(testSelectedOneShippingOption) + .then(testMultiSelectedShippingOptions) + .then(testSelectedByUser) + .then(testUpdateSelectedByMerchant) + .then(testUpdateShippingOptionsToNull) .then(teardown) .catch( e => { ok(false, "Unexpected error: " + e.name); SimpleTest.finish(); }); } window.addEventListener('load', function() { @@ -130,11 +197,12 @@ https://bugzilla.mozilla.org/show_bug.cg ['dom.payments.request.enabled', true], ] }, runTests); }); </script> </head> <body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1440041">Mozilla Bug 1440041</a> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1443914">Mozilla Bug 1443914</a> </body> </html>
--- a/dom/url/URL.cpp +++ b/dom/url/URL.cpp @@ -121,31 +121,28 @@ URL::CreateSearchParamsIfNeeded() { if (!mSearchParams) { mSearchParams = new URLSearchParams(mParent, this); UpdateURLSearchParams(); } } void -URL::SetSearch(const nsAString& aSearch, ErrorResult& aRv) +URL::SetSearch(const nsAString& aSearch) { - SetSearchInternal(aSearch, aRv); + SetSearchInternal(aSearch); UpdateURLSearchParams(); } void URL::URLSearchParamsUpdated(URLSearchParams* aSearchParams) { MOZ_ASSERT(mSearchParams); MOZ_ASSERT(mSearchParams == aSearchParams); nsAutoString search; mSearchParams->Serialize(search); - ErrorResult rv; - SetSearchInternal(search, rv); - NS_WARNING_ASSERTION(!rv.Failed(), "SetSearchInternal failed"); - rv.SuppressException(); + SetSearchInternal(search); } } // namespace dom } // namespace mozilla
--- a/dom/url/URL.h +++ b/dom/url/URL.h @@ -73,104 +73,104 @@ public: RevokeObjectURL(const GlobalObject& aGlobal, const nsAString& aURL, ErrorResult& aRv); static bool IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL, ErrorResult& aRv); virtual void - GetHref(nsAString& aHref, ErrorResult& aRv) const = 0; + GetHref(nsAString& aHref) const = 0; virtual void SetHref(const nsAString& aHref, ErrorResult& aRv) = 0; virtual void GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const = 0; virtual void - GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const = 0; + GetProtocol(nsAString& aProtocol) const = 0; virtual void SetProtocol(const nsAString& aProtocol, ErrorResult& aRv) = 0; virtual void - GetUsername(nsAString& aUsername, ErrorResult& aRv) const = 0; + GetUsername(nsAString& aUsername) const = 0; virtual void - SetUsername(const nsAString& aUsername, ErrorResult& aRv) = 0; + SetUsername(const nsAString& aUsername) = 0; virtual void - GetPassword(nsAString& aPassword, ErrorResult& aRv) const = 0; + GetPassword(nsAString& aPassword) const = 0; virtual void - SetPassword(const nsAString& aPassword, ErrorResult& aRv) = 0; + SetPassword(const nsAString& aPassword) = 0; virtual void - GetHost(nsAString& aHost, ErrorResult& aRv) const = 0; + GetHost(nsAString& aHost) const = 0; virtual void - SetHost(const nsAString& aHost, ErrorResult& aRv) = 0; + SetHost(const nsAString& aHost) = 0; virtual void - GetHostname(nsAString& aHostname, ErrorResult& aRv) const = 0; + GetHostname(nsAString& aHostname) const = 0; virtual void - SetHostname(const nsAString& aHostname, ErrorResult& aRv) = 0; + SetHostname(const nsAString& aHostname) = 0; virtual void - GetPort(nsAString& aPort, ErrorResult& aRv) const = 0; + GetPort(nsAString& aPort) const = 0; virtual void - SetPort(const nsAString& aPort, ErrorResult& aRv) = 0; + SetPort(const nsAString& aPort) = 0; virtual void - GetPathname(nsAString& aPathname, ErrorResult& aRv) const = 0; + GetPathname(nsAString& aPathname) const = 0; virtual void - SetPathname(const nsAString& aPathname, ErrorResult& aRv) = 0; + SetPathname(const nsAString& aPathname) = 0; virtual void - GetSearch(nsAString& aSearch, ErrorResult& aRv) const = 0; + GetSearch(nsAString& aSearch) const = 0; virtual void - SetSearch(const nsAString& aSearch, ErrorResult& aRv); + SetSearch(const nsAString& aSearch); URLSearchParams* SearchParams(); virtual void - GetHash(nsAString& aHost, ErrorResult& aRv) const = 0; + GetHash(nsAString& aHost) const = 0; virtual void - SetHash(const nsAString& aHash, ErrorResult& aRv) = 0; + SetHash(const nsAString& aHash) = 0; - void Stringify(nsAString& aRetval, ErrorResult& aRv) const + void Stringify(nsAString& aRetval) const { - GetHref(aRetval, aRv); + GetHref(aRetval); } void - ToJSON(nsAString& aResult, ErrorResult& aRv) const + ToJSON(nsAString& aResult) const { - GetHref(aResult, aRv); + GetHref(aResult); } // URLSearchParamsObserver void URLSearchParamsUpdated(URLSearchParams* aSearchParams) override; protected: virtual ~URL() {} virtual void UpdateURLSearchParams() = 0; virtual void - SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv) = 0; + SetSearchInternal(const nsAString& aSearch) = 0; void CreateSearchParamsIfNeeded(); nsCOMPtr<nsISupports> mParent; RefPtr<URLSearchParams> mSearchParams; }; bool IsChromeURI(nsIURI* aURI);
--- a/dom/url/URLMainThread.cpp +++ b/dom/url/URLMainThread.cpp @@ -179,17 +179,17 @@ URLMainThread::IsValidURL(const GlobalOb ErrorResult& aRv) { MOZ_ASSERT(NS_IsMainThread()); NS_LossyConvertUTF16toASCII asciiurl(aURL); return nsHostObjectProtocolHandler::HasDataEntry(asciiurl); } void -URLMainThread::GetHref(nsAString& aHref, ErrorResult& aRv) const +URLMainThread::GetHref(nsAString& aHref) const { aHref.Truncate(); nsAutoCString href; nsresult rv = mURI->GetSpec(href); if (NS_SUCCEEDED(rv)) { CopyUTF8toUTF16(href, aHref); } @@ -220,17 +220,17 @@ URLMainThread::SetHref(const nsAString& void URLMainThread::GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const { nsContentUtils::GetUTFOrigin(mURI, aOrigin); } void -URLMainThread::GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const +URLMainThread::GetProtocol(nsAString& aProtocol) const { nsAutoCString protocol; if (NS_SUCCEEDED(mURI->GetScheme(protocol))) { aProtocol.Truncate(); } CopyASCIItoUTF16(protocol, aProtocol); aProtocol.Append(char16_t(':')); @@ -276,51 +276,51 @@ URLMainThread::SetProtocol(const nsAStri value.Truncate(); \ nsAutoCString tmp; \ nsresult rv = mURI->func(tmp); \ if (NS_SUCCEEDED(rv)) { \ CopyUTF8toUTF16(tmp, value); \ } void -URLMainThread::GetUsername(nsAString& aUsername, ErrorResult& aRv) const +URLMainThread::GetUsername(nsAString& aUsername) const { URL_GETTER(aUsername, GetUsername); } void -URLMainThread::SetUsername(const nsAString& aUsername, ErrorResult& aRv) +URLMainThread::SetUsername(const nsAString& aUsername) { Unused << NS_MutateURI(mURI) .SetUsername(NS_ConvertUTF16toUTF8(aUsername)) .Finalize(mURI); } void -URLMainThread::GetPassword(nsAString& aPassword, ErrorResult& aRv) const +URLMainThread::GetPassword(nsAString& aPassword) const { URL_GETTER(aPassword, GetPassword); } void -URLMainThread::SetPassword(const nsAString& aPassword, ErrorResult& aRv) +URLMainThread::SetPassword(const nsAString& aPassword) { Unused << NS_MutateURI(mURI) .SetPassword(NS_ConvertUTF16toUTF8(aPassword)) .Finalize(mURI); } void -URLMainThread::GetHost(nsAString& aHost, ErrorResult& aRv) const +URLMainThread::GetHost(nsAString& aHost) const { URL_GETTER(aHost, GetHostPort); } void -URLMainThread::SetHost(const nsAString& aHost, ErrorResult& aRv) +URLMainThread::SetHost(const nsAString& aHost) { Unused << NS_MutateURI(mURI) .SetHostPort(NS_ConvertUTF16toUTF8(aHost)) .Finalize(mURI); } void URLMainThread::UpdateURLSearchParams() @@ -334,48 +334,48 @@ URLMainThread::UpdateURLSearchParams() if (NS_WARN_IF(NS_FAILED(rv))) { search.Truncate(); } mSearchParams->ParseInput(search); } void -URLMainThread::GetHostname(nsAString& aHostname, ErrorResult& aRv) const +URLMainThread::GetHostname(nsAString& aHostname) const { aHostname.Truncate(); nsContentUtils::GetHostOrIPv6WithBrackets(mURI, aHostname); } void -URLMainThread::SetHostname(const nsAString& aHostname, ErrorResult& aRv) +URLMainThread::SetHostname(const nsAString& aHostname) { // nsStandardURL returns NS_ERROR_UNEXPECTED for an empty hostname // The return code is silently ignored mozilla::Unused << NS_MutateURI(mURI) .SetHost(NS_ConvertUTF16toUTF8(aHostname)) .Finalize(mURI); } void -URLMainThread::GetPort(nsAString& aPort, ErrorResult& aRv) const +URLMainThread::GetPort(nsAString& aPort) const { aPort.Truncate(); int32_t port; nsresult rv = mURI->GetPort(&port); if (NS_SUCCEEDED(rv) && port != -1) { nsAutoString portStr; portStr.AppendInt(port, 10); aPort.Assign(portStr); } } void -URLMainThread::SetPort(const nsAString& aPort, ErrorResult& aRv) +URLMainThread::SetPort(const nsAString& aPort) { nsresult rv; nsAutoString portStr(aPort); int32_t port = -1; // nsIURI uses -1 as default value. if (!portStr.IsEmpty()) { port = portStr.ToInteger(&rv); @@ -385,42 +385,42 @@ URLMainThread::SetPort(const nsAString& } Unused << NS_MutateURI(mURI) .SetPort(port) .Finalize(mURI); } void -URLMainThread::GetPathname(nsAString& aPathname, ErrorResult& aRv) const +URLMainThread::GetPathname(nsAString& aPathname) const { aPathname.Truncate(); // Do not throw! Not having a valid URI or URL should result in an empty // string. nsAutoCString file; nsresult rv = mURI->GetFilePath(file); if (NS_SUCCEEDED(rv)) { CopyUTF8toUTF16(file, aPathname); } } void -URLMainThread::SetPathname(const nsAString& aPathname, ErrorResult& aRv) +URLMainThread::SetPathname(const nsAString& aPathname) { // Do not throw! Unused << NS_MutateURI(mURI) .SetFilePath(NS_ConvertUTF16toUTF8(aPathname)) .Finalize(mURI); } void -URLMainThread::GetSearch(nsAString& aSearch, ErrorResult& aRv) const +URLMainThread::GetSearch(nsAString& aSearch) const { aSearch.Truncate(); // Do not throw! Not having a valid URI or URL should result in an empty // string. nsAutoCString search; nsresult rv; @@ -428,38 +428,38 @@ URLMainThread::GetSearch(nsAString& aSea rv = mURI->GetQuery(search); if (NS_SUCCEEDED(rv) && !search.IsEmpty()) { aSearch.Assign(u'?'); AppendUTF8toUTF16(search, aSearch); } } void -URLMainThread::GetHash(nsAString& aHash, ErrorResult& aRv) const +URLMainThread::GetHash(nsAString& aHash) const { aHash.Truncate(); nsAutoCString ref; nsresult rv = mURI->GetRef(ref); if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) { aHash.Assign(char16_t('#')); AppendUTF8toUTF16(ref, aHash); } } void -URLMainThread::SetHash(const nsAString& aHash, ErrorResult& aRv) +URLMainThread::SetHash(const nsAString& aHash) { Unused << NS_MutateURI(mURI) .SetRef(NS_ConvertUTF16toUTF8(aHash)) .Finalize(mURI); } void -URLMainThread::SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv) +URLMainThread::SetSearchInternal(const nsAString& aSearch) { // Ignore failures to be compatible with NS4. Unused << NS_MutateURI(mURI) .SetQuery(NS_ConvertUTF16toUTF8(aSearch)) .Finalize(mURI); }
--- a/dom/url/URLMainThread.h +++ b/dom/url/URLMainThread.h @@ -46,79 +46,79 @@ public: static bool IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL, ErrorResult& aRv); URLMainThread(nsISupports* aParent, already_AddRefed<nsIURI> aURI); virtual void - GetHref(nsAString& aHref, ErrorResult& aRv) const override; + GetHref(nsAString& aHref) const override; virtual void SetHref(const nsAString& aHref, ErrorResult& aRv) override; virtual void GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const override; virtual void - GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const override; + GetProtocol(nsAString& aProtocol) const override; virtual void SetProtocol(const nsAString& aProtocol, ErrorResult& aRv) override; virtual void - GetUsername(nsAString& aUsername, ErrorResult& aRv) const override; + GetUsername(nsAString& aUsername) const override; virtual void - SetUsername(const nsAString& aUsername, ErrorResult& aRv) override; + SetUsername(const nsAString& aUsername) override; virtual void - GetPassword(nsAString& aPassword, ErrorResult& aRv) const override; + GetPassword(nsAString& aPassword) const override; virtual void - SetPassword(const nsAString& aPassword, ErrorResult& aRv) override; + SetPassword(const nsAString& aPassword) override; virtual void - GetHost(nsAString& aHost, ErrorResult& aRv) const override; + GetHost(nsAString& aHost) const override; virtual void - SetHost(const nsAString& aHost, ErrorResult& aRv) override; + SetHost(const nsAString& aHost) override; virtual void - GetHostname(nsAString& aHostname, ErrorResult& aRv) const override; + GetHostname(nsAString& aHostname) const override; virtual void - SetHostname(const nsAString& aHostname, ErrorResult& aRv) override; + SetHostname(const nsAString& aHostname) override; virtual void - GetPort(nsAString& aPort, ErrorResult& aRv) const override; + GetPort(nsAString& aPort) const override; virtual void - SetPort(const nsAString& aPort, ErrorResult& aRv) override; + SetPort(const nsAString& aPort) override; virtual void - GetPathname(nsAString& aPathname, ErrorResult& aRv) const override; + GetPathname(nsAString& aPathname) const override; virtual void - SetPathname(const nsAString& aPathname, ErrorResult& aRv) override; + SetPathname(const nsAString& aPathname) override; virtual void - GetSearch(nsAString& aSearch, ErrorResult& aRv) const override; + GetSearch(nsAString& aSearch) const override; virtual void - GetHash(nsAString& aHost, ErrorResult& aRv) const override; + GetHash(nsAString& aHost) const override; virtual void - SetHash(const nsAString& aHash, ErrorResult& aRv) override; + SetHash(const nsAString& aHash) override; virtual void UpdateURLSearchParams() override; virtual void - SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv) override; + SetSearchInternal(const nsAString& aSearch) override; nsIURI* GetURI() const; private: ~URLMainThread(); nsCOMPtr<nsIURI> mURI;
--- a/dom/url/URLWorker.cpp +++ b/dom/url/URLWorker.cpp @@ -7,16 +7,17 @@ #include "URLWorker.h" #include "mozilla/dom/Blob.h" #include "mozilla/dom/WorkerPrivate.h" #include "mozilla/dom/WorkerRunnable.h" #include "mozilla/dom/WorkerScope.h" #include "mozilla/Unused.h" #include "nsHostObjectProtocolHandler.h" +#include "nsProxyRelease.h" #include "nsStandardURL.h" #include "nsURLHelper.h" namespace mozilla { using net::nsStandardURL; namespace dom { @@ -30,37 +31,23 @@ public: explicit URLProxy(already_AddRefed<URLMainThread> aURL) : mURL(aURL) { MOZ_ASSERT(NS_IsMainThread()); } URLMainThread* URL() { - MOZ_ASSERT(NS_IsMainThread()); return mURL; } - nsIURI* URI() - { - MOZ_ASSERT(NS_IsMainThread()); - return mURL->GetURI(); - } - - void ReleaseURI() - { - MOZ_ASSERT(NS_IsMainThread()); - mURL = nullptr; - } - private: - // Private destructor, to discourage deletion outside of Release(): ~URLProxy() { - MOZ_ASSERT(!mURL); + NS_ReleaseOnMainThreadSystemGroup("URLMainThread", mURL.forget()); } RefPtr<URLMainThread> mURL; }; // This class creates an URL from a DOM Blob on the main thread. class CreateURLRunnable : public WorkerMainThreadRunnable { @@ -274,154 +261,59 @@ public: if (!mRetval) { aRv.ThrowTypeError<MSG_INVALID_URL>(mURL); } return mRetval; } }; -class TeardownURLRunnable : public Runnable +class OriginGetterRunnable : public WorkerMainThreadRunnable { public: - explicit TeardownURLRunnable(URLWorker::URLProxy* aURLProxy) - : Runnable("dom::TeardownURLRunnable") - , mURLProxy(aURLProxy) - { - } - - NS_IMETHOD Run() override - { - AssertIsOnMainThread(); - - mURLProxy->ReleaseURI(); - mURLProxy = nullptr; - - return NS_OK; - } - -private: - RefPtr<URLWorker::URLProxy> mURLProxy; -}; - -// This class is the generic getter for any URL property. -class GetterRunnable : public WorkerMainThreadRunnable -{ -public: - enum GetterType { - GetterHref, - GetterOrigin, - GetterProtocol, - GetterUsername, - GetterPassword, - GetterHost, - GetterHostname, - GetterPort, - GetterPathname, - GetterSearch, - GetterHash, - }; - - GetterRunnable(WorkerPrivate* aWorkerPrivate, - GetterType aType, nsAString& aValue, - URLWorker::URLProxy* aURLProxy) + OriginGetterRunnable(WorkerPrivate* aWorkerPrivate, + nsAString& aValue, + URLWorker::URLProxy* aURLProxy) : WorkerMainThreadRunnable(aWorkerPrivate, // We can have telemetry keys for each getter when // needed. NS_LITERAL_CSTRING("URL :: getter")) , mValue(aValue) - , mType(aType) , mURLProxy(aURLProxy) { mWorkerPrivate->AssertIsOnWorkerThread(); } bool MainThreadRun() override { AssertIsOnMainThread(); ErrorResult rv; - - switch (mType) { - case GetterHref: - mURLProxy->URL()->GetHref(mValue, rv); - break; - - case GetterOrigin: - mURLProxy->URL()->GetOrigin(mValue, rv); - break; - - case GetterProtocol: - mURLProxy->URL()->GetProtocol(mValue, rv); - break; - - case GetterUsername: - mURLProxy->URL()->GetUsername(mValue, rv); - break; - - case GetterPassword: - mURLProxy->URL()->GetPassword(mValue, rv); - break; - - case GetterHost: - mURLProxy->URL()->GetHost(mValue, rv); - break; - - case GetterHostname: - mURLProxy->URL()->GetHostname(mValue, rv); - break; - - case GetterPort: - mURLProxy->URL()->GetPort(mValue, rv); - break; - - case GetterPathname: - mURLProxy->URL()->GetPathname(mValue, rv); - break; - - case GetterSearch: - mURLProxy->URL()->GetSearch(mValue, rv); - break; - - case GetterHash: - mURLProxy->URL()->GetHash(mValue, rv); - break; - } - + mURLProxy->URL()->GetOrigin(mValue, rv); MOZ_ASSERT(!rv.Failed(), "Main-thread getters do not fail."); return true; } void Dispatch(ErrorResult& aRv) { WorkerMainThreadRunnable::Dispatch(Terminating, aRv); } private: nsAString& mValue; - GetterType mType; RefPtr<URLWorker::URLProxy> mURLProxy; }; -// This class is the generic setter for any URL property. class SetterRunnable : public WorkerMainThreadRunnable { public: enum SetterType { SetterHref, SetterProtocol, - SetterUsername, - SetterPassword, - SetterHost, - SetterHostname, - SetterPort, - SetterPathname, - SetterSearch, - SetterHash, }; SetterRunnable(WorkerPrivate* aWorkerPrivate, SetterType aType, const nsAString& aValue, URLWorker::URLProxy* aURLProxy) : WorkerMainThreadRunnable(aWorkerPrivate, // We can have telemetry keys for each setter when // needed. @@ -444,48 +336,16 @@ public: case SetterHref: { mURLProxy->URL()->SetHref(mValue, rv); break; } case SetterProtocol: mURLProxy->URL()->SetProtocol(mValue, rv); break; - - case SetterUsername: - mURLProxy->URL()->SetUsername(mValue, rv); - break; - - case SetterPassword: - mURLProxy->URL()->SetPassword(mValue, rv); - break; - - case SetterHost: - mURLProxy->URL()->SetHost(mValue, rv); - break; - - case SetterHostname: - mURLProxy->URL()->SetHostname(mValue, rv); - break; - - case SetterPort: - mURLProxy->URL()->SetPort(mValue, rv); - break; - - case SetterPathname: - mURLProxy->URL()->SetPathname(mValue, rv); - break; - - case SetterSearch: - mURLProxy->URL()->SetSearch(mValue, rv); - break; - - case SetterHash: - mURLProxy->URL()->SetHash(mValue, rv); - break; } if (NS_WARN_IF(rv.Failed())) { rv.SuppressException(); mFailed = true; } return true; @@ -661,49 +521,33 @@ URLWorker::Init(const nsAString& aURL, c new ConstructorRunnable(mWorkerPrivate, aURL, aBase); runnable->Dispatch(Terminating, aRv); if (NS_WARN_IF(aRv.Failed())) { return; } mURLProxy = runnable->GetURLProxy(aRv); } -URLWorker::~URLWorker() -{ - if (mURLProxy) { - mWorkerPrivate->AssertIsOnWorkerThread(); - - RefPtr<TeardownURLRunnable> runnable = - new TeardownURLRunnable(mURLProxy); - mURLProxy = nullptr; - - if (NS_FAILED(NS_DispatchToMainThread(runnable))) { - NS_ERROR("Failed to dispatch teardown runnable!"); - } - } -} +URLWorker::~URLWorker() = default; void -URLWorker::GetHref(nsAString& aHref, ErrorResult& aRv) const +URLWorker::GetHref(nsAString& aHref) const { aHref.Truncate(); if (mStdURL) { nsAutoCString href; - aRv = mStdURL->GetSpec(href); - if (!aRv.Failed()) { + nsresult rv = mStdURL->GetSpec(href); + if (NS_SUCCEEDED(rv)) { CopyUTF8toUTF16(href, aHref); } return; } MOZ_ASSERT(mURLProxy); - RefPtr<GetterRunnable> runnable = - new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHref, aHref, - mURLProxy); - runnable->Dispatch(aRv); + mURLProxy->URL()->GetHref(aHref); } void URLWorker::SetHref(const nsAString& aHref, ErrorResult& aRv) { SetHrefInternal(aHref, eUseProxyIfNeeded, aRv); } @@ -719,28 +563,17 @@ URLWorker::SetHrefInternal(const nsAStri } if (aStrategy == eUseProxyIfNeeded && (scheme.EqualsLiteral("http") || scheme.EqualsLiteral("https"))) { nsCOMPtr<nsIURI> uri; aRv = NS_MutateURI(new nsStandardURL::Mutator()) .SetSpec(NS_ConvertUTF16toUTF8(aHref)) .Finalize(mStdURL); - if (mURLProxy) { - mWorkerPrivate->AssertIsOnWorkerThread(); - - RefPtr<TeardownURLRunnable> runnable = - new TeardownURLRunnable(mURLProxy); - mURLProxy = nullptr; - - if (NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable)))) { - return; - } - } - + mURLProxy = nullptr; UpdateURLSearchParams(); return; } mStdURL = nullptr; // fallback to using a main thread url proxy if (mURLProxy) { RefPtr<SetterRunnable> runnable = @@ -772,43 +605,38 @@ void URLWorker::GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const { if (mStdURL) { nsContentUtils::GetUTFOrigin(mStdURL, aOrigin); return; } MOZ_ASSERT(mURLProxy); - RefPtr<GetterRunnable> runnable = - new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterOrigin, aOrigin, - mURLProxy); + RefPtr<OriginGetterRunnable> runnable = + new OriginGetterRunnable(mWorkerPrivate, aOrigin, mURLProxy); runnable->Dispatch(aRv); } void -URLWorker::GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const +URLWorker::GetProtocol(nsAString& aProtocol) const { aProtocol.Truncate(); nsAutoCString protocol; if (mStdURL) { if (NS_SUCCEEDED(mStdURL->GetScheme(protocol))) { CopyASCIItoUTF16(protocol, aProtocol); aProtocol.Append(char16_t(':')); } return; } MOZ_ASSERT(mURLProxy); - RefPtr<GetterRunnable> runnable = - new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterProtocol, aProtocol, - mURLProxy); - - runnable->Dispatch(aRv); + mURLProxy->URL()->GetProtocol(aProtocol); } void URLWorker::SetProtocol(const nsAString& aProtocol, ErrorResult& aRv) { nsAString::const_iterator start, end; aProtocol.BeginReading(start); aProtocol.EndReading(end); @@ -866,176 +694,123 @@ URLWorker::SetProtocol(const nsAString& if (NS_SUCCEEDED(rv)) { \ CopyUTF8toUTF16(tmp, value); \ } \ return; \ } #define STDURL_SETTER(value, method) \ if (mStdURL) { \ - aRv = NS_MutateURI(mStdURL) \ - .method(NS_ConvertUTF16toUTF8(value)) \ - .Finalize(mStdURL); \ + Unused << NS_MutateURI(mStdURL) \ + .method(NS_ConvertUTF16toUTF8(value)) \ + .Finalize(mStdURL); \ return; \ } void -URLWorker::GetUsername(nsAString& aUsername, ErrorResult& aRv) const +URLWorker::GetUsername(nsAString& aUsername) const { STDURL_GETTER(aUsername, GetUsername); MOZ_ASSERT(mURLProxy); - RefPtr<GetterRunnable> runnable = - new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterUsername, aUsername, - mURLProxy); - - runnable->Dispatch(aRv); + mURLProxy->URL()->GetUsername(aUsername); } void -URLWorker::SetUsername(const nsAString& aUsername, ErrorResult& aRv) +URLWorker::SetUsername(const nsAString& aUsername) { STDURL_SETTER(aUsername, SetUsername); MOZ_ASSERT(mURLProxy); - RefPtr<SetterRunnable> runnable = - new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterUsername, - aUsername, mURLProxy); - - runnable->Dispatch(aRv); - if (NS_WARN_IF(aRv.Failed())) { - return; - } - - MOZ_ASSERT(!runnable->Failed()); + mURLProxy->URL()->SetUsername(aUsername); } void -URLWorker::GetPassword(nsAString& aPassword, ErrorResult& aRv) const +URLWorker::GetPassword(nsAString& aPassword) const { STDURL_GETTER(aPassword, GetPassword); MOZ_ASSERT(mURLProxy); - RefPtr<GetterRunnable> runnable = - new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPassword, aPassword, - mURLProxy); - - runnable->Dispatch(aRv); + mURLProxy->URL()->GetPassword(aPassword); } void -URLWorker::SetPassword(const nsAString& aPassword, ErrorResult& aRv) +URLWorker::SetPassword(const nsAString& aPassword) { STDURL_SETTER(aPassword, SetPassword); MOZ_ASSERT(mURLProxy); - RefPtr<SetterRunnable> runnable = - new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPassword, - aPassword, mURLProxy); - - runnable->Dispatch(aRv); - if (NS_WARN_IF(aRv.Failed())) { - return; - } - - MOZ_ASSERT(!runnable->Failed()); + mURLProxy->URL()->SetPassword(aPassword); } void -URLWorker::GetHost(nsAString& aHost, ErrorResult& aRv) const +URLWorker::GetHost(nsAString& aHost) const { STDURL_GETTER(aHost, GetHostPort); MOZ_ASSERT(mURLProxy); - RefPtr<GetterRunnable> runnable = - new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHost, aHost, - mURLProxy); - - runnable->Dispatch(aRv); + mURLProxy->URL()->GetHost(aHost); } void -URLWorker::SetHost(const nsAString& aHost, ErrorResult& aRv) +URLWorker::SetHost(const nsAString& aHost) { STDURL_SETTER(aHost, SetHostPort); MOZ_ASSERT(mURLProxy); - RefPtr<SetterRunnable> runnable = - new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHost, - aHost, mURLProxy); - - runnable->Dispatch(aRv); - if (NS_WARN_IF(aRv.Failed())) { - return; - } - - MOZ_ASSERT(!runnable->Failed()); + mURLProxy->URL()->SetHost(aHost); } void -URLWorker::GetHostname(nsAString& aHostname, ErrorResult& aRv) const +URLWorker::GetHostname(nsAString& aHostname) const { aHostname.Truncate(); if (mStdURL) { - aRv = nsContentUtils::GetHostOrIPv6WithBrackets(mStdURL, aHostname); + nsresult rv = nsContentUtils::GetHostOrIPv6WithBrackets(mStdURL, aHostname); + if (NS_FAILED(rv)) { + aHostname.Truncate(); + } return; } MOZ_ASSERT(mURLProxy); - RefPtr<GetterRunnable> runnable = - new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHostname, aHostname, - mURLProxy); - - runnable->Dispatch(aRv); + mURLProxy->URL()->GetHostname(aHostname); } void -URLWorker::SetHostname(const nsAString& aHostname, ErrorResult& aRv) +URLWorker::SetHostname(const nsAString& aHostname) { STDURL_SETTER(aHostname, SetHost); MOZ_ASSERT(mURLProxy); - RefPtr<SetterRunnable> runnable = - new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHostname, - aHostname, mURLProxy); - - runnable->Dispatch(aRv); - if (NS_WARN_IF(aRv.Failed())) { - return; - } - - MOZ_ASSERT(!runnable->Failed()); + mURLProxy->URL()->SetHostname(aHostname); } void -URLWorker::GetPort(nsAString& aPort, ErrorResult& aRv) const +URLWorker::GetPort(nsAString& aPort) const { aPort.Truncate(); if (mStdURL) { int32_t port; nsresult rv = mStdURL->GetPort(&port); if (NS_SUCCEEDED(rv) && port != -1) { nsAutoString portStr; portStr.AppendInt(port, 10); aPort.Assign(portStr); } return; } MOZ_ASSERT(mURLProxy); - RefPtr<GetterRunnable> runnable = - new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPort, aPort, - mURLProxy); - - runnable->Dispatch(aRv); + mURLProxy->URL()->GetPort(aPort); } void -URLWorker::SetPort(const nsAString& aPort, ErrorResult& aRv) +URLWorker::SetPort(const nsAString& aPort) { if (mStdURL) { nsresult rv; nsAutoString portStr(aPort); int32_t port = -1; // nsIURI uses -1 as default value. if (!portStr.IsEmpty()) { @@ -1047,167 +822,113 @@ URLWorker::SetPort(const nsAString& aPor Unused << NS_MutateURI(mStdURL) .SetPort(port) .Finalize(mStdURL); return; } MOZ_ASSERT(mURLProxy); - RefPtr<SetterRunnable> runnable = - new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPort, - aPort, mURLProxy); - - runnable->Dispatch(aRv); - if (NS_WARN_IF(aRv.Failed())) { - return; - } - - MOZ_ASSERT(!runnable->Failed()); + mURLProxy->URL()->SetPort(aPort); } void -URLWorker::GetPathname(nsAString& aPathname, ErrorResult& aRv) const +URLWorker::GetPathname(nsAString& aPathname) const { aPathname.Truncate(); if (mStdURL) { nsAutoCString file; nsresult rv = mStdURL->GetFilePath(file); if (NS_SUCCEEDED(rv)) { CopyUTF8toUTF16(file, aPathname); } return; } MOZ_ASSERT(mURLProxy); - RefPtr<GetterRunnable> runnable = - new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterPathname, - aPathname, mURLProxy); - - runnable->Dispatch(aRv); + mURLProxy->URL()->GetPathname(aPathname); } void -URLWorker::SetPathname(const nsAString& aPathname, ErrorResult& aRv) +URLWorker::SetPathname(const nsAString& aPathname) { STDURL_SETTER(aPathname, SetFilePath); MOZ_ASSERT(mURLProxy); - RefPtr<SetterRunnable> runnable = - new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterPathname, - aPathname, mURLProxy); - - runnable->Dispatch(aRv); - if (NS_WARN_IF(aRv.Failed())) { - return; - } - - MOZ_ASSERT(!runnable->Failed()); + mURLProxy->URL()->SetPathname(aPathname); } void -URLWorker::GetSearch(nsAString& aSearch, ErrorResult& aRv) const +URLWorker::GetSearch(nsAString& aSearch) const { aSearch.Truncate(); if (mStdURL) { nsAutoCString search; nsresult rv; rv = mStdURL->GetQuery(search); if (NS_SUCCEEDED(rv) && !search.IsEmpty()) { aSearch.Assign(u'?'); AppendUTF8toUTF16(search, aSearch); } return; } MOZ_ASSERT(mURLProxy); - RefPtr<GetterRunnable> runnable = - new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterSearch, aSearch, - mURLProxy); - - runnable->Dispatch(aRv); + mURLProxy->URL()->GetSearch(aSearch); } void -URLWorker::GetHash(nsAString& aHash, ErrorResult& aRv) const +URLWorker::GetHash(nsAString& aHash) const { aHash.Truncate(); if (mStdURL) { nsAutoCString ref; nsresult rv = mStdURL->GetRef(ref); if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) { aHash.Assign(char16_t('#')); AppendUTF8toUTF16(ref, aHash); } return; } MOZ_ASSERT(mURLProxy); - RefPtr<GetterRunnable> runnable = - new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHash, aHash, - mURLProxy); - - runnable->Dispatch(aRv); + mURLProxy->URL()->GetHash(aHash); } void -URLWorker::SetHash(const nsAString& aHash, ErrorResult& aRv) +URLWorker::SetHash(const nsAString& aHash) { STDURL_SETTER(aHash, SetRef); MOZ_ASSERT(mURLProxy); - RefPtr<SetterRunnable> runnable = - new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterHash, - aHash, mURLProxy); - - runnable->Dispatch(aRv); - if (NS_WARN_IF(aRv.Failed())) { - return; - } - - MOZ_ASSERT(!runnable->Failed()); + mURLProxy->URL()->SetHash(aHash); } void -URLWorker::SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv) +URLWorker::SetSearchInternal(const nsAString& aSearch) { if (mStdURL) { // URLMainThread ignores failures here. Unused << NS_MutateURI(mStdURL) .SetQuery(NS_ConvertUTF16toUTF8(aSearch)) .Finalize(mStdURL); return; } MOZ_ASSERT(mURLProxy); - RefPtr<SetterRunnable> runnable = - new SetterRunnable(mWorkerPrivate, SetterRunnable::SetterSearch, - aSearch, mURLProxy); - - runnable->Dispatch(aRv); - if (NS_WARN_IF(aRv.Failed())) { - return; - } - - MOZ_ASSERT(!runnable->Failed()); + mURLProxy->URL()->SetSearch(aSearch); } void URLWorker::UpdateURLSearchParams() { if (mSearchParams) { nsAutoString search; - - ErrorResult rv; - GetSearch(search, rv); - if (NS_WARN_IF(rv.Failed())) { - rv.SuppressException(); - } - + GetSearch(search); mSearchParams->ParseInput(NS_ConvertUTF16toUTF8(Substring(search, 1))); } } } // namespace dom } // namespace mozilla
--- a/dom/url/URLWorker.h +++ b/dom/url/URLWorker.h @@ -48,79 +48,79 @@ public: explicit URLWorker(WorkerPrivate* aWorkerPrivate); void Init(const nsAString& aURL, const Optional<nsAString>& aBase, ErrorResult& aRv); virtual void - GetHref(nsAString& aHref, ErrorResult& aRv) const override; + GetHref(nsAString& aHref) const override; virtual void SetHref(const nsAString& aHref, ErrorResult& aRv) override; virtual void GetOrigin(nsAString& aOrigin, ErrorResult& aRv) const override; virtual void - GetProtocol(nsAString& aProtocol, ErrorResult& aRv) const override; + GetProtocol(nsAString& aProtocol) const override; virtual void SetProtocol(const nsAString& aProtocol, ErrorResult& aRv) override; virtual void - GetUsername(nsAString& aUsername, ErrorResult& aRv) const override; + GetUsername(nsAString& aUsername) const override; virtual void - SetUsername(const nsAString& aUsername, ErrorResult& aRv) override; + SetUsername(const nsAString& aUsername) override; virtual void - GetPassword(nsAString& aPassword, ErrorResult& aRv) const override; + GetPassword(nsAString& aPassword) const override; virtual void - SetPassword(const nsAString& aPassword, ErrorResult& aRv) override; + SetPassword(const nsAString& aPassword) override; virtual void - GetHost(nsAString& aHost, ErrorResult& aRv) const override; + GetHost(nsAString& aHost) const override; virtual void - SetHost(const nsAString& aHost, ErrorResult& aRv) override; + SetHost(const nsAString& aHost) override; virtual void - GetHostname(nsAString& aHostname, ErrorResult& aRv) const override; + GetHostname(nsAString& aHostname) const override; virtual void - SetHostname(const nsAString& aHostname, ErrorResult& aRv) override; + SetHostname(const nsAString& aHostname) override; virtual void - GetPort(nsAString& aPort, ErrorResult& aRv) const override; + GetPort(nsAString& aPort) const override; virtual void - SetPort(const nsAString& aPort, ErrorResult& aRv) override; + SetPort(const nsAString& aPort) override; virtual void - GetPathname(nsAString& aPathname, ErrorResult& aRv) const override; + GetPathname(nsAString& aPathname) const override; virtual void - SetPathname(const nsAString& aPathname, ErrorResult& aRv) override; + SetPathname(const nsAString& aPathname) override; virtual void - GetSearch(nsAString& aSearch, ErrorResult& aRv) const override; + GetSearch(nsAString& aSearch) const override; virtual void - GetHash(nsAString& aHost, ErrorResult& aRv) const override; + GetHash(nsAString& aHost) const override; virtual void - SetHash(const nsAString& aHash, ErrorResult& aRv) override; + SetHash(const nsAString& aHash) override; virtual void UpdateURLSearchParams() override; virtual void - SetSearchInternal(const nsAString& aSearch, ErrorResult& aRv) override; + SetSearchInternal(const nsAString& aSearch) override; private: ~URLWorker(); enum Strategy { eAlwaysUseProxy, eUseProxyIfNeeded, };
--- a/dom/webidl/URL.webidl +++ b/dom/webidl/URL.webidl @@ -14,44 +14,35 @@ [Constructor(USVString url, optional USVString base), Exposed=(Window,Worker,WorkerDebugger)] interface URL { // Bug 824857: no support for stringifier attributes yet. // stringifier attribute USVString href; // Bug 824857 should remove this. - [Throws] stringifier; - [Throws] + [SetterThrows] attribute USVString href; - [Throws] + [GetterThrows] readonly attribute USVString origin; - [Throws] + [SetterThrows] attribute USVString protocol; - [Throws] attribute USVString username; - [Throws] attribute USVString password; - [Throws] attribute USVString host; - [Throws] attribute USVString hostname; - [Throws] attribute USVString port; - [Throws] attribute USVString pathname; - [Throws] attribute USVString search; - [SameObject] readonly attribute URLSearchParams searchParams; - [Throws] + [SameObject] + readonly attribute URLSearchParams searchParams; attribute USVString hash; - [Throws] USVString toJSON(); }; partial interface URL { [Throws] static DOMString createObjectURL(Blob blob); [Throws] static DOMString createObjectURL(MediaStream stream);
--- a/dom/xhr/XMLHttpRequestMainThread.cpp +++ b/dom/xhr/XMLHttpRequestMainThread.cpp @@ -242,30 +242,16 @@ XMLHttpRequestMainThread::~XMLHttpReques MOZ_ASSERT(!mFlagSyncLooping, "we rather crash than hang"); mFlagSyncLooping = false; mResultJSON.setUndefined(); mResultArrayBuffer = nullptr; mozilla::DropJSObjects(this); } -/** - * This Init method should only be called by C++ consumers. - */ -nsresult -XMLHttpRequestMainThread::Init(nsIPrincipal* aPrincipal, - nsIGlobalObject* aGlobalObject, - nsIURI* aBaseURI, - nsILoadGroup* aLoadGroup) -{ - NS_ENSURE_ARG_POINTER(aPrincipal); - Construct(aPrincipal, aGlobalObject, aBaseURI, aLoadGroup); - return NS_OK; -} - void XMLHttpRequestMainThread::InitParameters(bool aAnon, bool aSystem) { if (!aAnon && !aSystem) { return; } // Check for permissions.
--- a/dom/xhr/XMLHttpRequestMainThread.h +++ b/dom/xhr/XMLHttpRequestMainThread.h @@ -462,22 +462,16 @@ public: // This fires a trusted readystatechange event, which is not cancelable and // doesn't bubble. nsresult FireReadystatechangeEvent(); void DispatchProgressEvent(DOMEventTargetHelper* aTarget, const ProgressEventType aType, int64_t aLoaded, int64_t aTotal); - // This is called by nsXULTemplateQueryProcessorXML. - nsresult Init(nsIPrincipal* aPrincipal, - nsIGlobalObject* aGlobalObject, - nsIURI* aBaseURI, - nsILoadGroup* aLoadGroup); - void SetRequestObserver(nsIRequestObserver* aObserver); NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(XMLHttpRequestMainThread, XMLHttpRequest) virtual bool IsCertainlyAliveForCC() const override; bool AllowUploadProgress();
--- a/intl/lwbrk/LineBreaker.cpp +++ b/intl/lwbrk/LineBreaker.cpp @@ -4,16 +4,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/intl/LineBreaker.h" #include "jisx4051class.h" #include "nsComplexBreaker.h" #include "nsTArray.h" #include "nsUnicodeProperties.h" +#include "mozilla/ArrayUtils.h" using namespace mozilla::unicode; using namespace mozilla::intl; /*static*/ already_AddRefed<LineBreaker> LineBreaker::Create() {
--- a/intl/uconv/nsTextToSubURI.cpp +++ b/intl/uconv/nsTextToSubURI.cpp @@ -2,16 +2,17 @@ /* 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 "nsString.h" #include "nsITextToSubURI.h" #include "nsEscape.h" #include "nsTextToSubURI.h" #include "nsCRT.h" +#include "mozilla/ArrayUtils.h" #include "mozilla/Encoding.h" #include "mozilla/Preferences.h" #include "nsISupportsPrimitives.h" using namespace mozilla; // Fallback value for the pref "network.IDN.blacklist_chars". // UnEscapeURIForUI allows unescaped space; other than that, this is
--- a/js/public/Conversions.h +++ b/js/public/Conversions.h @@ -5,16 +5,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* ECMAScript conversion operations. */ #ifndef js_Conversions_h #define js_Conversions_h #include "mozilla/Casting.h" +#include "mozilla/Compiler.h" #include "mozilla/FloatingPoint.h" #include "mozilla/MathAlgorithms.h" #include "mozilla/TypeTraits.h" #include "mozilla/WrappingOperations.h" #include <math.h> #include "jspubtd.h" @@ -393,17 +394,17 @@ ToIntWidth(double d) } // namespace detail /* ES5 9.5 ToInt32 (specialized for doubles). */ inline int32_t ToInt32(double d) { // clang crashes compiling this when targeting arm: // https://llvm.org/bugs/show_bug.cgi?id=22974 -#if defined (__arm__) && defined (__GNUC__) && !defined(__clang__) +#if defined (__arm__) && MOZ_IS_GCC int32_t i; uint32_t tmp0; uint32_t tmp1; uint32_t tmp2; asm ( // We use a pure integer solution here. In the 'softfp' ABI, the argument // will start in r0 and r1, and VFP can't do all of the necessary ECMA // conversions by itself so some integer code will be required anyway. A
--- a/js/public/HashTable.h +++ b/js/public/HashTable.h @@ -1767,25 +1767,20 @@ class HashTable : private AllocPolicy } MOZ_ALWAYS_INLINE AddPtr lookupForAdd(const Lookup& l) const { mozilla::ReentrancyGuard g(*this); if (!EnsureHash<HashPolicy>(l)) return AddPtr(); HashNumber keyHash = prepareHash(l); - // Calling constructor in return statement here avoid excess copying - // when build with Visual Studio 2015 and 2017, but it triggers a bug in - // gcc which is fixed in gcc-6. See bug 1385181. -#if MOZ_IS_GCC && __GNUC__ < 6 - AddPtr p(lookup(l, keyHash, sCollisionBit), *this, keyHash); - return p; -#else + // Directly call the constructor in the return statement to avoid + // excess copying when building with Visual Studio 2017. + // See bug 1385181. return AddPtr(lookup(l, keyHash, sCollisionBit), *this, keyHash); -#endif } template <typename... Args> MOZ_MUST_USE bool add(AddPtr& p, Args&&... args) { mozilla::ReentrancyGuard g(*this); MOZ_ASSERT(table); MOZ_ASSERT_IF(p.isValid(), p.table_ == this);
--- a/js/public/Proxy.h +++ b/js/public/Proxy.h @@ -674,19 +674,16 @@ extern JS_FRIEND_API(void) assertEnteredPolicy(JSContext* cx, JSObject* obj, jsid id, BaseProxyHandler::Action act); #else inline void assertEnteredPolicy(JSContext* cx, JSObject* obj, jsid id, BaseProxyHandler::Action act) {} #endif -extern JS_FRIEND_API(JSObject*) -InitProxyClass(JSContext* cx, JS::HandleObject obj); - extern JS_FRIEND_DATA(const js::ClassOps) ProxyClassOps; extern JS_FRIEND_DATA(const js::ClassExtension) ProxyClassExtension; extern JS_FRIEND_DATA(const js::ObjectOps) ProxyObjectOps; template <unsigned Flags> constexpr unsigned CheckProxyFlags() {
--- a/js/public/Value.h +++ b/js/public/Value.h @@ -179,40 +179,28 @@ enum JSWhyMagic JS_ELEMENTS_HOLE, /** there is not a pending iterator value */ JS_NO_ITER_VALUE, /** exception value thrown when closing a generator */ JS_GENERATOR_CLOSING, - /** compiler sentinel value */ - JS_NO_CONSTANT, - - /** used in debug builds to catch tracing errors */ - JS_THIS_POISON, - /** used in debug builds to catch tracing errors */ JS_ARG_POISON, /** an empty subnode in the AST serializer */ JS_SERIALIZE_NO_NODE, - /** lazy arguments value on the stack */ - JS_LAZY_ARGUMENTS, - /** optimized-away 'arguments' value */ JS_OPTIMIZED_ARGUMENTS, /** magic value passed to natives to indicate construction */ JS_IS_CONSTRUCTING, - /** value of static block object slot */ - JS_BLOCK_NEEDS_CLONE, - /** see class js::HashableValue */ JS_HASH_KEY_EMPTY, /** error while running Ion code */ JS_ION_ERROR, /** missing recover instruction result */ JS_ION_BAILOUT,
--- a/js/src/builtin/AtomicsObject.cpp +++ b/js/src/builtin/AtomicsObject.cpp @@ -1008,17 +1008,15 @@ AtomicsObject::initClass(JSContext* cx, if (!DefineDataProperty(cx, global, cx->names().Atomics, AtomicsValue, JSPROP_RESOLVING)) return nullptr; global->setConstructor(JSProto_Atomics, AtomicsValue); return Atomics; } JSObject* -js::InitAtomicsClass(JSContext* cx, HandleObject obj) +js::InitAtomicsClass(JSContext* cx, Handle<GlobalObject*> global) { - MOZ_ASSERT(obj->is<GlobalObject>()); - Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>()); return AtomicsObject::initClass(cx, global); } #undef CXX11_ATOMICS #undef GNU_ATOMICS
--- a/js/src/builtin/AtomicsObject.h +++ b/js/src/builtin/AtomicsObject.h @@ -12,16 +12,18 @@ #include "threading/ConditionVariable.h" #include "vm/JSObject.h" #include "vm/MutexIDs.h" #include "vm/NativeObject.h" namespace js { +class GlobalObject; + class AtomicsObject : public NativeObject { public: static const Class class_; static JSObject* initClass(JSContext* cx, Handle<GlobalObject*> global); static MOZ_MUST_USE bool toString(JSContext* cx, unsigned int argc, Value* vp); }; @@ -136,17 +138,17 @@ public: // or coarser. static mozilla::Atomic<js::Mutex*> lock_; // A flag that controls whether waiting is allowed. ThreadLocalData<bool> canWait_; }; JSObject* -InitAtomicsClass(JSContext* cx, HandleObject obj); +InitAtomicsClass(JSContext* cx, Handle<GlobalObject*> global); // Go to sleep if the int32_t value at the given address equals `value`. MOZ_MUST_USE FutexThread::WaitResult atomics_wait_impl(JSContext* cx, SharedArrayRawBuffer* sarb, uint32_t byteOffset, int32_t value, const mozilla::Maybe<mozilla::TimeDuration>& timeout); // Go to sleep if the int64_t value at the given address equals `value`. MOZ_MUST_USE FutexThread::WaitResult
--- a/js/src/builtin/Boolean.cpp +++ b/js/src/builtin/Boolean.cpp @@ -123,22 +123,18 @@ Boolean(JSContext* cx, unsigned argc, Va args.rval().setObject(*obj); } else { args.rval().setBoolean(b); } return true; } JSObject* -js::InitBooleanClass(JSContext* cx, HandleObject obj) +js::InitBooleanClass(JSContext* cx, Handle<GlobalObject*> global) { - MOZ_ASSERT(obj->isNative()); - - Handle<GlobalObject*> global = obj.as<GlobalObject>(); - Rooted<BooleanObject*> booleanProto(cx, GlobalObject::createBlankPrototype<BooleanObject>(cx, global)); if (!booleanProto) return nullptr; booleanProto->setFixedSlot(BooleanObject::PRIMITIVE_VALUE_SLOT, BooleanValue(false)); RootedFunction ctor(cx, GlobalObject::createConstructor(cx, Boolean, cx->names().Boolean, 1, gc::AllocKind::FUNCTION, &jit::JitInfo_Boolean));
--- a/js/src/builtin/Boolean.h +++ b/js/src/builtin/Boolean.h @@ -10,17 +10,19 @@ /* * JS boolean interface. */ #include "NamespaceImports.h" namespace js { +class GlobalObject; + extern JSObject* -InitBooleanClass(JSContext* cx, js::HandleObject obj); +InitBooleanClass(JSContext* cx, js::Handle<GlobalObject*> global); extern JSString* BooleanToString(JSContext* cx, bool b); } // namespace js #endif /* builtin_Boolean_h */
--- a/js/src/builtin/DataViewObject.h +++ b/js/src/builtin/DataViewObject.h @@ -152,17 +152,16 @@ class DataViewObject : public NativeObje static bool fun_setUint32(JSContext* cx, unsigned argc, Value* vp); static bool setFloat32Impl(JSContext* cx, const CallArgs& args); static bool fun_setFloat32(JSContext* cx, unsigned argc, Value* vp); static bool setFloat64Impl(JSContext* cx, const CallArgs& args); static bool fun_setFloat64(JSContext* cx, unsigned argc, Value* vp); - static bool initClass(JSContext* cx); template<typename NativeType> static bool read(JSContext* cx, Handle<DataViewObject*> obj, const CallArgs& args, NativeType* val); template<typename NativeType> static bool write(JSContext* cx, Handle<DataViewObject*> obj, const CallArgs& args); void notifyBufferDetached(void* newData);
--- a/js/src/builtin/JSON.cpp +++ b/js/src/builtin/JSON.cpp @@ -979,20 +979,18 @@ json_stringify(JSContext* cx, unsigned a static const JSFunctionSpec json_static_methods[] = { JS_FN(js_toSource_str, json_toSource, 0, 0), JS_FN("parse", json_parse, 2, 0), JS_FN("stringify", json_stringify, 3, 0), JS_FS_END }; JSObject* -js::InitJSONClass(JSContext* cx, HandleObject obj) +js::InitJSONClass(JSContext* cx, Handle<GlobalObject*> global) { - Handle<GlobalObject*> global = obj.as<GlobalObject>(); - RootedObject proto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global)); if (!proto) return nullptr; RootedObject JSON(cx, NewObjectWithGivenProto(cx, &JSONClass, proto, SingletonObject)); if (!JSON) return nullptr; if (!JS_DefineProperty(cx, global, js_JSON_str, JSON, JSPROP_RESOLVING))
--- a/js/src/builtin/JSON.h +++ b/js/src/builtin/JSON.h @@ -9,20 +9,25 @@ #include "mozilla/Range.h" #include "NamespaceImports.h" #include "js/RootingAPI.h" namespace js { + +struct Class; +class GlobalObject; class StringBuffer; +extern const Class JSONClass; + extern JSObject* -InitJSONClass(JSContext* cx, HandleObject obj); +InitJSONClass(JSContext* cx, Handle<GlobalObject*> obj); enum class StringifyBehavior { Normal, RestrictedSafe }; /** * If maybeSafely is true, Stringify will attempt to assert the API requirements
--- a/js/src/builtin/ModuleObject.cpp +++ b/js/src/builtin/ModuleObject.cpp @@ -144,21 +144,20 @@ ImportEntryObject::create(JSContext* cx, HandleAtom localName, uint32_t lineNumber, uint32_t columnNumber) { RootedObject proto(cx, GlobalObject::getOrCreateImportEntryPrototype(cx, cx->global())); if (!proto) return nullptr; - RootedObject obj(cx, NewObjectWithGivenProto(cx, &class_, proto)); - if (!obj) + ImportEntryObject* self = NewObjectWithGivenProto<ImportEntryObject>(cx, proto); + if (!self) return nullptr; - RootedImportEntryObject self(cx, &obj->as<ImportEntryObject>()); self->initReservedSlot(ModuleRequestSlot, StringValue(moduleRequest)); self->initReservedSlot(ImportNameSlot, StringValue(importName)); self->initReservedSlot(LocalNameSlot, StringValue(localName)); self->initReservedSlot(LineNumberSlot, NumberValue(lineNumber)); self->initReservedSlot(ColumnNumberSlot, NumberValue(columnNumber)); return self; } @@ -233,21 +232,20 @@ ExportEntryObject::create(JSContext* cx, { // Line and column numbers are optional for export entries since direct // entries are checked at parse time. RootedObject proto(cx, GlobalObject::getOrCreateExportEntryPrototype(cx, cx->global())); if (!proto) return nullptr; - RootedObject obj(cx, NewObjectWithGivenProto(cx, &class_, proto)); - if (!obj) + ExportEntryObject* self = NewObjectWithGivenProto<ExportEntryObject>(cx, proto); + if (!self) return nullptr; - RootedExportEntryObject self(cx, &obj->as<ExportEntryObject>()); self->initReservedSlot(ExportNameSlot, StringOrNullValue(maybeExportName)); self->initReservedSlot(ModuleRequestSlot, StringOrNullValue(maybeModuleRequest)); self->initReservedSlot(ImportNameSlot, StringOrNullValue(maybeImportName)); self->initReservedSlot(LocalNameSlot, StringOrNullValue(maybeLocalName)); self->initReservedSlot(LineNumberSlot, NumberValue(lineNumber)); self->initReservedSlot(ColumnNumberSlot, NumberValue(columnNumber)); return self; } @@ -302,21 +300,20 @@ RequestedModuleObject::create(JSContext* HandleAtom moduleSpecifier, uint32_t lineNumber, uint32_t columnNumber) { RootedObject proto(cx, GlobalObject::getOrCreateRequestedModulePrototype(cx, cx->global())); if (!proto) return nullptr; - RootedObject obj(cx, NewObjectWithGivenProto(cx, &class_, proto)); - if (!obj) + RequestedModuleObject* self = NewObjectWithGivenProto<RequestedModuleObject>(cx, proto); + if (!self) return nullptr; - RootedRequestedModuleObject self(cx, &obj->as<RequestedModuleObject>()); self->initReservedSlot(ModuleSpecifierSlot, StringValue(moduleSpecifier)); self->initReservedSlot(LineNumberSlot, NumberValue(lineNumber)); self->initReservedSlot(ColumnNumberSlot, NumberValue(columnNumber)); return self; } /////////////////////////////////////////////////////////////////////////// // IndirectBindingMap @@ -766,22 +763,20 @@ ModuleObject::isInstance(HandleValue val /* static */ ModuleObject* ModuleObject::create(JSContext* cx) { RootedObject proto(cx, GlobalObject::getOrCreateModulePrototype(cx, cx->global())); if (!proto) return nullptr; - RootedObject obj(cx, NewObjectWithGivenProto(cx, &class_, proto)); - if (!obj) + RootedModuleObject self(cx, NewObjectWithGivenProto<ModuleObject>(cx, proto)); + if (!self) return nullptr; - RootedModuleObject self(cx, &obj->as<ModuleObject>()); - Zone* zone = cx->zone(); IndirectBindingMap* bindings = zone->new_<IndirectBindingMap>(); if (!bindings) { ReportOutOfMemory(cx); return nullptr; } self->initReservedSlot(ImportBindingsSlot, PrivateValue(bindings));
--- a/js/src/builtin/ModuleObject.h +++ b/js/src/builtin/ModuleObject.h @@ -43,17 +43,16 @@ class ImportEntryObject : public NativeO ImportNameSlot, LocalNameSlot, LineNumberSlot, ColumnNumberSlot, SlotCount }; static const Class class_; - static JSObject* initClass(JSContext* cx, HandleObject obj); static bool isInstance(HandleValue value); static ImportEntryObject* create(JSContext* cx, HandleAtom moduleRequest, HandleAtom importName, HandleAtom localName, uint32_t lineNumber, uint32_t columnNumber); JSAtom* moduleRequest() const; @@ -76,17 +75,16 @@ class ExportEntryObject : public NativeO ImportNameSlot, LocalNameSlot, LineNumberSlot, ColumnNumberSlot, SlotCount }; static const Class class_; - static JSObject* initClass(JSContext* cx, HandleObject obj); static bool isInstance(HandleValue value); static ExportEntryObject* create(JSContext* cx, HandleAtom maybeExportName, HandleAtom maybeModuleRequest, HandleAtom maybeImportName, HandleAtom maybeLocalName, uint32_t lineNumber, uint32_t columnNumber); @@ -108,17 +106,16 @@ class RequestedModuleObject : public Nat { ModuleSpecifierSlot = 0, LineNumberSlot, ColumnNumberSlot, SlotCount }; static const Class class_; - static JSObject* initClass(JSContext* cx, HandleObject obj); static bool isInstance(HandleValue value); static RequestedModuleObject* create(JSContext* cx, HandleAtom moduleSpecifier, uint32_t lineNumber, uint32_t columnNumber); JSAtom* moduleSpecifier() const; uint32_t lineNumber() const; uint32_t columnNumber() const;
--- a/js/src/builtin/Object.h +++ b/js/src/builtin/Object.h @@ -7,17 +7,16 @@ #ifndef builtin_Object_h #define builtin_Object_h #include "jsapi.h" #include "vm/NativeObject.h" namespace JS { -class CallArgs; union Value; } // namespace JS namespace js { // Object constructor native. Exposed only so the JIT can know its address. MOZ_MUST_USE bool obj_construct(JSContext* cx, unsigned argc, JS::Value* vp); @@ -59,15 +58,11 @@ GetOwnPropertyDescriptorToArray(JSContex */ MOZ_MUST_USE bool IdToStringOrSymbol(JSContext* cx, JS::HandleId id, JS::MutableHandleValue result); // Object.prototype.toSource. Function.prototype.toSource and uneval use this. JSString* ObjectToSource(JSContext* cx, JS::HandleObject obj); -extern MOZ_MUST_USE bool -WatchHandler(JSContext* cx, JSObject* obj, jsid id, const JS::Value& old, - JS::Value* nvp, void* closure); - } /* namespace js */ #endif /* builtin_Object_h */
--- a/js/src/builtin/Promise.h +++ b/js/src/builtin/Promise.h @@ -21,20 +21,19 @@ enum PromiseSlots { PromiseSlot_AwaitGenerator = PromiseSlot_RejectFunction, PromiseSlot_DebugInfo, PromiseSlots, }; #define PROMISE_FLAG_RESOLVED 0x1 #define PROMISE_FLAG_FULFILLED 0x2 #define PROMISE_FLAG_HANDLED 0x4 -#define PROMISE_FLAG_REPORTED 0x8 -#define PROMISE_FLAG_DEFAULT_RESOLVE_FUNCTION 0x10 -#define PROMISE_FLAG_DEFAULT_REJECT_FUNCTION 0x20 -#define PROMISE_FLAG_ASYNC 0x40 +#define PROMISE_FLAG_DEFAULT_RESOLVE_FUNCTION 0x08 +#define PROMISE_FLAG_DEFAULT_REJECT_FUNCTION 0x10 +#define PROMISE_FLAG_ASYNC 0x20 class AutoSetNewObjectMetadata; class PromiseObject : public NativeObject { public: static const unsigned RESERVED_SLOTS = PromiseSlots; static const Class class_; @@ -83,21 +82,16 @@ class PromiseObject : public NativeObjec return resolutionTime() - allocationTime(); } MOZ_MUST_USE bool dependentPromises(JSContext* cx, MutableHandle<GCVector<Value>> values); uint64_t getID(); bool isUnhandled() { MOZ_ASSERT(state() == JS::PromiseState::Rejected); return !(getFixedSlot(PromiseSlot_Flags).toInt32() & PROMISE_FLAG_HANDLED); } - void markAsReported() { - MOZ_ASSERT(isUnhandled()); - int32_t flags = getFixedSlot(PromiseSlot_Flags).toInt32(); - setFixedSlot(PromiseSlot_Flags, Int32Value(flags | PROMISE_FLAG_REPORTED)); - } }; /** * Unforgeable version of the JS builtin Promise.all. * * Takes an AutoObjectVector of Promise objects and returns a promise that's * resolved with an array of resolution values when all those promises have * been resolved, or rejected with the rejection value of the first rejected
--- a/js/src/builtin/Reflect.cpp +++ b/js/src/builtin/Reflect.cpp @@ -200,29 +200,28 @@ static const JSFunctionSpec methods[] = JS_FN("setPrototypeOf", Reflect_setPrototypeOf, 2, 0), JS_FS_END }; /*** Setup **************************************************************************************/ JSObject* -js::InitReflect(JSContext* cx, HandleObject obj) +js::InitReflect(JSContext* cx, Handle<GlobalObject*> global) { - Handle<GlobalObject*> global = obj.as<GlobalObject>(); RootedObject proto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global)); if (!proto) return nullptr; RootedObject reflect(cx, NewObjectWithGivenProto<PlainObject>(cx, proto, SingletonObject)); if (!reflect) return nullptr; if (!JS_DefineFunctions(cx, reflect, methods)) return nullptr; RootedValue value(cx, ObjectValue(*reflect)); - if (!DefineDataProperty(cx, obj, cx->names().Reflect, value, JSPROP_RESOLVING)) + if (!DefineDataProperty(cx, global, cx->names().Reflect, value, JSPROP_RESOLVING)) return nullptr; - obj->as<GlobalObject>().setConstructor(JSProto_Reflect, value); + global->setConstructor(JSProto_Reflect, value); return reflect; }
--- a/js/src/builtin/Reflect.h +++ b/js/src/builtin/Reflect.h @@ -6,18 +6,20 @@ #ifndef builtin_Reflect_h #define builtin_Reflect_h #include "vm/JSObject.h" namespace js { +class GlobalObject; + extern JSObject* -InitReflect(JSContext* cx, js::HandleObject obj); +InitReflect(JSContext* cx, js::Handle<GlobalObject*> global); } namespace js { extern MOZ_MUST_USE bool Reflect_getPrototypeOf(JSContext* cx, unsigned argc, Value* vp);
--- a/js/src/builtin/SIMD.cpp +++ b/js/src/builtin/SIMD.cpp @@ -683,19 +683,18 @@ SimdObject::resolve(JSContext* cx, JS::H return *resolved; \ } FOR_EACH_SIMD(TRY_RESOLVE_) #undef TRY_RESOLVE_ return true; } JSObject* -js::InitSimdClass(JSContext* cx, HandleObject obj) +js::InitSimdClass(JSContext* cx, Handle<GlobalObject*> global) { - Handle<GlobalObject*> global = obj.as<GlobalObject>(); return GlobalObject::getOrCreateSimdGlobalObject(cx, global); } template<typename V> JSObject* js::CreateSimd(JSContext* cx, const typename V::Elem* data) { typedef typename V::Elem Elem;
--- a/js/src/builtin/SIMD.h +++ b/js/src/builtin/SIMD.h @@ -779,16 +779,18 @@ _(fromInt8x16Bits) \ _(fromInt16x8Bits) \ _(fromInt32x4Bits) \ _(fromInt32x4) \ _(fromUint32x4) namespace js { +class GlobalObject; + // Complete set of SIMD types. // It must be kept in sync with the enumeration of values in // TypedObjectConstants.h; in particular we need to ensure that Count is // appropriately set with respect to the number of actual types. enum class SimdType { Int8x16 = JS_SIMDTYPEREPR_INT8X16, Int16x8 = JS_SIMDTYPEREPR_INT16X8, Int32x4 = JS_SIMDTYPEREPR_INT32X4, @@ -1128,17 +1130,17 @@ JSObject* CreateSimd(JSContext* cx, cons template<typename V> bool IsVectorObject(HandleValue v); template<typename V> MOZ_MUST_USE bool ToSimdConstant(JSContext* cx, HandleValue v, jit::SimdConstant* out); JSObject* -InitSimdClass(JSContext* cx, HandleObject obj); +InitSimdClass(JSContext* cx, Handle<GlobalObject*> global); namespace jit { extern const JSJitInfo JitInfo_SimdInt32x4_extractLane; extern const JSJitInfo JitInfo_SimdFloat32x4_extractLane; } // namespace jit
--- a/js/src/builtin/Stream.h +++ b/js/src/builtin/Stream.h @@ -8,18 +8,16 @@ #define builtin_Stream_h #include "builtin/Promise.h" #include "vm/NativeObject.h" namespace js { -class AutoSetNewObjectMetadata; - class ReadableStream : public NativeObject { public: static ReadableStream* createDefaultStream(JSContext* cx, HandleValue underlyingSource, HandleValue size, HandleValue highWaterMark, HandleObject proto = nullptr); static ReadableStream* createByteStream(JSContext* cx, HandleValue underlyingSource, HandleValue highWaterMark,
--- a/js/src/builtin/String.cpp +++ b/js/src/builtin/String.cpp @@ -3617,28 +3617,23 @@ StringObject::assignInitialShape(JSConte { MOZ_ASSERT(obj->empty()); return NativeObject::addDataProperty(cx, obj, cx->names().length, LENGTH_SLOT, JSPROP_PERMANENT | JSPROP_READONLY); } JSObject* -js::InitStringClass(JSContext* cx, HandleObject obj) +js::InitStringClass(JSContext* cx, Handle<GlobalObject*> global) { - MOZ_ASSERT(obj->isNative()); - - Handle<GlobalObject*> global = obj.as<GlobalObject>(); - Rooted<JSString*> empty(cx, cx->runtime()->emptyString); - RootedObject proto(cx, GlobalObject::createBlankPrototype(cx, global, &StringObject::class_)); + Rooted<StringObject*> proto(cx, GlobalObject::createBlankPrototype<StringObject>(cx, global)); if (!proto) return nullptr; - Handle<StringObject*> protoObj = proto.as<StringObject>(); - if (!StringObject::init(cx, protoObj, empty)) + if (!StringObject::init(cx, proto, empty)) return nullptr; /* Now create the String function. */ RootedFunction ctor(cx); ctor = GlobalObject::createConstructor(cx, StringConstructor, cx->names().String, 1, AllocKind::FUNCTION, &jit::JitInfo_String); if (!ctor) return nullptr; @@ -3651,27 +3646,27 @@ js::InitStringClass(JSContext* cx, Handl { return nullptr; } // Create "trimLeft" as an alias for "trimStart". RootedValue trimFn(cx); RootedId trimId(cx, NameToId(cx->names().trimStart)); RootedId trimAliasId(cx, NameToId(cx->names().trimLeft)); - if (!NativeGetProperty(cx, protoObj, trimId, &trimFn) || - !NativeDefineDataProperty(cx, protoObj, trimAliasId, trimFn, 0)) + if (!NativeGetProperty(cx, proto, trimId, &trimFn) || + !NativeDefineDataProperty(cx, proto, trimAliasId, trimFn, 0)) { return nullptr; } // Create "trimRight" as an alias for "trimEnd". trimId = NameToId(cx->names().trimEnd); trimAliasId = NameToId(cx->names().trimRight); - if (!NativeGetProperty(cx, protoObj, trimId, &trimFn) || - !NativeDefineDataProperty(cx, protoObj, trimAliasId, trimFn, 0)) + if (!NativeGetProperty(cx, proto, trimId, &trimFn) || + !NativeDefineDataProperty(cx, proto, trimAliasId, trimFn, 0)) { return nullptr; } /* * Define escape/unescape, the URI encode/decode functions, and maybe * uneval on the global object. */
--- a/js/src/builtin/String.h +++ b/js/src/builtin/String.h @@ -19,19 +19,21 @@ #include "gc/Rooting.h" #include "js/RootingAPI.h" #include "js/UniquePtr.h" #include "util/Unicode.h" #include "vm/Printer.h" namespace js { +class GlobalObject; + /* Initialize the String class, returning its prototype object. */ extern JSObject* -InitStringClass(JSContext* cx, HandleObject obj); +InitStringClass(JSContext* cx, Handle<GlobalObject*> global); extern bool str_fromCharCode(JSContext* cx, unsigned argc, Value* vp); extern bool str_fromCharCode_one_arg(JSContext* cx, HandleValue code, MutableHandleValue rval); extern bool
--- a/js/src/builtin/Symbol.cpp +++ b/js/src/builtin/Symbol.cpp @@ -18,22 +18,21 @@ using namespace js; const Class SymbolObject::class_ = { "Symbol", JSCLASS_HAS_RESERVED_SLOTS(RESERVED_SLOTS) | JSCLASS_HAS_CACHED_PROTO(JSProto_Symbol) }; SymbolObject* SymbolObject::create(JSContext* cx, JS::HandleSymbol symbol) { - JSObject* obj = NewBuiltinClassInstance(cx, &class_); + SymbolObject* obj = NewBuiltinClassInstance<SymbolObject>(cx); if (!obj) return nullptr; - SymbolObject& symobj = obj->as<SymbolObject>(); - symobj.setPrimitiveValue(symbol); - return &symobj; + obj->setPrimitiveValue(symbol); + return obj; } const JSPropertySpec SymbolObject::properties[] = { JS_PS_END }; const JSFunctionSpec SymbolObject::methods[] = { JS_FN(js_toString_str, toString, 0, 0), @@ -44,20 +43,18 @@ const JSFunctionSpec SymbolObject::metho const JSFunctionSpec SymbolObject::staticMethods[] = { JS_FN("for", for_, 1, 0), JS_FN("keyFor", keyFor, 1, 0), JS_FS_END }; JSObject* -SymbolObject::initClass(JSContext* cx, HandleObject obj, bool defineMembers) +SymbolObject::initClass(JSContext* cx, Handle<GlobalObject*> global, bool defineMembers) { - Handle<GlobalObject*> global = obj.as<GlobalObject>(); - // This uses &JSObject::class_ because: "The Symbol prototype object is an // ordinary object. It is not a Symbol instance and does not have a // [[SymbolData]] internal slot." (ES6 rev 24, 19.4.3) RootedObject proto(cx, GlobalObject::createBlankPrototype<PlainObject>(cx, global)); if (!proto) return nullptr; RootedFunction ctor(cx, GlobalObject::createConstructor(cx, construct, @@ -230,18 +227,18 @@ SymbolObject::toPrimitive(JSContext* cx, CallArgs args = CallArgsFromVp(argc, vp); // The specification gives exactly the same algorithm for @@toPrimitive as // for valueOf, so reuse the valueOf implementation. return CallNonGenericMethod<IsSymbol, valueOf_impl>(cx, args); } JSObject* -js::InitSymbolClass(JSContext* cx, HandleObject obj) +js::InitSymbolClass(JSContext* cx, Handle<GlobalObject*> global) { - return SymbolObject::initClass(cx, obj, true); + return SymbolObject::initClass(cx, global, true); } JSObject* -js::InitBareSymbolCtor(JSContext* cx, HandleObject obj) +js::InitBareSymbolCtor(JSContext* cx, Handle<GlobalObject*> global) { - return SymbolObject::initClass(cx, obj, false); + return SymbolObject::initClass(cx, global, false); }
--- a/js/src/builtin/Symbol.h +++ b/js/src/builtin/Symbol.h @@ -7,27 +7,29 @@ #ifndef builtin_Symbol_h #define builtin_Symbol_h #include "vm/NativeObject.h" #include "vm/SymbolType.h" namespace js { +class GlobalObject; + class SymbolObject : public NativeObject { /* Stores this Symbol object's [[PrimitiveValue]]. */ static const unsigned PRIMITIVE_VALUE_SLOT = 0; public: static const unsigned RESERVED_SLOTS = 1; static const Class class_; - static JSObject* initClass(JSContext* cx, js::HandleObject obj, bool defineMembers); + static JSObject* initClass(JSContext* cx, Handle<GlobalObject*> global, bool defineMembers); /* * Creates a new Symbol object boxing the given primitive Symbol. The * object's [[Prototype]] is determined from context. */ static SymbolObject* create(JSContext* cx, JS::HandleSymbol symbol); JS::Symbol* unbox() const { @@ -53,16 +55,16 @@ class SymbolObject : public NativeObject static MOZ_MUST_USE bool toPrimitive(JSContext* cx, unsigned argc, Value* vp); static const JSPropertySpec properties[]; static const JSFunctionSpec methods[]; static const JSFunctionSpec staticMethods[]; }; extern JSObject* -InitSymbolClass(JSContext* cx, HandleObject obj); +InitSymbolClass(JSContext* cx, Handle<GlobalObject*> global); extern JSObject* -InitBareSymbolCtor(JSContext* cx, HandleObject obj); +InitBareSymbolCtor(JSContext* cx, Handle<GlobalObject*> global); } /* namespace js */ #endif /* builtin_Symbol_h */
--- a/js/src/builtin/TypedObject.cpp +++ b/js/src/builtin/TypedObject.cpp @@ -1305,19 +1305,18 @@ GlobalObject::initTypedObjectModule(JSCo } global->setConstructor(JSProto_TypedObject, moduleValue); return module; } JSObject* -js::InitTypedObjectModuleObject(JSContext* cx, HandleObject obj) +js::InitTypedObjectModuleObject(JSContext* cx, Handle<GlobalObject*> global) { - Handle<GlobalObject*> global = obj.as<GlobalObject>(); return GlobalObject::getOrCreateTypedObjectModule(cx, global); } /****************************************************************************** * Typed objects */ uint32_t
--- a/js/src/builtin/TypedObject.h +++ b/js/src/builtin/TypedObject.h @@ -88,16 +88,18 @@ * Typed objects (no matter their class) are non-native objects that * fully override the property accessors etc. The overridden accessor * methods are the same in each and are defined in methods of * TypedObject. */ namespace js { +class GlobalObject; + /* * Helper method for converting a double into other scalar * types in the same way that JavaScript would. In particular, * simple C casting from double to int32_t gets things wrong * for values like 0xF0000000. */ template <typename T> static T ConvertScalar(double d) @@ -1016,17 +1018,17 @@ IsTypeDescrClass(const Class* clasp) inline bool TypedObject::opaque() const { return IsOpaqueTypedObjectClass(getClass()); } JSObject* -InitTypedObjectModuleObject(JSContext* cx, JS::HandleObject obj); +InitTypedObjectModuleObject(JSContext* cx, JS::Handle<GlobalObject*> global); } // namespace js template <> inline bool JSObject::is<js::SimpleTypeDescr>() const { return IsSimpleTypeDescrClass(getClass());
--- a/js/src/builtin/WeakMapObject.cpp +++ b/js/src/builtin/WeakMapObject.cpp @@ -185,17 +185,17 @@ WeakCollection_finalize(FreeOp* fop, JSO MOZ_ASSERT(fop->maybeOnHelperThread()); if (ObjectValueMap* map = obj->as<WeakCollectionObject>().getMap()) fop->delete_(map); } JS_PUBLIC_API(JSObject*) JS::NewWeakMapObject(JSContext* cx) { - return NewBuiltinClassInstance(cx, &WeakMapObject::class_); + return NewBuiltinClassInstance<WeakMapObject>(cx); } JS_PUBLIC_API(bool) JS::IsWeakMapObject(JSObject* obj) { return obj->is<WeakMapObject>(); } @@ -285,22 +285,18 @@ static const JSFunctionSpec weak_map_met JS_FN("has", WeakMap_has, 1, 0), JS_FN("get", WeakMap_get, 1, 0), JS_FN("delete", WeakMap_delete, 1, 0), JS_FN("set", WeakMap_set, 2, 0), JS_FS_END }; JSObject* -js::InitWeakMapClass(JSContext* cx, HandleObject obj) +js::InitWeakMapClass(JSContext* cx, Handle<GlobalObject*> global) { - MOZ_ASSERT(obj->isNative()); - - Handle<GlobalObject*> global = obj.as<GlobalObject>(); - RootedPlainObject proto(cx, NewBuiltinClassInstance<PlainObject>(cx)); if (!proto) return nullptr; RootedFunction ctor(cx, GlobalObject::createConstructor(cx, WeakMap_construct, cx->names().WeakMap, 0)); if (!ctor) return nullptr;
--- a/js/src/builtin/WeakMapObject.h +++ b/js/src/builtin/WeakMapObject.h @@ -7,16 +7,18 @@ #ifndef builtin_WeakMapObject_h #define builtin_WeakMapObject_h #include "gc/WeakMap.h" #include "vm/JSObject.h" namespace js { +class GlobalObject; + // Abstract base class for WeakMapObject and WeakSetObject. class WeakCollectionObject : public NativeObject { public: ObjectValueMap* getMap() { return static_cast<ObjectValueMap*>(getPrivate()); } static MOZ_MUST_USE bool nondeterministicGetKeys(JSContext* cx, Handle<WeakCollectionObject*> obj, @@ -28,13 +30,13 @@ class WeakCollectionObject : public Nati class WeakMapObject : public WeakCollectionObject { public: static const Class class_; }; extern JSObject* -InitWeakMapClass(JSContext* cx, HandleObject obj); +InitWeakMapClass(JSContext* cx, Handle<GlobalObject*> global); } // namespace js #endif /* builtin_WeakMapObject_h */
--- a/js/src/builtin/WeakSetObject.cpp +++ b/js/src/builtin/WeakSetObject.cpp @@ -145,19 +145,18 @@ const JSPropertySpec WeakSetObject::prop const JSFunctionSpec WeakSetObject::methods[] = { JS_FN("add", WeakSet_add, 1, 0), JS_FN("delete", WeakSet_delete, 1, 0), JS_FN("has", WeakSet_has, 1, 0), JS_FS_END }; JSObject* -WeakSetObject::initClass(JSContext* cx, HandleObject obj) +WeakSetObject::initClass(JSContext* cx, Handle<GlobalObject*> global) { - Handle<GlobalObject*> global = obj.as<GlobalObject>(); RootedPlainObject proto(cx, NewBuiltinClassInstance<PlainObject>(cx)); if (!proto) return nullptr; Rooted<JSFunction*> ctor(cx, GlobalObject::createConstructor(cx, construct, ClassName(JSProto_WeakSet, cx), 0)); if (!ctor || !LinkConstructorAndPrototype(cx, ctor, proto) || @@ -233,19 +232,19 @@ WeakSetObject::construct(JSContext* cx, } args.rval().setObject(*obj); return true; } JSObject* -js::InitWeakSetClass(JSContext* cx, HandleObject obj) +js::InitWeakSetClass(JSContext* cx, Handle<GlobalObject*> global) { - return WeakSetObject::initClass(cx, obj); + return WeakSetObject::initClass(cx, global); } JS_FRIEND_API(bool) JS_NondeterministicGetWeakSetKeys(JSContext* cx, HandleObject objArg, MutableHandleObject ret) { RootedObject obj(cx, UncheckedUnwrap(objArg)); if (!obj || !obj->is<WeakSetObject>()) { ret.set(nullptr);
--- a/js/src/builtin/WeakSetObject.h +++ b/js/src/builtin/WeakSetObject.h @@ -6,34 +6,36 @@ #ifndef builtin_WeakSetObject_h #define builtin_WeakSetObject_h #include "builtin/WeakMapObject.h" namespace js { +class GlobalObject; + class WeakSetObject : public WeakCollectionObject { public: - static JSObject* initClass(JSContext* cx, HandleObject obj); + static JSObject* initClass(JSContext* cx, Handle<GlobalObject*> global); static const Class class_; private: static const JSPropertySpec properties[]; static const JSFunctionSpec methods[]; static WeakSetObject* create(JSContext* cx, HandleObject proto = nullptr); static MOZ_MUST_USE bool construct(JSContext* cx, unsigned argc, Value* vp); static bool isBuiltinAdd(HandleValue add); }; extern JSObject* -InitWeakSetClass(JSContext* cx, HandleObject obj); +InitWeakSetClass(JSContext* cx, Handle<GlobalObject*> global); } // namespace js template<> inline bool JSObject::is<js::WeakCollectionObject>() const { return is<js::WeakMapObject>() || is<js::WeakSetObject>();
--- a/js/src/builtin/intl/IntlObject.cpp +++ b/js/src/builtin/intl/IntlObject.cpp @@ -563,16 +563,15 @@ GlobalObject::initIntlObject(JSContext* // Use |setConstructor| to correspond with |JSProto_Intl|. // // XXX We should possibly do a one-off reserved slot like above. global->setConstructor(JSProto_Intl, ObjectValue(*intl)); return true; } JSObject* -js::InitIntlClass(JSContext* cx, HandleObject obj) +js::InitIntlClass(JSContext* cx, Handle<GlobalObject*> global) { - Handle<GlobalObject*> global = obj.as<GlobalObject>(); if (!GlobalObject::initIntlObject(cx, global)) return nullptr; return &global->getConstructor(JSProto_Intl).toObject(); }
--- a/js/src/builtin/intl/IntlObject.h +++ b/js/src/builtin/intl/IntlObject.h @@ -9,22 +9,27 @@ #include "mozilla/Attributes.h" #include "js/RootingAPI.h" #include "js/TypeDecls.h" namespace js { +struct Class; +class GlobalObject; + +extern const Class IntlClass; + /** * Initializes the Intl Object and its standard built-in properties. * Spec: ECMAScript Internationalization API Specification, 8.0, 8.1 */ extern JSObject* -InitIntlClass(JSContext* cx, JS::Handle<JSObject*> obj); +InitIntlClass(JSContext* cx, JS::Handle<GlobalObject*> global); /** * Returns a plain object with calendar information for a single valid locale * (callers must perform this validation). The object will have these * properties: * * firstDayOfWeek * an integer in the range 1=Sunday to 7=Saturday indicating the day
--- a/js/src/frontend/FoldConstants.cpp +++ b/js/src/frontend/FoldConstants.cpp @@ -1005,32 +1005,23 @@ ComputeBinary(ParseNodeKind kind, double if (kind == ParseNodeKind::Sub) return left - right; if (kind == ParseNodeKind::Star) return left * right; if (kind == ParseNodeKind::Mod) - return right == 0 ? GenericNaN() : fmod(left, right); + return NumberMod(left, right); if (kind == ParseNodeKind::Ursh) return ToUint32(left) >> (ToUint32(right) & 31); - if (kind == ParseNodeKind::Div) { - if (right == 0) { - if (left == 0 || IsNaN(left)) - return GenericNaN(); - if (IsNegative(left) != IsNegative(right)) - return NegativeInfinity<double>(); - return PositiveInfinity<double>(); - } - - return left / right; - } + if (kind == ParseNodeKind::Div) + return NumberDiv(left, right); MOZ_ASSERT(kind == ParseNodeKind::Lsh || kind == ParseNodeKind::Rsh); int32_t i = ToInt32(left); uint32_t j = ToUint32(right) & 31; return int32_t((kind == ParseNodeKind::Lsh) ? uint32_t(i) << j : i >> j); }
--- a/js/src/frontend/FullParseHandler.h +++ b/js/src/frontend/FullParseHandler.h @@ -710,24 +710,16 @@ class FullParseHandler } ParseNode* newObjectMethodOrPropertyDefinition(ParseNode* key, ParseNode* fn, AccessorType atype) { MOZ_ASSERT(isUsableAsObjectPropertyName(key)); return newBinary(ParseNodeKind::Colon, key, fn, AccessorTypeToJSOp(atype)); } - bool setComprehensionLambdaBody(ParseNode* pn, ParseNode* body) { - MOZ_ASSERT(body->isKind(ParseNodeKind::StatementList)); - ParseNode* paramsBody = newList(ParseNodeKind::ParamsBody, body); - if (!paramsBody) - return false; - setFunctionFormalParametersAndBody(pn, paramsBody); - return true; - } void setFunctionFormalParametersAndBody(ParseNode* funcNode, ParseNode* kid) { MOZ_ASSERT_IF(kid, kid->isKind(ParseNodeKind::ParamsBody)); funcNode->pn_body = kid; } void setFunctionBox(ParseNode* pn, FunctionBox* funbox) { MOZ_ASSERT(pn->isKind(ParseNodeKind::Function)); pn->pn_funbox = funbox; funbox->functionNode = pn;
--- a/js/src/gc/ArenaList.h +++ b/js/src/gc/ArenaList.h @@ -217,31 +217,31 @@ class ArenaLists * For each arena kind its free list is represented as the first span with * free things. Initially all the spans are initialized as empty. After we * find a new arena with available things we move its first free span into * the list and set the arena as fully allocated. way we do not need to * update the arena after the initial allocation. When starting the * GC we only move the head of the of the list of spans back to the arena * only for the arena that was not fully allocated. */ - ZoneGroupData<AllAllocKindArray<FreeSpan*>> freeLists_; + ZoneData<AllAllocKindArray<FreeSpan*>> freeLists_; AllAllocKindArray<FreeSpan*>& freeLists() { return freeLists_.ref(); } const AllAllocKindArray<FreeSpan*>& freeLists() const { return freeLists_.ref(); } FreeSpan* freeList(AllocKind i) const { return freeLists()[i]; } inline void setFreeList(AllocKind i, FreeSpan* span); inline void clearFreeList(AllocKind i); // Because the JITs can allocate from the free lists, they cannot be null. // We use a placeholder FreeSpan that is empty (and wihout an associated // Arena) so the JITs can fall back gracefully. static FreeSpan placeholder; - ZoneGroupOrGCTaskData<AllAllocKindArray<ArenaList>> arenaLists_; + ZoneOrGCTaskData<AllAllocKindArray<ArenaList>> arenaLists_; ArenaList& arenaLists(AllocKind i) { return arenaLists_.ref()[i]; } const ArenaList& arenaLists(AllocKind i) const { return arenaLists_.ref()[i]; } enum BackgroundFinalizeStateEnum { BFS_DONE, BFS_RUN }; typedef mozilla::Atomic<BackgroundFinalizeStateEnum, mozilla::SequentiallyConsistent> BackgroundFinalizeState; @@ -251,29 +251,29 @@ class ArenaLists const BackgroundFinalizeState& backgroundFinalizeState(AllocKind i) const { return backgroundFinalizeState_.ref()[i]; } /* For each arena kind, a list of arenas remaining to be swept. */ ActiveThreadOrGCTaskData<AllAllocKindArray<Arena*>> arenaListsToSweep_; Arena*& arenaListsToSweep(AllocKind i) { return arenaListsToSweep_.ref()[i]; } Arena* arenaListsToSweep(AllocKind i) const { return arenaListsToSweep_.ref()[i]; } /* During incremental sweeping, a list of the arenas already swept. */ - ZoneGroupOrGCTaskData<AllocKind> incrementalSweptArenaKind; - ZoneGroupOrGCTaskData<ArenaList> incrementalSweptArenas; + ZoneOrGCTaskData<AllocKind> incrementalSweptArenaKind; + ZoneOrGCTaskData<ArenaList> incrementalSweptArenas; // Arena lists which have yet to be swept, but need additional foreground // processing before they are swept. - ZoneGroupData<Arena*> gcShapeArenasToUpdate; - ZoneGroupData<Arena*> gcAccessorShapeArenasToUpdate; - ZoneGroupData<Arena*> gcScriptArenasToUpdate; - ZoneGroupData<Arena*> gcObjectGroupArenasToUpdate; + ZoneData<Arena*> gcShapeArenasToUpdate; + ZoneData<Arena*> gcAccessorShapeArenasToUpdate; + ZoneData<Arena*> gcScriptArenasToUpdate; + ZoneData<Arena*> gcObjectGroupArenasToUpdate; // The list of empty arenas which are collected during sweep phase and released at the end of // sweeping every sweep group. - ZoneGroupData<Arena*> savedEmptyArenas; + ZoneData<Arena*> savedEmptyArenas; public: explicit ArenaLists(JSRuntime* rt, JS::Zone* zone); ~ArenaLists(); const void* addressOfFreeList(AllocKind thingKind) const { return reinterpret_cast<const void*>(&freeLists_.refNoCheck()[thingKind]); }
--- a/js/src/gc/Cell.h +++ b/js/src/gc/Cell.h @@ -40,16 +40,17 @@ CurrentThreadIsIonCompiling(); extern void TraceManuallyBarrieredGenericPointerEdge(JSTracer* trc, gc::Cell** thingp, const char* name); namespace gc { class Arena; enum class AllocKind : uint8_t; struct Chunk; +class StoreBuffer; class TenuredCell; // A GC cell is the base class for all GC things. struct Cell { public: MOZ_ALWAYS_INLINE bool isTenured() const { return !IsInsideNursery(this); } MOZ_ALWAYS_INLINE const TenuredCell& asTenured() const;
--- a/js/src/gc/Heap.h +++ b/js/src/gc/Heap.h @@ -39,16 +39,17 @@ class AutoLockGCBgAlloc; class FreeOp; namespace gc { class Arena; class ArenaCellSet; class ArenaList; class SortedArenaList; +class StoreBuffer; class TenuredCell; struct Chunk; /* * This flag allows an allocation site to request a specific heap based upon the * estimated lifetime or lifetime requirements of objects allocated from that * site. */
--- a/js/src/gc/Scheduling.h +++ b/js/src/gc/Scheduling.h @@ -335,17 +335,17 @@ class GCSchedulingTunables * * Initial malloc bytes threshold. */ UnprotectedData<size_t> maxMallocBytes_; /* * JSGC_MAX_NURSERY_BYTES * - * Maximum nursery size for each zone group. + * Maximum nursery size for each runtime. */ ActiveThreadData<size_t> gcMaxNurseryBytes_; /* * JSGC_ALLOCATION_THRESHOLD * * The base value used to compute zone->threshold.gcTriggerBytes(). When * usage.gcBytes() surpasses threshold.gcTriggerBytes() for a zone, the
--- a/js/src/gc/Zone.h +++ b/js/src/gc/Zone.h @@ -255,26 +255,26 @@ struct Zone : public JS::shadow::Zone, void sweepBreakpoints(js::FreeOp* fop); void sweepUniqueIds(); void sweepWeakMaps(); void sweepCompartments(js::FreeOp* fop, bool keepAtleastOne, bool lastGC); using DebuggerVector = js::Vector<js::Debugger*, 0, js::SystemAllocPolicy>; private: - js::ZoneGroupData<DebuggerVector*> debuggers; + js::ZoneData<DebuggerVector*> debuggers; js::jit::JitZone* createJitZone(JSContext* cx); bool isQueuedForBackgroundSweep() { return isOnList(); } // Side map for storing a unique ids for cells, independent of address. - js::ZoneGroupOrGCTaskData<js::gc::UniqueIdMap> uniqueIds_; + js::ZoneOrGCTaskData<js::gc::UniqueIdMap> uniqueIds_; js::gc::UniqueIdMap& uniqueIds() { return uniqueIds_.ref(); } public: bool hasDebuggers() const { return debuggers && debuggers->length(); } DebuggerVector* getDebuggers() const { return debuggers; } DebuggerVector* getOrCreateDebuggers(JSContext* cx); @@ -286,66 +286,66 @@ struct Zone : public JS::shadow::Zone, * When true, skip calling the metadata callback. We use this: * - to avoid invoking the callback recursively; * - to avoid observing lazy prototype setup (which confuses callbacks that * want to use the types being set up!); * - to avoid attaching allocation stacks to allocation stack nodes, which * is silly * And so on. */ - js::ZoneGroupData<bool> suppressAllocationMetadataBuilder; + js::ZoneData<bool> suppressAllocationMetadataBuilder; js::gc::ArenaLists arenas; js::TypeZone types; private: /* Live weakmaps in this zone. */ - js::ZoneGroupOrGCTaskData<mozilla::LinkedList<js::WeakMapBase>> gcWeakMapList_; + js::ZoneOrGCTaskData<mozilla::LinkedList<js::WeakMapBase>> gcWeakMapList_; public: mozilla::LinkedList<js::WeakMapBase>& gcWeakMapList() { return gcWeakMapList_.ref(); } typedef js::Vector<JSCompartment*, 1, js::SystemAllocPolicy> CompartmentVector; private: // The set of compartments in this zone. js::ActiveThreadOrGCTaskData<CompartmentVector> compartments_; public: CompartmentVector& compartments() { return compartments_.ref(); } // This zone's gray roots. typedef js::Vector<js::gc::Cell*, 0, js::SystemAllocPolicy> GrayRootVector; private: - js::ZoneGroupOrGCTaskData<GrayRootVector> gcGrayRoots_; + js::ZoneOrGCTaskData<GrayRootVector> gcGrayRoots_; public: GrayRootVector& gcGrayRoots() { return gcGrayRoots_.ref(); } // This zone's weak edges found via graph traversal during marking, // preserved for re-scanning during sweeping. using WeakEdges = js::Vector<js::gc::TenuredCell**, 0, js::SystemAllocPolicy>; private: - js::ZoneGroupOrGCTaskData<WeakEdges> gcWeakRefs_; + js::ZoneOrGCTaskData<WeakEdges> gcWeakRefs_; public: WeakEdges& gcWeakRefs() { return gcWeakRefs_.ref(); } private: // List of non-ephemeron weak containers to sweep during beginSweepingSweepGroup. - js::ZoneGroupOrGCTaskData<mozilla::LinkedList<detail::WeakCacheBase>> weakCaches_; + js::ZoneOrGCTaskData<mozilla::LinkedList<detail::WeakCacheBase>> weakCaches_; public: mozilla::LinkedList<detail::WeakCacheBase>& weakCaches() { return weakCaches_.ref(); } void registerWeakCache(detail::WeakCacheBase* cachep) { weakCaches().insertBack(cachep); } private: /* * Mapping from not yet marked keys to a vector of all values that the key * maps to in any live weak map. */ - js::ZoneGroupOrGCTaskData<js::gc::WeakKeyTable> gcWeakKeys_; + js::ZoneOrGCTaskData<js::gc::WeakKeyTable> gcWeakKeys_; public: js::gc::WeakKeyTable& gcWeakKeys() { return gcWeakKeys_.ref(); } private: // A set of edges from this zone to other zones. // // This is used during GC while calculating sweep groups to record edges // that can't be determined by examining this zone by itself. @@ -360,17 +360,17 @@ struct Zone : public JS::shadow::Zone, // // There are no barriers here - the set contains only tenured objects so no // post-barrier is required, and these are weak references so no pre-barrier // is required. using TypeDescrObjectSet = js::GCHashSet<JSObject*, js::MovableCellHasher<JSObject*>, js::SystemAllocPolicy>; private: - js::ZoneGroupData<JS::WeakCache<TypeDescrObjectSet>> typeDescrObjects_; + js::ZoneData<JS::WeakCache<TypeDescrObjectSet>> typeDescrObjects_; // Malloc counter to measure memory pressure for GC scheduling. This // counter should be used only when it's not possible to know the size of // a free. js::gc::MemoryCounter gcMallocCounter; // Counter of JIT code executable memory for GC scheduling. Also imprecise, // since wasm can generate code that outlives a zone. @@ -435,26 +435,26 @@ struct Zone : public JS::shadow::Zone, js::gc::TriggerKind shouldTriggerGCForTooMuchMalloc() { auto& gc = runtimeFromAnyThread()->gc; return std::max(gcMallocCounter.shouldTriggerGC(gc.tunables), jitCodeCounter.shouldTriggerGC(gc.tunables)); } private: // Bitmap of atoms marked by this zone. - js::ZoneGroupOrGCTaskData<js::SparseBitmap> markedAtoms_; + js::ZoneOrGCTaskData<js::SparseBitmap> markedAtoms_; // Set of atoms recently used by this Zone. Purged on GC. - js::ZoneGroupOrGCTaskData<js::AtomSet> atomCache_; + js::ZoneOrGCTaskData<js::AtomSet> atomCache_; // Cache storing allocated external strings. Purged on GC. - js::ZoneGroupOrGCTaskData<js::ExternalStringCache> externalStringCache_; + js::ZoneOrGCTaskData<js::ExternalStringCache> externalStringCache_; // Cache for Function.prototype.toString. Purged on GC. - js::ZoneGroupOrGCTaskData<js::FunctionToStringCache> functionToStringCache_; + js::ZoneOrGCTaskData<js::FunctionToStringCache> functionToStringCache_; public: js::SparseBitmap& markedAtoms() { return markedAtoms_.ref(); } js::AtomSet& atomCache() { return atomCache_.ref(); } js::ExternalStringCache& externalStringCache() { return externalStringCache_.ref(); }; @@ -465,58 +465,58 @@ struct Zone : public JS::shadow::Zone, // Thresholds used to trigger GC. js::gc::ZoneHeapThreshold threshold; // Amount of data to allocate before triggering a new incremental slice for // the current GC. js::UnprotectedData<size_t> gcDelayBytes; - js::ZoneGroupData<uint32_t> tenuredStrings; - js::ZoneGroupData<bool> allocNurseryStrings; + js::ZoneData<uint32_t> tenuredStrings; + js::ZoneData<bool> allocNurseryStrings; private: // Shared Shape property tree. - js::ZoneGroupData<js::PropertyTree> propertyTree_; + js::ZoneData<js::PropertyTree> propertyTree_; public: js::PropertyTree& propertyTree() { return propertyTree_.ref(); } private: // Set of all unowned base shapes in the Zone. - js::ZoneGroupData<js::BaseShapeSet> baseShapes_; + js::ZoneData<js::BaseShapeSet> baseShapes_; public: js::BaseShapeSet& baseShapes() { return baseShapes_.ref(); } private: // Set of initial shapes in the Zone. For certain prototypes -- namely, // those of various builtin classes -- there are two entries: one for a // lookup via TaggedProto, and one for a lookup via JSProtoKey. See // InitialShapeProto. - js::ZoneGroupData<js::InitialShapeSet> initialShapes_; + js::ZoneData<js::InitialShapeSet> initialShapes_; public: js::InitialShapeSet& initialShapes() { return initialShapes_.ref(); } private: // List of shapes that may contain nursery pointers. using NurseryShapeVector = js::Vector<js::AccessorShape*, 0, js::SystemAllocPolicy>; - js::ZoneGroupData<NurseryShapeVector> nurseryShapes_; + js::ZoneData<NurseryShapeVector> nurseryShapes_; public: NurseryShapeVector& nurseryShapes() { return nurseryShapes_.ref(); } #ifdef JSGC_HASH_TABLE_CHECKS void checkInitialShapesTableAfterMovingGC(); void checkBaseShapeTableAfterMovingGC(); #endif void fixupInitialShapeTable(); void fixupAfterMovingGC(); // Per-zone data for use by an embedder. - js::ZoneGroupData<void*> data; + js::ZoneData<void*> data; - js::ZoneGroupData<bool> isSystem; + js::ZoneData<bool> isSystem; private: // The helper thread context with exclusive access to this zone, if // usedByHelperThread(), or nullptr when on the main thread. js::UnprotectedData<JSContext*> helperThreadOwnerContext_; public: bool ownedByCurrentHelperThread(); @@ -551,17 +551,17 @@ struct Zone : public JS::shadow::Zone, helperThreadUse = HelperThreadUse::Active; } void clearUsedByHelperThread() { MOZ_ASSERT(helperThreadUse != HelperThreadUse::None); helperThreadUse = HelperThreadUse::None; } #ifdef DEBUG - js::ZoneGroupData<unsigned> gcLastSweepGroupIndex; + js::ZoneData<unsigned> gcLastSweepGroupIndex; #endif static js::HashNumber UniqueIdToHash(uint64_t uid) { return mozilla::HashGeneric(uid); } // Creates a HashNumber based on getUniqueId. Returns false on OOM. MOZ_MUST_USE bool getHashCode(js::gc::Cell* cell, js::HashNumber* hashp) { @@ -698,22 +698,22 @@ struct Zone : public JS::shadow::Zone, p = static_cast<T*>(rt->onOutOfMemoryCanGC(js::AllocFunction::Calloc, bytes)); if (!p) return nullptr; updateMallocCounter(bytes); return p; } private: - js::ZoneGroupData<js::jit::JitZone*> jitZone_; + js::ZoneData<js::jit::JitZone*> jitZone_; js::ActiveThreadData<bool> gcScheduled_; js::ActiveThreadData<bool> gcScheduledSaved_; - js::ZoneGroupData<bool> gcPreserveCode_; - js::ZoneGroupData<bool> keepShapeTables_; + js::ZoneData<bool> gcPreserveCode_; + js::ZoneData<bool> keepShapeTables_; // Allow zones to be linked into a list friend class js::gc::ZoneList; static Zone * const NotOnList; js::ActiveThreadOrGCTaskData<Zone*> listNext_; bool isOnList() const; Zone* nextZone() const;
deleted file mode 100644 --- a/js/src/gc/ZoneGroup.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 "gc/ZoneGroup.h" - -#include "gc/PublicIterators.h" -#include "jit/IonBuilder.h" -#include "jit/JitCompartment.h" -#include "vm/JSContext.h" - -using namespace js;
deleted file mode 100644 --- a/js/src/gc/ZoneGroup.h +++ /dev/null @@ -1,18 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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/. */ - -#ifndef gc_ZoneGroup_h -#define gc_ZoneGroup_h - -#include "gc/Statistics.h" -#include "vm/Caches.h" -#include "vm/Stack.h" - -namespace js { - -} // namespace js - -#endif // gc_Zone_h
--- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -6082,17 +6082,17 @@ CodeGenerator::visitNewTypedArray(LNewTy OutOfLineCode* ool = oolCallVM(TypedArrayConstructorOneArgInfo, lir, ArgList(ImmGCPtr(templateObject), Imm32(n)), StoreRegisterTo(objReg)); masm.createGCObject(objReg, tempReg, templateObject, initialHeap, ool->entry(), /*initContents*/true, /*convertDoubleElements*/false); masm.initTypedArraySlots(objReg, tempReg, lengthReg, liveRegs, ool->entry(), - ttemplate, TypedArrayLength::Fixed); + ttemplate, MacroAssembler::TypedArrayLength::Fixed); masm.bind(ool->rejoin()); } void CodeGenerator::visitNewTypedArrayDynamicLength(LNewTypedArrayDynamicLength* lir) { Register lengthReg = ToRegister(lir->length()); @@ -6108,17 +6108,17 @@ CodeGenerator::visitNewTypedArrayDynamic OutOfLineCode* ool = oolCallVM(TypedArrayConstructorOneArgInfo, lir, ArgList(ImmGCPtr(templateObject), lengthReg), StoreRegisterTo(objReg)); masm.createGCObject(objReg, tempReg, templateObject, initialHeap, ool->entry(), /*initContents*/true, /*convertDoubleElements*/false); masm.initTypedArraySlots(objReg, tempReg, lengthReg, liveRegs, ool->entry(), - ttemplate, TypedArrayLength::Dynamic); + ttemplate, MacroAssembler::TypedArrayLength::Dynamic); masm.bind(ool->rejoin()); } // Out-of-line object allocation for JSOP_NEWOBJECT. class OutOfLineNewObject : public OutOfLineCodeBase<CodeGenerator> { LNewObject* lir_; @@ -12064,19 +12064,16 @@ CodeGenerator::emitInstanceOf(LInstructi masm.bind(&testLazy); masm.branchPtr(Assembler::Equal, output, ImmWord(1), lazyEntry); masm.bind(&done); masm.bind(ool->rejoin()); } -typedef bool (*HasInstanceFn)(JSContext*, HandleObject, HandleValue, bool*); -static const VMFunction HasInstanceInfo = FunctionInfo<HasInstanceFn>(js::HasInstance, "HasInstance"); - void CodeGenerator::visitInstanceOfCache(LInstanceOfCache* ins) { // The Lowering ensures that RHS is an object, and that LHS is a value. LiveRegisterSet liveRegs = ins->safepoint()->liveRegs(); TypedOrValueRegister lhs = TypedOrValueRegister(ToValue(ins, LInstanceOfCache::LHS)); Register rhs = ToRegister(ins->rhs()); Register output = ToRegister(ins->output());
--- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -1962,27 +1962,27 @@ AttachFinishedCompilations(JSContext* cx return; AutoLockHelperThreadState lock; GlobalHelperThreadState::IonBuilderVector& finished = HelperThreadState().ionFinishedList(lock); // Incorporate any off thread compilations for the runtime which have // finished, failed or have been cancelled. while (true) { - // Find a finished builder for the zone group. + // Find a finished builder for the runtime. IonBuilder* builder = GetFinishedBuilder(rt, finished, lock); if (!builder) break; JSScript* script = builder->script(); MOZ_ASSERT(script->hasBaselineScript()); script->baselineScript()->setPendingIonBuilder(rt, script, builder); rt->jitRuntime()->ionLazyLinkListAdd(rt, builder); - // Don't keep more than 100 lazy link builders in a zone group. + // Don't keep more than 100 lazy link builders in a runtime. // Link the oldest ones immediately. while (rt->jitRuntime()->ionLazyLinkListSize() > 100) { jit::IonBuilder* builder = rt->jitRuntime()->ionLazyLinkList(rt).getLast(); RootedScript script(cx, builder->script()); AutoUnlockHelperThreadState unlock(lock); AutoCompartment ac(cx, script); jit::LinkIonScript(cx, script);
--- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -6262,17 +6262,17 @@ PropertyReadNeedsTypeBarrier(CompilerCon // are off, just as if it has unknown properties. if (key->unknownProperties() || observed->empty() || key->clasp()->isProxy()) { return BarrierKind::TypeSet; } if (!name && IsTypedArrayClass(key->clasp())) { - Scalar::Type arrayType = Scalar::Type(key->clasp() - &TypedArrayObject::classes[0]); + Scalar::Type arrayType = GetTypedArrayClassType(key->clasp()); MIRType type = MIRTypeForTypedArrayRead(arrayType, true); if (observed->mightBeMIRType(type)) return BarrierKind::NoBarrier; return BarrierKind::TypeSet; } jsid id = name ? NameToId(name) : JSID_VOID; HeapTypeSetKey property = key->property(id);
--- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -2250,16 +2250,19 @@ class MacroAssembler : public MacroAssem void callMallocStub(size_t nbytes, Register result, Label* fail); void callFreeStub(Register slots); void createGCObject(Register result, Register temp, JSObject* templateObj, gc::InitialHeap initialHeap, Label* fail, bool initContents = true, bool convertDoubleElements = false); void initGCThing(Register obj, Register temp, JSObject* templateObj, bool initContents = true, bool convertDoubleElements = false); + + enum class TypedArrayLength { Fixed, Dynamic }; + void initTypedArraySlots(Register obj, Register temp, Register lengthReg, LiveRegisterSet liveRegs, Label* fail, TypedArrayObject* templateObj, TypedArrayLength lengthKind); void initUnboxedObjectContents(Register object, UnboxedPlainObject* templateObject); void newGCString(Register result, Register temp, Label* fail, bool attemptNursery); void newGCFatInlineString(Register result, Register temp, Label* fail, bool attemptNursery);
--- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -957,18 +957,16 @@ JS_InitStandardClasses(JSContext* cx, Ha CHECK_REQUEST(cx); assertSameCompartment(cx, obj); Rooted<GlobalObject*> global(cx, &obj->global()); return GlobalObject::initStandardClasses(cx, global); } -#define EAGER_ATOM(name) NAME_OFFSET(name) - typedef struct JSStdName { size_t atomOffset; /* offset of atom pointer in JSAtomState */ JSProtoKey key; bool isDummy() const { return key == JSProto_Null; } bool isSentinel() const { return key == JSProto_LIMIT; } } JSStdName; static const JSStdName* @@ -986,52 +984,50 @@ LookupStdName(const JSAtomState& names, return nullptr; } /* * Table of standard classes, indexed by JSProtoKey. For entries where the * JSProtoKey does not correspond to a class with a meaningful constructor, we * insert a null entry into the table. */ -#define STD_NAME_ENTRY(name, init, clasp) { EAGER_ATOM(name), JSProto_##name }, +#define STD_NAME_ENTRY(name, init, clasp) { NAME_OFFSET(name), JSProto_##name }, #define STD_DUMMY_ENTRY(name, init, dummy) { 0, JSProto_Null }, static const JSStdName standard_class_names[] = { JS_FOR_PROTOTYPES(STD_NAME_ENTRY, STD_DUMMY_ENTRY) { 0, JSProto_LIMIT } }; /* * Table of top-level function and constant names and the JSProtoKey of the * standard class that initializes them. */ static const JSStdName builtin_property_names[] = { - { EAGER_ATOM(eval), JSProto_Object }, + { NAME_OFFSET(eval), JSProto_Object }, /* Global properties and functions defined by the Number class. */ - { EAGER_ATOM(NaN), JSProto_Number }, - { EAGER_ATOM(Infinity), JSProto_Number }, - { EAGER_ATOM(isNaN), JSProto_Number }, - { EAGER_ATOM(isFinite), JSProto_Number }, - { EAGER_ATOM(parseFloat), JSProto_Number }, - { EAGER_ATOM(parseInt), JSProto_Number }, + { NAME_OFFSET(NaN), JSProto_Number }, + { NAME_OFFSET(Infinity), JSProto_Number }, + { NAME_OFFSET(isNaN), JSProto_Number }, + { NAME_OFFSET(isFinite), JSProto_Number }, + { NAME_OFFSET(parseFloat), JSProto_Number }, + { NAME_OFFSET(parseInt), JSProto_Number }, /* String global functions. */ - { EAGER_ATOM(escape), JSProto_String }, - { EAGER_ATOM(unescape), JSProto_String }, - { EAGER_ATOM(decodeURI), JSProto_String }, - { EAGER_ATOM(encodeURI), JSProto_String }, - { EAGER_ATOM(decodeURIComponent), JSProto_String }, - { EAGER_ATOM(encodeURIComponent), JSProto_String }, - { EAGER_ATOM(uneval), JSProto_String }, + { NAME_OFFSET(escape), JSProto_String }, + { NAME_OFFSET(unescape), JSProto_String }, + { NAME_OFFSET(decodeURI), JSProto_String }, + { NAME_OFFSET(encodeURI), JSProto_String }, + { NAME_OFFSET(decodeURIComponent), JSProto_String }, + { NAME_OFFSET(encodeURIComponent), JSProto_String }, + { NAME_OFFSET(uneval), JSProto_String }, { 0, JSProto_LIMIT } }; -#undef EAGER_ATOM - JS_PUBLIC_API(bool) JS_ResolveStandardClass(JSContext* cx, HandleObject obj, HandleId id, bool* resolved) { const JSStdName* stdnm; AssertHeapIsIdle(); CHECK_REQUEST(cx); assertSameCompartment(cx, obj, id); @@ -1328,17 +1324,17 @@ JS::CurrentGlobalOrNull(JSContext* cx) return nullptr; return cx->global(); } JS_PUBLIC_API(bool) JS::detail::ComputeThis(JSContext* cx, Value* vp, MutableHandleObject thisObject) { AssertHeapIsIdle(); - assertSameCompartment(cx, JSValueArray(vp, 2)); + assertSameCompartment(cx, vp[0], vp[1]); MutableHandleValue thisv = MutableHandleValue::fromMarkedLocation(&vp[1]); if (!BoxNonStrictThis(cx, thisv, thisv)) return false; thisObject.set(&thisv.toObject()); return true; } @@ -6234,17 +6230,17 @@ JS_PUBLIC_API(JS::SymbolCode) JS::GetSymbolCode(Handle<Symbol*> symbol) { return symbol->code(); } JS_PUBLIC_API(JS::Symbol*) JS::GetWellKnownSymbol(JSContext* cx, JS::SymbolCode which) { - return cx->wellKnownSymbols().get(uint32_t(which)); + return cx->wellKnownSymbols().get(which); } #ifdef DEBUG static bool PropertySpecNameIsDigits(const char* s) { if (JS::PropertySpecNameIsSymbol(s)) return false; if (!*s)
--- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -442,19 +442,16 @@ enum class PromiseRejectionHandlingState } /* namespace JS */ typedef void (* JSPromiseRejectionTrackerCallback)(JSContext* cx, JS::HandleObject promise, JS::PromiseRejectionHandlingState state, void* data); -typedef void -(* JSProcessPromiseCallback)(JSContext* cx, JS::HandleObject promise); - /** * Possible exception types. These types are part of a JSErrorFormatString * structure. They define which error to throw in case of a runtime error. * * JSEXN_WARN is used for warnings in js.msg files (for instance because we * don't want to prepend 'Error:' to warning messages). This value can go away * if we ever decide to use an entirely separate mechanism for warnings. */
--- a/js/src/jsdate.cpp +++ b/js/src/jsdate.cpp @@ -3314,20 +3314,20 @@ const Class DateObject::protoClass_ = { JSCLASS_HAS_CACHED_PROTO(JSProto_Date), JS_NULL_CLASS_OPS, &DateObjectClassSpec }; JSObject* js::NewDateObjectMsec(JSContext* cx, ClippedTime t, HandleObject proto /* = nullptr */) { - JSObject* obj = NewObjectWithClassProto(cx, &DateObject::class_, proto); + DateObject* obj = NewObjectWithClassProto<DateObject>(cx, proto); if (!obj) return nullptr; - obj->as<DateObject>().setUTCTime(t); + obj->setUTCTime(t); return obj; } JS_FRIEND_API(JSObject*) js::NewDateObject(JSContext* cx, int year, int mon, int mday, int hour, int min, int sec) { MOZ_ASSERT(mon < 12);
--- a/js/src/jsexn.cpp +++ b/js/src/jsexn.cpp @@ -584,18 +584,17 @@ ErrorObject::createProto(JSContext* cx, return GlobalObject::createBlankPrototype(cx, cx->global(), &ErrorObject::protoClasses[JSEXN_ERR]); } RootedObject protoProto(cx, GlobalObject::getOrCreateErrorPrototype(cx, cx->global())); if (!protoProto) return nullptr; - return GlobalObject::createBlankPrototypeInheriting(cx, cx->global(), - &ErrorObject::protoClasses[type], + return GlobalObject::createBlankPrototypeInheriting(cx, &ErrorObject::protoClasses[type], protoProto); } /* static */ JSObject* ErrorObject::createConstructor(JSContext* cx, JSProtoKey key) { JSExnType type = ExnTypeFromProtoKey(key); RootedObject ctor(cx);
--- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -125,18 +125,17 @@ JS_FRIEND_API(JSObject*) JS_NewObjectWithUniqueType(JSContext* cx, const JSClass* clasp, HandleObject proto) { /* * Create our object with a null proto and then splice in the correct proto * after we setSingleton, so that we don't pollute the default * ObjectGroup attached to our proto with information about our object, since * we're not going to be using that ObjectGroup anyway. */ - RootedObject obj(cx, NewObjectWithGivenProto(cx, (const js::Class*)clasp, nullptr, - SingletonObject)); + RootedObject obj(cx, NewObjectWithGivenProto(cx, Valueify(clasp), nullptr, SingletonObject)); if (!obj) return nullptr; if (!JS_SplicePrototype(cx, obj, proto)) return nullptr; return obj; } JS_FRIEND_API(JSObject*) @@ -1530,22 +1529,16 @@ js::EnableAccessValidation(JSContext* cx } JS_FRIEND_API(void) js::SetCompartmentValidAccessPtr(JSContext* cx, JS::HandleObject global, bool* accessp) { global->compartment()->setValidAccessPtr(accessp); } -JS_FRIEND_API(void) -js::SetCooperativeYieldCallback(JSContext* cx, YieldCallback callback) -{ - cx->setYieldCallback(callback); -} - JS_FRIEND_API(bool) js::SystemZoneAvailable(JSContext* cx) { return true; } static LogCtorDtor sLogCtor = nullptr; static LogCtorDtor sLogDtor = nullptr;
--- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -71,19 +71,16 @@ JS_NewObjectWithUniqueType(JSContext* cx * Allocate an object in exactly the same way as JS_NewObjectWithGivenProto, but * without invoking the metadata callback on it. This allows creation of * internal bookkeeping objects that are guaranteed to not have metadata * attached to them. */ extern JS_FRIEND_API(JSObject*) JS_NewObjectWithoutMetadata(JSContext* cx, const JSClass* clasp, JS::Handle<JSObject*> proto); -extern JS_FRIEND_API(uint32_t) -JS_ObjectCountDynamicSlots(JS::HandleObject obj); - extern JS_FRIEND_API(bool) JS_NondeterministicGetWeakMapKeys(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject ret); extern JS_FRIEND_API(bool) JS_NondeterministicGetWeakSetKeys(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject ret); // Raw JSScript* because this needs to be callable from a signal handler. extern JS_FRIEND_API(unsigned) @@ -223,19 +220,16 @@ JS_CloneObject(JSContext* cx, JS::Handle * dst needs to have the compartment global as its parent. This function will * preserve the existing metadata on dst, if any. */ extern JS_FRIEND_API(bool) JS_InitializePropertiesFromCompatibleNativeObject(JSContext* cx, JS::HandleObject dst, JS::HandleObject src); -extern JS_FRIEND_API(JSString*) -JS_BasicObjectToString(JSContext* cx, JS::HandleObject obj); - namespace js { JS_FRIEND_API(bool) GetBuiltinClass(JSContext* cx, JS::HandleObject obj, ESClass* cls); JS_FRIEND_API(const char*) ObjectClassName(JSContext* cx, JS::HandleObject obj); @@ -383,19 +377,16 @@ struct JSFunctionSpecWithHelp { #define JS_FS_HELP_END \ {nullptr, nullptr, 0, 0, nullptr, nullptr} extern JS_FRIEND_API(bool) JS_DefineFunctionsWithHelp(JSContext* cx, JS::HandleObject obj, const JSFunctionSpecWithHelp* fs); namespace js { -extern JS_FRIEND_API(JSObject*) -proxy_WeakmapKeyDelegate(JSObject* obj); - /** * A class of objects that return source code on demand. * * When code is compiled with setSourceIsLazy(true), SpiderMonkey doesn't * retain the source code (and doesn't do lazy bytecode generation). If we ever * need the source code, say, in response to a call to Function.prototype. * toSource or Debugger.Source.prototype.text, then we call the 'load' member * function of the instance of this class that has hopefully been registered @@ -3130,25 +3121,16 @@ EnableAccessValidation(JSContext* cx, bo // See EnableAccessValidation above. The caller must guarantee that accessp will // live at least as long as |global| is alive. The JS engine reads accessp from // threads that are allowed to run code on |global|, so all changes to *accessp // should be made from whichever thread owns |global| at a given time. extern JS_FRIEND_API(void) SetCompartmentValidAccessPtr(JSContext* cx, JS::HandleObject global, bool* accessp); -// If the JS engine wants to block so that other cooperative threads can run, it -// will call the yield callback. It may do this if it needs to access a ZoneGroup -// that is held by another thread (such as the system zone group). -typedef void -(* YieldCallback)(JSContext* cx); - -extern JS_FRIEND_API(void) -SetCooperativeYieldCallback(JSContext* cx, YieldCallback callback); - // Returns true if the system zone is available (i.e., if no cooperative contexts // are using it now). extern JS_FRIEND_API(bool) SystemZoneAvailable(JSContext* cx); typedef void (* LogCtorDtor)(void* self, const char* type, uint32_t sz);
--- a/js/src/jslibmath.h +++ b/js/src/jslibmath.h @@ -6,33 +6,19 @@ #ifndef jslibmath_h #define jslibmath_h #include "mozilla/FloatingPoint.h" #include <math.h> -#include "jsnum.h" - +#include "js/Value.h" #include "vm/JSContext.h" -/* - * Use system provided math routines. - */ - -/* The right copysign function is not always named the same thing. */ -#ifdef __GNUC__ -#define js_copysign __builtin_copysign -#elif defined _WIN32 -#define js_copysign _copysign -#else -#define js_copysign copysign -#endif - namespace js { inline double NumberDiv(double a, double b) { AutoUnsafeCallWithABI unsafe; if (b == 0) { if (a == 0 || mozilla::IsNaN(a))
--- a/js/src/jsmath.cpp +++ b/js/src/jsmath.cpp @@ -12,16 +12,17 @@ #include "mozilla/FloatingPoint.h" #include "mozilla/MathAlgorithms.h" #include "mozilla/MemoryReporting.h" #include "mozilla/Unused.h" #include "mozilla/WrappingOperations.h" #include <algorithm> // for std::max +#include <cmath> #include <fcntl.h> #ifdef XP_UNIX # include <unistd.h> #endif #include "fdlibm.h" #include "jsapi.h" #include "jslibmath.h" @@ -847,34 +848,34 @@ js::math_round_impl(double x) if (NumberIsInt32(x, &ignored)) return x; /* Some numbers are so big that adding 0.5 would give the wrong number. */ if (ExponentComponent(x) >= int_fast16_t(FloatingPoint<double>::kExponentShift)) return x; double add = (x >= 0) ? GetBiggestNumberLessThan(0.5) : 0.5; - return js_copysign(fdlibm::floor(x + add), x); + return std::copysign(fdlibm::floor(x + add), x); } float js::math_roundf_impl(float x) { AutoUnsafeCallWithABI unsafe; int32_t ignored; if (NumberIsInt32(x, &ignored)) return x; /* Some numbers are so big that adding 0.5 would give the wrong number. */ if (ExponentComponent(x) >= int_fast16_t(FloatingPoint<float>::kExponentShift)) return x; float add = (x >= 0) ? GetBiggestNumberLessThan(0.5f) : 0.5f; - return js_copysign(fdlibm::floorf(x + add), x); + return std::copysign(fdlibm::floorf(x + add), x); } bool /* ES5 15.8.2.15. */ js::math_round(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (args.length() == 0) { @@ -1249,17 +1250,16 @@ js::math_atanh_uncached(double x) } bool js::math_atanh(JSContext* cx, unsigned argc, Value* vp) { return math_function<math_atanh_impl>(cx, argc, vp); } -/* Consistency wrapper for platform deviations in hypot() */ double js::ecmaHypot(double x, double y) { AutoUnsafeCallWithABI unsafe; return fdlibm::hypot(x, y); } static inline @@ -1275,19 +1275,17 @@ hypot_step(double& scale, double& sumsq, } } double js::hypot4(double x, double y, double z, double w) { AutoUnsafeCallWithABI unsafe; - /* Check for infinity or NaNs so that we can return immediatelly. - * Does not need to be WIN_XP specific as ecmaHypot - */ + // Check for infinities or NaNs so that we can return immediately. if (mozilla::IsInfinite(x) || mozilla::IsInfinite(y) || mozilla::IsInfinite(z) || mozilla::IsInfinite(w)) return mozilla::PositiveInfinity<double>(); if (mozilla::IsNaN(x) || mozilla::IsNaN(y) || mozilla::IsNaN(z) || mozilla::IsNaN(w)) return GenericNaN(); @@ -1314,17 +1312,17 @@ js::math_hypot(JSContext* cx, unsigned a { CallArgs args = CallArgsFromVp(argc, vp); return math_hypot_handle(cx, args, args.rval()); } bool js::math_hypot_handle(JSContext* cx, HandleValueArray args, MutableHandleValue res) { - // IonMonkey calls the system hypot function directly if two arguments are + // IonMonkey calls the ecmaHypot function directly if two arguments are // given. Do that here as well to get the same results. if (args.length() == 2) { double x, y; if (!ToNumber(cx, args[0], &x)) return false; if (!ToNumber(cx, args[1], &y)) return false; @@ -1471,31 +1469,30 @@ static const JSFunctionSpec math_static_ JS_INLINABLE_FN("hypot", math_hypot, 2, 0, MathHypot), JS_INLINABLE_FN("trunc", math_trunc, 1, 0, MathTrunc), JS_INLINABLE_FN("sign", math_sign, 1, 0, MathSign), JS_INLINABLE_FN("cbrt", math_cbrt, 1, 0, MathCbrt), JS_FS_END }; JSObject* -js::InitMathClass(JSContext* cx, HandleObject obj) +js::InitMathClass(JSContext* cx, Handle<GlobalObject*> global) { - Handle<GlobalObject*> global = obj.as<GlobalObject>(); RootedObject proto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global)); if (!proto) return nullptr; RootedObject Math(cx, NewObjectWithGivenProto(cx, &MathClass, proto, SingletonObject)); if (!Math) return nullptr; - if (!JS_DefineProperty(cx, obj, js_Math_str, Math, JSPROP_RESOLVING)) + if (!JS_DefineProperty(cx, global, js_Math_str, Math, JSPROP_RESOLVING)) return nullptr; if (!JS_DefineFunctions(cx, Math, math_static_methods)) return nullptr; if (!JS_DefineConstDoubles(cx, Math, math_constants)) return nullptr; if (!DefineToStringTag(cx, Math, cx->names().Math)) return nullptr; - obj->as<GlobalObject>().setConstructor(JSProto_Math, ObjectValue(*Math)); + global->setConstructor(JSProto_Math, ObjectValue(*Math)); return Math; }
--- a/js/src/jsmath.h +++ b/js/src/jsmath.h @@ -4,23 +4,25 @@ * 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/. */ #ifndef jsmath_h #define jsmath_h #include "mozilla/MemoryReporting.h" -#include <cmath> #include <stdint.h> #include "NamespaceImports.h" namespace js { +struct Class; +class GlobalObject; + typedef double (*UnaryFunType)(double); class MathCache { public: enum MathFuncId { Zero, Sin, Cos, Tan, Sinh, Cosh, Tanh, Asin, Acos, Atan, Asinh, Acosh, Atanh, @@ -79,18 +81,20 @@ class MathCache size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf); }; /* * JS math functions. */ +extern const Class MathClass; + extern JSObject* -InitMathClass(JSContext* cx, HandleObject obj); +InitMathClass(JSContext* cx, Handle<GlobalObject*> global); extern uint64_t GenerateRandomSeed(); // Fill |seed[0]| and |seed[1]| with random bits, suitable for // seeding a XorShift128+ random number generator. extern void GenerateXorShift128PlusSeed(mozilla::Array<uint64_t, 2>& seed);
--- a/js/src/jsnum.cpp +++ b/js/src/jsnum.cpp @@ -1189,27 +1189,23 @@ js::FinishRuntimeNumberState(JSRuntime* * strings. */ char* storage = const_cast<char*>(rt->thousandsSeparator.ref()); js_free(storage); } #endif JSObject* -js::InitNumberClass(JSContext* cx, HandleObject obj) +js::InitNumberClass(JSContext* cx, Handle<GlobalObject*> global) { - MOZ_ASSERT(obj->isNative()); - - Handle<GlobalObject*> global = obj.as<GlobalObject>(); - - RootedObject numberProto(cx, GlobalObject::createBlankPrototype(cx, global, - &NumberObject::class_)); + Rooted<NumberObject*> numberProto(cx); + numberProto = GlobalObject::createBlankPrototype<NumberObject>(cx, global); if (!numberProto) return nullptr; - numberProto->as<NumberObject>().setPrimitiveValue(0); + numberProto->setPrimitiveValue(0); RootedFunction ctor(cx); ctor = GlobalObject::createConstructor(cx, Number, cx->names().Number, 1); if (!ctor) return nullptr; if (!LinkConstructorAndPrototype(cx, ctor, numberProto)) return nullptr;
--- a/js/src/jsnum.h +++ b/js/src/jsnum.h @@ -2,56 +2,58 @@ * vim: set ts=8 sts=4 et sw=4 tw=99: * 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/. */ #ifndef jsnum_h #define jsnum_h +#include "mozilla/Compiler.h" #include "mozilla/FloatingPoint.h" #include "mozilla/Range.h" #include "NamespaceImports.h" #include "js/Conversions.h" #include "vm/StringType.h" // This macro is should be `one' if current compiler supports builtin functions // like __builtin_sadd_overflow. -#if __GNUC__ >= 5 - // GCC 5 and above supports these functions. +#if MOZ_IS_GCC + // GCC supports these functions. #define BUILTIN_CHECKED_ARITHMETIC_SUPPORTED(x) 1 #else // For CLANG, we use its own function to check for this. #ifdef __has_builtin #define BUILTIN_CHECKED_ARITHMETIC_SUPPORTED(x) __has_builtin(x) #endif #endif #ifndef BUILTIN_CHECKED_ARITHMETIC_SUPPORTED #define BUILTIN_CHECKED_ARITHMETIC_SUPPORTED(x) 0 #endif namespace js { +class GlobalObject; class StringBuffer; extern MOZ_MUST_USE bool InitRuntimeNumberState(JSRuntime* rt); #if !EXPOSE_INTL_API extern void FinishRuntimeNumberState(JSRuntime* rt); #endif /* Initialize the Number class, returning its prototype object. */ extern JSObject* -InitNumberClass(JSContext* cx, HandleObject obj); +InitNumberClass(JSContext* cx, Handle<GlobalObject*> global); /* * When base == 10, this function implements ToString() as specified by * ECMA-262-5 section 9.8.1; but note that it handles integers specially for * performance. See also js::NumberToCString(). */ template <AllowGC allowGC> extern JSString*
--- a/js/src/jspubtd.h +++ b/js/src/jspubtd.h @@ -6,21 +6,16 @@ #ifndef jspubtd_h #define jspubtd_h /* * JS public API typedefs. */ -#include "mozilla/Assertions.h" -#include "mozilla/EnumeratedArray.h" -#include "mozilla/LinkedList.h" -#include "mozilla/PodOperations.h" - #include "jstypes.h" #include "js/ProtoKey.h" #include "js/Result.h" #include "js/TraceKind.h" #include "js/TypeDecls.h" #if defined(JS_GC_ZEAL) || defined(DEBUG) @@ -76,27 +71,21 @@ struct JSPropertySpec; struct JSSecurityCallbacks; struct JSStructuredCloneCallbacks; struct JSStructuredCloneReader; struct JSStructuredCloneWriter; class JS_PUBLIC_API(JSTracer); class JSFlatString; -typedef bool (*JSInitCallback)(void); - template<typename T> struct JSConstScalarSpec; typedef JSConstScalarSpec<double> JSConstDoubleSpec; typedef JSConstScalarSpec<int32_t> JSConstIntegerSpec; namespace js { -namespace gc { -class AutoTraceSession; -class StoreBuffer; -} // namespace gc inline JSCompartment* GetContextCompartment(const JSContext* cx); inline JS::Zone* GetContextZone(const JSContext* cx); // Whether the current thread is permitted access to any part of the specified // runtime or zone. JS_FRIEND_API(bool) CurrentThreadCanAccessRuntime(const JSRuntime* rt); @@ -105,18 +94,16 @@ CurrentThreadCanAccessRuntime(const JSRu JS_FRIEND_API(bool) CurrentThreadIsPerformingGC(); #endif } // namespace js namespace JS { -class JS_PUBLIC_API(AutoEnterCycleCollection); -class JS_PUBLIC_API(AutoAssertOnBarrier); struct JS_PUBLIC_API(PropertyDescriptor); typedef void (*OffThreadCompileCallback)(void* token, void* callbackData); enum class HeapState { Idle, // doing nothing with the GC heap Tracing, // tracing the GC heap without collecting, e.g. IterateCompartments() MajorCollecting, // doing a GC of the major heap @@ -176,16 +163,16 @@ class MOZ_STACK_CLASS JS_PUBLIC_API(Auto public: explicit AutoEnterCycleCollection(JSRuntime* rt) {} ~AutoEnterCycleCollection() {} #endif }; } /* namespace JS */ -MOZ_BEGIN_EXTERN_C +extern "C" { // Defined in NSPR prio.h. typedef struct PRFileDesc PRFileDesc; -MOZ_END_EXTERN_C +} #endif /* jspubtd_h */
--- a/js/src/moz.build +++ b/js/src/moz.build @@ -225,17 +225,16 @@ UNIFIED_SOURCES += [ 'gc/PublicIterators.cpp', 'gc/RootMarking.cpp', 'gc/Statistics.cpp', 'gc/Tracer.cpp', 'gc/Verifier.cpp', 'gc/WeakMap.cpp', 'gc/WeakMapPtr.cpp', 'gc/Zone.cpp', - 'gc/ZoneGroup.cpp', 'irregexp/NativeRegExpMacroAssembler.cpp', 'irregexp/RegExpAST.cpp', 'irregexp/RegExpCharacters.cpp', 'irregexp/RegExpEngine.cpp', 'irregexp/RegExpInterpreter.cpp', 'irregexp/RegExpMacroAssembler.cpp', 'irregexp/RegExpParser.cpp', 'irregexp/RegExpStack.cpp',
--- a/js/src/old-configure.in +++ b/js/src/old-configure.in @@ -276,17 +276,16 @@ if test -n "$_WIN32_MSVC"; then SKIP_LIBRARY_CHECKS=1 # Since we're skipping compiler and library checks, hard-code # some facts here. # Common to all MSVC environments: AC_DEFINE(HAVE_LOCALECONV) - AC_DEFINE(HAVE_HYPOT) AC_CHECK_FUNCS([_getc_nolock]) fi fi # COMPILE_ENVIRONMENT # Check to see if we are running in a broken QEMU scratchbox. # We know that anything below 1.0.16 is broken. AC_CHECK_PROGS(SBCONF, sb-conf ve, "")
--- a/js/src/proxy/Proxy.cpp +++ b/js/src/proxy/Proxy.cpp @@ -720,18 +720,18 @@ ProxyObject::trace(JSTracer* trc, JSObje continue; } TraceEdge(trc, proxy->reservedSlotPtr(i), "proxy_reserved"); } Proxy::trace(trc, obj); } -JSObject* -js::proxy_WeakmapKeyDelegate(JSObject* obj) +static JSObject* +proxy_WeakmapKeyDelegate(JSObject* obj) { MOZ_ASSERT(obj->is<ProxyObject>()); return obj->as<ProxyObject>().handler()->weakmapKeyDelegate(obj); } static void proxy_Finalize(FreeOp* fop, JSObject* obj) { @@ -838,30 +838,29 @@ ProxyObject::renew(const BaseProxyHandle MOZ_ASSERT(hasDynamicPrototype()); setHandler(handler); setCrossCompartmentPrivate(priv); for (size_t i = 0; i < numReservedSlots(); i++) setReservedSlot(i, UndefinedValue()); } -JS_FRIEND_API(JSObject*) -js::InitProxyClass(JSContext* cx, HandleObject obj) +JSObject* +js::InitProxyClass(JSContext* cx, Handle<GlobalObject*> global) { static const JSFunctionSpec static_methods[] = { JS_FN("revocable", proxy_revocable, 2, 0), JS_FS_END }; - Handle<GlobalObject*> global = obj.as<GlobalObject>(); RootedFunction ctor(cx); ctor = GlobalObject::createConstructor(cx, proxy, cx->names().Proxy, 2); if (!ctor) return nullptr; if (!JS_DefineFunctions(cx, ctor, static_methods)) return nullptr; - if (!JS_DefineProperty(cx, obj, "Proxy", ctor, JSPROP_RESOLVING)) + if (!JS_DefineProperty(cx, global, "Proxy", ctor, JSPROP_RESOLVING)) return nullptr; global->setConstructor(JSProto_Proxy, ObjectValue(*ctor)); return ctor; }
--- a/js/src/proxy/Proxy.h +++ b/js/src/proxy/Proxy.h @@ -8,16 +8,18 @@ #define proxy_Proxy_h #include "NamespaceImports.h" #include "js/Class.h" namespace js { +class GlobalObject; + /* * Dispatch point for handlers that executes the appropriate C++ or scripted traps. * * Important: All proxy methods need either (a) an AutoEnterPolicy in their * Proxy::foo entry point below or (b) an override in SecurityWrapper. See bug * 945826 comment 0. */ class Proxy @@ -97,11 +99,14 @@ ProxyGetPropertyByValue(JSContext* cx, H bool ProxySetProperty(JSContext* cx, HandleObject proxy, HandleId id, HandleValue val, bool strict); bool ProxySetPropertyByValue(JSContext* cx, HandleObject proxy, HandleValue idVal, HandleValue val, bool strict); +extern JSObject* +InitProxyClass(JSContext* cx, Handle<GlobalObject*> global); + } /* namespace js */ #endif /* proxy_Proxy_h */
--- a/js/src/shell/OSObject.cpp +++ b/js/src/shell/OSObject.cpp @@ -399,24 +399,23 @@ class FileObject : public NativeObject FILE_SLOT = 0, NUM_SLOTS }; public: static const js::Class class_; static FileObject* create(JSContext* cx, RCFile* file) { - JSObject* obj = js::NewObjectWithClassProto(cx, &class_, nullptr); + FileObject* obj = js::NewObjectWithClassProto<FileObject>(cx, nullptr); if (!obj) return nullptr; - FileObject* fileObj = &obj->as<FileObject>(); - fileObj->setRCFile(file); + obj->setRCFile(file); file->acquire(); - return fileObj; + return obj; } static void finalize(FreeOp* fop, JSObject* obj) { FileObject* fileObj = &obj->as<FileObject>(); RCFile* file = fileObj->rcFile(); if (file->release()) { fileObj->setRCFile(nullptr); fop->delete_(file);
--- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -6552,18 +6552,16 @@ static const JSFunctionSpecWithHelp shel " Evaluate code as though it were the contents of a file.\n" " options is an optional object that may have these properties:\n" " isRunOnce: use the isRunOnce compiler option (default: false)\n" " noScriptRval: use the no-script-rval compiler option (default: false)\n" " fileName: filename for error messages and debug info\n" " lineNumber: starting line number for error messages and debug info\n" " columnNumber: starting column number for error messages and debug info\n" " global: global in which to execute the code\n" -" zoneGroup: pick a global from another zone group with no current context\n" -" to execute the code in\n" " newContext: if true, create and use a new cx (default: false)\n" " catchTermination: if true, catch termination (failure without\n" " an exception value, as for slow scripts or out-of-memory)\n" " and return 'terminated'\n" " element: if present with value |v|, convert |v| to an object |o| and\n" " mark the source as being attached to the DOM element |o|. If the\n" " property is omitted or |v| is null, don't attribute the source to\n" " any DOM element.\n"
--- a/js/src/threading/ProtectedData.cpp +++ b/js/src/threading/ProtectedData.cpp @@ -34,17 +34,17 @@ OnHelperThread() } void CheckThreadLocal::check() const { JSContext* cx = TlsContext.get(); MOZ_ASSERT(cx); - // As for CheckZoneGroup, in a cooperatively scheduled runtime the active + // As for CheckZone, in a cooperatively scheduled runtime the active // thread is permitted access to thread local state for other suspended // threads in the same runtime. if (cx->isCooperativelyScheduled()) MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime())); else MOZ_ASSERT(id == ThisThread::GetId()); } @@ -60,17 +60,17 @@ CheckActiveThread<Helper>::check() const } template class CheckActiveThread<AllowedHelperThread::None>; template class CheckActiveThread<AllowedHelperThread::GCTask>; template class CheckActiveThread<AllowedHelperThread::IonCompile>; template <AllowedHelperThread Helper> void -CheckZoneGroup<Helper>::check() const +CheckZone<Helper>::check() const { if (OnHelperThread<Helper>()) return; JSContext* cx = TlsContext.get(); if (zone->isAtomsZone()) { // The atoms zone is protected by the exclusive access lock. MOZ_ASSERT(cx->runtime()->currentThreadHasExclusiveAccess()); @@ -79,20 +79,20 @@ CheckZoneGroup<Helper>::check() const MOZ_ASSERT(zone->ownedByCurrentHelperThread()); } else { // The main thread is permitted access to all zones. These accesses // are threadsafe if the zone is not in use by a helper thread. MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime())); } } -template class CheckZoneGroup<AllowedHelperThread::None>; -template class CheckZoneGroup<AllowedHelperThread::GCTask>; -template class CheckZoneGroup<AllowedHelperThread::IonCompile>; -template class CheckZoneGroup<AllowedHelperThread::GCTaskOrIonCompile>; +template class CheckZone<AllowedHelperThread::None>; +template class CheckZone<AllowedHelperThread::GCTask>; +template class CheckZone<AllowedHelperThread::IonCompile>; +template class CheckZone<AllowedHelperThread::GCTaskOrIonCompile>; template <GlobalLock Lock, AllowedHelperThread Helper> void CheckGlobalLock<Lock, Helper>::check() const { if (OnHelperThread<Helper>()) return;
--- a/js/src/threading/ProtectedData.h +++ b/js/src/threading/ProtectedData.h @@ -138,25 +138,25 @@ class ProtectedDataNoCheckArgs : public explicit ProtectedDataNoCheckArgs(Args&&... args) : ProtectedData<Check, T>(Check(), mozilla::Forward<Args>(args)...) {} template <typename U> ThisType& operator=(const U& p) { this->ref() = p; return *this; } }; -// Intermediate class for protected data whose checks take a ZoneGroup constructor argument. +// Intermediate class for protected data whose checks take a Zone constructor argument. template <typename Check, typename T> -class ProtectedDataZoneGroupArg : public ProtectedData<Check, T> +class ProtectedDataZoneArg : public ProtectedData<Check, T> { - typedef ProtectedDataZoneGroupArg<Check, T> ThisType; + typedef ProtectedDataZoneArg<Check, T> ThisType; public: template <typename... Args> - explicit ProtectedDataZoneGroupArg(JS::Zone* zone, Args&&... args) + explicit ProtectedDataZoneArg(JS::Zone* zone, Args&&... args) : ProtectedData<Check, T>(Check(zone), mozilla::Forward<Args>(args)...) {} template <typename U> ThisType& operator=(const U& p) { this->ref() = p; return *this; } }; class CheckUnprotected @@ -187,17 +187,17 @@ class CheckThreadLocal #endif }; // Data which may only be accessed by the thread on which it is created. template <typename T> using ThreadLocalData = ProtectedDataNoCheckArgs<CheckThreadLocal, T>; // Enum describing which helper threads (GC tasks or Ion compilations) may -// access data even though they do not have exclusive access to any zone group. +// access data even though they do not have exclusive access to any zone. enum class AllowedHelperThread { None, GCTask, IonCompile, GCTaskOrIonCompile }; @@ -219,48 +219,48 @@ using ActiveThreadData = template <typename T> using ActiveThreadOrGCTaskData = ProtectedDataNoCheckArgs<CheckActiveThread<AllowedHelperThread::GCTask>, T>; template <typename T> using ActiveThreadOrIonCompileData = ProtectedDataNoCheckArgs<CheckActiveThread<AllowedHelperThread::IonCompile>, T>; template <AllowedHelperThread Helper> -class CheckZoneGroup +class CheckZone { #ifdef JS_HAS_PROTECTED_DATA_CHECKS JS::Zone* zone; public: - explicit CheckZoneGroup(JS::Zone* zone) : zone(zone) {} + explicit CheckZone(JS::Zone* zone) : zone(zone) {} void check() const; #else public: - explicit CheckZoneGroup(JS::Zone* zone) {} + explicit CheckZone(JS::Zone* zone) {} #endif }; // Data which may only be accessed by threads with exclusive access to the -// associated zone group, or by the runtime's cooperatively scheduled -// active thread for zone groups which are not in use by a helper thread. +// associated zone, or by the runtime's main thread for zones which are not in +// use by a helper thread. template <typename T> -using ZoneGroupData = - ProtectedDataZoneGroupArg<CheckZoneGroup<AllowedHelperThread::None>, T>; +using ZoneData = + ProtectedDataZoneArg<CheckZone<AllowedHelperThread::None>, T>; // Data which may only be accessed by threads with exclusive access to the -// associated zone group, or by various helper thread tasks. +// associated zone, or by various helper thread tasks. template <typename T> -using ZoneGroupOrGCTaskData = - ProtectedDataZoneGroupArg<CheckZoneGroup<AllowedHelperThread::GCTask>, T>; +using ZoneOrGCTaskData = + ProtectedDataZoneArg<CheckZone<AllowedHelperThread::GCTask>, T>; template <typename T> -using ZoneGroupOrIonCompileData = - ProtectedDataZoneGroupArg<CheckZoneGroup<AllowedHelperThread::IonCompile>, T>; +using ZoneOrIonCompileData = + ProtectedDataZoneArg<CheckZone<AllowedHelperThread::IonCompile>, T>; template <typename T> -using ZoneGroupOrGCTaskOrIonCompileData = - ProtectedDataZoneGroupArg<CheckZoneGroup<AllowedHelperThread::GCTaskOrIonCompile>, T>; +using ZoneOrGCTaskOrIonCompileData = + ProtectedDataZoneArg<CheckZone<AllowedHelperThread::GCTaskOrIonCompile>, T>; // Runtime wide locks which might protect some data. enum class GlobalLock { GCLock, ExclusiveAccessLock, ScriptDataLock, HelperThreadLock
--- a/js/src/vm/ArrayBufferObject.h +++ b/js/src/vm/ArrayBufferObject.h @@ -11,18 +11,16 @@ #include "builtin/TypedObjectConstants.h" #include "js/GCHashTable.h" #include "vm/JSObject.h" #include "vm/Runtime.h" #include "vm/SharedMem.h" #include "wasm/WasmTypes.h" -typedef struct JSProperty JSProperty; - namespace js { class ArrayBufferViewObject; class WasmArrayRawBuffer; // Create a new mapping of size `mappedSize` with an initially committed prefix // of size `initialCommittedSize`. Both arguments denote bytes and must be // multiples of the page size, with `initialCommittedSize` <= `mappedSize`.
--- a/js/src/vm/AsyncIteration.cpp +++ b/js/src/vm/AsyncIteration.cpp @@ -43,18 +43,17 @@ WrappedAsyncGenerator(JSContext* cx, uns if (!args2.init(cx, argc)) return false; for (size_t i = 0, len = argc; i < len; i++) args2[i].set(args[i]); if (!Call(cx, unwrappedVal, thisValue, args2, &generatorVal)) return false; // Step 2. - Rooted<AsyncGeneratorObject*> asyncGenObj( - cx, AsyncGeneratorObject::create(cx, wrapped, generatorVal)); + AsyncGeneratorObject* asyncGenObj = AsyncGeneratorObject::create(cx, wrapped, generatorVal); if (!asyncGenObj) return false; // Step 3 (skipped). // Done in AsyncGeneratorObject::create and generator. // Step 4. args.rval().setObject(*asyncGenObj); @@ -182,28 +181,23 @@ js::CreateAsyncFromSyncIterator(JSContex AsyncFromSyncIteratorObject::create(JSContext* cx, HandleObject iter, HandleValue nextMethod) { // Step 2. RootedObject proto(cx, GlobalObject::getOrCreateAsyncFromSyncIteratorPrototype(cx, cx->global())); if (!proto) return nullptr; - RootedObject obj(cx, NewNativeObjectWithGivenProto(cx, &class_, proto)); - if (!obj) + AsyncFromSyncIteratorObject* asyncIter = + NewObjectWithGivenProto<AsyncFromSyncIteratorObject>(cx, proto); + if (!asyncIter) return nullptr; - Handle<AsyncFromSyncIteratorObject*> asyncIter = obj.as<AsyncFromSyncIteratorObject>(); - // Step 3. - asyncIter->setIterator(iter); - - // Spec update pending: - // https://github.com/tc39/proposal-async-iteration/issues/116 - asyncIter->setNextMethod(nextMethod); + asyncIter->init(iter, nextMethod); // Step 4. return asyncIter; } // Async Iteration proposal 11.1.3.2.1 %AsyncFromSyncIteratorPrototype%.next. static bool AsyncFromSyncIteratorNext(JSContext* cx, unsigned argc, Value* vp) @@ -262,54 +256,48 @@ AsyncGeneratorThrow(JSContext* cx, unsig } const Class AsyncGeneratorObject::class_ = { "AsyncGenerator", JSCLASS_HAS_RESERVED_SLOTS(AsyncGeneratorObject::Slots) }; // ES 2017 draft 9.1.13. -template <typename ProtoGetter> -static JSObject* -OrdinaryCreateFromConstructor(JSContext* cx, HandleFunction fun, - ProtoGetter protoGetter, const Class* clasp) +// OrdinaryCreateFromConstructor specialized for AsyncGeneratorObjects. +static AsyncGeneratorObject* +OrdinaryCreateFromConstructorAsynGen(JSContext* cx, HandleFunction fun) { // Step 1 (skipped). // Step 2. RootedValue protoVal(cx); if (!GetProperty(cx, fun, fun, cx->names().prototype, &protoVal)) return nullptr; RootedObject proto(cx, protoVal.isObject() ? &protoVal.toObject() : nullptr); if (!proto) { - proto = protoGetter(cx, cx->global()); + proto = GlobalObject::getOrCreateAsyncGeneratorPrototype(cx, cx->global()); if (!proto) return nullptr; } // Step 3. - return NewNativeObjectWithGivenProto(cx, clasp, proto); + return NewObjectWithGivenProto<AsyncGeneratorObject>(cx, proto); } /* static */ AsyncGeneratorObject* AsyncGeneratorObject::create(JSContext* cx, HandleFunction asyncGen, HandleValue generatorVal) { MOZ_ASSERT(generatorVal.isObject()); MOZ_ASSERT(generatorVal.toObject().is<GeneratorObject>()); - RootedObject obj( - cx, OrdinaryCreateFromConstructor(cx, asyncGen, - GlobalObject::getOrCreateAsyncGeneratorPrototype, - &class_)); - if (!obj) + AsyncGeneratorObject* asyncGenObj = OrdinaryCreateFromConstructorAsynGen(cx, asyncGen); + if (!asyncGenObj) return nullptr; - Handle<AsyncGeneratorObject*> asyncGenObj = obj.as<AsyncGeneratorObject>(); - // Async Iteration proposal 6.4.3.2 AsyncGeneratorStart. // Step 6. asyncGenObj->setGenerator(generatorVal); // Step 7. asyncGenObj->setSuspendedStart(); // Step 8. @@ -390,21 +378,20 @@ const Class AsyncGeneratorRequest::class JSCLASS_HAS_RESERVED_SLOTS(AsyncGeneratorRequest::Slots) }; // Async Iteration proposal 11.4.3.1. /* static */ AsyncGeneratorRequest* AsyncGeneratorRequest::create(JSContext* cx, CompletionKind completionKind, HandleValue completionValue, HandleObject promise) { - RootedObject obj(cx, NewNativeObjectWithGivenProto(cx, &class_, nullptr)); - if (!obj) + AsyncGeneratorRequest* request = NewObjectWithGivenProto<AsyncGeneratorRequest>(cx, nullptr); + if (!request) return nullptr; - Handle<AsyncGeneratorRequest*> request = obj.as<AsyncGeneratorRequest>(); request->init(completionKind, completionValue, promise); return request; } // Async Iteration proposal 11.4.3.2 AsyncGeneratorStart steps 5.d-g. static MOZ_MUST_USE bool AsyncGeneratorReturned(JSContext* cx, Handle<AsyncGeneratorObject*> asyncGenObj, HandleValue value) @@ -536,30 +523,30 @@ GlobalObject::initAsyncGenerators(JSCont RootedObject asyncIterProto(cx, GlobalObject::createBlankPrototype<PlainObject>(cx, global)); if (!asyncIterProto) return false; if (!DefinePropertiesAndFunctions(cx, asyncIterProto, nullptr, async_iterator_proto_methods)) return false; // Async Iteration proposal 11.1.3.2 %AsyncFromSyncIteratorPrototype%. RootedObject asyncFromSyncIterProto( - cx, GlobalObject::createBlankPrototypeInheriting(cx, global, &PlainObject::class_, + cx, GlobalObject::createBlankPrototypeInheriting(cx, &PlainObject::class_, asyncIterProto)); if (!asyncFromSyncIterProto) return false; if (!DefinePropertiesAndFunctions(cx, asyncFromSyncIterProto, nullptr, async_from_sync_iter_methods) || !DefineToStringTag(cx, asyncFromSyncIterProto, cx->names().AsyncFromSyncIterator)) { return false; } // Async Iteration proposal 11.4.1 %AsyncGeneratorPrototype%. RootedObject asyncGenProto( - cx, GlobalObject::createBlankPrototypeInheriting(cx, global, &PlainObject::class_, + cx, GlobalObject::createBlankPrototypeInheriting(cx, &PlainObject::class_, asyncIterProto)); if (!asyncGenProto) return false; if (!DefinePropertiesAndFunctions(cx, asyncGenProto, nullptr, async_generator_methods) || !DefineToStringTag(cx, asyncGenProto, cx->names().AsyncGenerator)) { return false; }
--- a/js/src/vm/AsyncIteration.h +++ b/js/src/vm/AsyncIteration.h @@ -57,20 +57,18 @@ class AsyncGeneratorRequest : public Nat private: enum AsyncGeneratorRequestSlots { Slot_CompletionKind = 0, Slot_CompletionValue, Slot_Promise, Slots, }; - void init(CompletionKind completionKind, HandleValue completionValue, - HandleObject promise) { - setFixedSlot(Slot_CompletionKind, - Int32Value(static_cast<int32_t>(completionKind))); + void init(CompletionKind completionKind, const Value& completionValue, JSObject* promise) { + setFixedSlot(Slot_CompletionKind, Int32Value(static_cast<int32_t>(completionKind))); setFixedSlot(Slot_CompletionValue, completionValue); setFixedSlot(Slot_Promise, ObjectValue(*promise)); } void clearData() { setFixedSlot(Slot_CompletionValue, NullValue()); setFixedSlot(Slot_Promise, NullValue()); } @@ -268,21 +266,18 @@ class AsyncFromSyncIteratorObject : publ { private: enum AsyncFromSyncIteratorObjectSlots { Slot_Iterator = 0, Slot_NextMethod = 1, Slots }; - void setIterator(HandleObject iterator) { + void init(JSObject* iterator, const Value& nextMethod) { setFixedSlot(Slot_Iterator, ObjectValue(*iterator)); - } - - void setNextMethod(HandleValue nextMethod) { setFixedSlot(Slot_NextMethod, nextMethod); } public: static const Class class_; static JSObject* create(JSContext* cx, HandleObject iter, HandleValue nextMethod);
--- a/js/src/vm/BooleanObject.h +++ b/js/src/vm/BooleanObject.h @@ -8,16 +8,18 @@ #define vm_BooleanObject_h #include "builtin/Boolean.h" #include "vm/NativeObject.h" namespace js { +class GlobalObject; + class BooleanObject : public NativeObject { /* Stores this Boolean object's [[PrimitiveValue]]. */ static const unsigned PRIMITIVE_VALUE_SLOT = 0; public: static const unsigned RESERVED_SLOTS = 1; @@ -36,14 +38,14 @@ class BooleanObject : public NativeObjec private: inline void setPrimitiveValue(bool b) { setFixedSlot(PRIMITIVE_VALUE_SLOT, BooleanValue(b)); } /* For access to init, as Boolean.prototype is special. */ friend JSObject* - js::InitBooleanClass(JSContext* cx, js::HandleObject global); + js::InitBooleanClass(JSContext* cx, js::Handle<GlobalObject*> global); }; } // namespace js #endif /* vm_BooleanObject_h */
--- a/js/src/vm/Debugger-inl.h +++ b/js/src/vm/Debugger-inl.h @@ -24,17 +24,17 @@ js::Debugger::onLeaveFrame(JSContext* cx ok = slowPathOnLeaveFrame(cx, frame, pc, ok); MOZ_ASSERT(!inFrameMaps(frame)); return ok; } /* static */ inline js::Debugger* js::Debugger::fromJSObject(const JSObject* obj) { - MOZ_ASSERT(js::GetObjectClass(obj) == &class_); + MOZ_ASSERT(obj->getClass() == &class_); return (Debugger*) obj->as<NativeObject>().getPrivate(); } /* static */ inline bool js::Debugger::checkNoExecute(JSContext* cx, HandleScript script) { if (!cx->compartment()->isDebuggee() || !cx->noExecuteDebuggerTop) return true;
--- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -7480,43 +7480,40 @@ ScriptedOnPopHandler::onPop(JSContext* c RootedValue rval(cx); if (!js::Call(cx, fval, frame, completion, &rval)) return false; return ParseResumptionValue(cx, rval, resumeMode, vp); }; /* static */ NativeObject* -DebuggerFrame::initClass(JSContext* cx, HandleObject dbgCtor, HandleObject obj) -{ - Handle<GlobalObject*> global = obj.as<GlobalObject>(); +DebuggerFrame::initClass(JSContext* cx, HandleObject dbgCtor, Handle<GlobalObject*> global) +{ RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global)); return InitClass(cx, dbgCtor, objProto, &class_, construct, 0, properties_, methods_, nullptr, nullptr); } /* static */ DebuggerFrame* DebuggerFrame::create(JSContext* cx, HandleObject proto, const FrameIter& iter, HandleNativeObject debugger) { - JSObject* obj = NewObjectWithGivenProto(cx, &DebuggerFrame::class_, proto); - if (!obj) + DebuggerFrame* frame = NewObjectWithGivenProto<DebuggerFrame>(cx, proto); + if (!frame) return nullptr; - DebuggerFrame& frame = obj->as<DebuggerFrame>(); - FrameIter::Data* data = iter.copyData(); if (!data) return nullptr; - frame.setPrivate(data); - - frame.setReservedSlot(JSSLOT_DEBUGFRAME_OWNER, ObjectValue(*debugger)); - - return &frame; + frame->setPrivate(data); + + frame->setReservedSlot(JSSLOT_DEBUGFRAME_OWNER, ObjectValue(*debugger)); + + return frame; } /* static */ bool DebuggerFrame::getCallee(JSContext* cx, HandleDebuggerFrame frame, MutableHandleDebuggerObject result) { MOZ_ASSERT(frame->isLive()); @@ -8369,17 +8366,17 @@ DebuggerArguments_getArg(JSContext* cx, return true; } /* static */ DebuggerArguments* DebuggerArguments::create(JSContext* cx, HandleObject proto, HandleDebuggerFrame frame) { AbstractFramePtr referent = DebuggerFrame::getReferent(frame); - RootedNativeObject obj(cx, NewNativeObjectWithGivenProto(cx, &DebuggerArguments::class_, proto)); + Rooted<DebuggerArguments*> obj(cx, NewObjectWithGivenProto<DebuggerArguments>(cx, proto)); if (!obj) return nullptr; SetReservedSlot(obj, FRAME_SLOT, ObjectValue(*frame)); MOZ_ASSERT(referent.numActualArgs() <= 0x7fffffff); unsigned fargc = referent.numActualArgs(); RootedValue fargcVal(cx, Int32Value(fargc)); @@ -8402,17 +8399,17 @@ DebuggerArguments::create(JSContext* cx, JS_DATA_TO_FUNC_PTR(GetterOp, getobj.get()), nullptr, JSPROP_ENUMERATE | JSPROP_GETTER)) { return nullptr; } getobj->setExtendedSlot(0, Int32Value(i)); } - return &obj->as<DebuggerArguments>(); + return obj; } /* static */ bool DebuggerFrame::argumentsGetter(JSContext* cx, unsigned argc, Value* vp) { THIS_DEBUGGER_FRAME(cx, argc, vp, "get arguments", args, frame); RootedDebuggerArguments result(cx); @@ -9778,19 +9775,18 @@ const JSFunctionSpec DebuggerObject::met JS_FN("executeInGlobalWithBindings", DebuggerObject::executeInGlobalWithBindingsMethod, 2, 0), JS_FN("makeDebuggeeValue", DebuggerObject::makeDebuggeeValueMethod, 1, 0), JS_FN("unsafeDereference", DebuggerObject::unsafeDereferenceMethod, 0, 0), JS_FN("unwrap", DebuggerObject::unwrapMethod, 0, 0), JS_FS_END }; /* static */ NativeObject* -DebuggerObject::initClass(JSContext* cx, HandleObject obj, HandleObject debugCtor) -{ - Handle<GlobalObject*> global = obj.as<GlobalObject>(); +DebuggerObject::initClass(JSContext* cx, Handle<GlobalObject*> global, HandleObject debugCtor) +{ RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global)); RootedNativeObject objectProto(cx, InitClass(cx, debugCtor, objProto, &class_, construct, 0, properties_, methods_, nullptr, nullptr)); if (!objectProto) return nullptr; @@ -9801,25 +9797,24 @@ DebuggerObject::initClass(JSContext* cx, return objectProto; } /* static */ DebuggerObject* DebuggerObject::create(JSContext* cx, HandleObject proto, HandleObject referent, HandleNativeObject debugger) { NewObjectKind newKind = IsInsideNursery(referent) ? GenericObject : TenuredObject; - JSObject* obj = NewObjectWithGivenProto(cx, &DebuggerObject::class_, proto, newKind); + DebuggerObject* obj = NewObjectWithGivenProto<DebuggerObject>(cx, proto, newKind); if (!obj) return nullptr; - DebuggerObject& object = obj->as<DebuggerObject>(); - object.setPrivateGCThing(referent); - object.setReservedSlot(JSSLOT_DEBUGOBJECT_OWNER, ObjectValue(*debugger)); - - return &object; + obj->setPrivateGCThing(referent); + obj->setReservedSlot(JSSLOT_DEBUGOBJECT_OWNER, ObjectValue(*debugger)); + + return obj; } bool DebuggerObject::isCallable() const { return referent()->isCallable(); } @@ -11032,39 +11027,37 @@ const JSFunctionSpec DebuggerEnvironment JS_FN("names", DebuggerEnvironment::namesMethod, 0, 0), JS_FN("find", DebuggerEnvironment::findMethod, 1, 0), JS_FN("getVariable", DebuggerEnvironment::getVariableMethod, 1, 0), JS_FN("setVariable", DebuggerEnvironment::setVariableMethod, 2, 0), JS_FS_END }; /* static */ NativeObject* -DebuggerEnvironment::initClass(JSContext* cx, HandleObject dbgCtor, HandleObject obj) -{ - Handle<GlobalObject*> global = obj.as<GlobalObject>(); +DebuggerEnvironment::initClass(JSContext* cx, HandleObject dbgCtor, Handle<GlobalObject*> global) +{ RootedObject objProto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global)); return InitClass(cx, dbgCtor, objProto, &DebuggerEnvironment::class_, construct, 0, properties_, methods_, nullptr, nullptr); } /* static */ DebuggerEnvironment* DebuggerEnvironment::create(JSContext* cx, HandleObject proto, HandleObject referent, HandleNativeObject debugger) { NewObjectKind newKind = IsInsideNursery(referent) ? GenericObject : TenuredObject; - RootedObject obj(cx, NewObjectWithGivenProto(cx, &DebuggerEnvironment::class_, proto, newKind)); + DebuggerEnvironment* obj = NewObjectWithGivenProto<DebuggerEnvironment>(cx, proto, newKind); if (!obj) return nullptr; - DebuggerEnvironment& environment = obj->as<DebuggerEnvironment>(); - environment.setPrivateGCThing(referent); - environment.setReservedSlot(OWNER_SLOT, ObjectValue(*debugger)); - - return &environment; + obj->setPrivateGCThing(referent); + obj->setReservedSlot(OWNER_SLOT, ObjectValue(*debugger)); + + return obj; } /* static */ DebuggerEnvironmentType DebuggerEnvironment::type() const { /* Don't bother switching compartments just to check env's type. */ if (IsDeclarative(referent())) return DebuggerEnvironmentType::Declarative; @@ -11411,24 +11404,24 @@ JS_DefineDebuggerObject(JSContext* cx, H memoryProto(cx); RootedObject debuggeeWouldRunProto(cx); RootedValue debuggeeWouldRunCtor(cx); Handle<GlobalObject*> global = obj.as<GlobalObject>(); objProto = GlobalObject::getOrCreateObjectPrototype(cx, global); if (!objProto) return false; - debugProto = InitClass(cx, obj, + debugProto = InitClass(cx, global, objProto, &Debugger::class_, Debugger::construct, 1, Debugger::properties, Debugger::methods, nullptr, Debugger::static_methods, debugCtor.address()); if (!debugProto) return false; - frameProto = DebuggerFrame::initClass(cx, debugCtor, obj); + frameProto = DebuggerFrame::initClass(cx, debugCtor, global); if (!frameProto) return false; scriptProto = InitClass(cx, debugCtor, objProto, &DebuggerScript_class, DebuggerScript_construct, 0, DebuggerScript_properties, DebuggerScript_methods, nullptr, nullptr); if (!scriptProto) @@ -11436,21 +11429,21 @@ JS_DefineDebuggerObject(JSContext* cx, H sourceProto = InitClass(cx, debugCtor, sourceProto, &DebuggerSource_class, DebuggerSource_construct, 0, DebuggerSource_properties, DebuggerSource_methods, nullptr, nullptr); if (!sourceProto) return false; - objectProto = DebuggerObject::initClass(cx, obj, debugCtor); + objectProto = DebuggerObject::initClass(cx, global, debugCtor); if (!objectProto) return false; - envProto = DebuggerEnvironment::initClass(cx, debugCtor, obj); + envProto = DebuggerEnvironment::initClass(cx, debugCtor, global); if (!envProto) return false; memoryProto = InitClass(cx, debugCtor, objProto, &DebuggerMemory::class_, DebuggerMemory::construct, 0, DebuggerMemory::properties, DebuggerMemory::methods, nullptr, nullptr); if (!memoryProto) return false; @@ -11473,17 +11466,17 @@ JS_DefineDebuggerObject(JSContext* cx, H return true; } JS_PUBLIC_API(bool) JS::dbg::IsDebugger(JSObject& obj) { JSObject* unwrapped = CheckedUnwrap(&obj); return unwrapped && - js::GetObjectClass(unwrapped) == &Debugger::class_ && + unwrapped->getClass() == &Debugger::class_ && js::Debugger::fromJSObject(unwrapped) != nullptr; } JS_PUBLIC_API(bool) JS::dbg::GetDebuggeeGlobals(JSContext* cx, JSObject& dbgObj, AutoObjectVector& vector) { MOZ_ASSERT(IsDebugger(dbgObj)); js::Debugger* dbg = js::Debugger::fromJSObject(CheckedUnwrap(&dbgObj));
--- a/js/src/vm/Debugger.h +++ b/js/src/vm/Debugger.h @@ -1131,17 +1131,18 @@ class DebuggerEnvironment : public Nativ enum { OWNER_SLOT }; static const unsigned RESERVED_SLOTS = 1; static const Class class_; - static NativeObject* initClass(JSContext* cx, HandleObject dbgCtor, HandleObject objProto); + static NativeObject* initClass(JSContext* cx, HandleObject dbgCtor, + Handle<GlobalObject*> global); static DebuggerEnvironment* create(JSContext* cx, HandleObject proto, HandleObject referent, HandleNativeObject debugger); DebuggerEnvironmentType type() const; MOZ_MUST_USE bool getParent(JSContext* cx, MutableHandleDebuggerEnvironment result) const; MOZ_MUST_USE bool getObject(JSContext* cx, MutableHandleDebuggerObject result) const; MOZ_MUST_USE bool getCallee(JSContext* cx, MutableHandleDebuggerObject result) const; bool isDebuggee() const; @@ -1320,17 +1321,18 @@ class DebuggerFrame : public NativeObjec enum { OWNER_SLOT }; static const unsigned RESERVED_SLOTS = 1; static const Class class_; - static NativeObject* initClass(JSContext* cx, HandleObject dbgCtor, HandleObject objProto); + static NativeObject* initClass(JSContext* cx, HandleObject dbgCtor, + Handle<GlobalObject*> global); static DebuggerFrame* create(JSContext* cx, HandleObject proto, const FrameIter& iter, HandleNativeObject debugger); void freeFrameIterData(FreeOp* fop); static MOZ_MUST_USE bool getArguments(JSContext* cx, HandleDebuggerFrame frame, MutableHandleDebuggerArguments result); static MOZ_MUST_USE bool getCallee(JSContext* cx, HandleDebuggerFrame frame, MutableHandleDebuggerObject result); @@ -1396,17 +1398,18 @@ class DebuggerFrame : public NativeObjec FrameIter::Data* frameIterData() const; }; class DebuggerObject : public NativeObject { public: static const Class class_; - static NativeObject* initClass(JSContext* cx, HandleObject obj, HandleObject debugCtor); + static NativeObject* initClass(JSContext* cx, Handle<GlobalObject*> global, + HandleObject debugCtor); static DebuggerObject* create(JSContext* cx, HandleObject proto, HandleObject obj, HandleNativeObject debugger); // Properties static MOZ_MUST_USE bool getClassName(JSContext* cx, HandleDebuggerObject object, MutableHandleString result); static MOZ_MUST_USE bool getGlobal(JSContext* cx, HandleDebuggerObject object, MutableHandleDebuggerObject result);
--- a/js/src/vm/DebuggerMemory.cpp +++ b/js/src/vm/DebuggerMemory.cpp @@ -35,24 +35,24 @@ using mozilla::Forward; using mozilla::Maybe; using mozilla::Nothing; /* static */ DebuggerMemory* DebuggerMemory::create(JSContext* cx, Debugger* dbg) { Value memoryProtoValue = dbg->object->getReservedSlot(Debugger::JSSLOT_DEBUG_MEMORY_PROTO); RootedObject memoryProto(cx, &memoryProtoValue.toObject()); - RootedNativeObject memory(cx, NewNativeObjectWithGivenProto(cx, &class_, memoryProto)); + Rooted<DebuggerMemory*> memory(cx, NewObjectWithGivenProto<DebuggerMemory>(cx, memoryProto)); if (!memory) return nullptr; dbg->object->setReservedSlot(Debugger::JSSLOT_DEBUG_MEMORY_INSTANCE, ObjectValue(*memory)); memory->setReservedSlot(JSSLOT_DEBUGGER, ObjectValue(*dbg->object)); - return &memory->as<DebuggerMemory>(); + return memory; } Debugger* DebuggerMemory::getDebugger() { const Value& dbgVal = getReservedSlot(JSSLOT_DEBUGGER); return Debugger::fromJSObject(&dbgVal.toObject()); }
--- a/js/src/vm/ErrorObject.cpp +++ b/js/src/vm/ErrorObject.cpp @@ -144,17 +144,17 @@ js::ErrorObject::getOrCreateErrorReport( // Message. Note that |new Error()| will result in an undefined |message| // slot, so we need to explicitly substitute the empty string in that case. RootedString message(cx, getMessage()); if (!message) message = cx->runtime()->emptyString; if (!message->ensureFlat(cx)) return nullptr; - UniquePtr<char[], JS::FreePolicy> utf8 = StringToNewUTF8CharsZ(cx, *message); + UniqueChars utf8 = StringToNewUTF8CharsZ(cx, *message); if (!utf8) return nullptr; report.initOwnedMessage(utf8.release()); // Cache and return. JSErrorReport* copy = CopyErrorReport(cx, &report); if (!copy) return nullptr;
--- a/js/src/vm/GeneratorObject.cpp +++ b/js/src/vm/GeneratorObject.cpp @@ -31,30 +31,28 @@ GeneratorObject::create(JSContext* cx, A if (!GetProperty(cx, fun, fun, cx->names().prototype, &pval)) return nullptr; RootedObject proto(cx, pval.isObject() ? &pval.toObject() : nullptr); if (!proto) { proto = GlobalObject::getOrCreateGeneratorObjectPrototype(cx, global); if (!proto) return nullptr; } - RootedNativeObject obj(cx, - NewNativeObjectWithGivenProto(cx, &GeneratorObject::class_, proto)); - if (!obj) + Rooted<GeneratorObject*> genObj(cx, NewObjectWithGivenProto<GeneratorObject>(cx, proto)); + if (!genObj) return nullptr; - GeneratorObject* genObj = &obj->as<GeneratorObject>(); genObj->setCallee(*frame.callee()); genObj->setNewTarget(frame.newTarget()); genObj->setEnvironmentChain(*frame.environmentChain()); if (frame.script()->needsArgsObj()) genObj->setArgsObj(frame.argsObj()); genObj->clearExpressionStack(); - return obj; + return genObj; } bool GeneratorObject::suspend(JSContext* cx, HandleObject obj, AbstractFramePtr frame, jsbytecode* pc, Value* vp, unsigned nvalues) { MOZ_ASSERT(*pc == JSOP_INITIALYIELD || *pc == JSOP_YIELD || *pc == JSOP_AWAIT); @@ -208,17 +206,17 @@ GlobalObject::initGenerators(JSContext* { if (global->getReservedSlot(GENERATOR_OBJECT_PROTO).isObject()) return true; RootedObject iteratorProto(cx, GlobalObject::getOrCreateIteratorPrototype(cx, global)); if (!iteratorProto) return false; - RootedObject genObjectProto(cx, GlobalObject::createBlankPrototypeInheriting(cx, global, + RootedObject genObjectProto(cx, GlobalObject::createBlankPrototypeInheriting(cx, &PlainObject::class_, iteratorProto)); if (!genObjectProto) return false; if (!DefinePropertiesAndFunctions(cx, genObjectProto, nullptr, generator_methods) || !DefineToStringTag(cx, genObjectProto, cx->names().Generator)) { return false;
--- a/js/src/vm/GlobalObject.cpp +++ b/js/src/vm/GlobalObject.cpp @@ -4,22 +4,20 @@ * 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 "vm/GlobalObject.h" #include "jsdate.h" #include "jsexn.h" #include "jsfriendapi.h" -#include "jsmath.h" #include "builtin/AtomicsObject.h" #include "builtin/DataViewObject.h" #include "builtin/Eval.h" -#include "builtin/JSON.h" #include "builtin/MapObject.h" #include "builtin/ModuleObject.h" #include "builtin/Object.h" #include "builtin/Promise.h" #include "builtin/RegExp.h" #include "builtin/SelfHostingDefines.h" #include "builtin/Stream.h" #include "builtin/Symbol.h" @@ -30,41 +28,45 @@ #include "js/ProtoKey.h" #include "vm/Debugger.h" #include "vm/EnvironmentObject.h" #include "vm/HelperThreads.h" #include "vm/JSContext.h" #include "vm/PIC.h" #include "vm/RegExpStatics.h" #include "vm/RegExpStaticsObject.h" -#include "wasm/WasmJS.h" #include "vm/JSCompartment-inl.h" #include "vm/JSObject-inl.h" #include "vm/JSScript-inl.h" #include "vm/NativeObject-inl.h" using namespace js; struct ProtoTableEntry { const Class* clasp; ClassInitializerOp init; }; namespace js { +extern const Class IntlClass; +extern const Class JSONClass; +extern const Class MathClass; +extern const Class WebAssemblyClass; + #define DECLARE_PROTOTYPE_CLASS_INIT(name,init,clasp) \ - extern JSObject* init(JSContext* cx, Handle<JSObject*> obj); + extern JSObject* init(JSContext* cx, Handle<GlobalObject*> global); JS_FOR_EACH_PROTOTYPE(DECLARE_PROTOTYPE_CLASS_INIT) #undef DECLARE_PROTOTYPE_CLASS_INIT } // namespace js JSObject* -js::InitViaClassSpec(JSContext* cx, Handle<JSObject*> obj) +js::InitViaClassSpec(JSContext* cx, Handle<GlobalObject*> global) { MOZ_CRASH("InitViaClassSpec() should not be called."); } static const ProtoTableEntry protoTable[JSProto_LIMIT] = { #define INIT_FUNC(name,init,clasp) { clasp, init }, #define INIT_FUNC_DUMMY(name,init,clasp) { nullptr, nullptr }, JS_FOR_PROTOTYPES(INIT_FUNC, INIT_FUNC_DUMMY) @@ -694,17 +696,17 @@ GlobalObject::createConstructor(JSContex if (jitInfo) fun->setJitInfo(jitInfo); return fun; } static NativeObject* -CreateBlankProto(JSContext* cx, const Class* clasp, HandleObject proto, HandleObject global) +CreateBlankProto(JSContext* cx, const Class* clasp, HandleObject proto) { MOZ_ASSERT(clasp != &JSFunction::class_); RootedNativeObject blankProto(cx, NewNativeObjectWithGivenProto(cx, clasp, proto, SingletonObject)); if (!blankProto || !JSObject::setDelegate(cx, blankProto)) return nullptr; @@ -713,24 +715,24 @@ CreateBlankProto(JSContext* cx, const Cl /* static */ NativeObject* GlobalObject::createBlankPrototype(JSContext* cx, Handle<GlobalObject*> global, const Class* clasp) { RootedObject objectProto(cx, getOrCreateObjectPrototype(cx, global)); if (!objectProto) return nullptr; - return CreateBlankProto(cx, clasp, objectProto, global); + return CreateBlankProto(cx, clasp, objectProto); } /* static */ NativeObject* -GlobalObject::createBlankPrototypeInheriting(JSContext* cx, Handle<GlobalObject*> global, - const Class* clasp, HandleObject proto) +GlobalObject::createBlankPrototypeInheriting(JSContext* cx, const Class* clasp, + HandleObject proto) { - return CreateBlankProto(cx, clasp, proto, global); + return CreateBlankProto(cx, clasp, proto); } bool js::LinkConstructorAndPrototype(JSContext* cx, JSObject* ctor_, JSObject* proto_, unsigned prototypeAttrs, unsigned constructorAttrs) { RootedObject ctor(cx, ctor_), proto(cx, proto_);
--- a/js/src/vm/GlobalObject.h +++ b/js/src/vm/GlobalObject.h @@ -186,28 +186,16 @@ class GlobalObject : public NativeObject Value getPrototype(JSProtoKey key) const { return getSlot(prototypeSlot(key)); } void setPrototype(JSProtoKey key, const Value& value) { setSlot(prototypeSlot(key), value); } - bool classIsInitialized(JSProtoKey key) const { - bool inited = !getConstructor(key).isUndefined(); - MOZ_ASSERT(inited == !getPrototype(key).isUndefined()); - return inited; - } - - bool functionObjectClassesInitialized() const { - bool inited = classIsInitialized(JSProto_Function); - MOZ_ASSERT(inited == classIsInitialized(JSProto_Object)); - return inited; - } - /* * Lazy standard classes need a way to indicate they have been initialized. * Otherwise, when we delete them, we might accidentally recreate them via * a lazy initialization. We use the presence of an object in the * getConstructor(key) reserved slot to indicate that they've been * initialized. * * Note: A few builtin objects, like JSON and Math, are not constructors, @@ -217,32 +205,29 @@ class GlobalObject : public NativeObject // If the constructor is undefined, then it hasn't been initialized. Value value = getConstructor(key); MOZ_ASSERT(value.isUndefined() || value.isObject() || value.isMagic(JS_OFF_THREAD_CONSTRUCTOR)); return !value.isUndefined(); } - /* - * Using a Handle<GlobalObject*> as a Handle<Object*> is always safe as - * GlobalObject derives JSObject. However, with C++'s semantics, Handle<T> - * is not related to Handle<S>, independent of how S and T are related. - * Further, Handle stores an indirect pointer and, again because of C++'s - * semantics, T** is not related to S**, independent of how S and T are - * related. Since we know that this specific case is safe, we provide a - * manual upcast operation here to do the reinterpret_cast in a known-safe - * manner. - */ - static HandleObject upcast(Handle<GlobalObject*> global) { - return HandleObject::fromMarkedLocation( - reinterpret_cast<JSObject * const*>(global.address())); + private: + bool classIsInitialized(JSProtoKey key) const { + bool inited = !getConstructor(key).isUndefined(); + MOZ_ASSERT(inited == !getPrototype(key).isUndefined()); + return inited; } - private: + bool functionObjectClassesInitialized() const { + bool inited = classIsInitialized(JSProto_Function); + MOZ_ASSERT(inited == classIsInitialized(JSProto_Object)); + return inited; + } + bool arrayClassInitialized() const { return classIsInitialized(JSProto_Array); } bool booleanClassInitialized() const { return classIsInitialized(JSProto_Boolean); } bool numberClassInitialized() const { @@ -298,18 +283,17 @@ class GlobalObject : public NativeObject static NativeObject* createBlankPrototype(JSContext* cx, Handle<GlobalObject*> global, const js::Class* clasp); /* * Identical to createBlankPrototype, but uses proto as the [[Prototype]] * of the returned blank prototype. */ static NativeObject* - createBlankPrototypeInheriting(JSContext* cx, Handle<GlobalObject*> global, - const js::Class* clasp, HandleObject proto); + createBlankPrototypeInheriting(JSContext* cx, const js::Class* clasp, HandleObject proto); template <typename T> static T* createBlankPrototype(JSContext* cx, Handle<GlobalObject*> global) { NativeObject* res = createBlankPrototype(cx, global, &T::class_); return res ? &res->template as<T>() : nullptr; } @@ -915,17 +899,17 @@ GenericCreatePrototype(JSContext* cx, JS { MOZ_ASSERT(key != JSProto_Object); const Class* clasp = ProtoKeyToClass(key); MOZ_ASSERT(clasp); JSProtoKey protoKey = InheritanceProtoKeyForStandardClass(key); if (!GlobalObject::ensureConstructor(cx, cx->global(), protoKey)) return nullptr; RootedObject parentProto(cx, &cx->global()->getPrototype(protoKey).toObject()); - return GlobalObject::createBlankPrototypeInheriting(cx, cx->global(), clasp, parentProto); + return GlobalObject::createBlankPrototypeInheriting(cx, clasp, parentProto); } inline JSProtoKey StandardProtoKeyOrNull(const JSObject* obj) { return JSCLASS_CACHED_PROTO_KEY(obj->getClass()); }
--- a/js/src/vm/HelperThreads.cpp +++ b/js/src/vm/HelperThreads.cpp @@ -752,20 +752,20 @@ StartOffThreadParseTask(JSContext* cx, P gc::AutoSuppressGC nogc(cx); gc::AutoSuppressNurseryCellAlloc noNurseryAlloc(cx); AutoSuppressAllocationMetadataBuilder suppressMetadata(cx); JSObject* global = CreateGlobalForOffThreadParse(cx, nogc); if (!global) return false; - // Mark the global's zone group as created for a helper thread. This - // prevents it from being collected until clearUsedByHelperThread() is - // called after parsing is complete. If this function exits due to error - // this state is cleared automatically. + // Mark the global's zone as created for a helper thread. This prevents it + // from being collected until clearUsedByHelperThread() is called after + // parsing is complete. If this function exits due to error this state is + // cleared automatically. AutoSetCreatedForHelperThread createdForHelper(global); if (!task->init(cx, options, global)) return false; if (!QueueOffThreadParseTask(cx, task)) return false;
--- a/js/src/vm/Iteration.cpp +++ b/js/src/vm/Iteration.cpp @@ -1392,18 +1392,17 @@ GlobalObject::initArrayIteratorProto(JSC if (global->getReservedSlot(ARRAY_ITERATOR_PROTO).isObject()) return true; RootedObject iteratorProto(cx, GlobalObject::getOrCreateIteratorPrototype(cx, global)); if (!iteratorProto) return false; const Class* cls = &ArrayIteratorPrototypeClass; - RootedObject proto(cx, GlobalObject::createBlankPrototypeInheriting(cx, global, cls, - iteratorProto)); + RootedObject proto(cx, GlobalObject::createBlankPrototypeInheriting(cx, cls, iteratorProto)); if (!proto || !DefinePropertiesAndFunctions(cx, proto, nullptr, array_iterator_methods) || !DefineToStringTag(cx, proto, cx->names().ArrayIterator)) { return false; } global->setReservedSlot(ARRAY_ITERATOR_PROTO, ObjectValue(*proto)); @@ -1416,18 +1415,17 @@ GlobalObject::initStringIteratorProto(JS if (global->getReservedSlot(STRING_ITERATOR_PROTO).isObject()) return true; RootedObject iteratorProto(cx, GlobalObject::getOrCreateIteratorPrototype(cx, global)); if (!iteratorProto) return false; const Class* cls = &StringIteratorPrototypeClass; - RootedObject proto(cx, GlobalObject::createBlankPrototypeInheriting(cx, global, cls, - iteratorProto)); + RootedObject proto(cx, GlobalObject::createBlankPrototypeInheriting(cx, cls, iteratorProto)); if (!proto || !DefinePropertiesAndFunctions(cx, proto, nullptr, string_iterator_methods) || !DefineToStringTag(cx, proto, cx->names().StringIterator)) { return false; } global->setReservedSlot(STRING_ITERATOR_PROTO, ObjectValue(*proto));
--- a/js/src/vm/JSAtom.cpp +++ b/js/src/vm/JSAtom.cpp @@ -127,21 +127,16 @@ js::AtomToPrintableString(JSContext* cx, #define DEFINE_PROTO_STRING(name,init,clasp) const char js_##name##_str[] = #name; JS_FOR_EACH_PROTOTYPE(DEFINE_PROTO_STRING) #undef DEFINE_PROTO_STRING #define CONST_CHAR_STR(idpart, id, text) const char js_##idpart##_str[] = text; FOR_EACH_COMMON_PROPERTYNAME(CONST_CHAR_STR) #undef CONST_CHAR_STR -/* Constant strings that are not atomized. */ -const char js_getter_str[] = "getter"; -const char js_send_str[] = "send"; -const char js_setter_str[] = "setter"; - // Use a low initial capacity for atom hash tables to avoid penalizing runtimes // which create a small number of atoms. static const uint32_t JS_STRING_HASH_COUNT = 64; MOZ_ALWAYS_INLINE AtomSet::Ptr js::FrozenAtomSet::readonlyThreadsafeLookup(const AtomSet::Lookup& l) const { return mSet->readonlyThreadsafeLookup(l);
--- a/js/src/vm/JSAtom.h +++ b/js/src/vm/JSAtom.h @@ -32,21 +32,16 @@ class PropertyName; #define DECLARE_PROTO_STR(name,init,clasp) extern const char js_##name##_str[]; JS_FOR_EACH_PROTOTYPE(DECLARE_PROTO_STR) #undef DECLARE_PROTO_STR #define DECLARE_CONST_CHAR_STR(idpart, id, text) extern const char js_##idpart##_str[]; FOR_EACH_COMMON_PROPERTYNAME(DECLARE_CONST_CHAR_STR) #undef DECLARE_CONST_CHAR_STR -/* Constant strings that are not atomized. */ -extern const char js_getter_str[]; -extern const char js_send_str[]; -extern const char js_setter_str[]; - namespace js { class AutoLockForExclusiveAccess; /* * Atom tracing and garbage collection hooks. */ void
--- a/js/src/vm/JSContext-inl.h +++ b/js/src/vm/JSContext-inl.h @@ -134,26 +134,16 @@ class CompartmentChecker decltype(((Container*)nullptr)->end()) >::value >::Type check(const Container& container) { for (auto i : container) check(i); } - void check(const ValueArray& arr) { - for (size_t i = 0; i < arr.length; i++) - check(arr.array[i]); - } - - void check(const JSValueArray& arr) { - for (size_t i = 0; i < arr.length; i++) - check(arr.array[i]); - } - void check(const JS::HandleValueArray& arr) { for (size_t i = 0; i < arr.length(); i++) check(arr[i]); } void check(const CallArgs& args) { for (Value* p = args.base(); p != args.end(); ++p) check(*p);
--- a/js/src/vm/JSContext.cpp +++ b/js/src/vm/JSContext.cpp @@ -182,20 +182,18 @@ js::DestroyContext(JSContext* cx) { JS_AbortIfWrongThread(cx); if (cx->outstandingRequests != 0) MOZ_CRASH("Attempted to destroy a context while it is in a request."); cx->checkNoGCRooters(); - // Cancel all off thread Ion compiles before destroying a cooperative - // context. Completed Ion compiles may try to interrupt arbitrary - // cooperative contexts which they have read off the owner context of a - // zone group. See HelperThread::handleIonWorkload. + // Cancel all off thread Ion compiles. Completed Ion compiles may try to + // interrupt this context. See HelperThread::handleIonWorkload. CancelOffThreadIonCompile(cx->runtime()); FreeJobQueueHandling(cx); // Flush promise tasks executing in helper threads early, before any parts // of the JSRuntime that might be visible to helper threads are torn down. cx->runtime()->offThreadPromiseState.ref().shutdown(cx);
--- a/js/src/vm/JSContext.h +++ b/js/src/vm/JSContext.h @@ -203,19 +203,17 @@ struct JSContext : public JS::RootingCon #ifdef DEBUG unsigned getEnterCompartmentDepth() const { return enterCompartmentDepth_; } #endif private: // We distinguish between entering the atoms compartment and all other - // compartments. Entering the atoms compartment requires a lock. Also, we - // don't call enterZoneGroup when entering the atoms compartment since that - // can induce GC hazards. + // compartments. Entering the atoms compartment requires a lock. inline void enterNonAtomsCompartment(JSCompartment* c); inline void enterAtomsCompartment(JSCompartment* c, const js::AutoLockForExclusiveAccess& lock); friend class js::AutoCompartment; public: template <typename T> @@ -301,36 +299,20 @@ struct JSContext : public JS::RootingCon static size_t offsetOfCompartment() { return offsetof(JSContext, compartment_); } friend class JS::AutoSaveExceptionState; friend class js::jit::DebugModeOSRVolatileJitFrameIter; friend void js::ReportOverRecursed(JSContext*, unsigned errorNumber); - // Returns to the embedding to allow other cooperative threads to run. We - // may do this if we need access to a ZoneGroup that is in use by another - // thread. - void yieldToEmbedding() { - (*yieldCallback_)(this); - } - - void setYieldCallback(js::YieldCallback callback) { - yieldCallback_ = callback; - } - private: static JS::Error reportedError; static JS::OOM reportedOOM; - // This callback is used to ask the embedding to allow other cooperative - // threads to run. We may do this if we need access to a ZoneGroup that is - // in use by another thread. - js::ThreadLocalData<js::YieldCallback> yieldCallback_; - public: inline JS::Result<> boolToResult(bool ok); /** * Intentionally awkward signpost method that is stationed on the * boundary between Result-using and non-Result-using code. */ template <typename V, typename E>
--- a/js/src/vm/JSFunction.cpp +++ b/js/src/vm/JSFunction.cpp @@ -843,17 +843,17 @@ CreateFunctionPrototype(JSContext* cx, J return nullptr; RootedFunction functionProto(cx, &functionProto_->as<JSFunction>()); const char* rawSource = "function () {\n}"; size_t sourceLen = strlen(rawSource); size_t begin = 9; MOZ_ASSERT(rawSource[begin] == '('); - mozilla::UniquePtr<char16_t[], JS::FreePolicy> source(InflateString(cx, rawSource, sourceLen)); + UniqueTwoByteChars source(InflateString(cx, rawSource, sourceLen)); if (!source) return nullptr; ScriptSource* ss = cx->new_<ScriptSource>(); if (!ss) return nullptr; ScriptSourceHolder ssHolder(ss); if (!ss->setSource(cx, mozilla::Move(source), sourceLen)) @@ -2136,21 +2136,20 @@ NewFunctionClone(JSContext* cx, HandleFu { RootedObject cloneProto(cx, proto); if (!proto && (fun->isGenerator() || fun->isAsync())) { cloneProto = GlobalObject::getOrCreateGeneratorFunctionPrototype(cx, cx->global()); if (!cloneProto) return nullptr; } - JSObject* cloneobj = NewObjectWithClassProto(cx, &JSFunction::class_, cloneProto, - allocKind, newKind); - if (!cloneobj) + RootedFunction clone(cx); + clone = NewObjectWithClassProto<JSFunction>(cx, cloneProto, allocKind, newKind); + if (!clone) return nullptr; - RootedFunction clone(cx, &cloneobj->as<JSFunction>()); // JSFunction::HAS_INFERRED_NAME can be set at compile-time and at // runtime. In the latter case we should actually clear the flag before // cloning the function, but since we can't differentiate between both // cases here, we'll end up with a momentarily incorrect function name. // This will be fixed up in SetFunctionNameIfNoOwnName(), which should // happen through JSOP_SETFUNNAME directly after JSOP_LAMBDA. constexpr uint16_t NonCloneableFlags = JSFunction::EXTENDED |
--- a/js/src/vm/JSObject-inl.h +++ b/js/src/vm/JSObject-inl.h @@ -619,29 +619,39 @@ NewObjectWithGivenTaggedProto(JSContext* { JSObject* obj = NewObjectWithGivenTaggedProto(cx, &T::class_, proto, newKind, initialShapeFlags); return obj ? &obj->as<T>() : nullptr; } template <typename T> inline T* +NewObjectWithGivenTaggedProto(JSContext* cx, Handle<TaggedProto> proto, + gc::AllocKind allocKind, NewObjectKind newKind = GenericObject, + uint32_t initialShapeFlags = 0) +{ + JSObject* obj = NewObjectWithGivenTaggedProto(cx, &T::class_, proto, allocKind, newKind, + initialShapeFlags); + return obj ? &obj->as<T>() : nullptr; +} + +template <typename T> +inline T* NewObjectWithNullTaggedProto(JSContext* cx, NewObjectKind newKind = GenericObject, uint32_t initialShapeFlags = 0) { - Rooted<TaggedProto> nullProto(cx, TaggedProto(nullptr)); + Handle<TaggedProto> nullProto = AsTaggedProto(nullptr); return NewObjectWithGivenTaggedProto<T>(cx, nullProto, newKind, initialShapeFlags); } inline JSObject* NewObjectWithGivenProto(JSContext* cx, const Class* clasp, HandleObject proto, - gc::AllocKind allocKind, NewObjectKind newKind) + gc::AllocKind allocKind, NewObjectKind newKind = GenericObject) { - return NewObjectWithGivenTaggedProto(cx, clasp, AsTaggedProto(proto), allocKind, - newKind); + return NewObjectWithGivenTaggedProto(cx, clasp, AsTaggedProto(proto), allocKind, newKind); } inline JSObject* NewObjectWithGivenProto(JSContext* cx, const Class* clasp, HandleObject proto, NewObjectKind newKind = GenericObject) { return NewObjectWithGivenTaggedProto(cx, clasp, AsTaggedProto(proto), newKind); } @@ -799,18 +809,17 @@ GetClassOfValue(JSContext* cx, HandleVal return GetBuiltinClass(cx, obj, cls); } extern NativeObject* InitClass(JSContext* cx, HandleObject obj, HandleObject parent_proto, const Class* clasp, JSNative constructor, unsigned nargs, const JSPropertySpec* ps, const JSFunctionSpec* fs, const JSPropertySpec* static_ps, const JSFunctionSpec* static_fs, - NativeObject** ctorp = nullptr, - gc::AllocKind ctorKind = gc::AllocKind::FUNCTION); + NativeObject** ctorp = nullptr); MOZ_ALWAYS_INLINE const char* GetObjectClassName(JSContext* cx, HandleObject obj) { assertSameCompartment(cx, obj); if (obj->is<ProxyObject>()) return Proxy::className(cx, obj);
--- a/js/src/vm/JSObject.cpp +++ b/js/src/vm/JSObject.cpp @@ -267,16 +267,19 @@ js::Throw(JSContext* cx, jsid id, unsign } return false; } /*** PropertyDescriptor operations and DefineProperties ******************************************/ +static const char js_getter_str[] = "getter"; +static const char js_setter_str[] = "setter"; + static Result<> CheckCallable(JSContext* cx, JSObject* obj, const char* fieldName) { if (obj && !obj->isCallable()) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_GET_SET_FIELD, fieldName); return cx->alreadyReportedError(); } @@ -990,17 +993,17 @@ CreateThisForFunctionWithGroup(JSContext return res; } gc::AllocKind allocKind = NewObjectGCKind(&PlainObject::class_); if (newKind == SingletonObject) { Rooted<TaggedProto> protoRoot(cx, group->proto()); - return NewObjectWithGivenTaggedProto(cx, &PlainObject::class_, protoRoot, allocKind, newKind); + return NewObjectWithGivenTaggedProto<PlainObject>(cx, protoRoot, allocKind, newKind); } return NewObjectWithGroup<PlainObject>(cx, group, allocKind, newKind); } JSObject* js::CreateThisForFunctionWithProto(JSContext* cx, HandleObject callee, HandleObject newTarget, HandleObject proto, NewObjectKind newKind /* = GenericObject */) { @@ -1810,17 +1813,17 @@ ClearClassObject(JSObject* obj, JSProtoK } static NativeObject* DefineConstructorAndPrototype(JSContext* cx, HandleObject obj, JSProtoKey key, HandleAtom atom, HandleObject protoProto, const Class* clasp, Native constructor, unsigned nargs, const JSPropertySpec* ps, const JSFunctionSpec* fs, const JSPropertySpec* static_ps, const JSFunctionSpec* static_fs, - NativeObject** ctorp, AllocKind ctorKind) + NativeObject** ctorp) { /* * Create a prototype object for this class. * * FIXME: lazy standard (built-in) class initialization and even older * eager boostrapping code rely on all of these properties: * * 1. NewObject attempting to compute a default prototype object when @@ -1866,17 +1869,17 @@ DefineConstructorAndPrototype(JSContext* : 0; RootedValue value(cx, ObjectValue(*proto)); if (!DefineStandardSlot(cx, obj, atom, value, attrs, named)) goto bad; } ctor = proto; } else { - RootedFunction fun(cx, NewNativeConstructor(cx, constructor, nargs, atom, ctorKind)); + RootedFunction fun(cx, NewNativeConstructor(cx, constructor, nargs, atom)); if (!fun) goto bad; /* * Set the class object early for standard class constructors. Type * inference may need to access these, and js::GetBuiltinPrototype will * fail if it tries to do a reentrant reconstruction of the class. */ @@ -1931,17 +1934,17 @@ bad: return nullptr; } NativeObject* js::InitClass(JSContext* cx, HandleObject obj, HandleObject protoProto_, const Class* clasp, Native constructor, unsigned nargs, const JSPropertySpec* ps, const JSFunctionSpec* fs, const JSPropertySpec* static_ps, const JSFunctionSpec* static_fs, - NativeObject** ctorp, AllocKind ctorKind) + NativeObject** ctorp) { RootedObject protoProto(cx, protoProto_); RootedAtom atom(cx, Atomize(cx, clasp->name, strlen(clasp->name))); if (!atom) return nullptr; /* @@ -1956,17 +1959,17 @@ js::InitClass(JSContext* cx, HandleObjec JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(clasp); if (key != JSProto_Null && !protoProto) { protoProto = GlobalObject::getOrCreatePrototype(cx, JSProto_Object); if (!protoProto) return nullptr; } return DefineConstructorAndPrototype(cx, obj, key, atom, protoProto, clasp, constructor, nargs, - ps, fs, static_ps, static_fs, ctorp, ctorKind); + ps, fs, static_ps, static_fs, ctorp); } void JSObject::fixupAfterMovingGC() { // For copy-on-write objects that don't own their elements, fix up the // elements pointer if it points to inline elements in the owning object. if (is<NativeObject>()) { @@ -4061,19 +4064,19 @@ js::SpeciesConstructor(JSContext* cx, Ha "[Symbol.species] property of object's constructor"); return nullptr; } MOZ_MUST_USE JSObject* js::SpeciesConstructor(JSContext* cx, HandleObject obj, JSProtoKey ctorKey, bool (*isDefaultSpecies)(JSContext*, JSFunction*)) { - if (!GlobalObject::ensureConstructor(cx, cx->global(), ctorKey)) + RootedObject defaultCtor(cx, GlobalObject::getOrCreateConstructor(cx, ctorKey)); + if (!defaultCtor) return nullptr; - RootedObject defaultCtor(cx, &cx->global()->getConstructor(ctorKey).toObject()); return SpeciesConstructor(cx, obj, defaultCtor, isDefaultSpecies); } bool js::Unbox(JSContext* cx, HandleObject obj, MutableHandleValue vp) { if (MOZ_UNLIKELY(obj->is<ProxyObject>())) return Proxy::boxedValue_unbox(cx, obj, vp);
--- a/js/src/vm/JSObject.h +++ b/js/src/vm/JSObject.h @@ -29,20 +29,16 @@ class GCMarker; class Nursery; namespace gc { class RelocationOverlay; } // namespace gc /******************************************************************************/ -extern const Class IntlClass; -extern const Class JSONClass; -extern const Class MathClass; - class GlobalObject; class NewObjectCache; enum class IntegrityLevel { Sealed, Frozen }; @@ -183,17 +179,16 @@ class JSObject : public js::gc::Cell // environment chain. Optimization heuristics will make use of this flag. // See: ReshapeForProtoMutation, ReshapeForShadowedProp inline bool isDelegate() const; static bool setDelegate(JSContext* cx, JS::HandleObject obj) { return setFlags(cx, obj, js::BaseShape::DELEGATE, GENERATE_SHAPE); } inline bool isBoundFunction() const; - inline bool hasSpecialEquality() const; // A "qualified" varobj is the object on which "qualified" variable // declarations (i.e., those defined with "var") are kept. // // Conceptually, when a var binding is defined, it is defined on the // innermost qualified varobj on the scope chain. // // Function scopes (CallObjects) are qualified varobjs, and there can be @@ -642,32 +637,16 @@ JSObject::writeBarrierPost(void* cellp, } // Remove the prev entry if the new value does not need it. There will only // be a prev entry if the prev value was in the nursery. if (prev && (buffer = prev->storeBuffer())) buffer->unputCell(static_cast<js::gc::Cell**>(cellp)); } -class JSValueArray { - public: - const js::Value* array; - size_t length; - - JSValueArray(const js::Value* v, size_t c) : array(v), length(c) {} -}; - -class ValueArray { - public: - js::Value* array; - size_t length; - - ValueArray(js::Value* v, size_t c) : array(v), length(c) {} -}; - namespace js { /*** Standard internal methods ******************************************************************** * * The functions below are the fundamental operations on objects. See the * comment about "Standard internal methods" in jsapi.h. */ @@ -1041,17 +1020,17 @@ GetThisValue(JSObject* obj); Value GetThisValueOfLexical(JSObject* env); Value GetThisValueOfWith(JSObject* env); /* * */ -typedef JSObject* (*ClassInitializerOp)(JSContext* cx, JS::HandleObject obj); +using ClassInitializerOp = JSObject* (*)(JSContext* cx, Handle<GlobalObject*> global); } /* namespace js */ namespace js { inline gc::InitialHeap GetInitialHeap(NewObjectKind newKind, const Class* clasp) {
--- a/js/src/vm/JSScript.cpp +++ b/js/src/vm/JSScript.cpp @@ -1362,20 +1362,19 @@ const Class ScriptSourceObject::class_ = JSCLASS_IS_ANONYMOUS | JSCLASS_FOREGROUND_FINALIZE, &ScriptSourceObjectClassOps }; ScriptSourceObject* ScriptSourceObject::create(JSContext* cx, ScriptSource* source) { - RootedObject object(cx, NewObjectWithGivenProto(cx, &class_, nullptr)); - if (!object) + RootedScriptSource sourceObject(cx, NewObjectWithGivenProto<ScriptSourceObject>(cx, nullptr)); + if (!sourceObject) return nullptr; - RootedScriptSource sourceObject(cx, &object->as<ScriptSourceObject>()); source->incref(); // The matching decref is in ScriptSourceObject::finalize. sourceObject->initReservedSlot(SOURCE_SLOT, PrivateValue(source)); // The remaining slots should eventually be populated by a call to // initFromOptions. Poison them until that point. sourceObject->initReservedSlot(ELEMENT_SLOT, MagicValue(JS_GENERIC_MAGIC)); sourceObject->initReservedSlot(ELEMENT_PROPERTY_SLOT, MagicValue(JS_GENERIC_MAGIC)); @@ -1442,17 +1441,17 @@ JSScript::loadSource(JSContext* cx, Scri if (!cx->runtime()->sourceHook.ref() || !ss->sourceRetrievable()) return true; char16_t* src = nullptr; size_t length; if (!cx->runtime()->sourceHook->load(cx, ss->filename(), &src, &length)) return false; if (!src) return true; - if (!ss->setSource(cx, mozilla::UniquePtr<char16_t[], JS::FreePolicy>(src), length)) + if (!ss->setSource(cx, UniqueTwoByteChars(src), length)) return false; *worked = true; return true; } /* static */ JSFlatString* JSScript::sourceData(JSContext* cx, HandleScript script) @@ -1791,19 +1790,17 @@ ScriptSource::functionBodyString(JSConte MOZ_ASSERT(isFunctionBody()); size_t start = parameterListEnd_ + (sizeof(FunctionConstructorMedialSigils) - 1); size_t stop = length() - (sizeof(FunctionConstructorFinalBrace) - 1); return substring(cx, start, stop); } MOZ_MUST_USE bool -ScriptSource::setSource(JSContext* cx, - mozilla::UniquePtr<char16_t[], JS::FreePolicy>&& source, - size_t length) +ScriptSource::setSource(JSContext* cx, UniqueTwoByteChars&& source, size_t length) { auto& cache = cx->zone()->runtimeFromAnyThread()->sharedImmutableStrings(); auto deduped = cache.getOrCreate(mozilla::Move(source), length); if (!deduped) { ReportOutOfMemory(cx); return false; } setSource(mozilla::Move(*deduped)); @@ -1857,19 +1854,17 @@ ScriptSource::tryCompressOffThread(JSCon if (!task) { ReportOutOfMemory(cx); return false; } return EnqueueOffThreadCompression(cx, Move(task)); } MOZ_MUST_USE bool -ScriptSource::setCompressedSource(JSContext* cx, - mozilla::UniquePtr<char[], JS::FreePolicy>&& raw, - size_t rawLength, +ScriptSource::setCompressedSource(JSContext* cx, UniqueChars&& raw, size_t rawLength, size_t sourceLength) { MOZ_ASSERT(raw); auto& cache = cx->zone()->runtimeFromAnyThread()->sharedImmutableStrings(); auto deduped = cache.getOrCreate(mozilla::Move(raw), rawLength); if (!deduped) { ReportOutOfMemory(cx); return false; @@ -1894,30 +1889,30 @@ bool ScriptSource::setSourceCopy(JSContext* cx, SourceBufferHolder& srcBuf) { MOZ_ASSERT(!hasSourceData()); JSRuntime* runtime = cx->zone()->runtimeFromAnyThread(); auto& cache = runtime->sharedImmutableStrings(); auto deduped = cache.getOrCreate(srcBuf.get(), srcBuf.length(), [&]() { return srcBuf.ownsChars() - ? mozilla::UniquePtr<char16_t[], JS::FreePolicy>(srcBuf.take()) + ? UniqueTwoByteChars(srcBuf.take()) : DuplicateString(srcBuf.get(), srcBuf.length()); }); if (!deduped) { ReportOutOfMemory(cx); return false; } setSource(mozilla::Move(*deduped)); return true; } static MOZ_MUST_USE bool -reallocUniquePtr(UniquePtr<char[], JS::FreePolicy>& unique, size_t size) +reallocUniquePtr(UniqueChars& unique, size_t size) { auto newPtr = static_cast<char*>(js_realloc(unique.get(), size)); if (!newPtr) return false; // Since the realloc succeeded, unique is now holding a freed pointer. mozilla::Unused << unique.release(); unique.reset(newPtr); @@ -1932,17 +1927,17 @@ SourceCompressionTask::work() ScriptSource* source = sourceHolder_.get(); MOZ_ASSERT(source->data.is<ScriptSource::Uncompressed>()); // Try to keep the maximum memory usage down by only allocating half the // size of the string, first. size_t inputBytes = source->length() * sizeof(char16_t); size_t firstSize = inputBytes / 2; - mozilla::UniquePtr<char[], JS::FreePolicy> compressed(js_pod_malloc<char>(firstSize)); + UniqueChars compressed(js_pod_malloc<char>(firstSize)); if (!compressed) return; const char16_t* chars = source->data.as<ScriptSource::Uncompressed>().string.chars(); Compressor comp(reinterpret_cast<const unsigned char*>(chars), inputBytes); if (!comp.init()) return; @@ -2142,28 +2137,26 @@ ScriptSource::performXDR(XDRState<mode>* if (mode == XDR_ENCODE) { CompressedLengthMatcher m; compressedLength = data.match(m); } MOZ_TRY(xdr->codeUint32(&compressedLength)); size_t byteLen = compressedLength ? compressedLength : (len * sizeof(char16_t)); if (mode == XDR_DECODE) { - mozilla::UniquePtr<char[], JS::FreePolicy> bytes( - xdr->cx()->template pod_malloc<char>(Max<size_t>(byteLen, 1))); + UniqueChars bytes(xdr->cx()->template pod_malloc<char>(Max<size_t>(byteLen, 1))); if (!bytes) return xdr->fail(JS::TranscodeResult_Throw); MOZ_TRY(xdr->codeBytes(bytes.get(), byteLen)); if (compressedLength) { if (!setCompressedSource(xdr->cx(), mozilla::Move(bytes), byteLen, len)) return xdr->fail(JS::TranscodeResult_Throw); } else { - mozilla::UniquePtr<char16_t[], JS::FreePolicy> source( - reinterpret_cast<char16_t*>(bytes.release())); + UniqueTwoByteChars source(reinterpret_cast<char16_t*>(bytes.release())); if (!setSource(xdr->cx(), mozilla::Move(source), len)) return xdr->fail(JS::TranscodeResult_Throw); } } else { RawDataMatcher rdm; void* p = data.match(rdm); MOZ_TRY(xdr->codeBytes(p, byteLen)); }
--- a/js/src/vm/MatchPairs.h +++ b/js/src/vm/MatchPairs.h @@ -30,24 +30,18 @@ struct MatchPair : start(-1), limit(-1) { } MatchPair(int32_t start, int32_t limit) : start(start), limit(limit) { } size_t length() const { MOZ_ASSERT(!isUndefined()); return limit - start; } - bool isEmpty() const { return length() == 0; } bool isUndefined() const { return start < 0; } - void displace(size_t amount) { - start += (start < 0) ? 0 : amount; - limit += (limit < 0) ? 0 : amount; - } - inline bool check() const { MOZ_ASSERT(limit >= start); MOZ_ASSERT_IF(start < 0, start == -1); MOZ_ASSERT_IF(limit < 0, limit == -1); return true; } }; @@ -58,17 +52,17 @@ class MatchPairs protected: /* Length of pairs_. */ uint32_t pairCount_; /* Raw pointer into an allocated MatchPair buffer. */ MatchPair* pairs_; protected: - /* Not used directly: use ScopedMatchPairs or VectorMatchPairs. */ + /* Not used directly: use VectorMatchPairs. */ MatchPairs() : pairCount_(0), pairs_(nullptr) { } protected: /* Functions used by friend classes. */ friend class RegExpShared; friend class RegExpStatics; @@ -86,17 +80,16 @@ class MatchPairs } #endif } public: /* Querying functions in the style of RegExpStatics. */ bool empty() const { return pairCount_ == 0; } size_t pairCount() const { MOZ_ASSERT(pairCount_ > 0); return pairCount_; } - size_t parenCount() const { return pairCount_ - 1; } static size_t offsetOfPairs() { return offsetof(MatchPairs, pairs_); } static size_t offsetOfPairCount() { return offsetof(MatchPairs, pairCount_); } int32_t* pairsRaw() { return reinterpret_cast<int32_t*>(pairs_); } public: size_t length() const { return pairCount_; }
--- a/js/src/vm/NumberObject.h +++ b/js/src/vm/NumberObject.h @@ -6,16 +6,18 @@ #ifndef vm_NumberObject_h #define vm_NumberObject_h #include "jsnum.h" namespace js { +class GlobalObject; + class NumberObject : public NativeObject { /* Stores this Number object's [[PrimitiveValue]]. */ static const unsigned PRIMITIVE_VALUE_SLOT = 0; public: static const unsigned RESERVED_SLOTS = 1; @@ -34,14 +36,14 @@ class NumberObject : public NativeObject private: inline void setPrimitiveValue(double d) { setFixedSlot(PRIMITIVE_VALUE_SLOT, NumberValue(d)); } /* For access to init, as Number.prototype is special. */ friend JSObject* - js::InitNumberClass(JSContext* cx, HandleObject global); + js::InitNumberClass(JSContext* cx, Handle<GlobalObject*> global); }; } // namespace js #endif /* vm_NumberObject_h */
--- a/js/src/vm/PIC.h +++ b/js/src/vm/PIC.h @@ -237,17 +237,17 @@ struct ForOfPIC }; // Class for object that holds ForOfPIC chain. static const Class class_; static NativeObject* createForOfPICObject(JSContext* cx, Handle<GlobalObject*> global); static inline Chain* fromJSObject(NativeObject* obj) { - MOZ_ASSERT(js::GetObjectClass(obj) == &ForOfPIC::class_); + MOZ_ASSERT(obj->getClass() == &ForOfPIC::class_); return (ForOfPIC::Chain*) obj->getPrivate(); } static inline Chain* getOrCreate(JSContext* cx) { NativeObject* obj = cx->global()->getForOfPICObject(); if (obj) return fromJSObject(obj); return create(cx); }
--- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -22,17 +22,16 @@ #include <setjmp.h> #include "builtin/AtomicsObject.h" #include "builtin/intl/SharedIntlData.h" #include "builtin/Promise.h" #include "frontend/NameCollections.h" #include "gc/GCRuntime.h" #include "gc/Tracer.h" -#include "gc/ZoneGroup.h" #include "irregexp/RegExpStack.h" #include "js/Debug.h" #include "js/GCVector.h" #include "js/HashTable.h" #ifdef DEBUG # include "js/Proxy.h" // For AutoEnterPolicy #endif #include "js/UniquePtr.h" @@ -107,21 +106,21 @@ class Simulator; // // Threads interacting with a runtime are divided into two categories: // // - The main thread is capable of running JS. There's at most one main thread // per runtime. // // - Helper threads do not run JS, and are controlled or triggered by activity // on the main thread (or main threads, since all runtimes in a process share -// helper threads). Helper threads may have exclusive access to zone groups -// created for them, for parsing and similar tasks, but their activities do -// not cause observable changes in script behaviors. Activity on helper -// threads may be referred to as happening 'off thread' or on a background -// thread in some parts of the VM. +// helper threads). Helper threads may have exclusive access to zones created +// for them, for parsing and similar tasks, but their activities do not cause +// observable changes in script behaviors. Activity on helper threads may be +// referred to as happening 'off thread' or on a background thread in some +// parts of the VM. } /* namespace js */ namespace JS { struct RuntimeSizes; } // namespace JS /* Various built-in or commonly-used names pinned on first context. */
--- a/js/src/vm/SavedStacks.cpp +++ b/js/src/vm/SavedStacks.cpp @@ -561,22 +561,17 @@ SavedFrame::create(JSContext* cx) // accidentally cause O(n^2) behavior. SavedStacks::AutoReentrancyGuard guard(cx->compartment()->savedStacks()); RootedNativeObject proto(cx, GlobalObject::getOrCreateSavedFramePrototype(cx, global)); if (!proto) return nullptr; assertSameCompartment(cx, proto); - RootedObject frameObj(cx, NewObjectWithGivenProto(cx, &SavedFrame::class_, proto, - TenuredObject)); - if (!frameObj) - return nullptr; - - return &frameObj->as<SavedFrame>(); + return NewObjectWithGivenProto<SavedFrame>(cx, proto, TenuredObject); } bool SavedFrame::isSelfHosted(JSContext* cx) { JSAtom* source = getSource(); return source == cx->names().selfHosted; }
--- a/js/src/vm/SavedStacks.h +++ b/js/src/vm/SavedStacks.h @@ -6,18 +6,16 @@ #ifndef vm_SavedStacks_h #define vm_SavedStacks_h #include "mozilla/Attributes.h" #include "mozilla/FastBernoulliTrial.h" #include "mozilla/Maybe.h" -#include "jsmath.h" - #include "js/HashTable.h" #include "js/Wrapper.h" #include "vm/JSContext.h" #include "vm/SavedFrame.h" #include "vm/Stack.h" namespace js {
--- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -3078,17 +3078,17 @@ CloneValue(JSContext* cx, HandleValue se JSString* clone = CloneString(cx, selfHostedString); if (!clone) return false; vp.setString(clone); } else if (selfHostedValue.isSymbol()) { // Well-known symbols are shared. mozilla::DebugOnly<JS::Symbol*> sym = selfHostedValue.toSymbol(); MOZ_ASSERT(sym->isWellKnownSymbol()); - MOZ_ASSERT(cx->wellKnownSymbols().get(size_t(sym->code())) == sym); + MOZ_ASSERT(cx->wellKnownSymbols().get(sym->code()) == sym); vp.set(selfHostedValue); } else { MOZ_CRASH("Self-hosting CloneValue can't clone given value."); } return true; } bool
--- a/js/src/vm/SharedArrayObject.h +++ b/js/src/vm/SharedArrayObject.h @@ -11,18 +11,16 @@ #include "jsapi.h" #include "jstypes.h" #include "gc/Barrier.h" #include "vm/ArrayBufferObject.h" #include "vm/JSObject.h" -typedef struct JSProperty JSProperty; - namespace js { class FutexWaiter; /* * SharedArrayRawBuffer * * A bookkeeping object always stored immediately before the raw buffer.
--- a/js/src/vm/StringObject-inl.h +++ b/js/src/vm/StringObject-inl.h @@ -27,20 +27,19 @@ StringObject::init(JSContext* cx, Handle obj->setStringThis(str); return true; } /* static */ inline StringObject* StringObject::create(JSContext* cx, HandleString str, HandleObject proto, NewObjectKind newKind) { - JSObject* obj = NewObjectWithClassProto(cx, &class_, proto, newKind); + Rooted<StringObject*> obj(cx, NewObjectWithClassProto<StringObject>(cx, proto, newKind)); if (!obj) return nullptr; - Rooted<StringObject*> strobj(cx, &obj->as<StringObject>()); - if (!StringObject::init(cx, strobj, str)) + if (!StringObject::init(cx, obj, str)) return nullptr; - return strobj; + return obj; } } // namespace js #endif /* vm_StringObject_inl_h */
--- a/js/src/vm/StringObject.h +++ b/js/src/vm/StringObject.h @@ -9,16 +9,18 @@ #include "builtin/String.h" #include "vm/JSObject.h" #include "vm/Shape.h" namespace js { +class GlobalObject; + class StringObject : public NativeObject { static const unsigned PRIMITIVE_VALUE_SLOT = 0; static const unsigned LENGTH_SLOT = 1; public: static const unsigned RESERVED_SLOTS = 2; @@ -61,14 +63,14 @@ class StringObject : public NativeObject void setStringThis(JSString* str) { MOZ_ASSERT(getReservedSlot(PRIMITIVE_VALUE_SLOT).isUndefined()); setFixedSlot(PRIMITIVE_VALUE_SLOT, StringValue(str)); setFixedSlot(LENGTH_SLOT, Int32Value(int32_t(str->length()))); } /* For access to init, as String.prototype is special. */ friend JSObject* - js::InitStringClass(JSContext* cx, HandleObject global); + js::InitStringClass(JSContext* cx, Handle<GlobalObject*> global); }; } // namespace js #endif /* vm_StringObject_h */
--- a/js/src/vm/TypeInference.cpp +++ b/js/src/vm/TypeInference.cpp @@ -2335,17 +2335,17 @@ Scalar::Type TemporaryTypeSet::getTypedArrayType(CompilerConstraintList* constraints, TypedArraySharedness* sharedness) { const Class* clasp = getKnownClass(constraints); if (clasp && IsTypedArrayClass(clasp)) { if (sharedness) getTypedArraySharedness(constraints, sharedness); - return (Scalar::Type) (clasp - &TypedArrayObject::classes[0]); + return GetTypedArrayClassType(clasp); } return Scalar::MaxTypedArrayViewType; } bool TemporaryTypeSet::isDOMClass(CompilerConstraintList* constraints, DOMObjectKind* kind) { if (unknownObject())
--- a/js/src/vm/TypeInference.h +++ b/js/src/vm/TypeInference.h @@ -1333,42 +1333,42 @@ class HeapTypeSetKey struct AutoEnterAnalysis; class TypeZone { JS::Zone* const zone_; /* Pool for type information in this zone. */ static const size_t TYPE_LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 8 * 1024; - ZoneGroupData<LifoAlloc> typeLifoAlloc_; + ZoneData<LifoAlloc> typeLifoAlloc_; // Under CodeGenerator::link, the id of the current compilation. - ZoneGroupData<mozilla::Maybe<IonCompilationId>> currentCompilationId_; + ZoneData<mozilla::Maybe<IonCompilationId>> currentCompilationId_; TypeZone(const TypeZone&) = delete; void operator=(const TypeZone&) = delete; public: // Current generation for sweeping. - ZoneGroupOrGCTaskOrIonCompileData<uint32_t> generation; + ZoneOrGCTaskOrIonCompileData<uint32_t> generation; // During incremental sweeping, allocator holding the old type information // for the zone. - ZoneGroupData<LifoAlloc> sweepTypeLifoAlloc; + ZoneData<LifoAlloc> sweepTypeLifoAlloc; // During incremental sweeping, whether to try to destroy all type // information attached to scripts. - ZoneGroupData<bool> sweepReleaseTypes; + ZoneData<bool> sweepReleaseTypes; - ZoneGroupData<bool> sweepingTypes; + ZoneData<bool> sweepingTypes; - ZoneGroupData<bool> keepTypeScripts; + ZoneData<bool> keepTypeScripts; // The topmost AutoEnterAnalysis on the stack, if there is one. - ZoneGroupData<AutoEnterAnalysis*> activeAnalysis; + ZoneData<AutoEnterAnalysis*> activeAnalysis; explicit TypeZone(JS::Zone* zone); ~TypeZone(); JS::Zone* zone() const { return zone_; } LifoAlloc& typeLifoAlloc() { #ifdef JS_CRASH_DIAGNOSTICS
--- a/js/src/vm/TypedArrayObject-inl.h +++ b/js/src/vm/TypedArrayObject-inl.h @@ -7,16 +7,17 @@ #ifndef vm_TypedArrayObject_inl_h #define vm_TypedArrayObject_inl_h /* Utilities and common inline code for TypedArray */ #include "vm/TypedArrayObject.h" #include "mozilla/Assertions.h" +#include "mozilla/Compiler.h" #include "mozilla/FloatingPoint.h" #include "mozilla/PodOperations.h" #include "jsnum.h" #include "builtin/Array.h" #include "gc/Zone.h" #include "jit/AtomicOperations.h" @@ -259,17 +260,17 @@ class ElementSpecific uint32_t count = source->length(); if (source->type() == target->type()) { Ops::podCopy(dest, source->viewDataEither().template cast<T*>(), count); return true; } // Inhibit unaligned accesses on ARM (bug 1097253, a compiler bug). -#if defined(__arm__) && defined(__GNUC__) && !defined(__clang__) +#if defined(__arm__) && MOZ_IS_GCC # define JS_VOLATILE_ARM volatile #else # define JS_VOLATILE_ARM #endif SharedMem<void*> data = Ops::extract(source); switch (source->type()) { case Scalar::Int8: {
--- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -336,17 +336,17 @@ class TypedArrayObjectTemplate : public createPrototype(JSContext* cx, JSProtoKey key) { Handle<GlobalObject*> global = cx->global(); RootedObject typedArrayProto(cx, GlobalObject::getOrCreateTypedArrayPrototype(cx, global)); if (!typedArrayProto) return nullptr; const Class* clasp = TypedArrayObject::protoClassForType(ArrayTypeID()); - return GlobalObject::createBlankPrototypeInheriting(cx, global, clasp, typedArrayProto); + return GlobalObject::createBlankPrototypeInheriting(cx, clasp, typedArrayProto); } static JSObject* createConstructor(JSContext* cx, JSProtoKey key) { Handle<GlobalObject*> global = cx->global(); RootedFunction ctorProto(cx, GlobalObject::getOrCreateTypedArrayConstructor(cx, global)); if (!ctorProto) @@ -398,17 +398,17 @@ class TypedArrayObjectTemplate : public } } static TypedArrayObject* makeProtoInstance(JSContext* cx, HandleObject proto, AllocKind allocKind) { MOZ_ASSERT(proto); - JSObject* obj = NewObjectWithClassProto(cx, instanceClass(), proto, allocKind); + JSObject* obj = NewObjectWithGivenProto(cx, instanceClass(), proto, allocKind); return obj ? &obj->as<TypedArrayObject>() : nullptr; } static TypedArrayObject* makeTypedInstance(JSContext* cx, CreateSingleton createSingleton, gc::AllocKind allocKind) { const Class* clasp = instanceClass(); if (createSingleton == CreateSingleton::Yes) { @@ -1400,47 +1400,22 @@ TypedArrayObject::GetTemplateObjectForNa return !!res; \ } \ } JS_FOR_EACH_TYPED_ARRAY(CHECK_TYPED_ARRAY_CONSTRUCTOR) #undef CHECK_TYPED_ARRAY_CONSTRUCTOR return true; } -/* - * These next 3 functions are brought to you by the buggy GCC we use to build - * B2G ICS. Older GCC versions have a bug in which they fail to compile - * reinterpret_casts of templated functions with the message: "insufficient - * contextual information to determine type". JS_PSG needs to - * reinterpret_cast<JSGetterOp>, so this causes problems for us here. - * - * We could restructure all this code to make this nicer, but since ICS isn't - * going to be around forever (and since this bug is fixed with the newer GCC - * versions we use on JB and KK), the workaround here is designed for ease of - * removal. When you stop seeing ICS Emulator builds on TBPL, remove these 3 - * JSNatives and insert the templated callee directly into the JS_PSG below. - */ static bool TypedArray_lengthGetter(JSContext* cx, unsigned argc, Value* vp) { return TypedArrayObject::Getter<TypedArrayObject::lengthValue>(cx, argc, vp); } -static bool -TypedArray_byteLengthGetter(JSContext* cx, unsigned argc, Value* vp) -{ - return TypedArrayObject::Getter<TypedArrayObject::byteLengthValue>(cx, argc, vp); -} - -static bool -TypedArray_byteOffsetGetter(JSContext* cx, unsigned argc, Value* vp) -{ - return TypedArrayObject::Getter<TypedArrayObject::byteOffsetValue>(cx, argc, vp); -} - bool BufferGetterImpl(JSContext* cx, const CallArgs& args) { MOZ_ASSERT(TypedArrayObject::is(args.thisv())); Rooted<TypedArrayObject*> tarray(cx, &args.thisv().toObject().as<TypedArrayObject>()); if (!TypedArrayObject::ensureHasBuffer(cx, tarray)) return false; args.rval().set(TypedArrayObject::bufferValue(tarray)); @@ -1453,18 +1428,18 @@ js::TypedArray_bufferGetter(JSContext* c CallArgs args = CallArgsFromVp(argc, vp); return CallNonGenericMethod<TypedArrayObject::is, BufferGetterImpl>(cx, args); } /* static */ const JSPropertySpec TypedArrayObject::protoAccessors[] = { JS_PSG("length", TypedArray_lengthGetter, 0), JS_PSG("buffer", TypedArray_bufferGetter, 0), - JS_PSG("byteLength", TypedArray_byteLengthGetter, 0), - JS_PSG("byteOffset", TypedArray_byteOffsetGetter, 0), + JS_PSG("byteLength", TypedArrayObject::Getter<TypedArrayObject::byteLengthValue>, 0), + JS_PSG("byteOffset", TypedArrayObject::Getter<TypedArrayObject::byteOffsetValue>, 0), JS_SELF_HOSTED_SYM_GET(toStringTag, "TypedArrayToStringTag", 0), JS_PS_END }; template<typename T> static inline bool SetFromTypedArray(Handle<TypedArrayObject*> target, Handle<TypedArrayObject*> source, uint32_t offset)
--- a/js/src/vm/TypedArrayObject.h +++ b/js/src/vm/TypedArrayObject.h @@ -21,22 +21,18 @@ macro(int16_t, Int16) \ macro(uint16_t, Uint16) \ macro(int32_t, Int32) \ macro(uint32_t, Uint32) \ macro(float, Float32) \ macro(double, Float64) \ macro(uint8_clamped, Uint8Clamped) -typedef struct JSProperty JSProperty; - namespace js { -enum class TypedArrayLength { Fixed, Dynamic }; - /* * TypedArrayObject * * The non-templated base class for the specific typed implementations. * This class holds all the member variables that are used by * the subclasses. */ @@ -309,29 +305,35 @@ TypedArrayCreateWithTemplate(JSContext* inline bool IsTypedArrayClass(const Class* clasp) { return &TypedArrayObject::classes[0] <= clasp && clasp < &TypedArrayObject::classes[Scalar::MaxTypedArrayViewType]; } +inline Scalar::Type +GetTypedArrayClassType(const Class* clasp) +{ + MOZ_ASSERT(IsTypedArrayClass(clasp)); + return static_cast<Scalar::Type>(clasp - &TypedArrayObject::classes[0]); +} + bool IsTypedArrayConstructor(HandleValue v, uint32_t type); // In WebIDL terminology, a BufferSource is either an ArrayBuffer or a typed // array view. In either case, extract the dataPointer/byteLength. bool IsBufferSource(JSObject* object, SharedMem<uint8_t*>* dataPointer, size_t* byteLength); inline Scalar::Type TypedArrayObject::type() const { - MOZ_ASSERT(IsTypedArrayClass(getClass())); - return static_cast<Scalar::Type>(getClass() - &classes[0]); + return GetTypedArrayClassType(getClass()); } inline size_t TypedArrayObject::bytesPerElement() const { return Scalar::byteSize(type()); }
--- a/js/src/wasm/WasmJS.cpp +++ b/js/src/wasm/WasmJS.cpp @@ -3123,21 +3123,20 @@ InitErrorClass(JSContext* cx, HandleObje return false; RootedId id(cx, AtomToId(className)); RootedValue ctorValue(cx, global->getConstructor(GetExceptionProtoKey(exn))); return DefineDataProperty(cx, wasm, id, ctorValue, 0); } JSObject* -js::InitWebAssemblyClass(JSContext* cx, HandleObject obj) +js::InitWebAssemblyClass(JSContext* cx, Handle<GlobalObject*> global) { MOZ_RELEASE_ASSERT(HasSupport(cx)); - Handle<GlobalObject*> global = obj.as<GlobalObject>(); MOZ_ASSERT(!global->isStandardClassResolved(JSProto_WebAssembly)); RootedObject proto(cx, GlobalObject::getOrCreateObjectPrototype(cx, global)); if (!proto) return nullptr; RootedObject wasm(cx, NewObjectWithGivenProto(cx, &WebAssemblyClass, proto, SingletonObject)); if (!wasm)
--- a/js/src/wasm/WasmJS.h +++ b/js/src/wasm/WasmJS.h @@ -20,16 +20,17 @@ #define wasm_js_h #include "gc/Policy.h" #include "vm/NativeObject.h" #include "wasm/WasmTypes.h" namespace js { +class GlobalObject; class TypedArrayObject; class WasmFunctionScope; class WasmInstanceScope; namespace wasm { // Return whether WebAssembly can be compiled on this platform. // This must be checked and must be true to call any of the top-level wasm @@ -85,17 +86,17 @@ IsSharedWasmMemoryObject(JSObject* obj); } // namespace wasm // The class of the WebAssembly global namespace object. extern const Class WebAssemblyClass; JSObject* -InitWebAssemblyClass(JSContext* cx, HandleObject global); +InitWebAssemblyClass(JSContext* cx, Handle<GlobalObject*> global); // The class of WebAssembly.Module. Each WasmModuleObject owns a // wasm::Module. These objects are used both as content-facing JS objects and as // internal implementation details of asm.js. class WasmModuleObject : public NativeObject { static const unsigned MODULE_SLOT = 0;
--- a/media/libaom/config/win/ia32/aom_config.h +++ b/media/libaom/config/win/ia32/aom_config.h @@ -5,17 +5,17 @@ /* was not distributed with this source code in the LICENSE file, you can */ /* obtain it at www.aomedia.org/license/software. If the Alliance for Open */ /* Media Patent License 1.0 was not distributed with this source code in the */ /* PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ /* This file automatically generated by configure. Do not edit! */ #ifndef AOM_CONFIG_H #define AOM_CONFIG_H #define RESTRICT -#define INLINE __inline +#define INLINE __forceinline #define ARCH_ARM 0 #define ARCH_MIPS 0 #define ARCH_X86 1 #define ARCH_X86_64 0 #define HAVE_NEON 0 #define HAVE_NEON_ASM 0 #define HAVE_MIPS32 0 #define HAVE_DSPR2 0
--- a/media/libaom/config/win/x64/aom_config.h +++ b/media/libaom/config/win/x64/aom_config.h @@ -5,17 +5,17 @@ /* was not distributed with this source code in the LICENSE file, you can */ /* obtain it at www.aomedia.org/license/software. If the Alliance for Open */ /* Media Patent License 1.0 was not distributed with this source code in the */ /* PATENTS file, you can obtain it at www.aomedia.org/license/patent. */ /* This file automatically generated by configure. Do not edit! */ #ifndef AOM_CONFIG_H #define AOM_CONFIG_H #define RESTRICT -#define INLINE __inline +#define INLINE __forceinline #define ARCH_ARM 0 #define ARCH_MIPS 0 #define ARCH_X86 0 #define ARCH_X86_64 1 #define HAVE_NEON 0 #define HAVE_NEON_ASM 0 #define HAVE_MIPS32 0 #define HAVE_DSPR2 0
--- a/media/libvpx/config/win/x64/vpx_config.h +++ b/media/libvpx/config/win/x64/vpx_config.h @@ -4,17 +4,17 @@ /* that can be found in the LICENSE file in the root of the source */ /* tree. An additional intellectual property rights grant can be found */ /* in the file PATENTS. All contributing project authors may */ /* be found in the AUTHORS file in the root of the source tree. */ /* This file automatically generated by configure. Do not edit! */ #ifndef VPX_CONFIG_H #define VPX_CONFIG_H #define RESTRICT -#define INLINE __inline +#define INLINE __forceinline #define ARCH_ARM 0 #define ARCH_MIPS 0 #define ARCH_X86 0 #define ARCH_X86_64 1 #define HAVE_NEON 0 #define HAVE_NEON_ASM 0 #define HAVE_MIPS32 0 #define HAVE_DSPR2 0
--- a/media/libvpx/libvpx/configure +++ b/media/libvpx/libvpx/configure @@ -639,17 +639,17 @@ process_toolchain() { case "$tgt_cc" in vs*) enable_feature msvs enable_feature solution vs_version=${tgt_cc##vs} VCPROJ_SFX=vcxproj gen_vcproj_cmd=${source_path}/build/make/gen_msvs_vcxproj.sh enabled werror && gen_vcproj_cmd="${gen_vcproj_cmd} --enable-werror" all_targets="${all_targets} solution" - INLINE="__inline" + INLINE="__forceinline" ;; esac # Other toolchain specific defaults case $toolchain in x86*) soft_enable postproc;; esac if enabled postproc_visualizer; then enabled postproc || die "postproc_visualizer requires postproc to be enabled"
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TestRunnerActivity.java +++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TestRunnerActivity.java @@ -105,20 +105,22 @@ public class TestRunnerActivity extends @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final Intent intent = getIntent(); if (sRuntime == null) { - final GeckoRuntimeSettings geckoSettings = new GeckoRuntimeSettings(); - geckoSettings.setArguments(new String[] { "-purgecaches" }); - geckoSettings.setExtras(intent.getExtras()); - sRuntime = GeckoRuntime.create(this, geckoSettings); + final GeckoRuntimeSettings.Builder runtimeSettingsBuilder = + new GeckoRuntimeSettings.Builder(); + runtimeSettingsBuilder.arguments(new String[] { "-purgecaches" }) + .extras(intent.getExtras()); + + sRuntime = GeckoRuntime.create(this, runtimeSettingsBuilder.build()); sRuntime.setDelegate(new GeckoRuntime.Delegate() { @Override public void onShutdown() { mKillProcessOnDestroy = true; finish(); } }); }
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java +++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java @@ -722,21 +722,23 @@ public class GeckoSessionTestRule extend } }; final Class<?>[] classes = CALLBACK_CLASSES.toArray(new Class<?>[CALLBACK_CLASSES.size()]); mCallbackProxy = Proxy.newProxyInstance(GeckoSession.class.getClassLoader(), classes, recorder); if (sRuntime == null) { - final GeckoRuntimeSettings geckoSettings = new GeckoRuntimeSettings(); - geckoSettings.setArguments(new String[] { "-purgecaches" }); + final GeckoRuntimeSettings.Builder runtimeSettingsBuilder = + new GeckoRuntimeSettings.Builder(); + runtimeSettingsBuilder.arguments(new String[] { "-purgecaches" }); + sRuntime = GeckoRuntime.create( InstrumentationRegistry.getTargetContext(), - geckoSettings); + runtimeSettingsBuilder.build()); } mMainSession = new GeckoSession(settings); prepareSession(mMainSession); if (mDisplaySize != null) { mDisplayTexture = new SurfaceTexture(0); mDisplaySurface = new Surface(mDisplayTexture);
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java @@ -11,16 +11,17 @@ import android.os.Parcelable; import android.content.Context; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.Log; import org.mozilla.gecko.EventDispatcher; import org.mozilla.gecko.GeckoAppShell; import org.mozilla.gecko.GeckoThread; +import org.mozilla.gecko.PrefsHelper; import org.mozilla.gecko.util.BundleEventListener; import org.mozilla.gecko.util.EventCallback; import org.mozilla.gecko.util.GeckoBundle; public final class GeckoRuntime implements Parcelable { private static final String LOGTAG = "GeckoRuntime"; private static final boolean DEBUG = false; @@ -90,16 +91,19 @@ public final class GeckoRuntime implemen if (!GeckoThread.launch()) { Log.d(LOGTAG, "init failed (GeckoThread already launched)"); return false; } mSettings = settings; // Bug 1453062 -- the EventDispatcher should really live here (or in GeckoThread) EventDispatcher.getInstance().registerUiThreadListener(mEventListener, "Gecko:Exited"); + + mSettings.runtime = this; + mSettings.flush(); return true; } Log.d(LOGTAG, "init failed (could not initiate GeckoThread)"); return false; } /** * Create a new runtime with default settings and attach it to the given @@ -177,16 +181,24 @@ public final class GeckoRuntime implemen * Returns the current delegate, if any. * * @return an instance of {@link GeckoRuntime.Delegate} or null if no delegate has been set. */ public @Nullable Delegate getDelegate() { return mDelegate; } + public GeckoRuntimeSettings getSettings() { + return mSettings; + } + + /* package */ void setPref(final String name, final Object value) { + PrefsHelper.setPref(name, value, /* flush */ false); + } + @Override // Parcelable public int describeContents() { return 0; } @Override // Parcelable public void writeToParcel(Parcel out, int flags) { out.writeParcelable(mSettings, flags);
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java @@ -8,35 +8,158 @@ package org.mozilla.geckoview; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.annotation.Nullable; public final class GeckoRuntimeSettings implements Parcelable { - private boolean mUseContentProcess; - private String[] mArgs; - private Bundle mExtras; + /** + * Settings builder used to construct the settings object. + */ + public static final class Builder { + private final GeckoRuntimeSettings mSettings; + + public Builder() { + mSettings = new GeckoRuntimeSettings(); + } + + public Builder(final GeckoRuntimeSettings settings) { + mSettings = new GeckoRuntimeSettings(settings); + } + + /** + * Finalize and return the settings. + * + * @return The constructed settings. + */ + public @NonNull GeckoRuntimeSettings build() { + return new GeckoRuntimeSettings(mSettings); + } + + /** + * Set the content process hint flag. + * + * @param use If true, this will reload the content process for future use. + */ + public @NonNull Builder useContentProcessHint(final boolean use) { + mSettings.mUseContentProcess = use; + return this; + } + + /** + * Set the custom Gecko process arguments. + * + * @param args The Gecko process arguments. + */ + public @NonNull Builder arguments(final @NonNull String[] args) { + mSettings.mArgs = args; + return this; + } + + /** + * Set the custom Gecko intent extras. + * + * @param extras The Gecko intent extras. + */ + public @NonNull Builder extras(final @NonNull Bundle extras) { + mSettings.mExtras = extras; + return this; + } - /** - * Initialize default settings. - */ - public GeckoRuntimeSettings() { + /** + * Set whether JavaScript support should be enabled. + * + * @param flag A flag determining whether JavaScript should be enabled. + */ + public @NonNull Builder javaScriptEnabled(final boolean flag) { + mSettings.mJavaScript.set(flag); + return this; + } + + /** + * Set whether support for web fonts should be enabled. + * + * @param flag A flag determining whether web fonts should be enabled. + */ + public @NonNull Builder webFontsEnabled(final boolean flag) { + mSettings.mWebFonts.set(flag); + return this; + } + } + + /* package */ GeckoRuntime runtime; + /* package */ boolean mUseContentProcess; + /* package */ String[] mArgs; + /* package */ Bundle mExtras; + /* package */ int prefCount; + + private class Pref<T> { + public final String name; + public final T defaultValue; + private T value; + + public Pref(final String name, final T defaultValue) { + GeckoRuntimeSettings.this.prefCount++; + + this.name = name; + this.defaultValue = defaultValue; + value = defaultValue; + } + + public void set(T newValue) { + value = newValue; + flush(); + } + + public T get() { + return value; + } + + public void flush() { + if (GeckoRuntimeSettings.this.runtime != null) { + GeckoRuntimeSettings.this.runtime.setPref(name, value); + } + } + } + + /* package */ Pref<Boolean> mJavaScript = new Pref<Boolean>( + "javascript.enabled", true); + /* package */ Pref<Boolean> mWebFonts = new Pref<Boolean>( + "browser.display.use_document_fonts", true); + + private final Pref<?>[] mPrefs = new Pref<?>[] { + mJavaScript, mWebFonts + }; + + /* package */ GeckoRuntimeSettings() { this(null); } /* package */ GeckoRuntimeSettings(final @Nullable GeckoRuntimeSettings settings) { - if (settings != null) { - mUseContentProcess = settings.mUseContentProcess; - mArgs = settings.mArgs.clone(); - mExtras = new Bundle(settings.mExtras); - } else { + if (BuildConfig.DEBUG && prefCount != mPrefs.length) { + throw new AssertionError("Add new pref to prefs list"); + } + + if (settings == null) { mArgs = new String[0]; mExtras = new Bundle(); + } else { + mUseContentProcess = settings.getUseContentProcessHint(); + mArgs = settings.getArguments().clone(); + mExtras = new Bundle(settings.getExtras()); + mJavaScript.set(settings.mJavaScript.get()); + mWebFonts.set(settings.mWebFonts.get()); + } + } + + /* package */ void flush() { + for (final Pref<?> pref: mPrefs) { + pref.flush(); } } /** * Get the content process hint flag. * * @return The content process hint flag. */ @@ -58,59 +181,74 @@ public final class GeckoRuntimeSettings * * @return The Gecko intent extras. */ public Bundle getExtras() { return mExtras; } /** - * Set the content process hint flag. + * Get whether JavaScript support is enabled. * - * @param use If true, this will reload the content process for future use. + * @return Whether JavaScript support is enabled. */ - public void setUseContentProcessHint(boolean use) { - mUseContentProcess = use; + public boolean getJavaScriptEnabled() { + return mJavaScript.get(); } /** - * Set the custom Gecko process arguments. + * Set whether JavaScript support should be enabled. * - * @param args The Gecko process arguments. + * @param flag A flag determining whether JavaScript should be enabled. */ - public void setArguments(final @NonNull String[] args) { - mArgs = args; + public @NonNull GeckoRuntimeSettings setJavaScriptEnabled(final boolean flag) { + mJavaScript.set(flag); + return this; } /** - * Set the custom Gecko intent extras. + * Get whether web fonts support is enabled. * - * @param extras The Gecko intent extras. + * @return Whether web fonts support is enabled. */ - public void setExtras(final @NonNull Bundle extras) { - mExtras = extras; + public boolean getWebFontsEnabled() { + return mWebFonts.get(); + } + + /** + * Set whether support for web fonts should be enabled. + * + * @param flag A flag determining whether web fonts should be enabled. + */ + public @NonNull GeckoRuntimeSettings setWebFontsEnabled(final boolean flag) { + mWebFonts.set(flag); + return this; } @Override // Parcelable public int describeContents() { return 0; } @Override // Parcelable public void writeToParcel(Parcel out, int flags) { out.writeByte((byte) (mUseContentProcess ? 1 : 0)); out.writeStringArray(mArgs); mExtras.writeToParcel(out, flags); + out.writeByte((byte) (mJavaScript.get() ? 1 : 0)); + out.writeByte((byte) (mWebFonts.get() ? 1 : 0)); } // AIDL code may call readFromParcel even though it's not part of Parcelable. public void readFromParcel(final Parcel source) { mUseContentProcess = source.readByte() == 1; mArgs = source.createStringArray(); mExtras.readFromParcel(source); + mJavaScript.set(source.readByte() == 1); + mWebFonts.set(source.readByte() == 1); } public static final Parcelable.Creator<GeckoRuntimeSettings> CREATOR = new Parcelable.Creator<GeckoRuntimeSettings>() { @Override public GeckoRuntimeSettings createFromParcel(final Parcel in) { final GeckoRuntimeSettings settings = new GeckoRuntimeSettings(); settings.readFromParcel(in);
--- a/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java +++ b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java @@ -49,27 +49,28 @@ public class GeckoViewActivity extends A setContentView(R.layout.geckoview_activity); mGeckoView = (GeckoView) findViewById(R.id.gecko_view); final boolean useMultiprocess = getIntent().getBooleanExtra(USE_MULTIPROCESS_EXTRA, true); if (sGeckoRuntime == null) { - final GeckoRuntimeSettings geckoSettings = new GeckoRuntimeSettings(); + final GeckoRuntimeSettings.Builder runtimeSettingsBuilder = + new GeckoRuntimeSettings.Builder(); if (BuildConfig.DEBUG) { // In debug builds, we want to load JavaScript resources fresh with // each build. - geckoSettings.setArguments(new String[] { "-purgecaches" }); + runtimeSettingsBuilder.arguments(new String[] { "-purgecaches" }); } - geckoSettings.setUseContentProcessHint(useMultiprocess); - geckoSettings.setExtras(getIntent().getExtras()); - sGeckoRuntime = GeckoRuntime.create(this, geckoSettings); + runtimeSettingsBuilder.useContentProcessHint(useMultiprocess) + .extras(getIntent().getExtras()); + sGeckoRuntime = GeckoRuntime.create(this, runtimeSettingsBuilder.build()); } final GeckoSessionSettings sessionSettings = new GeckoSessionSettings(); sessionSettings.setBoolean(GeckoSessionSettings.USE_MULTIPROCESS, useMultiprocess); mGeckoSession = new GeckoSession(sessionSettings); mGeckoView.setSession(mGeckoSession, sGeckoRuntime);
--- a/third_party/aom/configure +++ b/third_party/aom/configure @@ -887,17 +887,17 @@ process_toolchain() { case "$tgt_cc" in vs*) enable_feature msvs enable_feature solution vs_version=${tgt_cc##vs} VCPROJ_SFX=vcxproj gen_vcproj_cmd=${source_path}/build/make/gen_msvs_vcxproj.sh enabled werror && gen_vcproj_cmd="${gen_vcproj_cmd} --enable-werror" all_targets="${all_targets} solution" - INLINE="__inline" + INLINE="__forceinline" ;; esac # Other toolchain specific defaults case $toolchain in x86*) soft_enable postproc;; esac if enabled postproc_visualizer; then enabled postproc || die "postproc_visualizer requires postproc to be enabled"
--- a/toolkit/components/ctypes/tests/jsctypes-test-finalizer.cpp +++ b/toolkit/components/ctypes/tests/jsctypes-test-finalizer.cpp @@ -1,9 +1,10 @@ #include "errno.h" +#include "string.h" #include "jsctypes-test.h" #include "jsctypes-test-finalizer.h" /** * Shared infrastructure */
--- a/xpcom/threads/Scheduler.cpp +++ b/xpcom/threads/Scheduler.cpp @@ -680,17 +680,16 @@ SchedulerImpl::ThreadController::OnStart xpc::CreateCooperativeContext(); JSContext* cx = dom::danger::GetJSContext(); mScheduler->SetJSContext(aIndex, cx); if (sPrefPreemption) { JS_AddInterruptCallback(cx, SchedulerImpl::InterruptCallback); } - js::SetCooperativeYieldCallback(cx, SchedulerImpl::YieldCallback); Servo_InitializeCooperativeThread(); } void SchedulerImpl::ThreadController::OnStopThread(size_t aIndex) { xpc::DestroyCooperativeContext();