Merge inbound to mozilla-central. a=merge

This commit is contained in:
shindli 2018-03-30 12:56:21 +03:00
commit 3bfd0c07fd
47 changed files with 918 additions and 812 deletions

View File

@ -6,9 +6,10 @@ include $(topsrcdir)/config/rules.mk
# run the binscope tool to make sure the binary and all libraries
# are using all available Windows OS-level security mechanisms
# Don't do this in clang-cl since it doesn't support debug information yet.
ifndef CLANG_CL
# XXX this should use a better way of checking all our binaries
check::
$(PYTHON) $(srcdir)/autobinscope.py $(DIST)/bin/$(MOZ_APP_NAME)$(BIN_SUFFIX) $(DIST)/crashreporter-symbols/
$(PYTHON) $(srcdir)/autobinscope.py $(DIST)/bin/plugin-container.exe $(DIST)/crashreporter-symbols/
endif
$(PYTHON) $(srcdir)/autobinscope.py $(DIST)/bin/mozglue.dll $(DIST)/crashreporter-symbols/
$(PYTHON) $(srcdir)/autobinscope.py $(DIST)/bin/xul.dll $(DIST)/crashreporter-symbols/
$(PYTHON) $(srcdir)/autobinscope.py $(DIST)/bin/nss3.dll $(DIST)/crashreporter-symbols/

View File

@ -4,14 +4,10 @@
# 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/.
# run Microsoft's Binscope tool (http://www.microsoft.com/download/en/details.aspx?id=11910)
# run Microsoft's Binscope tool (https://www.microsoft.com/en-us/download/details.aspx?id=44995)
# against a fresh Windows build. output a 'binscope.log' file with full details
# of the run and appropriate strings to integrate with the buildbots
# from the docs : "The error code returned when running under the command line is equal
# to the number of failures the tool reported plus the number of errors. BinScope will return
# 0 only if there are no errors or failures."
# the symbol dir should point to the symbol dir hierarchy created
# via running make buildsymbols in a windows build's objdir
@ -40,36 +36,62 @@ else:
try:
binscope_path = os.environ['BINSCOPE']
except KeyError:
print "BINSCOPE environment variable is not set, can't check DEP/ASLR etc. status."
print "TEST-UNEXPECTED-FAIL | autobinscope.py | BINSCOPE environment variable is not set, can't check DEP/ASLR etc. status."
sys.exit(0)
try:
proc = subprocess.Popen([binscope_path, "/target", binary_path,
"/output", log_file_path, "/sympath", symbol_path,
"/c", "ATLVersionCheck", "/c", "ATLVulnCheck", "/c", "SharedSectionCheck", "/c", "APTCACheck", "/c", "NXCheck",
"/c", "GSCheck", "/c", "GSFriendlyInitCheck",
"/c", "CompilerVersionCheck", "/c", "SafeSEHCheck", "/c", "SNCheck",
"/c", "DBCheck"], stdout=subprocess.PIPE)
proc = subprocess.Popen([
binscope_path,
"/NoLogo",
"/Target", binary_path,
"/SymPath", symbol_path,
"/Checks", "ATLVersionCheck",
"/Checks", "ATLVulnCheck",
# We do not ship in the Windows Store
"/SkippedChecks", "AppContainerCheck",
# The CompilerVersionCheck doesn't like clang-cl (we would need to set MinimumCompilerVersion)
# But we check the compiler in our build system anyway, so this doesn't seem useful
"/SkippedChecks", "CompilerVersionCheck",
"/Checks", "DBCheck",
"/Checks", "DefaultGSCookieCheck",
"/Checks", "ExecutableImportsCheck",
# FunctonPointersCheck is disabled per bug 1014002
"/SkippedChecks", "FunctionPointersCheck",
# GSCheck doesn't know how to deal with Rust libs
"/SkippedChecks", "GSCheck",
"/Checks", "GSFriendlyInitCheck",
# We are not safebuffers-clean, bug 1449951
"/SkippedChecks", "GSFunctionSafeBuffersCheck",
"/Checks", "HighEntropyVACheck",
"/Checks", "NXCheck",
"/Checks", "RSA32Check",
"/Checks", "SafeSEHCheck",
"/Checks", "SharedSectionCheck",
"/Checks", "VB6Check",
"/Checks", "WXCheck"
], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except WindowsError, (errno, strerror):
if errno != 2 and errno != 3:
print "Unexpected error ! \nError " + str(errno) + " : " + strerror + "\nExiting !\n"
print "TEST-UNEXPECTED-FAIL | autobinscope.py | Unexpected error %d : %s" (errno, strerror)
sys.exit(0)
else:
print "Could not locate binscope at location : %s\n" % binscope_path
print "Binscope wasn't installed or the BINSCOPE env variable wasn't set correctly, skipping this check and exiting..."
print "TEST-UNEXPECTED-FAIL | autobinscope.py | Could not locate binscope at location : %s\n" % binscope_path
sys.exit(0)
proc.wait()
output = proc.communicate()[0]
output = proc.communicate()[1].decode('utf-8').splitlines()
errors = 0
for line in output:
print(line)
if 'error' in line:
errors += 1
# is this a PASS or a FAIL ?
if proc.returncode != 0:
print "Error count: %d" % proc.returncode
print "TEST-UNEXPECTED-FAIL | autobinscope.py | %s is missing a needed Windows protection, such as /GS or ASLR" % binary_path
logfile = open(log_file_path, "r")
for line in logfile:
print(line),
print "TEST-UNEXPECTED-FAIL | autobinscope.py | Binscope returned error code %d for file %s" % (proc.returncode, binary_path)
elif errors != 0:
print "TEST-UNEXPECTED-FAIL | autobinscope.py | Binscope reported %d error(s) for file %s" % (errors, binary_path)
else:
print "TEST-PASS | autobinscope.py | %s succeeded" % binary_path

View File

@ -1212,12 +1212,6 @@ nsScriptSecurityManager::CanCreateWrapper(JSContext *cx,
{
// XXX Special case for Exception ?
uint32_t flags;
if (aClassInfo && NS_SUCCEEDED(aClassInfo->GetFlags(&flags)) &&
(flags & nsIClassInfo::DOM_OBJECT)) {
return NS_OK;
}
// We give remote-XUL whitelisted domains a free pass here. See bug 932906.
JS::Rooted<JS::Realm*> contextRealm(cx, JS::GetCurrentRealmOrNull(cx));
MOZ_RELEASE_ASSERT(contextRealm);

View File

@ -1,9 +1,9 @@
This is the debugger.html project output.
See https://github.com/devtools-html/debugger.html
Version 30.0
Version 31.0
Comparison: https://github.com/devtools-html/debugger.html/compare/release-29...release-30
Comparison: https://github.com/devtools-html/debugger.html/compare/release-30...release-31
Packages:
- babel-plugin-transform-es2015-modules-commonjs @6.26.0

View File

@ -2893,6 +2893,7 @@ const dispatcher = new WorkerDispatcher();
const getOriginalURLs = dispatcher.task("getOriginalURLs");
const getGeneratedLocation = dispatcher.task("getGeneratedLocation");
const getAllGeneratedLocations = dispatcher.task("getAllGeneratedLocations");
const getOriginalLocation = dispatcher.task("getOriginalLocation");
const getLocationScopes = dispatcher.task("getLocationScopes");
const getOriginalSourceText = dispatcher.task("getOriginalSourceText");
@ -2908,6 +2909,7 @@ module.exports = {
hasMappedSource,
getOriginalURLs,
getGeneratedLocation,
getAllGeneratedLocations,
getOriginalLocation,
getLocationScopes,
getOriginalSourceText,
@ -3624,7 +3626,7 @@ function updateSource(state, source) {
return state;
}
const existingSource = state.getIn(["sources", source.id]);
const existingSource = state.sources.get(source.id);
if (existingSource) {
const updatedSource = existingSource.merge(source);
@ -4901,7 +4903,7 @@ function getSymbols(state, source) {
return null;
}
return state.ast.getIn(["symbols", source.id]) || null;
return state.ast.symbols.get(source.id) || null;
}
function hasSymbols(state, source) {
@ -4933,11 +4935,11 @@ function getEmptyLines(state, source) {
return null;
}
return state.ast.getIn(["emptyLines", source.id]);
return state.ast.emptyLines.get(source.id);
}
function getPausePoints(state, sourceId) {
return state.ast.getIn(["pausePoints", sourceId]);
return state.ast.pausePoints.get(sourceId);
}
function hasPausePoints(state, sourceId) {
@ -4955,7 +4957,7 @@ function getPreview(state) {
const emptySourceMetaData = {};
function getSourceMetaData(state, sourceId) {
return state.ast.getIn(["sourceMetaData", sourceId]) || emptySourceMetaData;
return state.ast.sourceMetaData.get(sourceId) || emptySourceMetaData;
}
function hasSourceMetaData(state, sourceId) {
@ -5304,6 +5306,7 @@ function trimUrlQuery(url) {
const contentMap = {
"js": "text/javascript",
"jsm": "text/javascript",
"mjs": "text/javascript",
"ts": "text/typescript",
"tsx": "text/typescript-jsx",
"jsx": "text/jsx",
@ -6350,14 +6353,14 @@ function evaluateExpression(expression) {
const frame = (0, _selectors.getSelectedFrame)(getState());
if (frame) {
const { location, generatedLocation } = frame;
const { location } = frame;
const source = (0, _selectors.getSource)(getState(), location.sourceId);
const sourceId = source.get("id");
const selectedSource = (0, _selectors.getSelectedSource)(getState());
if (selectedSource && !(0, _devtoolsSourceMap.isGeneratedId)(sourceId) && !(0, _devtoolsSourceMap.isGeneratedId)(selectedSource.get("id"))) {
input = await getMappedExpression({ getState, sourceMaps }, generatedLocation, input);
input = await dispatch(getMappedExpression(input));
}
}
@ -6375,13 +6378,18 @@ function evaluateExpression(expression) {
* Gets information about original variable names from the source map
* and replaces all posible generated names.
*/
async function getMappedExpression({ getState, sourceMaps }, generatedLocation, expression) {
const mappings = (0, _selectors.getSelectedScopeMappings)(getState());
if (!mappings) {
return expression;
}
function getMappedExpression(expression) {
return async function ({ dispatch, getState, client, sourceMaps }) {
const mappings = (0, _selectors.getSelectedScopeMappings)(getState());
if (!mappings) {
return expression;
}
return await parser.mapOriginalExpression(expression, mappings);
return await dispatch({
type: "MAP_EXPRESSION_RESULT",
[_promise.PROMISE]: parser.mapOriginalExpression(expression, mappings)
});
};
}
/***/ }),
@ -7821,20 +7829,20 @@ function update(state = createExpressionState(), action) {
if (action.expressionError) {
return state.set("expressionError", !!action.expressionError);
}
return appendToList(state, ["expressions"], {
return appendExpressionToList(state, {
input: action.input,
value: null,
updating: true
});
case "UPDATE_EXPRESSION":
const key = action.expression.input;
return updateItemInList(state, ["expressions"], key, {
return updateExpressionInList(state, key, {
input: action.input,
value: null,
updating: true
}).set("expressionError", !!action.expressionError);
case "EVALUATE_EXPRESSION":
return updateItemInList(state, ["expressions"], action.input, {
return updateExpressionInList(state, action.input, {
input: action.input,
value: action.value,
updating: false
@ -7859,7 +7867,7 @@ function travelTo(state, action) {
if (!expressions) {
return state;
}
return expressions.reduce((finalState, previousState) => updateItemInList(finalState, ["expressions"], previousState.input, {
return expressions.reduce((finalState, previousState) => updateExpressionInList(finalState, previousState.input, {
input: previousState.input,
value: previousState.value,
updating: false
@ -7874,26 +7882,26 @@ function restoreExpressions() {
return exprs;
}
function storeExpressions(state) {
const expressions = state.getIn(["expressions"]).map(expression => (0, _lodash.omit)(expression, "value")).toJS();
_prefs.prefs.expressions = expressions;
function storeExpressions({ expressions }) {
_prefs.prefs.expressions = expressions.map(expression => (0, _lodash.omit)(expression, "value")).toJS();
}
function appendToList(state, path, value) {
const newState = state.updateIn(path, () => {
return state.getIn(path).push(value);
function appendExpressionToList(state, value) {
const newState = state.update("expressions", () => {
return state.expressions.push(value);
});
storeExpressions(newState);
return newState;
}
function updateItemInList(state, path, key, value) {
const newState = state.updateIn(path, () => {
const list = state.getIn(path);
function updateExpressionInList(state, key, value) {
const newState = state.update("expressions", () => {
const list = state.expressions;
const index = list.findIndex(e => e.input == key);
return list.update(index, () => value);
});
storeExpressions(newState);
return newState;
}
@ -7907,13 +7915,13 @@ function deleteExpression(state, input) {
const getExpressionsWrapper = state => state.expressions;
const getExpressions = exports.getExpressions = (0, _reselect.createSelector)(getExpressionsWrapper, expressions => expressions.get("expressions"));
const getExpressions = exports.getExpressions = (0, _reselect.createSelector)(getExpressionsWrapper, expressions => expressions.expressions);
function getExpression(state, input) {
return getExpressions(state).find(exp => exp.input == input);
}
const getExpressionError = exports.getExpressionError = (0, _reselect.createSelector)(getExpressionsWrapper, expressions => expressions.get("expressionError"));
const getExpressionError = exports.getExpressionError = (0, _reselect.createSelector)(getExpressionsWrapper, expressions => expressions.expressionError);
exports.default = update;
@ -8118,7 +8126,7 @@ function removeBreakpoint(state, action) {
const { breakpoint } = action;
const locationId = (0, _breakpoint.makePendingLocationId)(breakpoint.location);
const pendingBp = state.getIn(["pendingBreakpoints", locationId]);
const pendingBp = state.pendingBreakpoints.get(locationId);
if (!pendingBp && action.status == "start") {
return state.set("pendingBreakpoints", I.Map());
@ -8444,7 +8452,7 @@ function update(state = createFileSearchState(), action) {
case "TOGGLE_FILE_SEARCH_MODIFIER":
{
const actionVal = !state.getIn(["modifiers", action.modifier]);
const actionVal = !state.modifiers[action.modifier];
if (action.modifier == "caseSensitive") {
_prefs.prefs.fileSearchCaseSensitive = actionVal;
@ -8471,15 +8479,15 @@ function update(state = createFileSearchState(), action) {
// NOTE: we'd like to have the app state fully typed
// https://github.com/devtools-html/debugger.html/blob/master/src/reducers/sources.js#L179-L185
function getFileSearchQuery(state) {
return state.fileSearch.get("query");
return state.fileSearch.query;
}
function getFileSearchModifiers(state) {
return state.fileSearch.get("modifiers");
return state.fileSearch.modifiers;
}
function getFileSearchResults(state) {
return state.fileSearch.get("searchResults");
return state.fileSearch.searchResults;
}
exports.default = update;
@ -10047,6 +10055,10 @@ ResultList.defaultProps = {
var _initialiseProps = function () {
this.renderListItem = (item, index) => {
if (item.value === "/" && item.title === "") {
item.title = "(index)";
}
const { selectItem, selected } = this.props;
const props = {
onClick: event => selectItem(event, item, index),
@ -25018,7 +25030,7 @@ class Tabs extends _react.PureComponent {
super(props);
this.renderDropdownSource = source => {
const { selectSource } = this.props;
const { selectSpecificSource } = this.props;
const filename = (0, _source.getFilename)(source.toJS());
const onClick = () => selectSpecificSource(source.id);
@ -30231,11 +30243,6 @@ function createLocation({
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /* 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/>. */
exports.getExtra = getExtra;
exports.updatePreview = updatePreview;
exports.setPreview = setPreview;
@ -30265,7 +30272,9 @@ async function getReactProps(evaluate) {
return {
displayName: reactDisplayName.result
};
}
} /* 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/>. */
async function getImmutableProps(expression, evaluate) {
const immutableEntries = await evaluate((exp => `${exp}.toJS()`)(expression));
@ -30383,9 +30392,7 @@ function setPreview(expression, location, tokenPos, cursorPos) {
const sourceId = source.get("id");
if (location && !(0, _devtoolsSourceMap.isGeneratedId)(sourceId)) {
const generatedLocation = await sourceMaps.getGeneratedLocation(_extends({}, location.start, { sourceId }), source.toJS());
expression = await (0, _expressions.getMappedExpression)({ sourceMaps, getState }, generatedLocation, expression);
expression = await dispatch((0, _expressions.getMappedExpression)(expression));
}
const selectedFrame = (0, _selectors.getSelectedFrame)(getState());
@ -31533,6 +31540,8 @@ var _extends = Object.assign || function (target) { for (var i = 1; i < argument
exports.selectSourceURL = selectSourceURL;
exports.selectSource = selectSource;
exports.selectLocation = selectLocation;
exports.selectSpecificLocation = selectSpecificLocation;
exports.selectSpecificSource = selectSpecificSource;
exports.jumpToMappedLocation = jumpToMappedLocation;
exports.jumpToMappedSelectedLocation = jumpToMappedSelectedLocation;
@ -31613,8 +31622,8 @@ function selectLocation(location) {
return;
}
const source = (0, _selectors.getSource)(getState(), location.sourceId);
if (!source) {
const sourceRecord = (0, _selectors.getSource)(getState(), location.sourceId);
if (!sourceRecord) {
// If there is no source we deselect the current selected source
return dispatch({ type: "CLEAR_SELECTED_SOURCE" });
}
@ -31624,21 +31633,23 @@ function selectLocation(location) {
dispatch((0, _ui.closeActiveSearch)());
}
dispatch((0, _tabs.addTab)(source.toJS(), 0));
const source = sourceRecord.toJS();
dispatch((0, _tabs.addTab)(source, 0));
dispatch({
type: "SELECT_SOURCE",
source: source.toJS(),
source,
location
});
await dispatch((0, _loadSourceText.loadSourceText)(source));
await dispatch((0, _loadSourceText.loadSourceText)(sourceRecord));
const selectedSource = (0, _selectors.getSelectedSource)(getState());
if (!selectedSource) {
return;
}
const sourceId = selectedSource.get("id");
const sourceId = selectedSource.id;
if (_prefs.prefs.autoPrettyPrint && !(0, _selectors.getPrettySource)(getState(), sourceId) && (0, _source.shouldPrettyPrint)(selectedSource) && (0, _source.isMinified)(selectedSource)) {
await dispatch((0, _prettyPrint.togglePrettyPrint)(sourceId));
dispatch((0, _tabs.closeTab)(source.url));
@ -31649,6 +31660,61 @@ function selectLocation(location) {
};
}
/**
* @memberof actions/sources
* @static
*/
function selectSpecificLocation(location) {
return async ({ dispatch, getState, client }) => {
if (!client) {
// No connection, do nothing. This happens when the debugger is
// shut down too fast and it tries to display a default source.
return;
}
const sourceRecord = (0, _selectors.getSource)(getState(), location.sourceId);
if (!sourceRecord) {
// If there is no source we deselect the current selected source
return dispatch({ type: "CLEAR_SELECTED_SOURCE" });
}
const activeSearch = (0, _selectors.getActiveSearch)(getState());
if (activeSearch !== "file") {
dispatch((0, _ui.closeActiveSearch)());
}
const source = sourceRecord.toJS();
dispatch((0, _tabs.addTab)(source, 0));
dispatch({
type: "SELECT_SOURCE",
source,
location
});
await dispatch((0, _loadSourceText.loadSourceText)(sourceRecord));
const selectedSource = (0, _selectors.getSelectedSource)(getState());
if (!selectedSource) {
return;
}
const sourceId = selectedSource.id;
dispatch((0, _ast.setSymbols)(sourceId));
dispatch((0, _ast.setOutOfScopeLocations)());
};
}
/**
* @memberof actions/sources
* @static
*/
function selectSpecificSource(sourceId) {
return async ({ dispatch }) => {
const location = (0, _location.createLocation)({ sourceId });
return await dispatch(selectSpecificLocation(location));
};
}
/**
* @memberof actions/sources
* @static
@ -33692,7 +33758,7 @@ class Tab extends _react.PureComponent {
render() {
const {
selectedSource,
selectSource,
selectSpecificSource,
closeTab,
source,
sourceMetaData
@ -33718,7 +33784,7 @@ class Tab extends _react.PureComponent {
return closeTab(source.url);
}
return selectSource(sourceId);
return selectSpecificSource(sourceId);
}
const className = (0, _classnames2.default)("source-tab", {
@ -33860,8 +33926,6 @@ var _extends = Object.assign || function (target) { for (var i = 1; i < argument
exports.setupHelper = setupHelper;
var _redux = __webpack_require__(3593);
var _timings = __webpack_require__(1657);
var timings = _interopRequireWildcard(_timings);
@ -33917,10 +33981,8 @@ function _formatPausePoints(dbg, url) {
function setupHelper(obj) {
const selectors = bindSelectors(obj);
const actions = (0, _redux.bindActionCreators)(obj.actions, obj.store.dispatch);
const dbg = _extends({}, obj, {
selectors,
actions,
prefs: _prefs.prefs,
features: _prefs.features,
timings,

View File

@ -116,6 +116,10 @@ DebuggerPanel.prototype = {
return { frames, selected };
},
getMappedExpression(expression) {
return this._actions.getMappedExpression(expression);
},
isPaused() {
return this._selectors.isPaused(this._getState());
},

View File

@ -784,6 +784,7 @@ const dispatcher = new WorkerDispatcher();
const getOriginalURLs = dispatcher.task("getOriginalURLs");
const getGeneratedLocation = dispatcher.task("getGeneratedLocation");
const getAllGeneratedLocations = dispatcher.task("getAllGeneratedLocations");
const getOriginalLocation = dispatcher.task("getOriginalLocation");
const getLocationScopes = dispatcher.task("getLocationScopes");
const getOriginalSourceText = dispatcher.task("getOriginalSourceText");
@ -799,6 +800,7 @@ module.exports = {
hasMappedSource,
getOriginalURLs,
getGeneratedLocation,
getAllGeneratedLocations,
getOriginalLocation,
getLocationScopes,
getOriginalSourceText,
@ -1160,6 +1162,7 @@ function trimUrlQuery(url) {
const contentMap = {
"js": "text/javascript",
"jsm": "text/javascript",
"mjs": "text/javascript",
"ts": "text/typescript",
"tsx": "text/typescript-jsx",
"jsx": "text/jsx",
@ -21286,6 +21289,8 @@ function getFirstExpression(ast) {
}
function mapOriginalExpression(expression, mappings) {
let didReplace = false;
const ast = (0, _ast.parseScript)(expression);
t.traverse(ast, (node, ancestors) => {
const parent = ancestors[ancestors.length - 1];
@ -21297,16 +21302,23 @@ function mapOriginalExpression(expression, mappings) {
if (t.isIdentifier(node) && t.isReferenced(node, parentNode)) {
if (mappings.hasOwnProperty(node.name)) {
const mapping = mappings[node.name];
if (mapping) {
if (mapping && mapping !== node.name) {
const mappingNode = getFirstExpression((0, _ast.parseScript)(mapping));
replaceNode(ancestors, mappingNode);
didReplace = true;
}
}
}
});
return (0, _generator2.default)(ast, { concise: true }).code;
if (!didReplace) {
// Avoid the extra code generation work and also avoid potentially
// reformatting the user's code unnecessarily.
return expression;
}
return (0, _generator2.default)(ast).code;
}
/***/ }),

View File

@ -85,19 +85,19 @@ add_task(async function() {
{
line: 5,
column: 7,
expression: "doThing;",
expression: "doThing",
result: "doThing(arg)",
},
{
line: 5,
column: 12,
expression: "x;",
expression: "x",
result: "1",
},
{
line: 8,
column: 16,
expression: "doThing;",
expression: "doThing",
result: "doThing(arg)",
},
]);
@ -110,7 +110,7 @@ add_task(async function() {
{
line: 2,
column: 9,
expression: "aVar;",
expression: "aVar",
result: '"var3"',
},
{
@ -128,7 +128,7 @@ add_task(async function() {
{
line: 10,
column: 11,
expression: "aVar;",
expression: "aVar",
result: '"var3"',
},
{
@ -148,7 +148,7 @@ add_task(async function() {
{
line: 14,
column: 13,
expression: "aVar;",
expression: "aVar",
result: '"var3"',
},
{
@ -193,7 +193,7 @@ add_task(async function() {
{
line: 26,
column: 16,
expression: "aNamespace;",
expression: "aNamespace",
fields: [
['aNamed', 'a-named'],
['default', 'a-default'],
@ -226,7 +226,7 @@ add_task(async function() {
{
line: 35,
column: 20,
expression: "aNamespace2;",
expression: "aNamespace2",
fields: [
['aNamed', 'a-named2'],
['default', 'a-default2'],

View File

@ -1011,7 +1011,6 @@ public:
void Disable(GLenum cap) { SetEnabled("disabled", cap, false); }
void Enable(GLenum cap) { SetEnabled("enabled", cap, true); }
bool GetStencilBits(GLint* const out_stencilBits) const;
bool GetChannelBits(const char* funcName, GLenum pname, GLint* const out_val);
virtual JS::Value GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv);
void GetParameter(JSContext* cx, GLenum pname,

View File

@ -74,87 +74,6 @@ WebGLContext::GetStencilBits(GLint* const out_stencilBits) const
return true;
}
bool
WebGLContext::GetChannelBits(const char* funcName, GLenum pname, GLint* const out_val)
{
if (mBoundDrawFramebuffer) {
if (!mBoundDrawFramebuffer->ValidateAndInitAttachments(funcName))
return false;
}
if (!mBoundDrawFramebuffer) {
switch (pname) {
case LOCAL_GL_RED_BITS:
case LOCAL_GL_GREEN_BITS:
case LOCAL_GL_BLUE_BITS:
*out_val = 8;
break;
case LOCAL_GL_ALPHA_BITS:
*out_val = (mOptions.alpha ? 8 : 0);
break;
case LOCAL_GL_DEPTH_BITS:
*out_val = (mOptions.depth ? 24 : 0);
break;
case LOCAL_GL_STENCIL_BITS:
*out_val = (mOptions.stencil ? 8 : 0);
break;
default:
MOZ_CRASH("GFX: bad pname");
}
return true;
}
if (!gl->IsCoreProfile()) {
gl->fGetIntegerv(pname, out_val);
return true;
}
GLenum fbAttachment = 0;
GLenum fbPName = 0;
switch (pname) {
case LOCAL_GL_RED_BITS:
fbAttachment = LOCAL_GL_COLOR_ATTACHMENT0;
fbPName = LOCAL_GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE;
break;
case LOCAL_GL_GREEN_BITS:
fbAttachment = LOCAL_GL_COLOR_ATTACHMENT0;
fbPName = LOCAL_GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE;
break;
case LOCAL_GL_BLUE_BITS:
fbAttachment = LOCAL_GL_COLOR_ATTACHMENT0;
fbPName = LOCAL_GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE;
break;
case LOCAL_GL_ALPHA_BITS:
fbAttachment = LOCAL_GL_COLOR_ATTACHMENT0;
fbPName = LOCAL_GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE;
break;
case LOCAL_GL_DEPTH_BITS:
fbAttachment = LOCAL_GL_DEPTH_ATTACHMENT;
fbPName = LOCAL_GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE;
break;
case LOCAL_GL_STENCIL_BITS:
fbAttachment = LOCAL_GL_STENCIL_ATTACHMENT;
fbPName = LOCAL_GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE;
break;
default:
MOZ_CRASH("GFX: bad pname");
}
gl->fGetFramebufferAttachmentParameteriv(LOCAL_GL_DRAW_FRAMEBUFFER, fbAttachment,
fbPName, out_val);
return true;
}
JS::Value
WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
{
@ -397,12 +316,72 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
case LOCAL_GL_ALPHA_BITS:
case LOCAL_GL_DEPTH_BITS:
case LOCAL_GL_STENCIL_BITS: {
// Deprecated and removed in GL Core profiles, so special handling required.
GLint val;
if (!GetChannelBits(funcName, pname, &val))
return JS::NullValue();
const auto format = [&]() -> const webgl::FormatInfo* {
if (mBoundDrawFramebuffer) {
const auto& fb = *mBoundDrawFramebuffer;
const auto& attachment = [&]() -> const auto& {
switch (pname) {
case LOCAL_GL_DEPTH_BITS:
return fb.AnyDepthAttachment();
return JS::Int32Value(val);
case LOCAL_GL_STENCIL_BITS:
return fb.AnyStencilAttachment();
default:
return fb.ColorAttachment0();
}
}();
if (!attachment.HasImage())
return nullptr;
return attachment.Format()->format;
}
auto effFormat = webgl::EffectiveFormat::RGB8;
switch (pname) {
case LOCAL_GL_DEPTH_BITS:
if (mOptions.depth) {
effFormat = webgl::EffectiveFormat::DEPTH24_STENCIL8;
}
break;
case LOCAL_GL_STENCIL_BITS:
if (mOptions.stencil) {
effFormat = webgl::EffectiveFormat::DEPTH24_STENCIL8;
}
break;
default:
if (mOptions.alpha) {
effFormat = webgl::EffectiveFormat::RGBA8;
}
break;
}
return webgl::GetFormat(effFormat);
}();
int32_t ret = 0;
if (format) {
switch (pname) {
case LOCAL_GL_RED_BITS:
ret = format->r;
break;
case LOCAL_GL_GREEN_BITS:
ret = format->g;
break;
case LOCAL_GL_BLUE_BITS:
ret = format->b;
break;
case LOCAL_GL_ALPHA_BITS:
ret = format->a;
break;
case LOCAL_GL_DEPTH_BITS:
ret = format->d;
break;
case LOCAL_GL_STENCIL_BITS:
ret = format->s;
break;
}
}
return JS::Int32Value(ret);
}
case LOCAL_GL_MAX_TEXTURE_SIZE:

View File

@ -38,7 +38,7 @@ public:
WebGLFramebuffer* const mFB;
const GLenum mAttachmentPoint;
protected:
private:
WebGLRefPtr<WebGLTexture> mTexturePtr;
WebGLRefPtr<WebGLRenderbuffer> mRenderbufferPtr;
TexImageTarget mTexImageTarget;
@ -49,6 +49,7 @@ protected:
WebGLFBAttachPoint();
WebGLFBAttachPoint(WebGLFramebuffer* fb, GLenum attachmentPoint);
explicit WebGLFBAttachPoint(WebGLFBAttachPoint&) = default; // Make this private.
public:
~WebGLFBAttachPoint();
@ -258,6 +259,22 @@ public:
#undef GETTER
const auto& ColorAttachment0() const {
return mColorAttachments[0];
}
const auto& AnyDepthAttachment() const {
if (mDepthStencilAttachment.IsDefined())
return mDepthStencilAttachment;
return mDepthAttachment;
}
const auto& AnyStencilAttachment() const {
if (mDepthStencilAttachment.IsDefined())
return mDepthStencilAttachment;
return mStencilAttachment;
}
////////////////
// Invalidation

View File

@ -226,6 +226,15 @@ function test() {
elem.value = "";
elem.blur();
}
function chromeListener(e) {
ok(false, "Picker should not be opened when dispatching untrusted click.");
}
SpecialPowers.addChromeEventListener("MozOpenDateTimePicker",
chromeListener);
input.click();
SpecialPowers.removeChromeEventListener("MozOpenDateTimePicker",
chromeListener);
}
</script>

View File

@ -62,7 +62,7 @@ interface nsIPaymentDetails : nsISupports
readonly attribute nsIArray modifiers;
readonly attribute AString error;
void update(in nsIPaymentDetails aDetails);
void update(in nsIPaymentDetails aDetails, in boolean aRequestShipping);
};
[scriptable, builtinclass, uuid(d53f9f20-138e-47cc-9fd5-db16a3f6d301)]

View File

@ -475,7 +475,7 @@ PaymentDetails::GetError(nsAString& aError)
}
NS_IMETHODIMP
PaymentDetails::Update(nsIPaymentDetails* aDetails)
PaymentDetails::Update(nsIPaymentDetails* aDetails, const bool aRequestShipping)
{
MOZ_ASSERT(aDetails);
/*
@ -501,12 +501,12 @@ PaymentDetails::Update(nsIPaymentDetails* aDetails)
mDisplayItems = displayItems;
}
nsCOMPtr<nsIArray> shippingOptions;
rv = aDetails->GetShippingOptions(getter_AddRefs(shippingOptions));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (shippingOptions) {
if (aRequestShipping) {
nsCOMPtr<nsIArray> shippingOptions;
rv = aDetails->GetShippingOptions(getter_AddRefs(shippingOptions));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mShippingOptions = shippingOptions;
}
@ -678,7 +678,12 @@ NS_IMETHODIMP
PaymentRequest::UpdatePaymentDetails(nsIPaymentDetails* aPaymentDetails)
{
MOZ_ASSERT(aPaymentDetails);
return mPaymentDetails->Update(aPaymentDetails);
bool requestShipping;
nsresult rv = mPaymentOptions->GetRequestShipping(&requestShipping);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return mPaymentDetails->Update(aPaymentDetails, requestShipping);
}
NS_IMETHODIMP

View File

@ -0,0 +1,80 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
const paymentSrv = Cc["@mozilla.org/dom/payments/payment-request-service;1"].getService(Ci.nsIPaymentRequestService);
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
const TestingUIService = {
showPayment: function(requestId) {
paymentSrv.changeShippingAddress(requestId, shippingAddress);
},
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));
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentUIService]),
};
addMessageListener("set-checking-shipping-options-ui-service", function() {
paymentSrv.setTestingUIService(TestingUIService.QueryInterface(Ci.nsIPaymentUIService));
});
addMessageListener("teardown", function() {
paymentSrv.cleanup();
paymentSrv.setTestingUIService(null);
sendAsyncMessage('teardown-complete');
});

View File

@ -6,6 +6,7 @@ support-files =
simple_payment_request.html
echo_payment_request.html
BasiccardChromeScript.js
Bug1443914ChromeScript.js
ConstructorChromeScript.js
CurrencyAmountValidationChromeScript.js
GeneralChromeScript.js
@ -18,6 +19,7 @@ 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]

View File

@ -0,0 +1,140 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1443914
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1443914</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">
"use strict";
SimpleTest.waitForExplicitFinish();
var gUrl = SimpleTest.getTestFileURL('Bug1443914ChromeScript.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'],
},
}, {
supportedMethods: "testing-payment-method",
}];
const defaultDetails = {
id: "test payment",
total: {
label: "Total",
amount: {
currency: "USD",
value: "1.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"
};
const updateDetails = {
total: {
label: "Total",
amount: {
currency: "USD",
value: "1.00"
}
},
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(() => {
resolve();
}).catch(error => {
ok(false, "Unexpected error: " + error.name);
resolve();
});
}).catch(error => {
ok(false, "Unexpected error: " + error.name);
resolve();
}).finally(handler.destruct);
});
}
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()
.then(teardown)
.catch( e => {
ok(false, "Unexpected error: " + e.name);
SimpleTest.finish();
});
}
window.addEventListener('load', function() {
SpecialPowers.pushPrefEnv({
'set': [
['dom.payments.request.enabled', true],
]
}, runTests);
});
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1443914">Mozilla Bug 1443914</a>
</body>
</html>

View File

@ -9,7 +9,7 @@
<body>
<!-- try to load an image which is forbidden by meta CSP -->
<img id="testimage" src="http://mochi.test:8888/tests/image/test/mochitest/blue.png"></img>
<img id="testimage"></img>
<script type="application/javascript">
var myImg = document.getElementById("testimage");
@ -19,6 +19,8 @@
myImg.onerror = function(e) {
window.parent.postMessage({result: "img-blocked"}, "*");
};
//Image should be tried to load only after onload/onerror event declaration.
myImg.src = "http://mochi.test:8888/tests/image/test/mochitest/blue.png";
</script>
</body>

View File

@ -264,6 +264,7 @@ bool
IpcResourceUpdateQueue::AddBlobImage(ImageKey key, const ImageDescriptor& aDescriptor,
Range<uint8_t> aBytes)
{
MOZ_RELEASE_ASSERT(aDescriptor.width > 0 && aDescriptor.height > 0);
auto bytes = mWriter.Write(aBytes);
if (!bytes.length()) {
return false;

View File

@ -18,12 +18,7 @@
using namespace mozilla;
// standard font descriptors that we construct the first time they're needed
CTFontDescriptorRef gfxCoreTextShaper::sDefaultFeaturesDescriptor = nullptr;
CTFontDescriptorRef gfxCoreTextShaper::sSmallCapsDescriptor = nullptr;
CTFontDescriptorRef gfxCoreTextShaper::sDisableLigaturesDescriptor = nullptr;
CTFontDescriptorRef gfxCoreTextShaper::sSmallCapDisableLigDescriptor = nullptr;
CTFontDescriptorRef gfxCoreTextShaper::sIndicFeaturesDescriptor = nullptr;
CTFontDescriptorRef gfxCoreTextShaper::sIndicDisableLigaturesDescriptor = nullptr;
CTFontDescriptorRef gfxCoreTextShaper::sFeaturesDescriptor[kMaxFontInstances];
// Helper to create a CFDictionary with the right attributes for shaping our
// text, including imposing the given directionality.
@ -45,7 +40,7 @@ gfxCoreTextShaper::CreateAttrDict(bool aRightToLeft)
&kCFTypeArrayCallBacks);
::CFRelease(dirNumber);
CFTypeRef attrs[] = { kCTFontAttributeName, kCTWritingDirectionAttributeName };
CFTypeRef values[] = { mCTFont, dirArray };
CFTypeRef values[] = { mCTFont[0], dirArray };
CFDictionaryRef attrDict =
::CFDictionaryCreate(kCFAllocatorDefault,
attrs, values, ArrayLength(attrs),
@ -60,9 +55,13 @@ gfxCoreTextShaper::gfxCoreTextShaper(gfxMacFont *aFont)
, mAttributesDictLTR(nullptr)
, mAttributesDictRTL(nullptr)
{
// Create our CTFontRef
mCTFont = CreateCTFontWithFeatures(aFont->GetAdjustedSize(),
GetDefaultFeaturesDescriptor());
for (size_t i = 0; i < kMaxFontInstances; i++) {
mCTFont[i] = nullptr;
}
// Create our default CTFontRef
mCTFont[0] =
CreateCTFontWithFeatures(aFont->GetAdjustedSize(),
GetFeaturesDescriptor(kDefaultFeatures));
}
gfxCoreTextShaper::~gfxCoreTextShaper()
@ -73,8 +72,10 @@ gfxCoreTextShaper::~gfxCoreTextShaper()
if (mAttributesDictRTL) {
::CFRelease(mAttributesDictRTL);
}
if (mCTFont) {
::CFRelease(mCTFont);
for (size_t i = 0; i < kMaxFontInstances; i++) {
if (mCTFont[i]) {
::CFRelease(mCTFont[i]);
}
}
}
@ -135,7 +136,7 @@ gfxCoreTextShaper::ShapeText(DrawTarget *aDrawTarget,
(isRightToLeft ? mAttributesDictRTL : mAttributesDictLTR) = attrObj;
}
CTFontRef tempCTFont = nullptr;
FeatureFlags featureFlags = kDefaultFeatures;
if (IsBuggyIndicScript(aScript)) {
// To work around buggy Indic AAT fonts shipped with OS X,
// we re-enable the Line Initial Smart Swashes feature that is needed
@ -143,36 +144,30 @@ gfxCoreTextShaper::ShapeText(DrawTarget *aDrawTarget,
// Affected fonts include Bangla MN, Bangla Sangam MN, Kannada MN,
// Kannada Sangam MN. See bugs 686225, 728557, 953231, 1145515.
// Also applies to Oriya and Khmer, see bug 1370927 and bug 1403166.
tempCTFont =
CreateCTFontWithFeatures(::CTFontGetSize(mCTFont),
aShapedText->DisableLigatures()
? GetIndicDisableLigaturesDescriptor()
: GetIndicFeaturesDescriptor());
} else if (aShapedText->DisableLigatures()) {
featureFlags |= kIndicFeatures;
}
if (aShapedText->DisableLigatures()) {
// For letterspacing (or maybe other situations) we need to make
// a copy of the CTFont with the ligature feature disabled.
tempCTFont =
CreateCTFontWithFeatures(::CTFontGetSize(mCTFont),
addSmallCaps
? GetSmallCapDisableLigDescriptor()
: GetDisableLigaturesDescriptor());
} else if (addSmallCaps) {
tempCTFont =
CreateCTFontWithFeatures(::CTFontGetSize(mCTFont),
GetSmallCapsDescriptor());
featureFlags |= kDisableLigatures;
}
if (addSmallCaps) {
featureFlags |= kAddSmallCaps;
}
// For the disabled-ligature, buggy-indic-font or small-caps case, replace
// the standard CTFont in the attribute dictionary with a tweaked version.
// the default CTFont in the attribute dictionary with a tweaked version.
CFMutableDictionaryRef mutableAttr = nullptr;
if (tempCTFont) {
mutableAttr = ::CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 2,
attrObj);
if (featureFlags != 0) {
if (!mCTFont[featureFlags]) {
mCTFont[featureFlags] =
CreateCTFontWithFeatures(mFont->GetAdjustedSize(),
GetFeaturesDescriptor(featureFlags));
}
mutableAttr =
::CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 2, attrObj);
::CFDictionaryReplaceValue(mutableAttr,
kCTFontAttributeName, tempCTFont);
// Having created the dict, we're finished with our temporary
// Indic and/or ligature-disabled or small-caps CTFontRef.
::CFRelease(tempCTFont);
kCTFontAttributeName, mCTFont[featureFlags]);
attrObj = mutableAttr;
}
@ -577,7 +572,7 @@ gfxCoreTextShaper::SetGlyphsFromRun(gfxShapedText *aShapedText,
CTFontDescriptorRef
gfxCoreTextShaper::CreateFontFeaturesDescriptor(
const std::pair<SInt16,SInt16> aFeatures[],
const std::pair<SInt16,SInt16>* aFeatures,
size_t aCount)
{
MOZ_ASSERT(aCount <= MAX_FEATURES);
@ -637,110 +632,34 @@ gfxCoreTextShaper::CreateFontFeaturesDescriptor(
}
CTFontDescriptorRef
gfxCoreTextShaper::GetDefaultFeaturesDescriptor()
gfxCoreTextShaper::GetFeaturesDescriptor(FeatureFlags aFeatureFlags)
{
if (sDefaultFeaturesDescriptor == nullptr) {
const std::pair<SInt16,SInt16> kDefaultFeatures[] = {
{ kSmartSwashType, kLineInitialSwashesOffSelector },
{ kSmartSwashType, kLineFinalSwashesOffSelector }
};
static_assert(ArrayLength(kDefaultFeatures) <= MAX_FEATURES,
"need to increase MAX_FEATURES");
sDefaultFeaturesDescriptor =
CreateFontFeaturesDescriptor(kDefaultFeatures,
ArrayLength(kDefaultFeatures));
MOZ_ASSERT(aFeatureFlags < kMaxFontInstances);
if (!sFeaturesDescriptor[aFeatureFlags]) {
typedef std::pair<SInt16,SInt16> FeatT;
AutoTArray<FeatT,MAX_FEATURES> features;
features.AppendElement(FeatT(kSmartSwashType,
kLineFinalSwashesOffSelector));
if ((aFeatureFlags & kIndicFeatures) == 0) {
features.AppendElement(FeatT(kSmartSwashType,
kLineInitialSwashesOffSelector));
}
if (aFeatureFlags & kAddSmallCaps) {
features.AppendElement(FeatT(kLetterCaseType,
kSmallCapsSelector));
features.AppendElement(FeatT(kLowerCaseType,
kLowerCaseSmallCapsSelector));
}
if (aFeatureFlags & kDisableLigatures) {
features.AppendElement(FeatT(kLigaturesType,
kCommonLigaturesOffSelector));
}
MOZ_ASSERT(features.Length() <= MAX_FEATURES);
sFeaturesDescriptor[aFeatureFlags] =
CreateFontFeaturesDescriptor(features.Elements(),
features.Length());
}
return sDefaultFeaturesDescriptor;
}
CTFontDescriptorRef
gfxCoreTextShaper::GetSmallCapsDescriptor()
{
if (sSmallCapsDescriptor == nullptr) {
const std::pair<SInt16,SInt16> kSmallCaps[] = {
{ kSmartSwashType, kLineInitialSwashesOffSelector },
{ kSmartSwashType, kLineFinalSwashesOffSelector },
{ kLetterCaseType, kSmallCapsSelector },
{ kLowerCaseType, kLowerCaseSmallCapsSelector }
};
static_assert(ArrayLength(kSmallCaps) <= MAX_FEATURES,
"need to increase MAX_FEATURES");
sSmallCapsDescriptor =
CreateFontFeaturesDescriptor(kSmallCaps,
ArrayLength(kSmallCaps));
}
return sSmallCapsDescriptor;
}
CTFontDescriptorRef
gfxCoreTextShaper::GetDisableLigaturesDescriptor()
{
if (sDisableLigaturesDescriptor == nullptr) {
const std::pair<SInt16,SInt16> kDisableLigatures[] = {
{ kSmartSwashType, kLineInitialSwashesOffSelector },
{ kSmartSwashType, kLineFinalSwashesOffSelector },
{ kLigaturesType, kCommonLigaturesOffSelector }
};
static_assert(ArrayLength(kDisableLigatures) <= MAX_FEATURES,
"need to increase MAX_FEATURES");
sDisableLigaturesDescriptor =
CreateFontFeaturesDescriptor(kDisableLigatures,
ArrayLength(kDisableLigatures));
}
return sDisableLigaturesDescriptor;
}
CTFontDescriptorRef
gfxCoreTextShaper::GetSmallCapDisableLigDescriptor()
{
if (sSmallCapDisableLigDescriptor == nullptr) {
const std::pair<SInt16,SInt16> kFeatures[] = {
{ kSmartSwashType, kLineInitialSwashesOffSelector },
{ kSmartSwashType, kLineFinalSwashesOffSelector },
{ kLigaturesType, kCommonLigaturesOffSelector },
{ kLetterCaseType, kSmallCapsSelector },
{ kLowerCaseType, kLowerCaseSmallCapsSelector }
};
static_assert(ArrayLength(kFeatures) <= MAX_FEATURES,
"need to increase MAX_FEATURES");
sSmallCapDisableLigDescriptor =
CreateFontFeaturesDescriptor(kFeatures,
ArrayLength(kFeatures));
}
return sSmallCapDisableLigDescriptor;
}
CTFontDescriptorRef
gfxCoreTextShaper::GetIndicFeaturesDescriptor()
{
if (sIndicFeaturesDescriptor == nullptr) {
const std::pair<SInt16,SInt16> kIndicFeatures[] = {
{ kSmartSwashType, kLineFinalSwashesOffSelector }
};
static_assert(ArrayLength(kIndicFeatures) <= MAX_FEATURES,
"need to increase MAX_FEATURES");
sIndicFeaturesDescriptor =
CreateFontFeaturesDescriptor(kIndicFeatures,
ArrayLength(kIndicFeatures));
}
return sIndicFeaturesDescriptor;
}
CTFontDescriptorRef
gfxCoreTextShaper::GetIndicDisableLigaturesDescriptor()
{
if (sIndicDisableLigaturesDescriptor == nullptr) {
const std::pair<SInt16,SInt16> kIndicDisableLigatures[] = {
{ kSmartSwashType, kLineFinalSwashesOffSelector },
{ kLigaturesType, kCommonLigaturesOffSelector }
};
static_assert(ArrayLength(kIndicDisableLigatures) <= MAX_FEATURES,
"need to increase MAX_FEATURES");
sIndicDisableLigaturesDescriptor =
CreateFontFeaturesDescriptor(kIndicDisableLigatures,
ArrayLength(kIndicDisableLigatures));
}
return sIndicDisableLigaturesDescriptor;
return sFeaturesDescriptor[aFeatureFlags];
}
CTFontRef
@ -755,20 +674,10 @@ gfxCoreTextShaper::CreateCTFontWithFeatures(CGFloat aSize,
void
gfxCoreTextShaper::Shutdown() // [static]
{
if (sIndicDisableLigaturesDescriptor != nullptr) {
::CFRelease(sIndicDisableLigaturesDescriptor);
sIndicDisableLigaturesDescriptor = nullptr;
}
if (sIndicFeaturesDescriptor != nullptr) {
::CFRelease(sIndicFeaturesDescriptor);
sIndicFeaturesDescriptor = nullptr;
}
if (sDisableLigaturesDescriptor != nullptr) {
::CFRelease(sDisableLigaturesDescriptor);
sDisableLigaturesDescriptor = nullptr;
}
if (sDefaultFeaturesDescriptor != nullptr) {
::CFRelease(sDefaultFeaturesDescriptor);
sDefaultFeaturesDescriptor = nullptr;
for (size_t i = 0; i < kMaxFontInstances; i++) {
if (sFeaturesDescriptor[i] != nullptr) {
::CFRelease(sFeaturesDescriptor[i]);
sFeaturesDescriptor[i] = nullptr;
}
}
}

View File

@ -30,8 +30,23 @@ public:
// clean up static objects that may have been cached
static void Shutdown();
// Flags used to track what AAT features should be enabled on the Core Text
// font instance. (Internal; only public so that we can use the
// MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS macro below.)
enum FeatureFlags : uint8_t {
kDefaultFeatures = 0x00,
// bit flags for non-default feature settings we might need
// to use, which will require separate font instances
kDisableLigatures = 0x01,
kAddSmallCaps = 0x02,
kIndicFeatures = 0x04,
// number of font instances, indexed by OR-ing the flags above
kMaxFontInstances = 8
};
protected:
CTFontRef mCTFont;
CTFontRef mCTFont[kMaxFontInstances];
// attributes for shaping text with LTR or RTL directionality
CFDictionaryRef mAttributesDictLTR;
@ -49,27 +64,15 @@ protected:
CFDictionaryRef CreateAttrDictWithoutDirection();
static CTFontDescriptorRef
CreateFontFeaturesDescriptor(const std::pair<SInt16,SInt16> aFeatures[],
CreateFontFeaturesDescriptor(const std::pair<SInt16,SInt16>* aFeatures,
size_t aCount);
static CTFontDescriptorRef GetDefaultFeaturesDescriptor();
static CTFontDescriptorRef GetSmallCapsDescriptor();
static CTFontDescriptorRef GetDisableLigaturesDescriptor();
static CTFontDescriptorRef GetSmallCapDisableLigDescriptor();
static CTFontDescriptorRef GetIndicFeaturesDescriptor();
static CTFontDescriptorRef GetIndicDisableLigaturesDescriptor();
static CTFontDescriptorRef GetFeaturesDescriptor(FeatureFlags aFeatureFlags);
// cached font descriptor, created the first time it's needed
static CTFontDescriptorRef sDefaultFeaturesDescriptor;
static CTFontDescriptorRef sSmallCapsDescriptor;
// cached descriptor for adding disable-ligatures setting to a font
static CTFontDescriptorRef sDisableLigaturesDescriptor;
static CTFontDescriptorRef sSmallCapDisableLigDescriptor;
// feature descriptors for buggy Indic AAT font workaround
static CTFontDescriptorRef sIndicFeaturesDescriptor;
static CTFontDescriptorRef sIndicDisableLigaturesDescriptor;
// cached font descriptors, created the first time they're needed
static CTFontDescriptorRef sFeaturesDescriptor[kMaxFontInstances];
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(gfxCoreTextShaper::FeatureFlags)
#endif /* GFX_CORETEXTSHAPER_H */

View File

@ -21,7 +21,7 @@
#include "base/singleton.h"
#include "mozilla/ipc/Faulty.h"
#endif
#if (!defined(RELEASE_OR_BETA) && !defined(FUZZING)) || defined(DEBUG)
#if !defined(FUZZING) && (!defined(RELEASE_OR_BETA) || defined(DEBUG))
#define MOZ_PICKLE_SENTINEL_CHECKING
#endif
class Pickle;

View File

@ -15,7 +15,17 @@
#include "js/TypeDecls.h"
#include "js/Utility.h"
class JSTracer;
#ifdef JS_BROKEN_GCC_ATTRIBUTE_WARNING
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wattributes"
#endif // JS_BROKEN_GCC_ATTRIBUTE_WARNING
class JS_PUBLIC_API(JSTracer);
#ifdef JS_BROKEN_GCC_ATTRIBUTE_WARNING
#pragma GCC diagnostic pop
#endif // JS_BROKEN_GCC_ATTRIBUTE_WARNING
class PseudoStack;
// This file defines the classes PseudoStack and ProfileEntry.

View File

@ -41,7 +41,7 @@ namespace JS {
typedef unsigned char Latin1Char;
class Symbol;
class Value;
union Value;
class Realm;
struct Runtime;
struct Zone;

View File

@ -25,7 +25,7 @@
#include "js/RootingAPI.h"
#include "js/Utility.h"
namespace JS { class Value; }
namespace JS { union Value; }
/* JS::Value can store a full int32_t. */
#define JSVAL_INT_BITS 32
@ -316,8 +316,81 @@ CanonicalizeNaN(double d)
* conditional move (not speculated) to zero the payload register if the type
* doesn't match.
*/
class MOZ_NON_PARAM alignas(8) Value
union MOZ_NON_PARAM alignas(8) Value
{
#if !defined(_MSC_VER) && !defined(__sparc)
// Don't expose Value's fields unless we have to: MSVC (bug 689101) and SPARC
// (bug 737344) require Value be POD to pass it by value and not in memory.
// More precisely, we don't want Value return values compiled as outparams.
private:
#endif
uint64_t asBits_;
double asDouble_;
#if defined(JS_PUNBOX64) && !defined(_WIN64)
// MSVC doesn't pack these correctly :-(
struct {
# if MOZ_LITTLE_ENDIAN
uint64_t payload47_ : 47;
JSValueTag tag_ : 17;
# else
JSValueTag tag_ : 17;
uint64_t payload47_ : 47;
# endif // MOZ_LITTLE_ENDIAN
} debugView_;
#endif // defined(JS_PUNBOX64) && !defined(_WIN64)
struct {
#if defined(JS_PUNBOX64)
# if MOZ_BIG_ENDIAN
uint32_t : 32; // padding
# endif // MOZ_BIG_ENDIAN
union {
int32_t i32_;
uint32_t u32_;
JSWhyMagic why_;
} payload_;
#elif defined(JS_NUNBOX32)
# if MOZ_BIG_ENDIAN
JSValueTag tag_;
# endif // MOZ_BIG_ENDIAN
union {
int32_t i32_;
uint32_t u32_;
uint32_t boo_; // Don't use |bool| -- it must be four bytes.
JSString* str_;
JS::Symbol* sym_;
JSObject* obj_;
js::gc::Cell* cell_;
void* ptr_;
JSWhyMagic why_;
} payload_;
# if MOZ_LITTLE_ENDIAN
JSValueTag tag_;
# endif // MOZ_LITTLE_ENDIAN
#endif // defined(JS_PUNBOX64)
} s_;
public:
// The default constructor leaves Value uninitialized. Adding a default
// constructor prevents Value from being stored in a union.
Value() = default;
Value(const Value& v) = default;
private:
explicit constexpr Value(uint64_t asBits) : asBits_(asBits) {}
explicit constexpr Value(double d) : asDouble_(d) {}
static_assert(sizeof(JSValueType) == 1,
"type bits must fit in a single byte");
static_assert(sizeof(JSValueTag) == 4,
"32-bit Value's tag_ must have size 4 to complement the "
"payload union's size 4");
static_assert(sizeof(JSWhyMagic) <= 4,
"32-bit Value's JSWhyMagic payload field must not inflate "
"the payload beyond 4 bytes");
public:
#if defined(JS_NUNBOX32)
using PayloadType = uint32_t;
@ -325,13 +398,38 @@ class MOZ_NON_PARAM alignas(8) Value
using PayloadType = uint64_t;
#endif
/*
* N.B. the default constructor leaves Value unitialized. Adding a default
* constructor prevents Value from being stored in a union.
*/
Value() = default;
Value(const Value& v) = default;
static constexpr uint64_t
bitsFromTagAndPayload(JSValueTag tag, PayloadType payload)
{
#if defined(JS_NUNBOX32)
return (uint64_t(uint32_t(tag)) << 32) | payload;
#elif defined(JS_PUNBOX64)
return (uint64_t(uint32_t(tag)) << JSVAL_TAG_SHIFT) | payload;
#endif
}
static constexpr Value
fromTagAndPayload(JSValueTag tag, PayloadType payload)
{
return fromRawBits(bitsFromTagAndPayload(tag, payload));
}
static constexpr Value
fromRawBits(uint64_t asBits) {
return Value(asBits);
}
static constexpr Value
fromInt32(int32_t i) {
return fromTagAndPayload(JSVAL_TAG_INT32, uint32_t(i));
}
static constexpr Value
fromDouble(double d) {
return Value(d);
}
public:
/**
* Returns false if creating a NumberValue containing the given type would
* be lossy, true otherwise.
@ -344,26 +442,26 @@ class MOZ_NON_PARAM alignas(8) Value
/*** Mutators ***/
void setNull() {
data.asBits = bitsFromTagAndPayload(JSVAL_TAG_NULL, 0);
asBits_ = bitsFromTagAndPayload(JSVAL_TAG_NULL, 0);
}
void setUndefined() {
data.asBits = bitsFromTagAndPayload(JSVAL_TAG_UNDEFINED, 0);
asBits_ = bitsFromTagAndPayload(JSVAL_TAG_UNDEFINED, 0);
}
void setInt32(int32_t i) {
data.asBits = bitsFromTagAndPayload(JSVAL_TAG_INT32, uint32_t(i));
asBits_ = bitsFromTagAndPayload(JSVAL_TAG_INT32, uint32_t(i));
}
int32_t& getInt32Ref() {
MOZ_ASSERT(isInt32());
return data.s.payload.i32;
return s_.payload_.i32_;
}
void setDouble(double d) {
// Don't assign to data.asDouble to fix a miscompilation with
// GCC 5.2.1 and 5.3.1. See bug 1312488.
data = layout(d);
// Don't assign to asDouble_ to fix a miscompilation with GCC 5.2.1 and
// 5.3.1. See bug 1312488.
*this = Value(d);
MOZ_ASSERT(isDouble());
}
@ -373,17 +471,17 @@ class MOZ_NON_PARAM alignas(8) Value
double& getDoubleRef() {
MOZ_ASSERT(isDouble());
return data.asDouble;
return asDouble_;
}
void setString(JSString* str) {
MOZ_ASSERT(js::gc::IsCellPointerValid(str));
data.asBits = bitsFromTagAndPayload(JSVAL_TAG_STRING, PayloadType(str));
asBits_ = bitsFromTagAndPayload(JSVAL_TAG_STRING, PayloadType(str));
}
void setSymbol(JS::Symbol* sym) {
MOZ_ASSERT(js::gc::IsCellPointerValid(sym));
data.asBits = bitsFromTagAndPayload(JSVAL_TAG_SYMBOL, PayloadType(sym));
asBits_ = bitsFromTagAndPayload(JSVAL_TAG_SYMBOL, PayloadType(sym));
}
void setObject(JSObject& obj) {
@ -413,22 +511,22 @@ class MOZ_NON_PARAM alignas(8) Value
private:
void setObjectNoCheck(JSObject* obj) {
data.asBits = bitsFromTagAndPayload(JSVAL_TAG_OBJECT, PayloadType(obj));
asBits_ = bitsFromTagAndPayload(JSVAL_TAG_OBJECT, PayloadType(obj));
}
friend inline Value js::PoisonedObjectValue(uintptr_t poison);
public:
void setBoolean(bool b) {
data.asBits = bitsFromTagAndPayload(JSVAL_TAG_BOOLEAN, uint32_t(b));
asBits_ = bitsFromTagAndPayload(JSVAL_TAG_BOOLEAN, uint32_t(b));
}
void setMagic(JSWhyMagic why) {
data.asBits = bitsFromTagAndPayload(JSVAL_TAG_MAGIC, uint32_t(why));
asBits_ = bitsFromTagAndPayload(JSVAL_TAG_MAGIC, uint32_t(why));
}
void setMagicUint32(uint32_t payload) {
data.asBits = bitsFromTagAndPayload(JSVAL_TAG_MAGIC, payload);
asBits_ = bitsFromTagAndPayload(JSVAL_TAG_MAGIC, payload);
}
bool setNumber(uint32_t ui) {
@ -460,17 +558,17 @@ class MOZ_NON_PARAM alignas(8) Value
}
void swap(Value& rhs) {
uint64_t tmp = rhs.data.asBits;
rhs.data.asBits = data.asBits;
data.asBits = tmp;
uint64_t tmp = rhs.asBits_;
rhs.asBits_ = asBits_;
asBits_ = tmp;
}
private:
JSValueTag toTag() const {
#if defined(JS_NUNBOX32)
return data.s.tag;
return s_.tag_;
#elif defined(JS_PUNBOX64)
return JSValueTag(data.asBits >> JSVAL_TAG_SHIFT);
return JSValueTag(asBits_ >> JSVAL_TAG_SHIFT);
#endif
}
@ -478,15 +576,15 @@ class MOZ_NON_PARAM alignas(8) Value
/*** JIT-only interfaces to interact with and create raw Values ***/
#if defined(JS_NUNBOX32)
PayloadType toNunboxPayload() const {
return static_cast<PayloadType>(data.s.payload.i32);
return static_cast<PayloadType>(s_.payload_.i32_);
}
JSValueTag toNunboxTag() const {
return data.s.tag;
return s_.tag_;
}
#elif defined(JS_PUNBOX64)
const void* bitsAsPunboxPointer() const {
return reinterpret_cast<void*>(data.asBits);
return reinterpret_cast<void*>(asBits_);
}
#endif
@ -503,7 +601,7 @@ class MOZ_NON_PARAM alignas(8) Value
#if defined(JS_NUNBOX32)
return toTag() == JSVAL_TAG_UNDEFINED;
#elif defined(JS_PUNBOX64)
return data.asBits == JSVAL_SHIFTED_TAG_UNDEFINED;
return asBits_ == JSVAL_SHIFTED_TAG_UNDEFINED;
#endif
}
@ -511,7 +609,7 @@ class MOZ_NON_PARAM alignas(8) Value
#if defined(JS_NUNBOX32)
return toTag() == JSVAL_TAG_NULL;
#elif defined(JS_PUNBOX64)
return data.asBits == JSVAL_SHIFTED_TAG_NULL;
return asBits_ == JSVAL_SHIFTED_TAG_NULL;
#endif
}
@ -524,14 +622,14 @@ class MOZ_NON_PARAM alignas(8) Value
}
bool isInt32(int32_t i32) const {
return data.asBits == bitsFromTagAndPayload(JSVAL_TAG_INT32, uint32_t(i32));
return asBits_ == bitsFromTagAndPayload(JSVAL_TAG_INT32, uint32_t(i32));
}
bool isDouble() const {
#if defined(JS_NUNBOX32)
return uint32_t(toTag()) <= uint32_t(JSVAL_TAG_CLEAR);
#elif defined(JS_PUNBOX64)
return (data.asBits | mozilla::DoubleTypeTraits::kSignBit) <= JSVAL_SHIFTED_TAG_MAX_DOUBLE;
return (asBits_ | mozilla::DoubleTypeTraits::kSignBit) <= JSVAL_SHIFTED_TAG_MAX_DOUBLE;
#endif
}
@ -540,7 +638,7 @@ class MOZ_NON_PARAM alignas(8) Value
MOZ_ASSERT(toTag() != JSVAL_TAG_CLEAR);
return uint32_t(toTag()) <= uint32_t(JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET);
#elif defined(JS_PUNBOX64)
return data.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET;
return asBits_ < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET;
#endif
}
@ -556,8 +654,8 @@ class MOZ_NON_PARAM alignas(8) Value
#if defined(JS_NUNBOX32)
return toTag() == JSVAL_TAG_OBJECT;
#elif defined(JS_PUNBOX64)
MOZ_ASSERT((data.asBits >> JSVAL_TAG_SHIFT) <= JSVAL_TAG_OBJECT);
return data.asBits >= JSVAL_SHIFTED_TAG_OBJECT;
MOZ_ASSERT((asBits_ >> JSVAL_TAG_SHIFT) <= JSVAL_TAG_OBJECT);
return asBits_ >= JSVAL_SHIFTED_TAG_OBJECT;
#endif
}
@ -565,7 +663,7 @@ class MOZ_NON_PARAM alignas(8) Value
#if defined(JS_NUNBOX32)
return uint32_t(toTag()) < uint32_t(JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET);
#elif defined(JS_PUNBOX64)
return data.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET;
return asBits_ < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET;
#endif
}
@ -578,7 +676,7 @@ class MOZ_NON_PARAM alignas(8) Value
/* gcc sometimes generates signed < without explicit casts. */
return uint32_t(toTag()) >= uint32_t(JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET);
#elif defined(JS_PUNBOX64)
return data.asBits >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET;
return asBits_ >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET;
#endif
}
@ -587,11 +685,11 @@ class MOZ_NON_PARAM alignas(8) Value
}
bool isTrue() const {
return data.asBits == bitsFromTagAndPayload(JSVAL_TAG_BOOLEAN, uint32_t(true));
return asBits_ == bitsFromTagAndPayload(JSVAL_TAG_BOOLEAN, uint32_t(true));
}
bool isFalse() const {
return data.asBits == bitsFromTagAndPayload(JSVAL_TAG_BOOLEAN, uint32_t(false));
return asBits_ == bitsFromTagAndPayload(JSVAL_TAG_BOOLEAN, uint32_t(false));
}
bool isMagic() const {
@ -599,7 +697,7 @@ class MOZ_NON_PARAM alignas(8) Value
}
bool isMagic(JSWhyMagic why) const {
MOZ_ASSERT_IF(isMagic(), data.s.payload.why == why);
MOZ_ASSERT_IF(isMagic(), s_.payload_.why_ == why);
return isMagic();
}
@ -618,22 +716,22 @@ class MOZ_NON_PARAM alignas(8) Value
JSWhyMagic whyMagic() const {
MOZ_ASSERT(isMagic());
return data.s.payload.why;
return s_.payload_.why_;
}
uint32_t magicUint32() const {
MOZ_ASSERT(isMagic());
return data.s.payload.u32;
return s_.payload_.u32_;
}
/*** Comparison ***/
bool operator==(const Value& rhs) const {
return data.asBits == rhs.data.asBits;
return asBits_ == rhs.asBits_;
}
bool operator!=(const Value& rhs) const {
return data.asBits != rhs.data.asBits;
return asBits_ != rhs.asBits_;
}
friend inline bool SameType(const Value& lhs, const Value& rhs);
@ -643,15 +741,15 @@ class MOZ_NON_PARAM alignas(8) Value
int32_t toInt32() const {
MOZ_ASSERT(isInt32());
#if defined(JS_NUNBOX32)
return data.s.payload.i32;
return s_.payload_.i32_;
#elif defined(JS_PUNBOX64)
return int32_t(data.asBits);
return int32_t(asBits_);
#endif
}
double toDouble() const {
MOZ_ASSERT(isDouble());
return data.asDouble;
return asDouble_;
}
double toNumber() const {
@ -662,27 +760,27 @@ class MOZ_NON_PARAM alignas(8) Value
JSString* toString() const {
MOZ_ASSERT(isString());
#if defined(JS_NUNBOX32)
return data.s.payload.str;
return s_.payload_.str_;
#elif defined(JS_PUNBOX64)
return reinterpret_cast<JSString*>(data.asBits ^ JSVAL_SHIFTED_TAG_STRING);
return reinterpret_cast<JSString*>(asBits_ ^ JSVAL_SHIFTED_TAG_STRING);
#endif
}
JS::Symbol* toSymbol() const {
MOZ_ASSERT(isSymbol());
#if defined(JS_NUNBOX32)
return data.s.payload.sym;
return s_.payload_.sym_;
#elif defined(JS_PUNBOX64)
return reinterpret_cast<JS::Symbol*>(data.asBits ^ JSVAL_SHIFTED_TAG_SYMBOL);
return reinterpret_cast<JS::Symbol*>(asBits_ ^ JSVAL_SHIFTED_TAG_SYMBOL);
#endif
}
JSObject& toObject() const {
MOZ_ASSERT(isObject());
#if defined(JS_NUNBOX32)
return *data.s.payload.obj;
return *s_.payload_.obj_;
#elif defined(JS_PUNBOX64)
uint64_t ptrBits = data.asBits ^ JSVAL_SHIFTED_TAG_OBJECT;
uint64_t ptrBits = asBits_ ^ JSVAL_SHIFTED_TAG_OBJECT;
MOZ_ASSERT(ptrBits);
MOZ_ASSERT((ptrBits & 0x7) == 0);
return *reinterpret_cast<JSObject*>(ptrBits);
@ -692,11 +790,11 @@ class MOZ_NON_PARAM alignas(8) Value
JSObject* toObjectOrNull() const {
MOZ_ASSERT(isObjectOrNull());
#if defined(JS_NUNBOX32)
return data.s.payload.obj;
return s_.payload_.obj_;
#elif defined(JS_PUNBOX64)
// Note: the 'Spectre mitigations' comment at the top of this class
// explains why we use XOR here and in other to* methods.
uint64_t ptrBits = (data.asBits ^ JSVAL_SHIFTED_TAG_OBJECT) & ~JSVAL_OBJECT_OR_NULL_BIT;
uint64_t ptrBits = (asBits_ ^ JSVAL_SHIFTED_TAG_OBJECT) & ~JSVAL_OBJECT_OR_NULL_BIT;
MOZ_ASSERT((ptrBits & 0x7) == 0);
return reinterpret_cast<JSObject*>(ptrBits);
#endif
@ -705,9 +803,9 @@ class MOZ_NON_PARAM alignas(8) Value
js::gc::Cell* toGCThing() const {
MOZ_ASSERT(isGCThing());
#if defined(JS_NUNBOX32)
return data.s.payload.cell;
return s_.payload_.cell_;
#elif defined(JS_PUNBOX64)
uint64_t ptrBits = data.asBits & JSVAL_PAYLOAD_MASK_GCTHING;
uint64_t ptrBits = asBits_ & JSVAL_PAYLOAD_MASK_GCTHING;
MOZ_ASSERT((ptrBits & 0x7) == 0);
return reinterpret_cast<js::gc::Cell*>(ptrBits);
#endif
@ -720,19 +818,19 @@ class MOZ_NON_PARAM alignas(8) Value
bool toBoolean() const {
MOZ_ASSERT(isBoolean());
#if defined(JS_NUNBOX32)
return bool(data.s.payload.boo);
return bool(s_.payload_.boo_);
#elif defined(JS_PUNBOX64)
return bool(int32_t(data.asBits));
return bool(int32_t(asBits_));
#endif
}
uint32_t payloadAsRawUint32() const {
MOZ_ASSERT(!isDouble());
return data.s.payload.u32;
return s_.payload_.u32_;
}
uint64_t asRawBits() const {
return data.asBits;
return asBits_;
}
JSValueType extractNonDoubleType() const {
@ -753,10 +851,10 @@ class MOZ_NON_PARAM alignas(8) Value
void setPrivate(void* ptr) {
MOZ_ASSERT((uintptr_t(ptr) & 1) == 0);
#if defined(JS_NUNBOX32)
data.s.tag = JSValueTag(0);
data.s.payload.ptr = ptr;
s_.tag_ = JSValueTag(0);
s_.payload_.ptr_ = ptr;
#elif defined(JS_PUNBOX64)
data.asBits = uintptr_t(ptr) >> 1;
asBits_ = uintptr_t(ptr) >> 1;
#endif
MOZ_ASSERT(isDouble());
}
@ -764,10 +862,10 @@ class MOZ_NON_PARAM alignas(8) Value
void* toPrivate() const {
MOZ_ASSERT(isDouble());
#if defined(JS_NUNBOX32)
return data.s.payload.ptr;
return s_.payload_.ptr_;
#elif defined(JS_PUNBOX64)
MOZ_ASSERT((data.asBits & 0x8000000000000000ULL) == 0);
return reinterpret_cast<void*>(data.asBits << 1);
MOZ_ASSERT((asBits_ & 0x8000000000000000ULL) == 0);
return reinterpret_cast<void*>(asBits_ << 1);
#endif
}
@ -805,130 +903,12 @@ class MOZ_NON_PARAM alignas(8) Value
// It throws syntax error.
MOZ_ASSERT((((uintptr_t)cell) >> JSVAL_TAG_SHIFT) == 0);
#endif
data.asBits = bitsFromTagAndPayload(JSVAL_TAG_PRIVATE_GCTHING, PayloadType(cell));
asBits_ = bitsFromTagAndPayload(JSVAL_TAG_PRIVATE_GCTHING, PayloadType(cell));
}
bool isPrivateGCThing() const {
return toTag() == JSVAL_TAG_PRIVATE_GCTHING;
}
const uintptr_t* payloadUIntPtr() const {
#if defined(JS_NUNBOX32)
return &data.s.payload.uintptr;
#elif defined(JS_PUNBOX64)
return &data.asUIntPtr;
#endif
}
#if !defined(_MSC_VER) && !defined(__sparc)
// Value must be POD so that MSVC will pass it by value and not in memory
// (bug 689101); the same is true for SPARC as well (bug 737344). More
// precisely, we don't want Value return values compiled as out params.
private:
#endif
union layout {
uint64_t asBits;
double asDouble;
void* asPtr;
#if defined(JS_PUNBOX64)
uintptr_t asUIntPtr;
#endif // defined(JS_PUNBOX64)
#if defined(JS_PUNBOX64) && !defined(_WIN64)
/* MSVC does not pack these correctly :-( */
struct {
# if MOZ_LITTLE_ENDIAN
uint64_t payload47 : 47;
JSValueTag tag : 17;
# else
JSValueTag tag : 17;
uint64_t payload47 : 47;
# endif // MOZ_LITTLE_ENDIAN
} debugView;
#endif // defined(JS_PUNBOX64) && !defined(_WIN64)
struct {
#if defined(JS_PUNBOX64)
# if MOZ_BIG_ENDIAN
uint32_t padding;
# endif // MOZ_BIG_ENDIAN
union {
int32_t i32;
uint32_t u32;
JSWhyMagic why;
} payload;
#else
# if MOZ_BIG_ENDIAN
JSValueTag tag;
# endif // MOZ_BIG_ENDIAN
union {
int32_t i32;
uint32_t u32;
uint32_t boo; // Don't use |bool| -- it must be four bytes.
JSString* str;
JS::Symbol* sym;
JSObject* obj;
js::gc::Cell* cell;
void* ptr;
JSWhyMagic why;
uintptr_t uintptr;
} payload;
# if MOZ_LITTLE_ENDIAN
JSValueTag tag;
# endif // MOZ_LITTLE_ENDIAN
#endif // defined(JS_PUNBOX64)
} s;
layout() : asBits(JSVAL_RAW64_UNDEFINED) {}
explicit constexpr layout(uint64_t bits) : asBits(bits) {}
explicit constexpr layout(double d) : asDouble(d) {}
} data;
private:
explicit constexpr Value(uint64_t asBits) : data(asBits) {}
explicit constexpr Value(double d) : data(d) {}
void staticAssertions() {
JS_STATIC_ASSERT(sizeof(JSValueType) == 1);
JS_STATIC_ASSERT(sizeof(JSValueTag) == 4);
JS_STATIC_ASSERT(sizeof(JSWhyMagic) <= 4);
JS_STATIC_ASSERT(sizeof(Value) == 8);
}
friend constexpr Value JS::UndefinedValue();
public:
static constexpr uint64_t
bitsFromTagAndPayload(JSValueTag tag, PayloadType payload)
{
#if defined(JS_NUNBOX32)
return (uint64_t(uint32_t(tag)) << 32) | payload;
#elif defined(JS_PUNBOX64)
return (uint64_t(uint32_t(tag)) << JSVAL_TAG_SHIFT) | payload;
#endif
}
static constexpr Value
fromTagAndPayload(JSValueTag tag, PayloadType payload)
{
return fromRawBits(bitsFromTagAndPayload(tag, payload));
}
static constexpr Value
fromRawBits(uint64_t asBits) {
return Value(asBits);
}
static constexpr Value
fromInt32(int32_t i) {
return fromTagAndPayload(JSVAL_TAG_INT32, uint32_t(i));
}
static constexpr Value
fromDouble(double d) {
return Value(d);
}
} JS_HAZ_GC_POINTER;
/**
@ -1268,7 +1248,7 @@ SameType(const Value& lhs, const Value& rhs)
return ltag == rtag || (ltag < JSVAL_TAG_CLEAR && rtag < JSVAL_TAG_CLEAR);
#elif defined(JS_PUNBOX64)
return (lhs.isDouble() && rhs.isDouble()) ||
(((lhs.data.asBits ^ rhs.data.asBits) & 0xFFFF800000000000ULL) == 0);
(((lhs.asBits_ ^ rhs.asBits_) & 0xFFFF800000000000ULL) == 0);
#endif
}

View File

@ -13,7 +13,7 @@
namespace JS {
class CallArgs;
class Value;
union Value;
} // namespace JS
namespace js {

View File

@ -474,6 +474,15 @@ TokenStreamAnyChars::internalUpdateLineInfoForEOL(uint32_t lineStartOffset)
return srcCoords.add(lineno, linebase);
}
void
TokenStreamAnyChars::undoInternalUpdateLineInfoForEOL()
{
MOZ_ASSERT(prevLinebase != size_t(-1)); // we should never get more than one EOL
linebase = prevLinebase;
prevLinebase = size_t(-1);
lineno--;
}
template<typename CharT, class AnyCharsAccess>
MOZ_MUST_USE MOZ_ALWAYS_INLINE bool
TokenStreamSpecific<CharT, AnyCharsAccess>::updateLineInfoForEOL()
@ -545,15 +554,6 @@ GeneralTokenStreamChars<CharT, AnyCharsAccess>::getCharIgnoreEOL()
return EOF;
}
void
TokenStreamAnyChars::undoGetChar()
{
MOZ_ASSERT(prevLinebase != size_t(-1)); // we should never get more than one EOL
linebase = prevLinebase;
prevLinebase = size_t(-1);
lineno--;
}
template<typename CharT, class AnyCharsAccess>
void
GeneralTokenStreamChars<CharT, AnyCharsAccess>::ungetChar(int32_t c)
@ -573,7 +573,7 @@ GeneralTokenStreamChars<CharT, AnyCharsAccess>::ungetChar(int32_t c)
if (!userbuf.atStart())
userbuf.matchRawCharBackwards('\r');
anyCharsAccess().undoGetChar();
anyCharsAccess().undoInternalUpdateLineInfoForEOL();
} else {
MOZ_ASSERT(userbuf.peekRawChar() == c);
}
@ -607,8 +607,8 @@ TokenStreamChars<char16_t, AnyCharsAccess>::ungetCodePointIgnoreEOL(uint32_t cod
}
// Return true iff |n| raw characters can be read from this without reading past
// EOF or a newline, and copy those characters into |cp| if so. The characters
// are not consumed: use skipChars(n) to do so after checking that the consumed
// EOF, and copy those characters into |cp| if so. The characters are not
// consumed: use skipChars(n) to do so after checking that the consumed
// characters had appropriate values.
template<typename CharT, class AnyCharsAccess>
bool
@ -620,11 +620,6 @@ TokenStreamSpecific<CharT, AnyCharsAccess>::peekChars(int n, CharT* cp)
if (c == EOF)
break;
if (c == '\n') {
ungetCharIgnoreEOL(c);
break;
}
cp[i] = char16_t(c);
}
@ -1189,15 +1184,10 @@ TokenStreamSpecific<CharT, AnyCharsAccess>::getDirective(bool isMultiline,
// Debugging directives can occur in both single- and multi-line
// comments. If we're currently inside a multi-line comment, we also
// need to recognize multi-line comment terminators.
if (isMultiline && c == '*') {
int32_t c2;
if (!peekChar(&c2))
return false;
if (c2 == '/') {
ungetChar('*');
break;
}
if (isMultiline && c == '*' && matchChar('/')) {
ungetCharIgnoreEOL('/');
ungetCharIgnoreEOL('*');
break;
}
if (!tokenbuf.append(c))
@ -1388,7 +1378,7 @@ enum FirstCharKind {
// Ident: 36, 65..90, 95, 97..122: '$', 'A'..'Z', '_', 'a'..'z'
// Dot: 46: '.'
// Equals: 61: '='
// String: 34, 39: '"', '\''
// String: 34, 39, 96: '"', '\'', '`'
// Dec: 49..57: '1'..'9'
// Plus: 43: '+'
// BasePrefix: 48: '0'
@ -1406,7 +1396,6 @@ enum FirstCharKind {
#define T_RB size_t(TokenKind::Rb)
#define T_LC size_t(TokenKind::Lc)
#define T_RC size_t(TokenKind::Rc)
#define Templat String
#define _______ Other
static const uint8_t firstCharKinds[] = {
/* 0 1 2 3 4 5 6 7 8 9 */
@ -1414,12 +1403,12 @@ static const uint8_t firstCharKinds[] = {
/* 10+ */ EOL, Space, Space, EOL, _______, _______, _______, _______, _______, _______,
/* 20+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
/* 30+ */ _______, _______, Space, _______, String, _______, Ident, _______, _______, String,
/* 40+ */ T_LP, T_RP, _______, _______, T_COMMA,_______, _______, _______,BasePrefix, Dec,
/* 50+ */ Dec, Dec, Dec, Dec, Dec, Dec, Dec, Dec, T_COLON, T_SEMI,
/* 40+ */ T_LP, T_RP, _______, _______, T_COMMA, _______, _______, _______,BasePrefix, Dec,
/* 50+ */ Dec, Dec, Dec, Dec, Dec, Dec, Dec, Dec, T_COLON, T_SEMI,
/* 60+ */ _______, _______, _______, T_HOOK, _______, Ident, Ident, Ident, Ident, Ident,
/* 70+ */ Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident,
/* 80+ */ Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident,
/* 90+ */ Ident, T_LB, _______, T_RB, _______, Ident, Templat, Ident, Ident, Ident,
/* 90+ */ Ident, T_LB, _______, T_RB, _______, Ident, String, Ident, Ident, Ident,
/* 100+ */ Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident,
/* 110+ */ Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident,
/* 120+ */ Ident, Ident, Ident, T_LC, _______, T_RC,T_BITNOT, _______
@ -1435,7 +1424,6 @@ static const uint8_t firstCharKinds[] = {
#undef T_RB
#undef T_LC
#undef T_RC
#undef Templat
#undef _______
static_assert(LastCharKind < (1 << (sizeof(firstCharKinds[0]) * 8)),
@ -1897,9 +1885,9 @@ TokenStreamSpecific<CharT, AnyCharsAccess>::getTokenInternal(TokenKind* ttp, Mod
if (matchChar('-')) {
if (matchChar('-'))
goto skipline;
ungetChar('-');
ungetCharIgnoreEOL('-');
}
ungetChar('!');
ungetCharIgnoreEOL('!');
}
}
if (matchChar('<')) {
@ -1930,23 +1918,21 @@ TokenStreamSpecific<CharT, AnyCharsAccess>::getTokenInternal(TokenKind* ttp, Mod
case '/':
// Look for a single-line comment.
if (matchChar('/')) {
if (!peekChar(&c))
goto error;
c = getCharIgnoreEOL();
if (c == '@' || c == '#') {
consumeKnownChar(c);
bool shouldWarn = c == '@';
if (!getDirectives(false, shouldWarn))
goto error;
} else {
ungetCharIgnoreEOL(c);
}
skipline:
do {
if (!getChar(&c))
goto error;
} while (c != EOF && c != '\n');
c = getCharIgnoreEOL();
} while (c != EOF && !TokenBuf::isRawEOLChar(c));
ungetChar(c);
ungetCharIgnoreEOL(c);
anyCharsAccess().cursor = (anyCharsAccess().cursor - 1) & ntokensMask;
goto retry;
}
@ -2013,37 +1999,34 @@ TokenStreamSpecific<CharT, AnyCharsAccess>::getTokenInternal(TokenKind* ttp, Mod
} while (true);
RegExpFlag reflags = NoFlags;
unsigned length = tokenbuf.length() + 1;
while (true) {
if (!peekChar(&c))
goto error;
if (c == 'g' && !(reflags & GlobalFlag))
reflags = RegExpFlag(reflags | GlobalFlag);
else if (c == 'i' && !(reflags & IgnoreCaseFlag))
reflags = RegExpFlag(reflags | IgnoreCaseFlag);
else if (c == 'm' && !(reflags & MultilineFlag))
reflags = RegExpFlag(reflags | MultilineFlag);
else if (c == 'y' && !(reflags & StickyFlag))
reflags = RegExpFlag(reflags | StickyFlag);
else if (c == 'u' && !(reflags & UnicodeFlag))
reflags = RegExpFlag(reflags | UnicodeFlag);
RegExpFlag flag;
c = getCharIgnoreEOL();
if (c == 'g')
flag = GlobalFlag;
else if (c == 'i')
flag = IgnoreCaseFlag;
else if (c == 'm')
flag = MultilineFlag;
else if (c == 'y')
flag = StickyFlag;
else if (c == 'u')
flag = UnicodeFlag;
else if (JS7_ISLET(c))
flag = NoFlags;
else
break;
if (!getChar(&c))
goto error;
length++;
}
if (!peekChar(&c))
goto error;
if (JS7_ISLET(c)) {
char buf[2] = { '\0', '\0' };
tp->pos.begin += length + 1;
buf[0] = char(c);
reportError(JSMSG_BAD_REGEXP_FLAG, buf);
consumeKnownChar(c);
goto error;
if ((reflags & flag) || flag == NoFlags) {
MOZ_ASSERT(userbuf.offset() > 0);
char buf[2] = { char(c), '\0' };
errorAt(userbuf.offset() - 1, JSMSG_BAD_REGEXP_FLAG, buf);
goto error;
}
reflags = RegExpFlag(reflags | flag);
}
ungetCharIgnoreEOL(c);
tp->type = TokenKind::RegExp;
tp->setRegExpFlags(reflags);
goto out;
@ -2061,11 +2044,7 @@ TokenStreamSpecific<CharT, AnyCharsAccess>::getTokenInternal(TokenKind* ttp, Mod
if (anyCharsAccess().options().allowHTMLComments &&
!anyCharsAccess().flags.isDirtyLine)
{
int32_t c2;
if (!peekChar(&c2))
goto error;
if (c2 == '>')
if (matchChar('>'))
goto skipline;
}
@ -2123,9 +2102,9 @@ TokenStreamSpecific<CharT, AnyCharsAccess>::getStringOrTemplateToken(char untilC
"unexpected string/template literal delimiter");
int c;
int nc = -1;
bool parsingTemplate = (untilChar == '`');
bool templateHead = false;
*tp = newToken(-1);
tokenbuf.clear();
@ -2170,17 +2149,10 @@ TokenStreamSpecific<CharT, AnyCharsAccess>::getStringOrTemplateToken(char untilC
// Unicode character specification.
case 'u': {
uint32_t code = 0;
int32_t c2;
if (!peekChar(&c2))
return false;
uint32_t start = userbuf.offset() - 2;
int32_t c2 = getCharIgnoreEOL();
if (c2 == '{') {
consumeKnownChar('{');
uint32_t start = userbuf.offset() - 3;
uint32_t code = 0;
bool first = true;
bool valid = true;
do {
@ -2258,16 +2230,18 @@ TokenStreamSpecific<CharT, AnyCharsAccess>::getStringOrTemplateToken(char untilC
break;
}
CharT cp[4];
if (peekChars(4, cp) &&
JS7_ISHEX(cp[0]) && JS7_ISHEX(cp[1]) && JS7_ISHEX(cp[2]) && JS7_ISHEX(cp[3]))
CharT cp[3];
if (JS7_ISHEX(c2) && peekChars(3, cp) &&
JS7_ISHEX(cp[0]) && JS7_ISHEX(cp[1]) && JS7_ISHEX(cp[2]))
{
c = JS7_UNHEX(cp[0]);
c = (c << 4) + JS7_UNHEX(cp[1]);
c = (c << 4) + JS7_UNHEX(cp[2]);
c = (c << 4) + JS7_UNHEX(cp[3]);
skipChars(4);
c = (JS7_UNHEX(c2) << 12) |
(JS7_UNHEX(cp[0]) << 8) |
(JS7_UNHEX(cp[1]) << 4) |
JS7_UNHEX(cp[2]);
skipChars(3);
} else {
ungetCharIgnoreEOL(c2);
uint32_t start = userbuf.offset() - 2;
if (parsingTemplate) {
TokenStreamAnyChars& anyChars = anyCharsAccess();
anyChars.setInvalidTemplateEscape(start, InvalidEscapeType::Unicode);
@ -2347,18 +2321,19 @@ TokenStreamSpecific<CharT, AnyCharsAccess>::getStringOrTemplateToken(char untilC
}
if (c == '\r') {
c = '\n';
if (userbuf.peekRawChar() == '\n')
skipCharsIgnoreEOL(1);
// If it's a \r\n sequence: treat as a single EOL, skip over the \n.
if (userbuf.hasRawChars())
userbuf.matchRawChar('\n');
}
if (!updateLineInfoForEOL())
return false;
anyCharsAccess().updateFlagsForEOL();
} else if (parsingTemplate && c == '$') {
if ((nc = getCharIgnoreEOL()) == '{')
break;
ungetCharIgnoreEOL(nc);
} else if (parsingTemplate && c == '$' && matchChar('{')) {
templateHead = true;
break;
}
if (!tokenbuf.append(c)) {
@ -2372,9 +2347,11 @@ TokenStreamSpecific<CharT, AnyCharsAccess>::getStringOrTemplateToken(char untilC
return false;
if (!parsingTemplate) {
MOZ_ASSERT(!templateHead);
(*tp)->type = TokenKind::String;
} else {
if (c == '$' && nc == '{')
if (templateHead)
(*tp)->type = TokenKind::TemplateHead;
else
(*tp)->type = TokenKind::NoSubsTemplate;

View File

@ -520,8 +520,6 @@ class TokenStreamAnyChars
private:
PropertyName* reservedWordToPropertyName(TokenKind tt) const;
void undoGetChar();
public:
PropertyName* currentName() const {
if (isCurrentTokenType(TokenKind::Name))
@ -749,6 +747,8 @@ class TokenStreamAnyChars
private:
MOZ_MUST_USE MOZ_ALWAYS_INLINE bool internalUpdateLineInfoForEOL(uint32_t lineStartOffset);
void undoInternalUpdateLineInfoForEOL();
public:
const Token& nextToken() const {
MOZ_ASSERT(hasLookahead());
@ -1483,7 +1483,7 @@ class MOZ_STACK_CLASS TokenStreamSpecific
while (n-- > 0) {
MOZ_ASSERT(userbuf.hasRawChars());
mozilla::DebugOnly<int32_t> c = getCharIgnoreEOL();
MOZ_ASSERT(c != '\n');
MOZ_ASSERT(!TokenBuf::isRawEOLChar(c));
}
}

View File

@ -10,11 +10,9 @@ mozilla.prettyprinters.clear_module_printers(__name__)
# Summary of the JS::Value type:
#
# Viewed abstractly, JS::Value is a 64-bit discriminated union, with
# JSString *, JSObject *, IEEE 64-bit floating-point, and 32-bit integer
# branches (and a few others). (It is not actually a C++ union;
# 'discriminated union' just describes the overall effect.) Note that
# JS::Value is always 64 bits long, even on 32-bit architectures.
# JS::Value is a 64-bit discriminated union, with JSString*, JSObject*, IEEE
# 64-bit floating-point, and 32-bit integer branches (and a few others).
# JS::Value is 64 bits long on all architectures.
#
# The ECMAScript standard specifies that ECMAScript numbers are IEEE 64-bit
# floating-point values. A JS::Value can represent any JavaScript number
@ -63,11 +61,10 @@ mozilla.prettyprinters.clear_module_printers(__name__)
# holds the address of a JSObject; if a string, the address of a
# JSString; and so on.
#
# On the only 64-bit platform we support, x86_64, only the lower 48 bits of
# an address are significant, and only those values whose top bit is zero
# are used for user-space addresses. This means that x86_64 addresses are
# effectively 47 bits long, and thus fit nicely in the available portion of
# the fraction field.
# On x86_64 only the lower 48 bits of an address are significant, and only
# those values whose top bit is zero are used for user-space addresses. Thus
# x86_64 addresses are effectively 47 bits long and fit nicely in the available
# portion of the fraction field.
#
# See Value.h for full details.
@ -75,8 +72,8 @@ class Box(object):
def __init__(self, asBits, jtc):
self.asBits = asBits
self.jtc = jtc
# Value::layout::asBits is uint64_t, but somehow the sign bit can be
# botched here, even though Python integers are arbitrary precision.
# Value::asBits is uint64_t, but somehow the sign bit can be botched
# here, even though Python integers are arbitrary precision.
if self.asBits < 0:
self.asBits = self.asBits + (1 << 64)
@ -167,9 +164,8 @@ class JSValue(object):
cache.mod_JS_Value = JSValueTypeCache(cache)
self.jtc = cache.mod_JS_Value
data = value['data']
self.data = data
self.box = self.jtc.boxer(data['asBits'], self.jtc)
self.value = value
self.box = self.jtc.boxer(value['asBits_'], self.jtc)
def to_string(self):
tag = self.box.tag()
@ -194,7 +190,7 @@ class JSValue(object):
return '$JS::Int32Value(%s)' % value
if tag == self.jtc.DOUBLE:
return '$JS::DoubleValue(%s)' % self.data['asDouble']
return '$JS::DoubleValue(%s)' % self.value['asDouble_']
if tag == self.jtc.STRING:
value = self.box.as_address().cast(self.cache.JSString_ptr_t)

View File

@ -211,7 +211,7 @@ def implemented_types(t):
if t.code == gdb.TYPE_CODE_TYPEDEF:
yield t.target()
for t2 in followers(t.target()): yield t2
elif t.code == gdb.TYPE_CODE_STRUCT:
elif is_struct_or_union(t):
base_classes = []
for f in t.fields():
if f.is_base_class:
@ -225,6 +225,9 @@ def implemented_types(t):
template_regexp = re.compile("([\w_:]+)<")
def is_struct_or_union(t):
return t.code in (gdb.TYPE_CODE_STRUCT, gdb.TYPE_CODE_UNION)
# Construct and return a pretty-printer lookup function for objfile, or
# return None if the objfile doesn't contain SpiderMonkey code
# (specifically, definitions for SpiderMonkey types).
@ -253,7 +256,7 @@ def lookup_for_objfile(objfile):
def check_table_by_type_name(table, t):
if t.code == gdb.TYPE_CODE_TYPEDEF:
return check_table(table, str(t))
elif t.code == gdb.TYPE_CODE_STRUCT and t.tag:
elif is_struct_or_union(t) and t.tag:
return check_table(table, t.tag)
else:
return None
@ -270,7 +273,7 @@ def lookup_for_objfile(objfile):
else:
p = check_table_by_type_name(printers_by_tag, t)
if p: return p
if t.code == gdb.TYPE_CODE_STRUCT and t.tag:
if is_struct_or_union(t) and t.tag:
m = template_regexp.match(t.tag)
if m:
p = check_table(template_printers_by_tag, m.group(1))

View File

@ -931,7 +931,7 @@ TraceIonJSFrame(JSTracer* trc, const JSJitFrameIter& frame)
if (v != Value::fromTagAndPayload(tag, rawPayload)) {
// GC moved the value, replace the stored payload.
rawPayload = *v.payloadUIntPtr();
rawPayload = v.toNunboxPayload();
WriteAllocation(frame, &payload, rawPayload);
}
}

View File

@ -483,15 +483,6 @@ interface nsIXPCComponents_Utils : nsISupports
[implicit_jscontext]
void forcePermissiveCOWs();
/*
* This seemingly-paradoxical API allows privileged code to explicitly give
* unprivileged code a reference to its own Components object (whereas it's
* normally hidden away on a scope chain visible only to XBL methods). See
* also SpecialPowers.getComponents.
*/
[implicit_jscontext]
jsval getComponentsForScope(in jsval vscope);
/*
* Dispatches a runnable to the current/main thread. If |scope| is passed,
* the runnable will be dispatch in the compartment of |scope|, which

View File

@ -163,9 +163,7 @@ nsXPCComponents_Interfaces::GetClassID(nsCID * *aClassID)
NS_IMETHODIMP
nsXPCComponents_Interfaces::GetFlags(uint32_t* aFlags)
{
// Mark ourselves as a DOM object so that instances may be created in
// unprivileged scopes.
*aFlags = nsIClassInfo::DOM_OBJECT;
*aFlags = 0;
return NS_OK;
}
@ -363,9 +361,7 @@ nsXPCComponents_InterfacesByID::GetClassID(nsCID * *aClassID)
NS_IMETHODIMP
nsXPCComponents_InterfacesByID::GetFlags(uint32_t* aFlags)
{
// Mark ourselves as a DOM object so that instances may be created in
// unprivileged scopes.
*aFlags = nsIClassInfo::DOM_OBJECT;
*aFlags = 0;
return NS_OK;
}
@ -957,9 +953,7 @@ nsXPCComponents_Results::GetClassID(nsCID * *aClassID)
NS_IMETHODIMP
nsXPCComponents_Results::GetFlags(uint32_t* aFlags)
{
// Mark ourselves as a DOM object so that instances may be created in
// unprivileged scopes.
*aFlags = nsIClassInfo::DOM_OBJECT;
*aFlags = 0;
return NS_OK;
}
@ -2683,23 +2677,6 @@ nsXPCComponents_Utils::ForcePermissiveCOWs(JSContext* cx)
return NS_OK;
}
NS_IMETHODIMP
nsXPCComponents_Utils::GetComponentsForScope(HandleValue vscope, JSContext* cx,
MutableHandleValue rval)
{
if (!vscope.isObject())
return NS_ERROR_INVALID_ARG;
JSObject* scopeObj = js::UncheckedUnwrap(&vscope.toObject());
XPCWrappedNativeScope* scope = ObjectScope(scopeObj);
RootedObject components(cx);
if (!scope->GetComponentsJSObject(&components))
return NS_ERROR_FAILURE;
if (!JS_WrapObject(cx, &components))
return NS_ERROR_FAILURE;
rval.setObject(*components);
return NS_OK;
}
NS_IMETHODIMP
nsXPCComponents_Utils::Dispatch(HandleValue runnableArg, HandleValue scope,
JSContext* cx)
@ -3265,10 +3242,10 @@ NS_IMPL_QUERY_INTERFACE(ComponentsSH, nsIXPCScriptable)
{ 0x3649f405, 0xf0ec, 0x4c28, \
{ 0xae, 0xb0, 0xaf, 0x9a, 0x51, 0xe4, 0x4c, 0x81 } }
NS_IMPL_CLASSINFO(nsXPCComponentsBase, &ComponentsSH::Get, nsIClassInfo::DOM_OBJECT, NSXPCCOMPONENTSBASE_CID)
NS_IMPL_CLASSINFO(nsXPCComponentsBase, &ComponentsSH::Get, 0, NSXPCCOMPONENTSBASE_CID)
NS_IMPL_ISUPPORTS_CI(nsXPCComponentsBase, nsIXPCComponentsBase)
NS_IMPL_CLASSINFO(nsXPCComponents, &ComponentsSH::Get, nsIClassInfo::DOM_OBJECT, NSXPCCOMPONENTS_CID)
NS_IMPL_CLASSINFO(nsXPCComponents, &ComponentsSH::Get, 0, NSXPCCOMPONENTS_CID)
// Below is more or less what NS_IMPL_ISUPPORTS_CI_INHERITED1 would look like
// if it existed.
NS_IMPL_ADDREF_INHERITED(nsXPCComponents, nsXPCComponentsBase)

View File

@ -267,12 +267,7 @@ DefinePropertyIfFound(XPCCallContext& ccx,
}
}
bool overwriteToString = !(flags & nsIClassInfo::DOM_OBJECT)
|| Preferences::GetBool("dom.XPCToStringForDOMClasses", false);
if(id == xpccx->GetStringID(XPCJSContext::IDX_TO_STRING)
&& overwriteToString)
{
if (id == xpccx->GetStringID(XPCJSContext::IDX_TO_STRING)) {
call = XPC_WN_Shared_ToString;
name = xpccx->GetStringName(XPCJSContext::IDX_TO_STRING);
} else if (id == xpccx->GetStringID(XPCJSContext::IDX_TO_SOURCE)) {

View File

@ -38,9 +38,4 @@ function run_test() {
evalAndCatch("objC.prop1", sbMaster);
evalAndCatch("objMaster.prop1", sbA);
evalAndCatch("objMaster.prop1", sbSubset);
// Bug 777705:
sbMaster.Components = Cu.getComponentsForScope(sbMaster);
Cu.evalInSandbox("Components.interfaces", sbMaster);
Assert.ok(true);
}

View File

@ -1,49 +1,21 @@
function run_test() {
var sb1 = Cu.Sandbox("http://www.blah.com");
var sb2 = Cu.Sandbox("http://www.blah.com");
var sb3 = Cu.Sandbox(this);
var sb4 = Cu.Sandbox("http://www.other.com");
var sb2 = Cu.Sandbox(this);
var rv;
// Components is normally hidden from content on the XBL scope chain, but we
// expose it to content here to make sure that the security wrappers work
// regardless.
[sb1, sb2, sb4].forEach(function(x) { x.Components = Cu.getComponentsForScope(x); });
// non-chrome accessing chrome Components
sb1.C = Components;
checkThrows("C.interfaces", sb1);
checkThrows("C.utils", sb1);
checkThrows("C.classes", sb1);
// non-chrome accessing own Components
Assert.equal(Cu.evalInSandbox("typeof Components.interfaces", sb1), 'object');
Assert.equal(Cu.evalInSandbox("typeof Components.utils", sb1), 'undefined');
Assert.equal(Cu.evalInSandbox("typeof Components.classes", sb1), 'undefined');
// Make sure an unprivileged Components is benign.
var C2 = Cu.evalInSandbox("Components", sb2);
var whitelist = ['interfaces', 'interfacesByID', 'results', 'isSuccessCode', 'QueryInterface'];
for (var prop in Components) {
info("Checking " + prop);
Assert.equal((prop in C2), whitelist.includes(prop));
}
// non-chrome same origin
sb1.C2 = C2;
Assert.equal(Cu.evalInSandbox("typeof C2.interfaces", sb1), 'object');
Assert.equal(Cu.evalInSandbox("typeof C2.utils", sb1), 'undefined');
Assert.equal(Cu.evalInSandbox("typeof C2.classes", sb1), 'undefined');
// non-chrome accessing own Components: shouldn't exist.
Assert.equal(Cu.evalInSandbox("typeof Components", sb1), 'undefined');
// chrome accessing chrome
sb3.C = Components;
rv = Cu.evalInSandbox("C.utils", sb3);
sb2.C = Components;
rv = Cu.evalInSandbox("C.utils", sb2);
Assert.equal(rv, Cu);
// non-chrome cross origin
sb4.C2 = C2;
checkThrows("C2.interfaces", sb4);
checkThrows("C2.utils", sb4);
checkThrows("C2.classes", sb4);
}
function checkThrows(expression, sb) {

View File

@ -38,7 +38,6 @@ SimpleTest.waitForExplicitFinish()
addLoadEvent(function test() {
var
CI = SpecialPowers.Components.interfaces,
WinUtils = SpecialPowers.getDOMWindowUtils(window),
sec = netscape.security,
eSelect = $("eSelect"),

View File

@ -5688,21 +5688,9 @@ nsFrame::ComputeSize(gfxContext* aRenderingContext,
// nsFrame::ComputeSizeWithIntrinsicDimensions().
const nsStyleCoord* flexBasis = &(stylePos->mFlexBasis);
if (flexBasis->GetUnit() != eStyleUnit_Auto) {
// One caveat for when flex-basis is stomping on 'height': We don't
// support enumerated values (e.g. "max-content") for height yet (that's
// bug 567039). So, if our computed flex-basis is an enumerated value,
// we'll just behave as if it were "auto", which means "use the main-size
// property after all" (which is "height", in this case). NOTE: Once we
// support intrinsic sizing keywords for "height", we should remove this
// check.
bool usingFlexBasisForHeight =
(usingFlexBasisForISize != aWM.IsVertical());
if (!usingFlexBasisForHeight ||
flexBasis->GetUnit() != eStyleUnit_Enumerated) {
// Override whichever coord we're overriding:
(usingFlexBasisForISize ? inlineStyleCoord : blockStyleCoord) =
flexBasis;
}
// Override whichever styleCoord is in flex container's main axis:
(usingFlexBasisForISize ? inlineStyleCoord : blockStyleCoord) =
flexBasis;
}
}
@ -5951,21 +5939,9 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(gfxContext* aRenderingConte
// inlineStyleCoord and blockStyleCoord in nsFrame::ComputeSize().
const nsStyleCoord* flexBasis = &(stylePos->mFlexBasis);
if (flexBasis->GetUnit() != eStyleUnit_Auto) {
// One caveat for when flex-basis is stomping on 'height': We don't
// support enumerated values (e.g. "max-content") for height yet
// (that's bug 567039). So, if our computed flex-basis is an enumerated
// value, we'll just behave as if it were "auto", which means "use the
// main-size property after all" (which is "height", in this case).
// NOTE: Once we support intrinsic sizing keywords for "height", we
// should remove this check.
bool usingFlexBasisForHeight =
(usingFlexBasisForISize != aWM.IsVertical());
if (!usingFlexBasisForHeight ||
flexBasis->GetUnit() != eStyleUnit_Enumerated) {
// Override whichever coord we're overriding:
(usingFlexBasisForISize ? inlineStyleCoord : blockStyleCoord) =
flexBasis;
}
// Override whichever styleCoord is in flex container's main axis:
(usingFlexBasisForISize ? inlineStyleCoord : blockStyleCoord) =
flexBasis;
}
}
}

View File

@ -10,7 +10,6 @@ config = {
'stage_platform': 'win32-add-on-devel',
#### 32 bit build specific #####
'env': {
'BINSCOPE': 'C:/Program Files (x86)/Microsoft/SDL BinScope/BinScope.exe',
'HG_SHARE_BASE_DIR': 'C:/builds/hg-shared',
'MOZBUILD_STATE_PATH': os.path.join(os.getcwd(), '.mozbuild'),
'MOZ_CRASHREPORTER_NO_REPORT': '1',

View File

@ -11,7 +11,6 @@ config = {
'debug_build': True,
#### 32 bit build specific #####
'env': {
'BINSCOPE': 'C:/Program Files (x86)/Microsoft/SDL BinScope/BinScope.exe',
'HG_SHARE_BASE_DIR': 'C:/builds/hg-shared',
'MOZBUILD_STATE_PATH': os.path.join(os.getcwd(), '.mozbuild'),
'MOZ_CRASHREPORTER_NO_REPORT': '1',

View File

@ -14,7 +14,6 @@ releng.manifest",
'perfherder_extra_options': ['static-analysis'],
#### 32 bit build specific #####
'env': {
'BINSCOPE': 'C:/Program Files (x86)/Microsoft/SDL BinScope/BinScope.exe',
'HG_SHARE_BASE_DIR': 'C:/builds/hg-shared',
'MOZBUILD_STATE_PATH': os.path.join(os.getcwd(), '.mozbuild'),
'MOZ_CRASHREPORTER_NO_REPORT': '1',

View File

@ -10,7 +10,6 @@ config = {
'stage_platform': 'win64-add-on-devel',
#### 64 bit build specific #####
'env': {
'BINSCOPE': 'C:/Program Files (x86)/Microsoft/SDL BinScope/BinScope.exe',
'HG_SHARE_BASE_DIR': 'C:/builds/hg-shared',
'MOZ_CRASHREPORTER_NO_REPORT': '1',
'MOZ_OBJDIR': '%(abs_obj_dir)s',

View File

@ -11,7 +11,6 @@ config = {
'debug_build': True,
#### 64 bit build specific #####
'env': {
'BINSCOPE': 'C:/Program Files (x86)/Microsoft/SDL BinScope/BinScope.exe',
'HG_SHARE_BASE_DIR': 'C:/builds/hg-shared',
'MOZ_CRASHREPORTER_NO_REPORT': '1',
'MOZ_OBJDIR': '%(abs_obj_dir)s',

View File

@ -4,9 +4,6 @@ config = {
'base_name': 'WINNT_5.2_%(branch)s',
'platform': 'win32',
'env': {
'BINSCOPE': os.path.join(
os.environ['ProgramFiles(x86)'], 'Microsoft', 'SDL BinScope', 'BinScope.exe'
),
'PDBSTR_PATH': 'C:/Program Files (x86)/Windows Kits/10/Debuggers/x86/srcsrv/pdbstr.exe',
},
"check_test_env": {

View File

@ -12,6 +12,9 @@ config = {
'max_build_output_timeout': 60 * 80,
'env': {
'BINSCOPE': os.path.join(
os.environ['ProgramFiles'], 'Microsoft BinScope 2014', 'Binscope.exe'
),
'HG_SHARE_BASE_DIR': os.path.join('y:', os.sep, 'hg-shared'),
'MOZBUILD_STATE_PATH': os.path.join(os.getcwd(), '.mozbuild'),
'MOZ_CRASHREPORTER_NO_REPORT': '1',

View File

@ -1250,17 +1250,18 @@
this.mResetButton.style.visibility = "hidden";
this.EVENTS.forEach((eventName) => {
this.addEventListener(eventName, this, { mozSystemGroup: true });
this.addEventListener(eventName, this, { mozSystemGroup: true }, false);
});
// Handle keypress separately since we need to catch it on capturing.
this.addEventListener("keypress", this, {
capture: true,
mozSystemGroup: true
});
}, false);
// This is to open the picker when input element is clicked (this
// includes padding area).
this.mInputElement.addEventListener("click", this,
{ mozSystemGroup: true });
{ mozSystemGroup: true },
false);
]]>
</constructor>

View File

@ -369,8 +369,6 @@ WinCompositorWidget::DestroyCompositorWindow()
void
WinCompositorWidget::UpdateCompositorWndSizeIfNecessary()
{
MOZ_ASSERT(mCompositorWnd);
if (!mCompositorWnd) {
return;
}