Bug 1648574 - Support lazy function. r=nbp

Differential Revision: https://phabricator.services.mozilla.com/D85363
This commit is contained in:
Tooru Fujisawa 2020-07-30 11:01:52 +00:00
parent d16e97fa44
commit 188db27510
17 changed files with 614 additions and 497 deletions

View File

@ -25,7 +25,7 @@ rev = "61dcc364ac0d6d0816ab88a494bbf20d824b009b"
[source."https://github.com/mozilla-spidermonkey/jsparagus"]
git = "https://github.com/mozilla-spidermonkey/jsparagus"
replace-with = "vendored-sources"
rev = "fb2a93267697c33d54e71be4bb5e8e768760c27c"
rev = "16bc2e48694c2a5b3cca854271f58cf8aae18a0e"
[source."https://github.com/kvark/spirv_cross"]
branch = "wgpu3"

16
Cargo.lock generated
View File

@ -2399,7 +2399,7 @@ dependencies = [
[[package]]
name = "jsparagus"
version = "0.1.0"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=fb2a93267697c33d54e71be4bb5e8e768760c27c#fb2a93267697c33d54e71be4bb5e8e768760c27c"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=16bc2e48694c2a5b3cca854271f58cf8aae18a0e#16bc2e48694c2a5b3cca854271f58cf8aae18a0e"
dependencies = [
"jsparagus-ast",
"jsparagus-emitter",
@ -2413,7 +2413,7 @@ dependencies = [
[[package]]
name = "jsparagus-ast"
version = "0.1.0"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=fb2a93267697c33d54e71be4bb5e8e768760c27c#fb2a93267697c33d54e71be4bb5e8e768760c27c"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=16bc2e48694c2a5b3cca854271f58cf8aae18a0e#16bc2e48694c2a5b3cca854271f58cf8aae18a0e"
dependencies = [
"bumpalo",
"indexmap",
@ -2422,7 +2422,7 @@ dependencies = [
[[package]]
name = "jsparagus-emitter"
version = "0.1.0"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=fb2a93267697c33d54e71be4bb5e8e768760c27c#fb2a93267697c33d54e71be4bb5e8e768760c27c"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=16bc2e48694c2a5b3cca854271f58cf8aae18a0e#16bc2e48694c2a5b3cca854271f58cf8aae18a0e"
dependencies = [
"bumpalo",
"byteorder",
@ -2435,7 +2435,7 @@ dependencies = [
[[package]]
name = "jsparagus-generated-parser"
version = "0.1.0"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=fb2a93267697c33d54e71be4bb5e8e768760c27c#fb2a93267697c33d54e71be4bb5e8e768760c27c"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=16bc2e48694c2a5b3cca854271f58cf8aae18a0e#16bc2e48694c2a5b3cca854271f58cf8aae18a0e"
dependencies = [
"bumpalo",
"jsparagus-ast",
@ -2445,12 +2445,12 @@ dependencies = [
[[package]]
name = "jsparagus-json-log"
version = "0.1.0"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=fb2a93267697c33d54e71be4bb5e8e768760c27c#fb2a93267697c33d54e71be4bb5e8e768760c27c"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=16bc2e48694c2a5b3cca854271f58cf8aae18a0e#16bc2e48694c2a5b3cca854271f58cf8aae18a0e"
[[package]]
name = "jsparagus-parser"
version = "0.1.0"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=fb2a93267697c33d54e71be4bb5e8e768760c27c#fb2a93267697c33d54e71be4bb5e8e768760c27c"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=16bc2e48694c2a5b3cca854271f58cf8aae18a0e#16bc2e48694c2a5b3cca854271f58cf8aae18a0e"
dependencies = [
"arrayvec",
"bumpalo",
@ -2462,7 +2462,7 @@ dependencies = [
[[package]]
name = "jsparagus-scope"
version = "0.1.0"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=fb2a93267697c33d54e71be4bb5e8e768760c27c#fb2a93267697c33d54e71be4bb5e8e768760c27c"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=16bc2e48694c2a5b3cca854271f58cf8aae18a0e#16bc2e48694c2a5b3cca854271f58cf8aae18a0e"
dependencies = [
"indexmap",
"jsparagus-ast",
@ -2472,7 +2472,7 @@ dependencies = [
[[package]]
name = "jsparagus-stencil"
version = "0.1.0"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=fb2a93267697c33d54e71be4bb5e8e768760c27c#fb2a93267697c33d54e71be4bb5e8e768760c27c"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=16bc2e48694c2a5b3cca854271f58cf8aae18a0e#16bc2e48694c2a5b3cca854271f58cf8aae18a0e"
dependencies = [
"jsparagus-ast",
]

View File

@ -95,6 +95,11 @@ class GCVector {
return vector.emplaceBack(std::forward<Args>(args)...);
}
template <typename... Args>
void infallibleEmplaceBack(Args&&... args) {
vector.infallibleEmplaceBack(std::forward<Args>(args)...);
}
template <typename U>
void infallibleAppend(U&& aU) {
return vector.infallibleAppend(std::forward<U>(aU));
@ -254,6 +259,10 @@ class MutableWrappedPtrOperations<JS::GCVector<T, Capacity, AllocPolicy>,
MOZ_MUST_USE bool emplaceBack(Args&&... aArgs) {
return vec().emplaceBack(std::forward<Args>(aArgs)...);
}
template <typename... Args>
void infallibleEmplaceBack(Args&&... args) {
vec().infallibleEmplaceBack(std::forward<Args>(args)...);
}
template <typename U>
MOZ_MUST_USE bool appendAll(const U& aU) {
return vec().appendAll(aU);

View File

@ -3,3 +3,4 @@ non262/String/normalize-generateddata-part1-not-listed.js
non262/String/normalize-generateddata-part1.js
non262/String/normalize-generateddata-part2.js
non262/String/normalize-generateddata-part3.js
non262/regress/regress-155081-2.js

View File

@ -226,7 +226,6 @@ bool ConvertScopeCreationData(JSContext* cx, const SmooshResult& result,
bool hasParameterExprs = function.has_parameter_exprs;
bool needsEnvironment = function.non_positional_formal_start;
// FIXME: Prepare function pointed by this index.
FunctionIndex functionIndex = FunctionIndex(function.function_index);
bool isArrow = function.is_arrow;
@ -369,6 +368,11 @@ bool ConvertGCThings(JSContext* cx, const SmooshResult& result,
mozilla::AsVariant(allAtoms[item.AsAtom()].get()));
break;
}
case SmooshGCThing::Tag::Function: {
gcThings.infallibleAppend(
mozilla::AsVariant(FunctionIndex(item.AsFunction())));
break;
}
case SmooshGCThing::Tag::Scope: {
gcThings.infallibleAppend(
mozilla::AsVariant(ScopeIndex(item.AsScope())));
@ -436,6 +440,21 @@ bool ConvertScriptStencil(JSContext* cx, const SmooshResult& result,
stencil.get().extent.lineno = smooshStencil.extent.lineno;
stencil.get().extent.column = smooshStencil.extent.column;
if (isFunction) {
if (smooshStencil.fun_name.IsSome()) {
stencil.get().functionAtom = allAtoms[smooshStencil.fun_name.AsSome()];
}
stencil.get().functionFlags = FunctionFlags(smooshStencil.fun_flags);
stencil.get().nargs = smooshStencil.fun_nargs;
if (smooshStencil.lazy_function_enclosing_scope_index.IsSome()) {
stencil.get().lazyFunctionEnclosingScopeIndex_ = mozilla::Some(ScopeIndex(
smooshStencil.lazy_function_enclosing_scope_index.AsSome()));
}
stencil.get().isStandaloneFunction = smooshStencil.is_standalone_function;
stencil.get().wasFunctionEmitted = smooshStencil.was_function_emitted;
stencil.get().isSingletonFunction = smooshStencil.is_singleton_function;
}
if (!ConvertGCThings(cx, result, smooshStencil, allAtoms, stencil)) {
return false;
}
@ -537,12 +556,24 @@ JSScript* Smoosh::compileGlobalScript(CompilationInfo& compilationInfo,
return nullptr;
}
// FIXME: Support functions.
if (!ConvertScriptStencil(cx, result, result.top_level_script, allAtoms,
compilationInfo, &compilationInfo.topLevel)) {
return nullptr;
}
if (!compilationInfo.funcData.reserve(result.functions.len)) {
return nullptr;
}
for (size_t i = 0; i < result.functions.len; i++) {
compilationInfo.funcData.infallibleEmplaceBack(cx);
if (!ConvertScriptStencil(cx, result, result.functions.data[i], allAtoms,
compilationInfo, compilationInfo.funcData[i])) {
return nullptr;
}
}
if (!compilationInfo.instantiateStencils()) {
return nullptr;
}

View File

@ -12,12 +12,12 @@ log = "0.4"
# Disable regex feature for code size.
env_logger = {version = "0.6", default-features = false}
# For non-jsparagus developers.
jsparagus = { git = "https://github.com/mozilla-spidermonkey/jsparagus", rev = "fb2a93267697c33d54e71be4bb5e8e768760c27c" }
jsparagus = { git = "https://github.com/mozilla-spidermonkey/jsparagus", rev = "16bc2e48694c2a5b3cca854271f58cf8aae18a0e" }
# For local development, replace above with
# jsparagus = { path = "{path to jsparagus}" }
[build-dependencies]
# For non-jsparagus developers.
jsparagus = { git = "https://github.com/mozilla-spidermonkey/jsparagus", rev = "fb2a93267697c33d54e71be4bb5e8e768760c27c" }
jsparagus = { git = "https://github.com/mozilla-spidermonkey/jsparagus", rev = "16bc2e48694c2a5b3cca854271f58cf8aae18a0e" }
# For local development, replace above with
# jsparagus = { path = "{path to jsparagus}" }

View File

@ -31,8 +31,8 @@ use jsparagus::stencil::script::{ImmutableScriptData, ScriptStencil, SourceExten
use std::boxed::Box;
use std::cell::RefCell;
use std::collections::HashMap;
use std::os::raw::{c_char, c_void};
use std::convert::TryInto;
use std::os::raw::{c_char, c_void};
use std::rc::Rc;
use std::{mem, slice, str};
@ -76,6 +76,7 @@ pub struct SmooshCompileOptions {
pub enum SmooshGCThing {
Null,
Atom(usize),
Function(usize),
Scope(usize),
RegExp(usize),
}
@ -84,9 +85,7 @@ fn convert_gcthing(item: GCThing, scope_index_map: &HashMap<usize, usize>) -> Sm
match item {
GCThing::Null => SmooshGCThing::Null,
GCThing::Atom(index) => SmooshGCThing::Atom(index.into()),
GCThing::Function(_index) => {
panic!("Not yet implemented");
}
GCThing::Function(index) => SmooshGCThing::Function(index.into()),
GCThing::RegExp(index) => SmooshGCThing::RegExp(index.into()),
GCThing::Scope(index) => {
let mapped_index = *scope_index_map

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"00c740f44b5681e3277e519d2e143e6edfbff186ca31a07ddce2eb46b803ddd7","src/array_emitter.rs":"bbc6528321f1d11d7c86c4f2bfdcfc9dced8f0b8b1c30c9f0a5355f300d196b6","src/ast_emitter.rs":"21f666ac7baa953f606d41a26d48cef8cf2c674d9b5953cf45bf539a9630a80b","src/block_emitter.rs":"78965260d87a66c5324d6f3bdfea0f1938f8037f70adde148dbb2db599d1b2c0","src/compilation_info.rs":"32ca7cdae514501de0d0d667ff2b27a3abf736ae207a23009c42eacbdffbd5b3","src/control_structures.rs":"bdb186e98c14fa4e769b23b3dee4376683e6c6530af0856d55c055aff4398b84","src/dis.rs":"4a335d813fa965482ca0f20a7b9295a55ce7625b577d42bd8b33b156b81c6306","src/emitter.rs":"14c06d1cf277a9017ad0feb440e598e9735b0d7c7a272a05bb7c604e34e8b8aa","src/emitter_scope.rs":"ba924ef541742a5c7be39d1b683bf3107241cf3ff5b8ff7f93987abc9f52e9d2","src/expression_emitter.rs":"f8e02785dffb179bbe9fe58e45bbfccc08adc3ad0a071a0073bed0feedc8ed9a","src/function_declaration_emitter.rs":"d76570732fd2d706f7861bf8be559ce998b25c8e028342831b759b17c54f7c13","src/lib.rs":"43285b5ddf164de2d90fc989ac25211e3e716751e6218df45f651ea75137d0f5","src/object_emitter.rs":"998423b3d6ef8797fadef6763803627df72fde292b1b34d6a41b2e66a331a181","src/reference_op_emitter.rs":"87c7e05934718921d72977746b93513850eab69465d33e190003cb86241f62b4","src/script_emitter.rs":"44a6be5ecdcde3c32d78d100a205d38be2591c7c2cc109967579af7393e09fe8"},"package":null}
{"files":{"Cargo.toml":"00c740f44b5681e3277e519d2e143e6edfbff186ca31a07ddce2eb46b803ddd7","src/array_emitter.rs":"bbc6528321f1d11d7c86c4f2bfdcfc9dced8f0b8b1c30c9f0a5355f300d196b6","src/ast_emitter.rs":"0a858e7cec12a3027f1ab5121a7f84f8493c38a7ea32bad4c9f0d8bf88d1cbba","src/block_emitter.rs":"78965260d87a66c5324d6f3bdfea0f1938f8037f70adde148dbb2db599d1b2c0","src/compilation_info.rs":"32ca7cdae514501de0d0d667ff2b27a3abf736ae207a23009c42eacbdffbd5b3","src/control_structures.rs":"bdb186e98c14fa4e769b23b3dee4376683e6c6530af0856d55c055aff4398b84","src/dis.rs":"4a335d813fa965482ca0f20a7b9295a55ce7625b577d42bd8b33b156b81c6306","src/emitter.rs":"14c06d1cf277a9017ad0feb440e598e9735b0d7c7a272a05bb7c604e34e8b8aa","src/emitter_scope.rs":"ba924ef541742a5c7be39d1b683bf3107241cf3ff5b8ff7f93987abc9f52e9d2","src/expression_emitter.rs":"f8e02785dffb179bbe9fe58e45bbfccc08adc3ad0a071a0073bed0feedc8ed9a","src/function_declaration_emitter.rs":"d76570732fd2d706f7861bf8be559ce998b25c8e028342831b759b17c54f7c13","src/lib.rs":"43285b5ddf164de2d90fc989ac25211e3e716751e6218df45f651ea75137d0f5","src/object_emitter.rs":"998423b3d6ef8797fadef6763803627df72fde292b1b34d6a41b2e66a331a181","src/reference_op_emitter.rs":"87c7e05934718921d72977746b93513850eab69465d33e190003cb86241f62b4","src/script_emitter.rs":"44a6be5ecdcde3c32d78d100a205d38be2591c7c2cc109967579af7393e09fe8"},"package":null}

View File

@ -137,9 +137,7 @@ impl<'alloc, 'opt> AstEmitter<'alloc, 'opt> {
TopLevelFunctionDeclarationEmitter { fun_index }.emit(self);
Err(EmitError::NotImplemented(
"TODO: Populate ScriptStencil fields",
))
Ok(())
}
fn emit_non_top_level_function_declaration(&mut self, fun: &Function) -> Result<(), EmitError> {
@ -176,9 +174,7 @@ impl<'alloc, 'opt> AstEmitter<'alloc, 'opt> {
LexicalFunctionDeclarationEmitter { fun_index, name }.emit(self)?;
}
Err(EmitError::NotImplemented(
"TODO: Populate ScriptStencil fields",
))
Ok(())
}
fn emit_statement(&mut self, ast: &Statement) -> Result<(), EmitError> {

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"553be3c198fe555913bbeb7473b24e0e1fff12e48890a2e399b311df8a97c814","src/ast_builder.rs":"ff3cd595b70e8359b4ce9ce78b066890a78572fee923fcd8cadd029b8fbc4d7a","src/context_stack.rs":"29331d03cd4c8ee9283cb426ebe893b7ba6ad6d8a69016399c4d92a81cb1363b","src/declaration_kind.rs":"fdfda2fe408cce1c637d17fee0813160619450472c6de9befc36ebeed892cc3c","src/early_error_checker.rs":"150a106a8f0901b72ae40581f0c12f785983514cbc9042404ed6cf4315693d60","src/early_errors.rs":"8674454af7ac5efe51eb6a8e2abe088aad5560e0a0bd88a3eae66c90f1527149","src/error.rs":"507e4dd9c66720f3da2db135c3024392d8aaac5ccdb90c7f7463ccb2eff7efa8","src/lib.rs":"b74105a84c4a141b880439f9ec724f7dc08224342be08a73490ac2c01410af08","src/parser_tables_generated.rs":"ead73abf96c1ff968faa25b92d1e77802530c4fcce68e4529242fe1d4e359d10","src/stack_value_generated.rs":"ce8567634ff2bb818593f56c0589b4ba2d508704db943eb0778d79dfd19cce36","src/token.rs":"479f4cb97d2e6bc654a70634f3809817cc73eaf749c845643beb3556b9ead383","src/traits/mod.rs":"ba74c71f7218027f8188247bc64df243117613fbc9893d40799402ef1e6dbf59"},"package":null}
{"files":{"Cargo.toml":"553be3c198fe555913bbeb7473b24e0e1fff12e48890a2e399b311df8a97c814","src/ast_builder.rs":"85cdbf14c559cf98837ef83cca84f28ff4e30498d507cda675c4ed4e02bdd3ea","src/context_stack.rs":"29331d03cd4c8ee9283cb426ebe893b7ba6ad6d8a69016399c4d92a81cb1363b","src/declaration_kind.rs":"fdfda2fe408cce1c637d17fee0813160619450472c6de9befc36ebeed892cc3c","src/early_error_checker.rs":"89da86f7f78392cb60a909c240e430779eed0fc250b3b3c8466665eeaf2fbc25","src/early_errors.rs":"8674454af7ac5efe51eb6a8e2abe088aad5560e0a0bd88a3eae66c90f1527149","src/error.rs":"507e4dd9c66720f3da2db135c3024392d8aaac5ccdb90c7f7463ccb2eff7efa8","src/lib.rs":"b74105a84c4a141b880439f9ec724f7dc08224342be08a73490ac2c01410af08","src/parser_tables_generated.rs":"3c5f3e1fb961832e9f00a1d20dc87c06550f552c61702387209431ceab0d3c2e","src/stack_value_generated.rs":"ce8567634ff2bb818593f56c0589b4ba2d508704db943eb0778d79dfd19cce36","src/token.rs":"479f4cb97d2e6bc654a70634f3809817cc73eaf749c845643beb3556b9ead383","src/traits/mod.rs":"ba74c71f7218027f8188247bc64df243117613fbc9893d40799402ef1e6dbf59"},"package":null}

View File

@ -1238,14 +1238,15 @@ impl<'alloc> AstBuilder<'alloc> {
&self,
start_token: arena::Box<'alloc, Token>,
private_identifier: arena::Box<'alloc, Token>,
) -> arena::Box<'alloc, Expression<'alloc>> {
) -> Result<'alloc, arena::Box<'alloc, Expression<'alloc>>> {
let private_identifier_loc = private_identifier.loc;
self.alloc_with(|| {
let field = self.private_identifier(private_identifier)?;
Ok(self.alloc_with(|| {
Expression::OptionalChain(OptionalChain::PrivateFieldExpressionTail {
field: self.private_identifier(private_identifier),
field,
loc: SourceLocation::from_parts(start_token.loc, private_identifier_loc),
})
})
}))
}
// OptionalChain : `?.` Arguments
@ -1313,18 +1314,19 @@ impl<'alloc> AstBuilder<'alloc> {
&self,
object: arena::Box<'alloc, Expression<'alloc>>,
private_identifier: arena::Box<'alloc, Token>,
) -> arena::Box<'alloc, Expression<'alloc>> {
) -> Result<'alloc, arena::Box<'alloc, Expression<'alloc>>> {
let object_loc = object.get_loc();
let private_identifier_loc = private_identifier.loc;
self.alloc_with(|| {
let field = self.private_identifier(private_identifier)?;
Ok(self.alloc_with(|| {
Expression::OptionalChain(OptionalChain::PrivateFieldExpression(
PrivateFieldExpression {
object: ExpressionOrSuper::Expression(object),
field: self.private_identifier(private_identifier),
field,
loc: SourceLocation::from_parts(object_loc, private_identifier_loc),
},
))
})
}))
}
// OptionalChain : OptionalChain Arguments
@ -1358,11 +1360,20 @@ impl<'alloc> AstBuilder<'alloc> {
}
}
fn private_identifier(&self, token: arena::Box<'alloc, Token>) -> PrivateIdentifier {
PrivateIdentifier {
value: token.value.as_atom(),
loc: token.loc,
}
fn private_identifier(
&self,
_token: arena::Box<'alloc, Token>,
) -> Result<'alloc, PrivateIdentifier> {
Err(ParseError::NotImplemented(
"private fields depends on shell switch, that is not supported",
)
.into())
/*
PrivateIdentifier {
value: token.value.as_atom(),
loc: token.loc,
}
*/
}
// MemberExpression : MemberExpression `.` IdentifierName
@ -1416,18 +1427,19 @@ impl<'alloc> AstBuilder<'alloc> {
&self,
object: arena::Box<'alloc, Expression<'alloc>>,
private_identifier: arena::Box<'alloc, Token>,
) -> arena::Box<'alloc, Expression<'alloc>> {
) -> Result<'alloc, arena::Box<'alloc, Expression<'alloc>>> {
let object_loc = object.get_loc();
let field_loc = private_identifier.loc;
self.alloc_with(|| {
let field = self.private_identifier(private_identifier)?;
Ok(self.alloc_with(|| {
Expression::MemberExpression(MemberExpression::PrivateFieldExpression(
PrivateFieldExpression {
object: ExpressionOrSuper::Expression(object),
field: self.private_identifier(private_identifier),
field,
loc: SourceLocation::from_parts(object_loc, field_loc),
},
))
})
}))
}
// SuperProperty : `super` `[` Expression `]`
@ -1436,9 +1448,11 @@ impl<'alloc> AstBuilder<'alloc> {
super_token: arena::Box<'alloc, Token>,
expression: arena::Box<'alloc, Expression<'alloc>>,
close_token: arena::Box<'alloc, Token>,
) -> arena::Box<'alloc, Expression<'alloc>> {
) -> Result<'alloc, arena::Box<'alloc, Expression<'alloc>>> {
self.check_super()?;
let super_loc = super_token.loc;
self.alloc_with(|| {
Ok(self.alloc_with(|| {
Expression::MemberExpression(MemberExpression::ComputedMemberExpression(
ComputedMemberExpression {
object: ExpressionOrSuper::Super { loc: super_loc },
@ -1446,7 +1460,7 @@ impl<'alloc> AstBuilder<'alloc> {
loc: SourceLocation::from_parts(super_loc, close_token.loc),
},
))
})
}))
}
// SuperProperty : `super` `.` IdentifierName
@ -1454,10 +1468,12 @@ impl<'alloc> AstBuilder<'alloc> {
&self,
super_token: arena::Box<'alloc, Token>,
identifier_token: arena::Box<'alloc, Token>,
) -> arena::Box<'alloc, Expression<'alloc>> {
) -> Result<'alloc, arena::Box<'alloc, Expression<'alloc>>> {
self.check_super()?;
let super_loc = super_token.loc;
let identifier_loc = identifier_token.loc;
self.alloc_with(|| {
Ok(self.alloc_with(|| {
Expression::MemberExpression(MemberExpression::StaticMemberExpression(
StaticMemberExpression {
object: ExpressionOrSuper::Super { loc: super_loc },
@ -1465,7 +1481,7 @@ impl<'alloc> AstBuilder<'alloc> {
loc: SourceLocation::from_parts(super_loc, identifier_loc),
},
))
})
}))
}
// NewTarget : `new` `.` `target`
@ -1520,16 +1536,18 @@ impl<'alloc> AstBuilder<'alloc> {
&self,
super_token: arena::Box<'alloc, Token>,
arguments: arena::Box<'alloc, Arguments<'alloc>>,
) -> arena::Box<'alloc, Expression<'alloc>> {
) -> Result<'alloc, arena::Box<'alloc, Expression<'alloc>>> {
self.check_super()?;
let super_loc = super_token.loc;
let arguments_loc = arguments.loc;
self.alloc_with(|| {
Ok(self.alloc_with(|| {
Expression::CallExpression(CallExpression {
callee: ExpressionOrSuper::Super { loc: super_loc },
arguments: arguments.unbox(),
loc: SourceLocation::from_parts(super_loc, arguments_loc),
})
})
}))
}
// ImportCall : `import` `(` AssignmentExpression `)`
@ -4168,10 +4186,9 @@ impl<'alloc> AstBuilder<'alloc> {
pub fn class_element_name_private(
&self,
private_identifier: arena::Box<'alloc, Token>,
) -> arena::Box<'alloc, ClassElementName<'alloc>> {
self.alloc_with(|| {
ClassElementName::PrivateFieldName(self.private_identifier(private_identifier))
})
) -> Result<'alloc, arena::Box<'alloc, ClassElementName<'alloc>>> {
let name = self.private_identifier(private_identifier)?;
Ok(self.alloc_with(|| ClassElementName::PrivateFieldName(name)))
}
// ClassElement : MethodDefinition

View File

@ -649,4 +649,8 @@ pub trait EarlyErrorChecker<'alloc> {
Ok(())
}
fn check_super(&self) -> Result<'alloc, ()> {
Err(ParseError::NotImplemented("EarlyError for super").into())
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -4,11 +4,34 @@
// Directory where to find the list of JavaScript sources to be used for
// benchmarking.
var dir = ".";
if (scriptArgs && scriptArgs[0]) {
// If an argument is given on the command line, assume this is the path to
// one of real-js-samples directory containing thousabds of JS files,
// otherwise this is assumed to be the current working directory.
dir = scriptArgs[0]; // "~/real-js-samples/20190416"
// Skip list cache to be used to be able to compare profiles. Without a skip
// list which ensure that only runnable test cases are used, the profile would
// not represent the actual values reported by this script.
var skipList = [], skipFile = "", skipLen = 0;
// Handle command line arguments.
for (var i = 0; i < scriptArgs.length; i++) {
switch (scriptArgs[i]) {
case "--dir":
if (++i >= scriptArgs.length) {
throw Error("--dir expects a path.");
}
dir = scriptArgs[i];
break;
case "--skip-file":
if (++i >= scriptArgs.length) {
throw Error("--skip-file expects a path.");
}
skipFile = scriptArgs[i];
try {
skipList = eval(os.file.readFile(skipFile));
} catch (e) {
// ignore errors
}
skipLen = skipList.length;
break;
}
}
// Execution mode of the parser, either "script" or "module".
@ -67,8 +90,10 @@ function for_all_files(parse, N = 1, prefix = "", result = {}) {
// The aggregated results is returned as an object, which reports the total time
// for each parser, the quantity of bytes parsed and skipped and an array of
// speed ratios for each file tested.
function compare(res1, res2) {
function compare(name1, res1, name2, res2) {
var result = {
name1: name1,
name2: name2,
time1: 0,
time2: 0,
parsed_files: 0,
@ -97,6 +122,15 @@ function compare(res1, res2) {
return result;
}
function print_result(result) {
print(result.name1, "\t", result.time1, "ms\t", 1e6 * result.time1 / result.parsed_bytes, 'ns/byte\t', result.parsed_bytes / (1e6 * result.time1), 'bytes/ns\t');
print(result.name2, "\t", result.time2, "ms\t", 1e6 * result.time2 / result.parsed_bytes, 'ns/byte\t', result.parsed_bytes / (1e6 * result.time2), 'bytes/ns\t');
print("Total parsed (scripts:", result.parsed_files, ", bytes:", result.parsed_bytes, ")");
print("Total skipped (scripts:", result.skipped_files, ", bytes:", result.skipped_bytes, ")");
print(result.name2, "/", result.name1, ":", result.time2 / result.time1);
print(result.name2, "/", result.name1, ":", spread(result.ratios_2over1, 0, 5, 0.05));
}
// Given a `table` of speed ratios, display a distribution chart of speed
// ratios. This is useful to check if the data is noisy, bimodal, and to easily
// eye-ball characteristics of the distribution.
@ -105,10 +139,19 @@ function spread(table, min, max, step) {
var chars = ["\xa0", "\u2581", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586", "\u2587", "\u2588"];
var s = ["\xa0", "\xa0", "" + min, "\xa0", "\xa0"];
var ending = ["\xa0", "\xa0", "" + max, "\xa0", "\xa0"];
var scale = "\xa0\xa0";
var scale_values = ["⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹"];
var ranges = [];
var vmax = table.length / 10;
for (var i = min; i < max; i += step) {
ranges.push(0);
var decimal = i - Math.trunc(i);
var error = Math.abs(decimal - Math.round(10 * decimal) / 10);
decimal = Math.round(decimal * 10) % 10;
if (error < step / 2)
scale += scale_values[decimal];
else
scale += "\xa0";
}
for (var x of table) {
if (x < min || max < x) continue;
@ -133,6 +176,7 @@ function spread(table, min, max, step) {
var res = "";
for (i = 0; i < s.length; i++)
res += "\n" + s[i];
res += "\n" + scale;
return res;
}
@ -148,26 +192,14 @@ function spread(table, min, max, step) {
function strategy_1() {
var res1 = for_all_files(parse_1, runs_per_script);
var res2 = for_all_files(parse_2, runs_per_script);
var result = compare(res1, res2);
print(name_1, "\t", result.time1, "ms\t", 1e6 * result.time1 / result.parsed_bytes, 'ns/byte\t', result.parsed_bytes / (1e6 * result.time1), 'bytes/ns\t');
print(name_2, "\t", result.time2, "ms\t", 1e6 * result.time2 / result.parsed_bytes, 'ns/byte\t', result.parsed_bytes / (1e6 * result.time2), 'bytes/ns\t');
print("Total parsed (scripts:", result.parsed_files, ", bytes:", result.parsed_bytes, ")");
print("Total skipped (scripts:", result.skipped_files, ", bytes:", result.skipped_bytes, ")");
print(name_2, "/", name_1, ":", result.time2 / result.time1);
print(name_2, "/", name_1, ":", spread(result.ratios_2over1, 0, 3, 0.05));
return compare(name_1, res1, name_2, res2);
}
// Compare Hot-parsers on cold data, and swap parse order.
function strategy_2() {
var res2 = for_all_files(parse_2, runs_per_script);
var res1 = for_all_files(parse_1, runs_per_script);
var result = compare(res1, res2);
print(name_1, "\t", result.time1, "ms\t", 1e6 * result.time1 / result.parsed_bytes, 'ns/byte\t', result.parsed_bytes / (1e6 * result.time1), 'bytes/ns\t');
print(name_2, "\t", result.time2, "ms\t", 1e6 * result.time2 / result.parsed_bytes, 'ns/byte\t', result.parsed_bytes / (1e6 * result.time2), 'bytes/ns\t');
print("Total parsed (scripts:", result.parsed_files, ", bytes:", result.parsed_bytes, ")");
print("Total skipped (scripts:", result.skipped_files, ", bytes:", result.skipped_bytes, ")");
print(name_2, "/", name_1, ":", result.time2 / result.time1);
print(name_2, "/", name_1, ":", spread(result.ratios_2over1, 0, 3, 0.05));
return compare(name_1, res1, name_2, res2);
}
// Interleaves N hot-parser results. (if N=1, then strategy_3 is identical to strategy_1)
@ -182,13 +214,7 @@ function strategy_3() {
for_all_files(parse_1, 1, "" + n, res1);
for_all_files(parse_2, 1, "" + n, res2);
}
var result = compare(res1, res2);
print(name_1, "\t", result.time1, "ms\t", 1e6 * result.time1 / result.parsed_bytes, 'ns/byte\t', result.parsed_bytes / (1e6 * result.time1), 'bytes/ns\t');
print(name_2, "\t", result.time2, "ms\t", 1e6 * result.time2 / result.parsed_bytes, 'ns/byte\t', result.parsed_bytes / (1e6 * result.time2), 'bytes/ns\t');
print("Total parsed (scripts:", result.parsed_files, ", bytes:", result.parsed_bytes, ")");
print("Total skipped (scripts:", result.skipped_files, ", bytes:", result.skipped_bytes, ")");
print(name_2, "/", name_1, ":", result.time2 / result.time1);
print(name_2, "/", name_1, ":", spread(result.ratios_2over1, 0, 5, 0.05));
return compare(name_1, res1, name_2, res2);
}
// Compare cold parsers, with alternatetively cold/hot data.
@ -210,6 +236,9 @@ function strategy_0() {
var parse1_first = true;
for (var file of list) {
path = os.path.join(dir, file);
if (skipList.includes(path)) {
continue;
}
content = "";
try {
// print(Math.round(100 * f / list.length), file);
@ -236,20 +265,51 @@ function strategy_0() {
// ignore all errors for now.
skipped++;
skipped_bytes += content.length;
skipList.push(path);
}
}
var total_bytes = count_bytes * runs_per_script;
print(name_1, "\t", time_1, "ms\t", 1e6 * time_1 / total_bytes, 'ns/byte\t', total_bytes / (1e6 * time_1), 'bytes/ns\t');
print(name_2, "\t", time_2, "ms\t", 1e6 * time_2 / total_bytes, 'ns/byte\t', total_bytes / (1e6 * time_2), 'bytes/ns\t');
print("Total parsed (scripts:", count * runs_per_script, ", bytes:", total_bytes, ")");
print("Total skipped (scripts:", skipped * runs_per_script, ", bytes:", skipped_bytes, ")");
print(name_2, "/", name_1, ":", time_2 / time_1);
print(name_2, "/", name_1, ":", spread(ratios_2over1, 0, 5, 0.05));
return {
name1: name_1,
name2: name_2,
time1: time_1,
time2: time_2,
parsed_files: count * runs_per_script,
parsed_bytes: count_bytes * runs_per_script,
skipped_files: skipped * runs_per_script,
skipped_bytes: skipped_bytes * runs_per_script,
ratios_2over1: ratios_2over1,
};
}
print("Main thread comparison:")
strategy_0();
print("")
print("Off-thread comparison:")
strategy_3();
var outputJSON = os.getenv("SMOOSH_BENCH_AS_JSON") !== undefined;
if (!outputJSON) {
print("Main thread comparison:");
}
var main_thread_result = strategy_0();
if (!outputJSON) {
print_result(main_thread_result);
print("");
print("Off-thread comparison:");
}
var off_thread_result = strategy_3();
if (!outputJSON) {
print_result(off_thread_result);
}
if (outputJSON) {
print(JSON.stringify({
main_thread: main_thread_result,
off_thread: main_thread_result
}));
}
if (skipFile && skipList.length > skipLen) {
var content = `[${skipList.map(s => `"${s}"`).join(",")}]`;
var data = new ArrayBuffer(content.length);
var view = new Uint8Array(data);
for (var i = 0; i < content.length; i++) {
view[i] = content.charCodeAt(i);
}
os.file.writeTypedArrayToFile(skipFile, view);
}

View File

@ -1 +1 @@
D84995:1655472
D85363:1648574

View File

@ -739,7 +739,7 @@ fn bench(args: &SimpleArgs) -> Result<(), Error> {
"Unable to serialize benchmark script path".into(),
))?;
run_mach(&["run", "-f", cmp_parsers, "--", "--", realjs_path], args)
run_mach(&["run", "-f", cmp_parsers, "--", "--", "--dir", realjs_path], args)
}
fn test(args: &SimpleArgs) -> Result<(), Error> {