Posted
about 7 years
ago
by
Air Mozilla
mconley livehacks on real Firefox bugs while thinking aloud.
|
Posted
about 7 years
ago
by
Air Mozilla
Mozilla builds products and platforms directly for developers, communities and publishers worldwide. How can we create and sustain experiences that are open, accessible and participatory?...
|
Posted
about 7 years
ago
An explanation of what it means to wash dishes clean, and how to do it.
|
Posted
about 7 years
ago
by
Air Mozilla
This is the sumo weekly call
|
Posted
about 7 years
ago
by
Tooru Fujisawa
After the release of ECMAScript 2015, a.k.a. ES6, the ECMAScript Language Specification is evolving rapidly: it’s getting many new features that will help developing web applications, with a new release planned every year.
Last week, Firefox Nightly
... [More]
54 reached 100% on the Kangax ECMAScript 2016+ compatibility table that currently covers ECMAScript 2016 and the ECMAScript 2017 draft.
Here are some highlights for those spec updates.
ECMAScript 2016
ECMAScript 2016 is the latest stable edition of the ECMAScript specification. ECMAScript 2016 introduces two new features, the Exponentiation Operator and Array.prototype.includes, and also contains various minor changes.
New Features
Exponentiation Operator
Status: Available from Firefox 52 (now Beta, will ship in March 2017).
The exponentiation operator (**) allows infix notation of exponentiation.
It’s a shorter and simpler replacement for Math.pow. The operator is right-associative.
// without Exponentiation Operator
console.log(Math.pow(2, 3)); // 8
console.log(Math.pow(2, Math.pow(3, 2)); // 512
// with Exponentiation Operator
console.log(2 ** 3); // 8
console.log(2 ** 3 ** 2); // 512
Specification
Exponentiation Operator
Documentation
Arithmetic Operators – Exponentiation (**)
Bugzilla Links
Bug 1135708 – Implement exponentiation operator (ES7 proposal)
Bug 1291212 – Ship the Exponentiation Operator
Bug 1243858 – Exponentiation Operator precedence update (ES2016/ES7, Stage 4)
Array.prototype.includes
Status: Available from Firefox 43.
Array.prototype.includes is an intuitive way to check the existence of an element in an array, replacing the array.indexOf(element) !== -1 idiom.
let supportedTypes = [
"text/plain",
"text/html",
"text/javascript",
];
// without Array.prototype.includes.
console.log(supportedTypes.indexOf("text/html") !== -1); // true
console.log(supportedTypes.indexOf("image/png") !== -1); // false
// with Array.prototype.includes.
console.log(supportedTypes.includes("text/html")); // true
console.log(supportedTypes.includes("image/png")); // false
Specification
Array.prototype.includes ( searchElement [ , fromIndex ] )
Documentation
Array.prototype.includes()
Bugzilla Links
Bug 1069063 – Implement Array.prototype.includes
Bug 1070767 – Enable {Array, %TypedArray%}.prototype.includes in all builds
Miscellaneous Changes
Generators can’t be constructed
Status: Available from Firefox 43.
Calling generator with new now throws.
function* g() {
}
new g(); // throws
Specifications
CreateDynamicFunction
Runtime Semantics: EvaluateNew(constructProduction, arguments)
Bugzilla Link
Bug 1191486 – Generators should not have [[Construct]]
Iterator for yield* can catch throw()
Status: Available from Firefox 27.
When Generator.prototype.throw is called on a generator while it’s executing yield*, the operand of the yield* can catch the exception and return to normal completion.
function* inner() {
try {
yield 10;
yield 11;
} catch (e) {
yield 20;
}
}
function* outer() {
yield* inner();
}
let g = outer();
console.log(g.next().value); // 10
console.log(g.throw().value); // 20, instead of throwing
Specifications
Runtime Semantics: Evaluation – YieldExpression : yield * AssignmentExpression
Normative: Fix yield * semantics when calling .throw
Documentation
yield*
Bugzilla Link
Bug 666396 – implement yield* operator
Function with non-simple parameters can’t have “use strict”
Status: Available from Firefox 52 (now Beta, will ship in March 2017).
When a function has non-simple parameters (destructuring parameters, default parameters, or rest parameters), the function can’t have the "use strict" directive in its body.
function assertEq(a, b, message="") {
"use strict"; // error
// ...
}
However, functions with non-simple parameters can appear in code that’s already strict mode.
"use strict";
function assertEq(a, b, message="") {
// ...
}
Specification
Function Definitions – Static Semantics: Early Errors
Bugzilla Link
Bug 1272784 – |function f(a = 1) { “use strict”; }| should throw Early Error.
Nested RestElement in Destructuring
Status: Available from Firefox 47.
Now a rest pattern in destructuring can be an arbitrary pattern, and also be nested.
let [a, ...[b, ...c]] = [1, 2, 3, 4, 5];
console.log(a); // 1
console.log(b); // 2
console.log(c); // [3, 4, 5]
let [x, y, ...{length}] = "abcdef";
console.log(x); // "a"
console.log(y); // "b"
console.log(length); // 4
Specification
BindingRestElement
Bugzilla Link
Bug 1111386 – Support nested rest in destructuring assignment
Remove [[Enumerate]]
Status: Removed in Firefox 47.
The enumerate trap of the Proxy handler has been removed.
Specification
Normative: Remove [[Enumerate]] and associated reflective capabilities
Documentation
Proxy handler.enumerate()
Bugzilla Link
Bug 1246318 – Remove [[Enumerate]] and associated reflective capabilities
ECMAScript 2017 draft
ECMAScript 2017 will be the next edition of ECMAScript specification, currently in draft. The ECMAScript 2017 draft introduces several new features, Object.values / Object.entries, Object.getOwnPropertyDescriptors, String padding, trailing commas in function parameter lists and calls, Async Functions, Shared memory and atomics, and also some minor changes.
New Features
Async Functions
Status: Available from Firefox 52 (now Beta, will ship in March 2017).
Async functions help with long promise chains broken up to separate scopes, letting you write the chains just like a synchronous function.
When an async function is called, it returns a Promise that gets resolved when the async function returns. When the async function throws, the promise gets rejected with the thrown value.
An async function can contain an await expression. That receives a promise and returns a resolved value. If the promise gets rejected, it throws the reject reason.
async function makeDinner(candidates) {
try {
let itemsInFridge = await fridge.peek();
let itemsInStore = await store.peek();
let recipe = await chooseDinner(
candidates,
itemsInFridge,
itemsInStore,
);
let [availableItems, missingItems]
= await fridge.get(recipe.ingredients);
let boughtItems = await store.buy(missingItems);
pot.put(availableItems, boughtItems);
await pot.startBoiling(recipe.temperature);
do {
await timer(5 * 60);
} while(taste(pot).isNotGood());
await pot.stopBoiling();
return pot;
} catch (e) {
return document.cookie;
}
}
async function eatDinner() {
eat(await makeDinner(["Curry", "Fried Rice", "Pizza"]));
}
Specification Drafts
AsyncFunctionDeclaration
AsyncFunctionExpression
AsyncArrowFunction
AsyncMethod
AsyncFunction Objects
AwaitExpression
Documentation
Async Function declaration
Async Function expression
Async methods
AsyncFunction
await
Bugzilla Link
Bug 1185106 – Implement async functions (ES 2017 proposal)
Shared memory and atomics
Status: Available behind a flag from Firefox 52 (now Beta, will ship in March 2017).
SharedArrayBuffer is an array buffer pointing to data that can be shared between Web Workers. Views on a shared memory can be created with the TypedArray and DataView constructors.
When transferring SharedArrayBuffer between the main thread and a worker, the underlying data is not transferred but instead the information about the data in memory is sent. As a result it reduces the cost of using a worker to process data retrieved on main thread, and also makes it possible to process data in parallel on multiple workers without creating separate data for each.
// main.js
let worker = new Worker("worker.js");
let sab = new SharedArrayBuffer(IMAGE_SIZE);
worker.onmessage = functions(event) {
let image = createImageFromBitmap(event.data.buffer);
document.body.appendChild(image);
};
captureImage(sab);
worker.postMessage({buffer: sab})
// worker.js
onmessage = function(event) {
let sab = event.data.buffer;
processImage(sab);
postMessage({buffer: sab});
};
Moreover, a new API called Atomics provides low-level atomic access and synchronization primitives for use with shared memory. Lars T Hansen has already written about this in the Mozilla Hacks post “A Taste of JavaScript’s New Parallel Primitives“.
Specifications Draft
SharedArrayBuffer Objects
The Atomics Object
Documentation
SharedArrayBuffer
Atomics
Bugzilla Links
Bug 1054841 – [meta] Shared memory for web workers
Bug 1312446 – Enable SharedArrayBuffer and Atomics in Firefox 52 Beta and Release
Object.values / Object.entries
Status: Available from Firefox 47.
Object.values returns an array of a given object’s own enumerable property values, like Object.keys does for property keys, and Object.entries returns an array of [key, value] pairs.
Object.entries is useful to iterate over objects.
createElement("img", {
width: 320,
height: 240,
src: "http://localhost/a.png"
});
// without Object.entries
function createElement(name, attributes) {
let element = document.createElement(name);
for (let name in attributes) {
let value = attributes[name];
element.setAttribute(name, value);
}
return element;
}
// with Object.entries
function createElement(name, attributes) {
let element = document.createElement(name);
for (let [name, value] of Object.entries(attributes)) {
element.setAttribute(name, value);
}
return element;
}
When property keys are not used in the loop, Object.values can be used.
Specification Drafts
Object.values ( O )
Object.entries ( O )
Documentation
Object.values()
Object.entries()
Bugzilla Links
Bug 1208464 – Implement proposed ES7 functions Object.values and Object.entries
Bug 1232639 – Optimize Object.values() and Object.entries() and let them ride the trains
Object.getOwnPropertyDescriptors
Status: Available from Firefox 50.
Object.getOwnPropertyDescriptors returns all own property descriptors of a given object.
The return value of Object.getOwnPropertyDescriptors can be passed to Object.create, to create a shallow copy of the object.
function shallowCopy(obj) {
return Object.create(Object.getPrototypeOf(obj),
Object.getOwnPropertyDescriptors(obj));
}
Specification Draft
Object.getOwnPropertyDescriptors ( O )
Documentation
Object.getOwnPropertyDescriptors()
Bugzilla Link
Bug 1245024 – [es7] implement Object.getOwnPropertyDescriptors() proposal
String padding
Status: Available from Firefox 48.
String.prototype.padStart and String.prototype.padEnd add padding to a string, if necessary, to extend it to the given maximum length. The padding characters can be specified by argument.
They can be used to output data in a tabular format, by adding leading spaces (align to end) or trailing spaces (align to start), or to add leading "0" to numbers.
let stock = {
apple: 105,
pear: 52,
orange: 78,
};
for (let [name, count] of Object.entries(stock)) {
console.log(name.padEnd(10) + ": " + String(count).padStart(5, 0));
// "apple : 00105"
// "pear : 00052"
// "orange : 00078"
}
Specification Drafts
String.prototype.padStart( maxLength [ , fillString ] )
String.prototype.padEnd( maxLength [ , fillString ] )
Documentation
String.prototype.padStart()
String.prototype.padEnd()
Bugzilla Link
Bug 1260509 – Implement String.prototype.padStart / padEnd
Trailing commas in function parameter lists and calls
Status: Available from Firefox 52 (now Beta, will ship in March 2017).
Just like array elements and object properties, function parameter list and function call arguments can now have trailing commas, except for the rest parameter.
function addItem(
name,
price,
count = 1,
) {
}
addItem(
"apple",
30,
2,
);
This simplifies generating JavaScript code programatically, i.e. transpiling from other language. Code generator doesn’t have to worry about whether to emit comma or not, while emitting function parameters or function call arguments.
Also this makes it easier to rearrange parameters by copy/paste.
Specification Drafts
FormalParameters
CoverParenthesizedExpressionAndArrowParameterList
Arguments
Bugzilla Link
Bug 1303788 – ES2017: Implement trailing comma proposal
Miscellaneous Changes
Remove proxy OwnPropertyKeys error with duplicate keys
Status: Available from Firefox 51.
The ownKeys trap of a user-defined Proxy handler is now permitted to return duplicate keys for non-extensible object.
let nonExtensibleObject = Object.preventExtensions({ a: 10 });
let x = new Proxy(nonExtensibleObject, {
ownKeys() {
return ["a", "a", "a"];
}
});
Object.getOwnPropertyNames(x); // ["a", "a", "a"]
Specification Drafts
[[OwnPropertyKeys]] ( )
Normative: Remove proxy OwnPropertyKeys error with duplicate keys
Bugzilla Link
Bug 1293995 – Remove proxy OwnPropertyKeys error with duplicate keys
Case folding for \w, \W, \b, and \B in unicode RegExp
Status: Available from Firefox 54 (now Nightly, will ship in June 2017).
\w, \W, \b, and \B in RegExp with unicode+ignoreCase flags now treat U+017F (LATIN SMALL LETTER LONG S) and U+212A (KELVIN SIGN) as word characters.
console.log(/\w/iu.test("\u017F")); // true
console.log(/\w/iu.test("\u212A")); // true
Specification Drafts
Runtime Semantics: WordCharacters ( )
Unify handling of RegExp CharacterClassEscapes \w and \W and Word Asserts \b and \B
Bugzilla Link
Bug 1281739 – Match updated spec for `/\w/iu` and `/\W/iu`
Bug 1338373 – Match updated spec for `/\b/iu` and `/\B/iu`
Remove arguments.caller
Status: Removed in Firefox 53 (now Developer Edition, will ship in April 2017).
The caller property on arguments objects, that threw a TypeError when gotten or set, has been removed.
function f() {
"use strict";
arguments.caller; // doesn't throw.
}
f();
Specification Draft
Normative: Remove arguments.caller poison pill
Bugzilla Link
Bug 1324208 – Remove strict arguments poison pill for “caller” property
What’s Next?
We’re also working on implementing ECMAScript proposals.
New Feature
Function.prototype.toString revision (proposal Stage 3)
Status: Work in progress.
This proposal standardizes the string representation of functions to make it interoperable between browsers.
Proposal
Function.prototype.toString revision
Bugzilla Link
Bug 1317400 – Implement “Function.prototype.toString revision” proposal
Lifting Template Literal Restriction (proposal Stage 3)
Status: Available from Firefox 53 (now Developer Edition, will ship in April 2017).
This proposal removes a restriction on escape sequences in Tagged Template Literals.
If an invalid escape sequence is found in a tagged template literal, the template value becomes undefined but the template raw value becomes the raw string.
function f(callSite) {
console.log(callSite); // [undefined]
console.log(callSite.raw); // ["\\f. (\\x. f (x x)) (\\x. f (x x))"]
}
f`\f. (\x. f (x x)) (\x. f (x x))`;
Proposal
Template Literal Revision
Bugzilla Link
Bug 1317375 – Implement “Template Literals Revision / Lifting Template Literal Restriction” ECMAScript proposal
Async Iteration (proposal Stage 3)
Status: Work in progress.
The Async Iteration proposal comes with two new features: async generator and for-await-of syntax.
The async generator is a mixture of a generator function and an async function. It can contain yield, yield*, and await. It returns a generator object that behaves asynchronously by returning promises from next/throw/return methods.
The for-await-of syntax can be used inside an async function and an async generator. It behaves like for-of, but interacts with the async generator and awaits internally on the returned promise.
async function* loadImagesSequentially(urls) {
for (let url of urls) {
yield await loadImage(url);
}
}
async function processImages(urls) {
let processedImages = [];
for await (let image of loadImagesSequentially(urls)) {
let processedImage = await processImageInWorker(image);
processedImages.push(processedImage);
}
return processedImage;
}
Proposal
Async Iteration
Bugzilla Link
Bug 1331092 – Implement Async Iteration
Conclusion
100% on the ES2016+ compatibility table is an important milestone to achieve, but the ECMAScript language will continue evolving. We’ll keep working on implementing new features and fixing existing ones to make them standards-compliant and improve their performance. If you find any bug, performance issue, or compatibility fault, please let us know by filing a bug in Bugzilla. Firefox’s JavaScript engine engineers can also be found in #jsapi on irc.mozilla.org. [Less]
|
Posted
about 7 years
ago
by
Tooru Fujisawa
After the release of ECMAScript 2015, a.k.a. ES6, the ECMAScript Language Specification is evolving rapidly: it’s getting many new features that will help developing web applications, with a new release planned every year.
Last week, Firefox Nightly
... [More]
54 reached 100% on the Kangax ECMAScript 2016+ compatibility table that currently covers and the ECMAScript 2017 draft.
Here are some highlights for those spec updates.
ECMAScript 2016
ECMAScript 2016 is the latest stable edition of the ECMAScript specification. ECMAScript 2016 introduces two new features, the Exponentiation Operator and Array.prototype.includes, and also contains various minor changes.
New Features
Exponentiation Operator
Status: Available from Firefox 52 (now Beta, will ship in March 2017).
The exponentiation operator (**) allows infix notation of exponentiation.
It’s a shorter and simpler replacement for Math.pow. The operator is right-associative.
// without Exponentiation Operator
console.log(Math.pow(2, 3)); // 8
console.log(Math.pow(2, Math.pow(3, 2)); // 512
// with Exponentiation Operator
console.log(2 ** 3); // 8
console.log(2 ** 3 ** 2); // 512
Specification
Exponentiation Operator
Documentation
Arithmetic Operators – Exponentiation (**)
Bugzilla Links
Bug 1135708 – Implement exponentiation operator (ES7 proposal)
Bug 1291212 – Ship the Exponentiation Operator
Bug 1243858 – Exponentiation Operator precedence update (ES2016/ES7, Stage 4)
Array.prototype.includes
Status: Available from Firefox 43.
Array.prototype.includes is an intuitive way to check the existence of an element in an array, replacing the array.indexOf(element) !== -1 idiom.
let supportedTypes = [
"text/plain",
"text/html",
"text/javascript",
];
// without Array.prototype.includes.
console.log(supportedTypes.indexOf("text/html") !== -1); // true
console.log(supportedTypes.indexOf("image/png") !== -1); // false
// with Array.prototype.includes.
console.log(supportedTypes.includes("text/html")); // true
console.log(supportedTypes.includes("image/png")); // false
Specification
Array.prototype.includes ( searchElement [ , fromIndex ] )
Documentation
Array.prototype.includes()
Bugzilla Links
Bug 1069063 – Implement Array.prototype.includes
Bug 1070767 – Enable {Array, %TypedArray%}.prototype.includes in all builds
Miscellaneous Changes
Generators can’t be constructed
Status: Available from Firefox 43.
Calling generator with new now throws.
function* g() {
}
new g(); // throws
Specifications
CreateDynamicFunction
Runtime Semantics: EvaluateNew(constructProduction, arguments)
Bugzilla Link
Bug 1191486 – Generators should not have [[Construct]]
Iterator for yield* can catch throw()
Status: Available from Firefox 27.
When Generator.prototype.throw is called on a generator while it’s executing yield*, the operand of the yield* can catch the exception and return to normal completion.
function* inner() {
try {
yield 10;
yield 11;
} catch (e) {
yield 20;
}
}
function* outer() {
yield* inner();
}
let g = outer();
console.log(g.next().value); // 10
console.log(g.throw().value); // 20, instead of throwing
Specifications
Runtime Semantics: Evaluation – YieldExpression : yield * AssignmentExpression
Normative: Fix yield * semantics when calling .throw
Documentation
yield*
Bugzilla Link
Bug 666396 – implement yield* operator
Function with non-simple parameters can’t have “use strict”
Status: Available from Firefox 52 (now Beta, will ship in March 2017).
When a function has non-simple parameters (destructuring parameters, default parameters, or rest parameters), the function can’t have the "use strict" directive in its body.
function assertEq(a, b, message="") {
"use strict"; // error
// ...
}
However, functions with non-simple parameters can appear in code that’s already strict mode.
"use strict";
function assertEq(a, b, message="") {
// ...
}
Specification
Function Definitions – Static Semantics: Early Errors
Bugzilla Link
Bug 1272784 – |function f(a = 1) { “use strict”; }| should throw Early Error.
Nested RestElement in Destructuring
Status: Available from Firefox 47.
Now a rest pattern in destructuring can be an arbitrary pattern, and also be nested.
let [a, ...[b, ...c]] = [1, 2, 3, 4, 5];
console.log(a); // 1
console.log(b); // 2
console.log(c); // [3, 4, 5]
let [x, y, ...{length}] = "abcdef";
console.log(x); // "a"
console.log(y); // "b"
console.log(length); // 4
Specification
BindingRestElement
Bugzilla Link
Bug 1111386 – Support nested rest in destructuring assignment
Remove [[Enumerate]]
Status: Removed in Firefox 47.
The enumerate trap of the Proxy handler has been removed.
Specification
Normative: Remove [[Enumerate]] and associated reflective capabilities
Documentation
Proxy handler.enumerate()
Bugzilla Link
Bug 1246318 – Remove [[Enumerate]] and associated reflective capabilities
ECMAScript 2017 draft
ECMAScript 2017 will be the next edition of ECMAScript specification, currently in draft. The ECMAScript 2017 draft introduces several new features, Object.values / Object.entries, Object.getOwnPropertyDescriptors, String padding, trailing commas in function parameter lists and calls, Async Functions, Shared memory and atomics, and also some minor changes.
New Features
Async Functions
Status: Available from Firefox 52 (now Beta, will ship in March 2017).
Async functions help with long promise chains broken up to separate scopes, letting you write the chains just like a synchronous function.
When an async function is called, it returns a Promise that gets resolved when the async function returns. When the async function throws, the promise gets rejected with the thrown value.
An async function can contain an await expression. That receives a promise and returns a resolved value. If the promise gets rejected, it throws the reject reason.
async function makeDinner(candidates) {
try {
let itemsInFridge = await fridge.peek();
let itemsInStore = await store.peek();
let recipe = await chooseDinner(
candidates,
itemsInFridge,
itemsInStore,
);
let [availableItems, missingItems]
= await fridge.get(recipe.ingredients);
let boughtItems = await store.buy(missingItems);
pot.put(availableItems, boughtItems);
await pot.startBoiling(recipe.temperature);
do {
await timer(5 * 60);
} while(taste(pot).isNotGood());
await pot.stopBoiling();
return pot;
} catch (e) {
return document.cookie;
}
}
async function eatDinner() {
eat(await makeDinner(["Curry", "Fried Rice", "Pizza"]));
}
Specification Drafts
AsyncFunctionDeclaration
AsyncFunctionExpression
AsyncArrowFunction
AsyncMethod
AsyncFunction Objects
AwaitExpression
Documentation
Async Function declaration
Async Function expression
Async methods
AsyncFunction
await
Bugzilla Link
Bug 1185106 – Implement async functions (ES 2017 proposal)
Shared memory and atomics
Status: Available behind a flag from Firefox 52 (now Beta, will ship in March 2017).
SharedArrayBuffer is an array buffer pointing to data that can be shared between Web Workers. Views on a shared memory can be created with the TypedArray and DataView constructors.
When transferring SharedArrayBuffer between the main thread and a worker, the underlying data is not transferred but instead the information about the data in memory is sent. As a result it reduces the cost of using a worker to process data retrieved on main thread, and also makes it possible to process data in parallel on multiple workers without creating separate data for each.
// main.js
let worker = new Worker("worker.js");
let sab = new SharedArrayBuffer(IMAGE_SIZE);
worker.onmessage = functions(event) {
let image = createImageFromBitmap(event.data.buffer);
document.body.appendChild(image);
};
captureImage(sab);
worker.postMessage({buffer: sab})
// worker.js
onmessage = function(event) {
let sab = event.data.buffer;
processImage(sab);
postMessage({buffer: sab});
};
Moreover, a new API called Atomics provides low-level atomic access and synchronization primitives for use with shared memory. Lars T Hansen has already written about this in the Mozilla Hacks post “A Taste of JavaScript’s New Parallel Primitives“.
Specifications Draft
SharedArrayBuffer Objects
The Atomics Object
Documentation
SharedArrayBuffer
Atomics
Bugzilla Links
Bug 1054841 – [meta] Shared memory for web workers
Bug 1312446 – Enable SharedArrayBuffer and Atomics in Firefox 52 Beta and Release
Object.values / Object.entries
Status: Available from Firefox 47.
Object.values returns an array of a given object’s own enumerable property values, like Object.keys does for property keys, and Object.entries returns an array of [key, value] pairs.
Object.entries is useful to iterate over objects.
createElement("img", {
width: 320,
height: 240,
src: "http://localhost/a.png"
});
// without Object.entries
function createElement(name, attributes) {
let element = document.createElement(name);
for (let name in attributes) {
let value = attributes[name];
element.setAttribute(name, value);
}
return element;
}
// with Object.entries
function createElement(name, attributes) {
let element = document.createElement(name);
for (let [name, value] of Object.entries(attributes)) {
element.setAttribute(name, value);
}
return element;
}
When property keys are not used in the loop, Object.values can be used.
Specification Drafts
Object.values ( O )
Object.entries ( O )
Documentation
Object.values()
Object.entries()
Bugzilla Links
Bug 1208464 – Implement proposed ES7 functions Object.values and Object.entries
Bug 1232639 – Optimize Object.values() and Object.entries() and let them ride the trains
Object.getOwnPropertyDescriptors
Status: Available from Firefox 50.
Object.getOwnPropertyDescriptors returns all own property descriptors of a given object.
The return value of Object.getOwnPropertyDescriptors can be passed to Object.create, to create a shallow copy of the object.
function shallowCopy(obj) {
return Object.create(Object.getPrototypeOf(obj),
Object.getOwnPropertyDescriptors(obj));
}
Specification Draft
Object.getOwnPropertyDescriptors ( O )
Documentation
Object.getOwnPropertyDescriptors()
Bugzilla Link
Bug 1245024 – [es7] implement Object.getOwnPropertyDescriptors() proposal
String padding
Status: Available from Firefox 48.
String.prototype.padStart and String.prototype.padEnd add padding to a string, if necessary, to extend it to the given maximum length. The padding characters can be specified by argument.
They can be used to output data in a tabular format, by adding leading spaces (align to end) or trailing spaces (align to start), or to add leading "0" to numbers.
let stock = {
apple: 105,
pear: 52,
orange: 78,
};
for (let [name, count] of Object.entries(stock)) {
console.log(name.padEnd(10) + ": " + String(count).padStart(5, 0));
// "apple : 00105"
// "pear : 00052"
// "orange : 00078"
}
Specification Drafts
String.prototype.padStart( maxLength [ , fillString ] )
String.prototype.padEnd( maxLength [ , fillString ] )
Documentation
String.prototype.padStart()
String.prototype.padEnd()
Bugzilla Link
Bug 1260509 – Implement String.prototype.padStart / padEnd
Trailing commas in function parameter lists and calls
Status: Available from Firefox 52 (now Beta, will ship in March 2017).
Just like array elements and object properties, function parameter list and function call arguments can now have trailing commas, except for the rest parameter.
function addItem(
name,
price,
count = 1,
) {
}
addItem(
"apple",
30,
2,
);
This simplifies generating JavaScript code programatically, i.e. transpiling from other language. Code generator doesn’t have to worry about whether to emit comma or not, while emitting function parameters or function call arguments.
Also this makes it easier to rearrange parameters by copy/paste.
Specification Drafts
FormalParameters
CoverParenthesizedExpressionAndArrowParameterList
Arguments
Bugzilla Link
Bug 1303788 – ES2017: Implement trailing comma proposal
Miscellaneous Changes
Remove proxy OwnPropertyKeys error with duplicate keys
Status: Available from Firefox 51.
The ownKeys trap of a user-defined Proxy handler is now permitted to return duplicate keys for non-extensible object.
let nonExtensibleObject = Object.preventExtensions({ a: 10 });
let x = new Proxy(nonExtensibleObject, {
ownKeys() {
return ["a", "a", "a"];
}
});
Object.getOwnPropertyNames(x); // ["a", "a", "a"]
Specification Drafts
[[OwnPropertyKeys]] ( )
Normative: Remove proxy OwnPropertyKeys error with duplicate keys
Bugzilla Link
Bug 1293995 – Remove proxy OwnPropertyKeys error with duplicate keys
Case folding for \w, \W, \b, and \B in unicode RegExp
Status: Available from Firefox 54 (now Nightly, will ship in June 2017).
\w, \W, \b, and \B in RegExp with unicode+ignoreCase flags now treat U+017F (LATIN SMALL LETTER LONG S) and U+212A (KELVIN SIGN) as word characters.
console.log(/\w/iu.test("\u017F")); // true
console.log(/\w/iu.test("\u212A")); // true
Specification Drafts
Runtime Semantics: WordCharacters ( )
Unify handling of RegExp CharacterClassEscapes \w and \W and Word Asserts \b and \B
Bugzilla Link
Bug 1281739 – Match updated spec for `/\w/iu` and `/\W/iu`
Bug 1338373 – Match updated spec for `/\b/iu` and `/\B/iu`
Remove arguments.caller
Status: Removed in Firefox 53 (now Developer Edition, will ship in April 2017).
The caller property on arguments objects, that threw a TypeError when gotten or set, has been removed.
function f() {
"use strict";
arguments.caller; // doesn't throw.
}
f();
Specification Draft
Normative: Remove arguments.caller poison pill
Bugzilla Link
Bug 1324208 – Remove strict arguments poison pill for “caller” property
What’s Next?
We’re also working on implementing ECMAScript proposals.
New Feature
Function.prototype.toString revision (proposal Stage 3)
Status: Work in progress.
This proposal standardizes the string representation of functions to make it interoperable between browsers.
Proposal
Function.prototype.toString revision
Bugzilla Link
Bug 1317400 – Implement “Function.prototype.toString revision” proposal
Lifting Template Literal Restriction (proposal Stage 3)
Status: Available from Firefox 53 (now Developer Edition, will ship in April 2017).
This proposal removes a restriction on escape sequences in Tagged Template Literals.
If an invalid escape sequence is found in a tagged template literal, the template value becomes undefined but the template raw value becomes the raw string.
function f(callSite) {
console.log(callSite); // [undefined]
console.log(callSite.raw); // ["\\f. (\\x. f (x x)) (\\x. f (x x))"]
}
f`\f. (\x. f (x x)) (\x. f (x x))`;
Proposal
Template Literal Revision
Bugzilla Link
Bug 1317375 – Implement “Template Literals Revision / Lifting Template Literal Restriction” ECMAScript proposal
Async Iteration (proposal Stage 3)
Status: Work in progress.
The Async Iteration proposal comes with two new features: async generator and for-await-of syntax.
The async generator is a mixture of a generator function and an async function. It can contain yield, yield*, and await. It returns a generator object that behaves asynchronously by returning promises from next/throw/return methods.
The for-await-of syntax can be used inside an async function and an async generator. It behaves like for-of, but interacts with the async generator and awaits internally on the returned promise.
async function* loadImagesSequentially(urls) {
for (let url of urls) {
yield await loadImage(url);
}
}
async function processImages(urls) {
let processedImages = [];
for await (let image of loadImagesSequentially(urls)) {
let processedImage = await processImageInWorker(image);
processedImages.push(processedImage);
}
return processedImage;
}
Proposal
Async Iteration
Bugzilla Link
Bug 1331092 – Implement Async Iteration
Conclusion
100% on the ES2016+ compatibility table is an important milestone to achieve, but the ECMAScript language will continue evolving. We’ll keep working on implementing new features and fixing existing ones to make them standards-compliant and improve their performance. If you find any bug, performance issue, or compatibility fault, please let us know by filing a bug in Bugzilla. Firefox’s JavaScript engine engineers can also be found in #jsapi on irc.mozilla.org. [Less]
|
Posted
about 7 years
ago
I wrote a Rust crate to demangle C++ symbols: cpp_demangle. Find it
on crates.io and github.
C++ symbols are mangled? Why?
Yes.
Linkers only support C identifiers for symbol names. They don’t have any
knowledge of C++’s namespaces
... [More]
, monomorphization of a template function,
overloaded functions, etc. That means that the C++ compiler needs to generate C
identifier compatible symbols for C++ constructs. This process is called
“mangling”, the resulting symbol is a “mangled symbol”, and reconstructing the
original C++ name is “demangling”.
Let’s take an overloaded function as a concrete example. Say there are two
overloads: one that takes a char* and another that takes an int:
void overloaded(char* string) { /* ... */ }
void overloaded(int n) { /* ... */ }
Although overloaded is a valid C identifier that the linker could understand,
we can’t name both versions of the function overloaded because we need to
differentiate them from each other for the linker.
We can see mangling in action if we run nm on the object file:
$ nm -j overloaded.o
__Z10overloadedPc
__Z10overloadedi
There is some prefixed gunk and then the types of parameters got mangled
themselves and appended to the end of the function name: Pc for a pointer to a
char, and i for int.
Here is a more complex example:
namespace foo {
template <typename T>
struct Bar {
void some_method(Bar<T>* one, Bar<T>* two, Bar<T>* three) {
/* ... */
}
};
}
void instantiate() {
// Instantiate a Foo and trigger a Foo::some_method
// monomorphization.
foo::Bar<int> foo_bar_int;
foo_bar_int.some_method(&foo_bar_int, &foo_bar_int, &foo_bar_int);
// And do the same for Foo.
foo::Bar<char*> foo_bar_char;
foo_bar_char.some_method(&foo_bar_char, &foo_bar_char, &foo_bar_char);
}
This time the mangled symbols are a bit less human readable, and its a bit less
obvious where some of the mangled bits even came from:
$ nm -j complex.o
__Z11instantiatev
__ZN3foo3BarIPcE11some_methodEPS2_S3_S3_
__ZN3foo3BarIiE11some_methodEPS1_S2_S2_
Do compilers have to agree on the mangling format?
If they want code compiled from one compiler to inter-operate with code compiled
from another compiler (or even different versions of the same compiler), then
yes, they need to agree on names.
These days, almost every C++ compiler uses
the Itanium C++ ABI’s name mangling rules. The notable exception is
MSVC, which uses a completely different format.
We’ve been looking at the Itanium C++ ABI style mangled names, and that’s what
cpp_demangle supports.
Why demangle C++ symbols in Rust?
A few reasons:
I wanted to demangle some C++ symbols
for gimli’s addr2line clone. But I also didn’t want to
introduce complexity into the build system for some old C code, nor a
dependency on a system library outside of the Rust ecosystem, nor spawn a
c++filt subprocess.
Tom Tromey, a GNU hacker and buddy of mine, mentioned that
historically, the canonical C++ demangler in libiberty (used by c++filt
and gdb) has had tons of classic C bugs: use-after-free, out-of-bounds array
accesses, etc, and that it falls over immediately when faced with a fuzzer. In
fact, there were so many of these issues that gdb went so far as to install
a signal handler to catch SIGSEGVs during demangling. It “recovered” from
the segfaults by longjmping out of the signal handler and printing a warning
message before moving along and pretending that nothing happened. My ears
perked up. Those are the exact kinds of things Rust protects us from at
compile time! A robust alternative might actually be a boon not just for the
Rust community, but everybody who wants to demangle C++ symbols.
Finally, I was looking for something to kill a little bit of free time.
What I didn’t anticipate was how complicated parsing mangled C++ symbols
actually is! The second bullet point should have been a hint. I hadn’t looked to
deeply into how C++ symbols are mangled, and I expected simple replacement
rules. But if that was the case, why would the canonical demangler have had so
many bugs?
What makes demangling C++ symbols difficult?
Maybe I’ve oversold how complicated it is a little bit: it isn’t terribly
difficult, its just more difficult than I expected it was going to be. That
said, here are some things I didn’t expect.
The grammar is pretty huge, and has to allow encoding all of C++’s
expressions, e.g. because of decltype. And its not just the grammar that’s
huge, the symbols themselves are too. Here is a pretty big mangled C++ symbol
from SpiderMonkey, Firefox’s JavaScript engine:
__ZN7mozilla6detail21VariantImplementationIhLm3EJNS_5TupleIJPN2js12NativeObjectEP8JSObjectNS3_19CrossCompartmentKey18DebuggerObjectKindEEEEEE5matchIRZNS8_14applyToWrappedIN12_GLOBAL__N_128NeedsSweepUnbarrieredFunctorEEEDTclfp_scPS7_LDnEEET_E14WrappedMatcherNS_7VariantIJS7_P8JSStringNS2_IJS5_P8JSScriptEEESA_EEEEEDTcldtfp_5matchcldtfp0_2asISA_EEEEOSI_RT0_
That’s 355 bytes!
And here is its demangled form – even bigger, with a whopping 909 bytes!
decltype(fp.match(fp0.as >())) mozilla::detail::VariantImplementation >::match(std::nullptr_t))) js::CrossCompartmentKey::applyToWrapped<(anonymous namespace)::NeedsSweepUnbarrieredFunctor>((anonymous namespace)::NeedsSweepUnbarrieredFunctor)::WrappedMatcher&, mozilla::Variant, mozilla::Tuple > >((anonymous namespace)::NeedsSweepUnbarrieredFunctor&&, mozilla::Variant, mozilla::Tuple >&)
The mangled symbol is smaller than the demangled form because the name mangling
algorithm also specifies a symbol compression algorithm:
To minimize the length of external names, we use two mechanisms, a
substitution encoding to eliminate repetition of name components, and
abbreviations for certain common names. Each non-terminal in the grammar above
for which appears on the right-hand side is both a source of
future substitutions and a candidate for being substituted.
After the first appearance of a type in the mangled symbol, all subsequent
references to it must actually be back references pointing to the first
appearance. The back references are encoded as S i _ where
i is the i + 1th substitutable AST node in an in-order walk of
the AST (and S_ is the 0th).
We have to be careful not to mess up the order in which we populate the
substitutions table. If we got it wrong, then all the back references will point
to the wrong component, and the final output of demangling will be
garbage. cpp_demangle uses a handwritten recursive descent parser. This makes
it easy to build the substitutions table as we parse the mangled symbol,
avoiding a second back reference resolution pass over the AST after
parsing. Except there’s a catch: the grammar contains left-recursion, which will
cause naive recursive descent parsers to infinitely recurse and blow the
stack. Can we transform the grammar to remove the left-recursion?
Nope. Although we would parse the exact same set of mangled symbols, the
resulting parse tree would be different, invalidating our substitutions table
and back references! Instead, we resign ourselves to peeking ahead a character
and switching on it.
The compression also means that the demangled symbol can be exponentially larger
than the mangled symbol in the worst case! Here is an example that makes it
plain:
template <typename T, typename U>
struct Pair {
T t;
U u;
};
using Pair2 = Pair<int, int>;
using Pair4 = Pair<Pair2, Pair2>;
using Pair8 = Pair<Pair4, Pair4>;
using Pair16 = Pair<Pair8, Pair8>;
using Pair32 = Pair<Pair16, Pair16>;
using Pair64 = Pair<Pair32, Pair32>;
using Pair128 = Pair<Pair64, Pair64>;
using Pair256 = Pair<Pair128, Pair128>;
using Pair512 = Pair<Pair256, Pair256>;
void lets_get_exponential(Pair512* p) {
/* ... */
}
The mangled lets_get_exponential symbol is 91 bytes long:
__Z20lets_get_exponentialP4PairIS_IS_IS_IS_IS_IS_IS_IS_IiiES0_ES1_ES2_ES3_ES4_ES5_ES6_ES7_E
The demangled lets_get_exponential symbol is 5902 bytes long; too big to
include here, but you can run that symbol through c++filt to verify it
yourself.
The final thing to watch out for with compression and back references is
malicious input that creates cycles with the references. If we aren’t checking
for and defending against cycles, we could hang indefinitely in the best case,
or more likely infinitely recurse and blow the stack.
What’s the implementation status?
The cpp_demangle crate can parse every mangled C++ symbol I’ve thrown at it,
and it can demangle them too. However, it doesn’t always match libiberty’s C++
demangler’s formatting character-for-character. I’m currently in the process of
getting all of libiberty’s C++ demangling tests passing.
Additionally, I’ve been running American Fuzzy Lop (with afl.rs) on
cpp_demangle overnight. It found a panic involving unhandled integer overflow,
which I fixed. Since then, AFL hasn’t triggered any panics, and its never been
able to find a crash (thanks Rust!) so I think cpp_demangle is fairly solid
and robust.
If you aren’t too particular about formatting, then cpp_demangle is ready for
you right now. If you do care more about formatting, it will be ready for you
soon.
What’s next?
Finish getting all the tests in libiberty’s test suite passing, so
cpp_demangle is character-for-character identical with libiberty’s C++
demangler.
Add a C API, so that non-Rust projects can use cpp_demangle.
Add benchmarks and compare performance with libiberty’s C++ demangler. Make
sure cpp_demangle is faster ;-)
A couple other things listed in the github issues.
That’s it! See you later, and happy demangling!
Thanks to Tom Tromey for sharing GNU war stories with me, and providing
feedback on an early draft of this blog post. [Less]
|
Posted
about 7 years
ago
by
[email protected] (ClassicHasClass)
45.8.0b1 is available (downloads, hashes). This was supposed to be in your hands last week, but I had a prolonged brownout (68VAC on the mains! thanks, So Cal Edison!) which finally pushed the G4 file server over the edge and ruined various other
... [More]
devices followed by two extended blackouts, so the G5 was just left completely off all week and I did work on my iBook G4 and i7 MBA until I was convinced I wasn't going to regret powering the Quad back on again. The other reason for the delay is because there's actually a lot of internal changes in this release: besides including the work so far on Operation Short Change (there is still a fair bit more to do, but this current snapshot improves benchmarks anywhere from four to eight percent depending on workload), this also has numerous minor bug fixes imported from later versions of Firefox and continues removing telemetry from UI-facing code to improve browser responsiveness. I also smoked out and fixed many variances from the JavaScript conformance test suite, mostly minor, but this now means we are fully compliant and some classes of glitchy bugs should just disappear. But there are two other big changes in this release. The first is to font support. While updating the ATSUI font blacklist for Apple's newest crock of crap, the fallback font (Helvetica Neue) appeared strangely spaced, with words as much as a 1/6th of the page between them. This looks like it's due to the 10.4-compatible way we use for getting native font metrics; there appears to be some weird edge case in CGFontGetGlyphAdvances() that occasionally yields preposterous values, meaning we've pretty much shipped this problem since the very beginning of TenFourFox and no one either noticed or reported it. It's not clear to me why (or if) other glyphs are unaffected but in the meantime the workaround is to check if the space glyph's horizontal advance value is redonkulous and if it is, assuming the font metrics are not consistent with a non-proportional font, heuristically generate a more reasonable size. In the process I also tuned up font handling a little bit, so text run generation should be a tiny bit faster as well. The second is this: As promised, user agent switching is now built-in to TenFourFox; no extension is required (and you should disable any you have installed or they may conflict). I chose five alternatives which have been useful to me in the past for sites that balk at TenFourFox (including cloaking your Power Mac as Intel Firefox), or for lower-powered systems, including the default Classilla user agent. I thought about allowing an arbitrary string but frankly you could do that in about:config if you really wanted, and was somewhat more bookwork. However, I'm willing to entertain additional suggestions for user agent strings that work well on a variety of sites. For fun, open Google in one tab and the preferences pane in another, change the agent to a variety of settings, and watch what happens to Google as you reload it. Note that the user agent switching feature is not intended to hide you're using TenFourFox; it's just for stupid sites that don't properly feature-sniff the browser (Chase Bank, I'm looking at yoooooouuuuu). The TenFourFox start page can still determine you're using TenFourFox for the purpose of checking if your browser is out of date by looking at navigator.isTenFourFox, which I added to 45.8 (it will only be defined in TenFourFox; the value is undefined in other browsers). And yes, there really are some sites that actually check for TenFourFox and serve specialized content, so this will preserve that functionality once they migrate to checking for the browser this way. If you notice font rendering is awry in this version, please compare it with 45.7 before reporting it. Even if the bug is actually old I'd still like to fix it, but new regressions are more serious than something I've been shipping for awhile. Similarly, please advise on user agent strings you think are useful, and I will consider them (no promises). 45.8 is scheduled for release on March 7. Finally, last but not least, who says you can't run Google Chrome on a Power Mac? Okay, okay, this is the PowerPC equivalent of a stupid pet trick, but this is qemu 2.2.1 (the last version that did not require thread-local storage, which won't work with OS X 10.6 and earlier) running on the Quad as a 64-bit PC, booting Instant Web Kiosk into Chromium 53. It is incredibly, crust-of-the-earth-coolingly slow, and that nasty blue tint is an endian problem in the emulator I need to smoke out. But it actually can browse websites (eventually, with patience, after a fashion) and do web-browsery things, and I was even able to hack the emulator to run on 10.4, a target this version of qemu doesn't support. So what's the point of running a ridiculously sluggish emulated web browser, particularly one I can't stand for philosophical reasons? Well, there's gotta be something I can work on "After TenFourFox"™ ... Jokes aside, even though I see some optimization possibilities in the machine code qemu's code generator emits, those are likely to yield only marginal improvements. Emulation will obviously never be anywhere near as fast as native code. If I end up doing anything with this idea of emulation for future browser support, it would likely only be for high-end G5 systems, and it may never be practical even then. But, hey, Google, guess what: it only took seven years to get Chrome running on a Tiger Power Mac. [Less]
|
Posted
about 7 years
ago
by
Air Mozilla
CLTC will present on Cybersecurity Futures 2020, a report that poses five scenarios for what cybersecurity may look like in 2020, extrapolating from technological, social,...
|
Posted
about 7 years
ago
by
Daniel Stenberg
We released the 163rd curl release ever today. curl 7.53.0 – approaching 19 years since the first curl release (6914 days to be exact).
It took 61 days since the previous release, during which 47 individuals helped us fix 95 separate bugs. 25 of
... [More]
these contributors were newcomers. In total, we now count more than 1500 individuals credited for their help in the project.
One of those bug-fixes, one was a security vulnerability, upping our total number of vulnerabilities through the years to 62.
Since the previous release, 7.52.1, 155 commits were made to the source repository.
The next curl release, our 164th, is planned to ship in exactly 8 weeks. [Less]
|