Bug 1638470 - Update jsparagus, and update SmooshMonkey to store atoms in gcthings. r=yulia

Differential Revision: https://phabricator.services.mozilla.com/D75711
This commit is contained in:
Tooru Fujisawa 2020-05-19 17:30:32 +00:00
Родитель 9443c95639
Коммит 2ac5bccc9b
43 изменённых файлов: 3714 добавлений и 3290 удалений

Просмотреть файл

@ -30,7 +30,7 @@ rev = "77a7f5eb12a8d93f2bd71bd4d844405e06743365"
[source."https://github.com/mozilla-spidermonkey/jsparagus"]
git = "https://github.com/mozilla-spidermonkey/jsparagus"
replace-with = "vendored-sources"
rev = "9871d65530f5fc0e3d953efbf40b51e9c56c6d2a"
rev = "ce731ef6014c41b1691a9be3480fbc43e5e9a396"
[source."https://github.com/kvark/spirv_cross"]
branch = "wgpu3"

14
Cargo.lock сгенерированный
Просмотреть файл

@ -2367,7 +2367,7 @@ dependencies = [
[[package]]
name = "jsparagus"
version = "0.1.0"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=9871d65530f5fc0e3d953efbf40b51e9c56c6d2a#9871d65530f5fc0e3d953efbf40b51e9c56c6d2a"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=ce731ef6014c41b1691a9be3480fbc43e5e9a396#ce731ef6014c41b1691a9be3480fbc43e5e9a396"
dependencies = [
"jsparagus-ast",
"jsparagus-emitter",
@ -2380,7 +2380,7 @@ dependencies = [
[[package]]
name = "jsparagus-ast"
version = "0.1.0"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=9871d65530f5fc0e3d953efbf40b51e9c56c6d2a#9871d65530f5fc0e3d953efbf40b51e9c56c6d2a"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=ce731ef6014c41b1691a9be3480fbc43e5e9a396#ce731ef6014c41b1691a9be3480fbc43e5e9a396"
dependencies = [
"bumpalo",
"indexmap",
@ -2391,7 +2391,7 @@ dependencies = [
[[package]]
name = "jsparagus-emitter"
version = "0.1.0"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=9871d65530f5fc0e3d953efbf40b51e9c56c6d2a#9871d65530f5fc0e3d953efbf40b51e9c56c6d2a"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=ce731ef6014c41b1691a9be3480fbc43e5e9a396#ce731ef6014c41b1691a9be3480fbc43e5e9a396"
dependencies = [
"bumpalo",
"byteorder",
@ -2403,7 +2403,7 @@ dependencies = [
[[package]]
name = "jsparagus-generated-parser"
version = "0.1.0"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=9871d65530f5fc0e3d953efbf40b51e9c56c6d2a#9871d65530f5fc0e3d953efbf40b51e9c56c6d2a"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=ce731ef6014c41b1691a9be3480fbc43e5e9a396#ce731ef6014c41b1691a9be3480fbc43e5e9a396"
dependencies = [
"bumpalo",
"jsparagus-ast",
@ -2413,12 +2413,12 @@ dependencies = [
[[package]]
name = "jsparagus-json-log"
version = "0.1.0"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=9871d65530f5fc0e3d953efbf40b51e9c56c6d2a#9871d65530f5fc0e3d953efbf40b51e9c56c6d2a"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=ce731ef6014c41b1691a9be3480fbc43e5e9a396#ce731ef6014c41b1691a9be3480fbc43e5e9a396"
[[package]]
name = "jsparagus-parser"
version = "0.1.0"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=9871d65530f5fc0e3d953efbf40b51e9c56c6d2a#9871d65530f5fc0e3d953efbf40b51e9c56c6d2a"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=ce731ef6014c41b1691a9be3480fbc43e5e9a396#ce731ef6014c41b1691a9be3480fbc43e5e9a396"
dependencies = [
"bumpalo",
"jsparagus-ast",
@ -2430,7 +2430,7 @@ dependencies = [
[[package]]
name = "jsparagus-scope"
version = "0.1.0"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=9871d65530f5fc0e3d953efbf40b51e9c56c6d2a#9871d65530f5fc0e3d953efbf40b51e9c56c6d2a"
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=ce731ef6014c41b1691a9be3480fbc43e5e9a396#ce731ef6014c41b1691a9be3480fbc43e5e9a396"
dependencies = [
"indexmap",
"jsparagus-ast",

Просмотреть файл

@ -160,6 +160,10 @@ class SmooshScriptStencil : public ScriptStencil {
SmooshGCThing& item = result_.gcthings.data[i];
switch (item.kind) {
case SmooshGCThingKind::AtomIndex: {
gcThings.infallibleAppend(mozilla::AsVariant(allAtoms_[item.index]));
break;
}
case SmooshGCThingKind::ScopeIndex: {
gcThings.infallibleAppend(mozilla::AsVariant(ScopeIndex(item.index)));
break;

Просмотреть файл

@ -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 = "9871d65530f5fc0e3d953efbf40b51e9c56c6d2a" }
jsparagus = { git = "https://github.com/mozilla-spidermonkey/jsparagus", rev = "ce731ef6014c41b1691a9be3480fbc43e5e9a396" }
# 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 = "9871d65530f5fc0e3d953efbf40b51e9c56c6d2a" }
jsparagus = { git = "https://github.com/mozilla-spidermonkey/jsparagus", rev = "ce731ef6014c41b1691a9be3480fbc43e5e9a396" }
# For local development, replace above with
# jsparagus = { path = "{path to jsparagus}" }

Просмотреть файл

@ -69,6 +69,7 @@ pub struct SmooshCompileOptions {
#[repr(C)]
pub enum SmooshGCThingKind {
AtomIndex,
ScopeIndex,
RegExpIndex,
}
@ -82,6 +83,10 @@ pub struct SmooshGCThing {
impl From<GCThing> for SmooshGCThing {
fn from(item: GCThing) -> Self {
match item {
GCThing::Atom(index) => Self {
kind: SmooshGCThingKind::AtomIndex,
index: index.into(),
},
GCThing::Function(_index) => {
panic!("Not yet implemented");
}
@ -211,7 +216,6 @@ pub struct SmooshResult {
unimplemented: bool,
error: CVec<u8>,
bytecode: CVec<u8>,
atoms: CVec<usize>,
gcthings: CVec<SmooshGCThing>,
scopes: CVec<SmooshScopeData>,
scope_notes: CVec<SmooshScopeNote>,
@ -277,7 +281,6 @@ impl SmooshResult {
unimplemented,
error,
bytecode: CVec::empty(),
atoms: CVec::empty(),
gcthings: CVec::empty(),
scopes: CVec::empty(),
scope_notes: CVec::empty(),
@ -344,7 +347,6 @@ pub unsafe extern "C" fn smoosh_run(
let script = result.scripts.remove(0);
let bytecode = CVec::from(script.bytecode);
let atoms = CVec::from(script.atoms.into_iter().map(|s| s.into()).collect());
let gcthings = CVec::from(script.gcthings.into_iter().map(|x| x.into()).collect());
let scopes = CVec::from(result.scopes.into_iter().map(|x| x.into()).collect());
let scope_notes =
@ -386,7 +388,6 @@ pub unsafe extern "C" fn smoosh_run(
unimplemented: false,
error: CVec::empty(),
bytecode,
atoms,
gcthings,
scopes,
scope_notes,
@ -543,7 +544,6 @@ pub unsafe extern "C" fn smoosh_get_slice_len_at(result: SmooshResult, index: us
pub unsafe extern "C" fn smoosh_free(result: SmooshResult) {
let _ = result.error.into();
let _ = result.bytecode.into();
let _ = result.atoms.into();
let _ = result.gcthings.into();
let _ = result.scopes.into();
let _ = result.scope_notes.into();

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"2f0c8ec9fd1c91e102de4204892131106741e99885a7418c60eb894ed1a51b82","ast.json":"c4af9931cba29f6eb065783e63cbf21c57f065f4ef89245f874941be6f318238","generate_ast.py":"0c24431d9c07af42d7d17739c2e21465964151562437cfca093ceddde898bc93","src/arena.rs":"03ef07c963556160a6f1a85fd901833d7322f8a5f265c20d3e3543432dd2a96d","src/associated_data.rs":"028b7d2b370e75da153b50d86d9ff809e871d81a7fd3266e2d3727ce2bcc178d","src/dump_generated.rs":"23d594138b9e03e1e6d80972da3251ec10f8868cd385bfdd88b63ad761daeb94","src/json.rs":"ccc437c27f3fdaabb3d92b28eeb6bdee083bdf8014639ce09e7204a6529661a9","src/lib.rs":"b35553bedec9f6d88cc5194592f857dc13669559cbc8b206048c35299c4f86be","src/source_atom_set.rs":"1e6fb4be166c9fe4cf63ae6475f1abb12cb3dfa268250328a60f483a09e1481c","src/source_location.rs":"3832440ecec6de726262837072810410bddb45c075288386509511c153f6afd9","src/source_location_accessor_generated.rs":"80e8dd2221d73f6465778a9dfa0703ef84387520cc3dcfe4ba77870efc0c7ab3","src/source_slice_list.rs":"c82413b3081e091a3c4ce5d2c3624e54ecbeb0bb9952f10d373d10faf589955a","src/type_id_generated.rs":"c70cbdc0f84c2fd7e84fa6ef1614be22f63e52ffcbf2f93714c189dce3dad557","src/types_generated.rs":"ba04b36602c019a06b44ceab9d99707d91e7cc6fac051fd8db64ef65c71acdb3","src/visit_generated.rs":"98caf3e2305f648f5d31848cf6d7c7234f8c94b8b4b77a9bcd15fa4952eaca55"},"package":null}
{"files":{"Cargo.toml":"2f0c8ec9fd1c91e102de4204892131106741e99885a7418c60eb894ed1a51b82","ast.json":"8bee02b419d90de0203ba7378aedecd5c94a447128b11231970119c9ecfecb77","generate_ast.py":"0c24431d9c07af42d7d17739c2e21465964151562437cfca093ceddde898bc93","src/arena.rs":"03ef07c963556160a6f1a85fd901833d7322f8a5f265c20d3e3543432dd2a96d","src/associated_data.rs":"028b7d2b370e75da153b50d86d9ff809e871d81a7fd3266e2d3727ce2bcc178d","src/dump_generated.rs":"a1368d31a8e3d286f230058e4a007ce7cd94240f2e59c0cc31c8a56756b1c1b3","src/json.rs":"ccc437c27f3fdaabb3d92b28eeb6bdee083bdf8014639ce09e7204a6529661a9","src/lib.rs":"b35553bedec9f6d88cc5194592f857dc13669559cbc8b206048c35299c4f86be","src/source_atom_set.rs":"1e6fb4be166c9fe4cf63ae6475f1abb12cb3dfa268250328a60f483a09e1481c","src/source_location.rs":"3832440ecec6de726262837072810410bddb45c075288386509511c153f6afd9","src/source_location_accessor_generated.rs":"4a016e4860a2b6b9b7637dff10c634255f6c1942231eb75224261679944fa169","src/source_slice_list.rs":"c82413b3081e091a3c4ce5d2c3624e54ecbeb0bb9952f10d373d10faf589955a","src/type_id_generated.rs":"c70cbdc0f84c2fd7e84fa6ef1614be22f63e52ffcbf2f93714c189dce3dad557","src/types_generated.rs":"965e0619315156b9fd918f26f6317aa98970b535a7df7442f163b23ee5eaf641","src/visit_generated.rs":"d09510127771be0c3a20c95ed48a4e4d387144e6cb08b02783a81739539111ed"},"package":null}

3
third_party/rust/jsparagus-ast/ast.json поставляемый
Просмотреть файл

@ -35,6 +35,9 @@
},
"CompoundAssignmentOperator": {
"_type": "enum",
"LogicalOr": null,
"LogicalAnd": null,
"Coalesce": null,
"Add": null,
"Sub": null,
"Mul": null,

Просмотреть файл

@ -140,6 +140,15 @@ impl<'alloc> ASTDump for CompoundAssignmentOperator {
where W: io::Write
{
match self {
CompoundAssignmentOperator::LogicalOr { .. } => {
write!(out, "LogicalOr").expect("failed to dump");
}
CompoundAssignmentOperator::LogicalAnd { .. } => {
write!(out, "LogicalAnd").expect("failed to dump");
}
CompoundAssignmentOperator::Coalesce { .. } => {
write!(out, "Coalesce").expect("failed to dump");
}
CompoundAssignmentOperator::Add { .. } => {
write!(out, "Add").expect("failed to dump");
}

Просмотреть файл

@ -606,6 +606,18 @@ impl<'alloc> SourceLocationAccessor for ClassExpression<'alloc> {
impl<'alloc> SourceLocationAccessor for CompoundAssignmentOperator {
fn set_loc(&mut self, start: SourceLocation, end: SourceLocation) {
match self {
CompoundAssignmentOperator::LogicalOr { mut loc } => {
loc.start = start.start;
loc.end = end.end;
}
CompoundAssignmentOperator::LogicalAnd { mut loc } => {
loc.start = start.start;
loc.end = end.end;
}
CompoundAssignmentOperator::Coalesce { mut loc } => {
loc.start = start.start;
loc.end = end.end;
}
CompoundAssignmentOperator::Add { mut loc } => {
loc.start = start.start;
loc.end = end.end;
@ -659,6 +671,15 @@ impl<'alloc> SourceLocationAccessor for CompoundAssignmentOperator {
fn get_loc(&self) -> SourceLocation {
match self {
CompoundAssignmentOperator::LogicalOr { loc } => {
*loc
}
CompoundAssignmentOperator::LogicalAnd { loc } => {
*loc
}
CompoundAssignmentOperator::Coalesce { loc } => {
*loc
}
CompoundAssignmentOperator::Add { loc } => {
*loc
}

Просмотреть файл

@ -60,6 +60,15 @@ pub enum VariableDeclarationKind {
#[derive(Debug, PartialEq)]
pub enum CompoundAssignmentOperator {
LogicalOr {
loc: SourceLocation,
},
LogicalAnd {
loc: SourceLocation,
},
Coalesce {
loc: SourceLocation,
},
Add {
loc: SourceLocation,
},

Просмотреть файл

@ -164,6 +164,15 @@ pub trait Pass<'alloc> {
fn visit_compound_assignment_operator(&mut self, ast: &'alloc CompoundAssignmentOperator) {
self.enter_compound_assignment_operator(ast);
match ast {
CompoundAssignmentOperator::LogicalOr { .. } => {
self.visit_enum_compound_assignment_operator_variant_logical_or()
}
CompoundAssignmentOperator::LogicalAnd { .. } => {
self.visit_enum_compound_assignment_operator_variant_logical_and()
}
CompoundAssignmentOperator::Coalesce { .. } => {
self.visit_enum_compound_assignment_operator_variant_coalesce()
}
CompoundAssignmentOperator::Add { .. } => {
self.visit_enum_compound_assignment_operator_variant_add()
}
@ -210,6 +219,15 @@ pub trait Pass<'alloc> {
fn leave_compound_assignment_operator(&mut self, ast: &'alloc CompoundAssignmentOperator) {
}
fn visit_enum_compound_assignment_operator_variant_logical_or(&mut self) {
}
fn visit_enum_compound_assignment_operator_variant_logical_and(&mut self) {
}
fn visit_enum_compound_assignment_operator_variant_coalesce(&mut self) {
}
fn visit_enum_compound_assignment_operator_variant_add(&mut self) {
}

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"44e966f17baf603f83e2c5ea05563744d1d564471a837ff025218c65c5de0b93","scripts/update_opcodes.py":"4b22ead637282b644020ea45aa20d93ba86dec0d1231f8edcd9a0ed1e5fa01e5","src/array_emitter.rs":"bbc6528321f1d11d7c86c4f2bfdcfc9dced8f0b8b1c30c9f0a5355f300d196b6","src/ast_emitter.rs":"937c4609b452dde38f2b5b92aad1c7ee2ed7b1b54eff7b8ce408c52b3e5aa713","src/block_emitter.rs":"a95e553b667990fb585d4186588b0b976a5a477649ab7b9ddf01b26a3ddc5918","src/bytecode_offset.rs":"2aa7ba8c3cfbbd832092e65b599ab1c5a28d784ccc65d9e351bba656421b9a69","src/compilation_info.rs":"259d16ed7580c973cc0bb24a1ff4c9e8a3ca37aab328d946aa7deeb832d46b4f","src/control_structures.rs":"36a5f050b7a5d9c46d18a83f36b23ce0aca8224aff690fdd652e8fab2ef7eb34","src/copy/AsyncFunctionResolveKind.h":"3851ecbb4728257595dd6e900749d1d8e02558574c00424a7ff0e3ca007fa6ec","src/copy/BytecodeFormatFlags.h":"7dc2932321cf7cf874cd92b6d8076ebd4139492730f3ee5a3b6ed7fc57a0c685","src/copy/CheckIsCallableKind.h":"66556f922d403cb46d4ad03a97a6795bcf22505eb9733cbfacd3f2cdd5f39463","src/copy/CheckIsObjectKind.h":"8f0e112396d966c9221a743d353f62671e04cdace7dd49a59898d94ba0f621b7","src/copy/FunctionFlags.h":"4376653f70711d916bc36c2096165f0be9a50c487b9d471821da1cad80daa3a3","src/copy/FunctionPrefixKind.h":"f540a5c646a519b2d61aa27e4be865e08a31438def00ad5ba4ba2982ad1f2275","src/copy/GeneratorAndAsyncKind.h":"301668ce705970a51abfa94f89fd5db29ef5f129525110860e9e9bf7586ef187","src/copy/GeneratorResumeKind.h":"9e3cd9dc9c7f50937c6c45d73ec092dbfd92c4b56818ae6d1504bcd77078d0a6","src/copy/Opcodes.h":"72e0faa4eb0ed4e59ee2205d0ed6734fc4e7383552545d605eef2201e69d4c99","src/copy/SourceNotes.h":"1e467f4e63d6f40a428e257fecd210bd14664516adf75a45cb17ab02ccd65fd8","src/copy/StencilEnums.h":"1c4d1a2c8b365c5dd01bbf09e921a0ef73f5614e5bfb1551cd7147def92ecdf9","src/copy/Symbol.h":"f68b32e1b7add89931a1fa82a6888ebf6d875d03b05872469de426844532bf33","src/copy/ThrowMsgKind.h":"da805756961d81a2b50aeb391a02fd59a0aa39a9e3eb6aae21b423b15875ab30","src/dis.rs":"945acee8fce373f160bdd53f538bcc97037eaade0029996c9c9cbda980c65205","src/emitter.rs":"c81b0f109e4b6f14778cd6ee23ca32f78f7e5bec7d6898de7b5f70fdce944bd3","src/emitter_scope.rs":"71c0621d5e58987916b1854d24ca8b8f10296b37000122e28ecac71bf6badcb8","src/expression_emitter.rs":"f8e02785dffb179bbe9fe58e45bbfccc08adc3ad0a071a0073bed0feedc8ed9a","src/function.rs":"2fe396b0ad3e1b73854ba8feff37353fe5986732868490c8ba1dfc51a4074f06","src/gcthings.rs":"7441b4a04ed56204682e3d328b2f87c25a3dacaab7b76011b521a4fc792ab6e9","src/lib.rs":"361ca4f6eff158ab18f5d765ec09cd9428590e84e59f9a0c7d219f5eea763904","src/object_emitter.rs":"1d3acaca4ec595473c0d31060dbab22eaaca7a02d76aa2e0d9c550541cdccdf1","src/opcode.rs":"4434a36d70387c5897f3349361e0010be08cf9d9499b47b22c0b4dbdb2ad4522","src/opcode_info.rs":"3475f87581ce05c301b915aca584577d15df3e1d7d4096c31546462d4ee1ece5","src/reference_op_emitter.rs":"8b5b3974830bcf77e78c96112522404a2edae21c5961c8386e70dc841709a100","src/regexp.rs":"7436cf545b990bec7dcc51ff28d67deaca9d4ce894468fdad0dd44b25c571cf2","src/scope_notes.rs":"e0861d8db2fae3410c3711fe3beb42b67faf90a49cb5f06ed40025a6b5ed6db5","src/script_atom_set.rs":"8a567a786c6cc15192ca629deb3544546ec204efd1d05d16ff9ccdbf42a94e96","src/script_emitter.rs":"44a6be5ecdcde3c32d78d100a205d38be2591c7c2cc109967579af7393e09fe8","src/stencil.rs":"38043a6eeb3e6b02010e98c49f88001516a1b7340eb976d2d3c175794e1c5b84"},"package":null}
{"files":{"Cargo.toml":"44e966f17baf603f83e2c5ea05563744d1d564471a837ff025218c65c5de0b93","scripts/update_opcodes.py":"5db429c128f8dfe67218f6097c0ebfce31dc0e0403e21453766216e35fdf9625","src/array_emitter.rs":"bbc6528321f1d11d7c86c4f2bfdcfc9dced8f0b8b1c30c9f0a5355f300d196b6","src/ast_emitter.rs":"3664a7417328e1bb400e6cc0e6a0a8b916068c67036aadb0d0616340518eee1a","src/block_emitter.rs":"a95e553b667990fb585d4186588b0b976a5a477649ab7b9ddf01b26a3ddc5918","src/bytecode_offset.rs":"2aa7ba8c3cfbbd832092e65b599ab1c5a28d784ccc65d9e351bba656421b9a69","src/compilation_info.rs":"259d16ed7580c973cc0bb24a1ff4c9e8a3ca37aab328d946aa7deeb832d46b4f","src/control_structures.rs":"6c746f18d6f84859ba1989635f343307acad4982f1e0b94092d2473a5ad451d4","src/copy/AsyncFunctionResolveKind.h":"3851ecbb4728257595dd6e900749d1d8e02558574c00424a7ff0e3ca007fa6ec","src/copy/BytecodeFormatFlags.h":"7dc2932321cf7cf874cd92b6d8076ebd4139492730f3ee5a3b6ed7fc57a0c685","src/copy/CheckIsCallableKind.h":"66556f922d403cb46d4ad03a97a6795bcf22505eb9733cbfacd3f2cdd5f39463","src/copy/CheckIsObjectKind.h":"8f0e112396d966c9221a743d353f62671e04cdace7dd49a59898d94ba0f621b7","src/copy/FunctionFlags.h":"4376653f70711d916bc36c2096165f0be9a50c487b9d471821da1cad80daa3a3","src/copy/FunctionPrefixKind.h":"f540a5c646a519b2d61aa27e4be865e08a31438def00ad5ba4ba2982ad1f2275","src/copy/GeneratorAndAsyncKind.h":"301668ce705970a51abfa94f89fd5db29ef5f129525110860e9e9bf7586ef187","src/copy/GeneratorResumeKind.h":"9e3cd9dc9c7f50937c6c45d73ec092dbfd92c4b56818ae6d1504bcd77078d0a6","src/copy/Opcodes.h":"72e0faa4eb0ed4e59ee2205d0ed6734fc4e7383552545d605eef2201e69d4c99","src/copy/SourceNotes.h":"1e467f4e63d6f40a428e257fecd210bd14664516adf75a45cb17ab02ccd65fd8","src/copy/StencilEnums.h":"1c4d1a2c8b365c5dd01bbf09e921a0ef73f5614e5bfb1551cd7147def92ecdf9","src/copy/Symbol.h":"f68b32e1b7add89931a1fa82a6888ebf6d875d03b05872469de426844532bf33","src/copy/ThrowMsgKind.h":"da805756961d81a2b50aeb391a02fd59a0aa39a9e3eb6aae21b423b15875ab30","src/dis.rs":"4da6c62ce04093d0deda035c1cf4289e026fb6c1aab1b11ff4c0542b84d219b2","src/emitter.rs":"72338bd777152fec3f7e49d6e399a3aafa7ffbb7ffd4643d94579aa36ba71cd1","src/emitter_scope.rs":"481139d52dcac11dbc75e91c5b815943545e959378e29ec4699b083323a1b399","src/expression_emitter.rs":"f8e02785dffb179bbe9fe58e45bbfccc08adc3ad0a071a0073bed0feedc8ed9a","src/function.rs":"5866f0a5d41b6bfa8f7d205cafcc2a3c2a20facdab4b98a1bd6c8c474dc82ad3","src/function_declaration_emitter.rs":"c75c4986322f98f870fb70ab1bea29321ad76a1c36555bcd8cfee7b7c79145ac","src/gcthings.rs":"1513cf94c0ceb002708f6a2ba6c642ae244763b708eb42991855d33c730290ef","src/lib.rs":"335e0e26909313b094a59c05c27ccdb69fc7fa7a51a45cc15bd7522b094bd3e2","src/object_emitter.rs":"998423b3d6ef8797fadef6763803627df72fde292b1b34d6a41b2e66a331a181","src/opcode.rs":"4434a36d70387c5897f3349361e0010be08cf9d9499b47b22c0b4dbdb2ad4522","src/opcode_info.rs":"3475f87581ce05c301b915aca584577d15df3e1d7d4096c31546462d4ee1ece5","src/reference_op_emitter.rs":"753c25b3ae16613b7e0efb3c79637d62ef4c61f54ee64c83c5f694d331a609e3","src/regexp.rs":"7436cf545b990bec7dcc51ff28d67deaca9d4ce894468fdad0dd44b25c571cf2","src/scope_notes.rs":"9947ba5aba3097321c76adcb5648a478e4a67e088fdc1e01511e51c4ad41a9f3","src/script_emitter.rs":"44a6be5ecdcde3c32d78d100a205d38be2591c7c2cc109967579af7393e09fe8","src/stencil.rs":"d578398c6c211f88fd932545b482eb13c5692dc4b2c919e64c202b7b2e411274"},"package":null}

Просмотреть файл

@ -349,10 +349,10 @@ def extract_function_types(paths):
types = {}
extract_enum(types, paths, 'FunctionKind', filename='FunctionFlags.h')
extract_enum(types, paths, 'GeneratorKind',
filename='GeneratorAndAsyncKind.h')
extract_enum(types, paths, 'FunctionAsyncKind',
filename='GeneratorAndAsyncKind.h')
#extract_enum(types, paths, 'GeneratorKind',
# filename='GeneratorAndAsyncKind.h')
#extract_enum(types, paths, 'FunctionAsyncKind',
# filename='GeneratorAndAsyncKind.h')
return types
@ -438,7 +438,7 @@ def parse_operands(opcode):
if 'JOF_ATOM' in opcode.format_:
assert ty == 'u32'
ty = 'ScriptAtomSetIndex'
ty = 'GCThingIndex'
if 'JOF_ICINDEX' in opcode.format_ or 'JOF_LOOPHEAD' in opcode.format_:
if ty == 'u32' and name == 'ic_index':

Просмотреть файл

@ -8,6 +8,7 @@ use crate::compilation_info::CompilationInfo;
use crate::emitter::{EmitError, EmitOptions, InstructionWriter};
use crate::emitter_scope::{EmitterScopeStack, NameLocation};
use crate::expression_emitter::*;
use crate::function_declaration_emitter::{DummyFunctionScriptEmitter, FunctionDeclarationEmitter};
use crate::object_emitter::*;
use crate::opcode::Opcode;
use crate::reference_op_emitter::{
@ -20,6 +21,7 @@ use crate::script_emitter::ScriptEmitter;
use crate::stencil::{EmitResult, ScriptStencilIndex, ScriptStencilList};
use ast::source_atom_set::{CommonSourceAtomSetIndices, SourceAtomSetIndex};
use ast::types::*;
use std::collections::HashSet;
use crate::control_structures::{
BreakEmitter, CForEmitter, ContinueEmitter, ControlStructureStack, DoWhileEmitter,
@ -54,6 +56,10 @@ pub struct AstEmitter<'alloc, 'opt> {
pub compilation_info: &'opt mut CompilationInfo<'alloc>,
pub scripts: &'opt mut ScriptStencilList,
pub control_stack: ControlStructureStack,
/// Holds the offset of top-level function declarations, to check if the
/// given function function declaration is top-level.
top_level_function_offsets: HashSet<usize>,
}
impl<'alloc, 'opt> AstEmitter<'alloc, 'opt> {
@ -69,14 +75,40 @@ impl<'alloc, 'opt> AstEmitter<'alloc, 'opt> {
compilation_info,
scripts,
control_stack: ControlStructureStack::new(),
top_level_function_offsets: HashSet::new(),
}
}
pub fn with_inner<ScriptFn>(
&mut self,
callback: ScriptFn,
) -> Result<ScriptStencilIndex, EmitError>
where
ScriptFn: Fn(&mut AstEmitter) -> Result<(), EmitError>,
{
let script_index = self.scripts.allocate();
let inner_script = {
let mut inner_emitter =
AstEmitter::new(self.options, self.compilation_info, self.scripts);
callback(&mut inner_emitter)?;
inner_emitter.emit.into()
};
self.scripts.populate(script_index, inner_script);
Ok(script_index)
}
pub fn lookup_name(&mut self, name: SourceAtomSetIndex) -> NameLocation {
self.scope_stack.lookup_name(name)
}
fn emit_script(mut self, ast: &Script) -> Result<ScriptStencilIndex, EmitError> {
let script_index = self.scripts.allocate();
let scope_data_map = &self.compilation_info.scope_data_map;
let function_map = &self.compilation_info.function_map;
@ -89,6 +121,10 @@ impl<'alloc, 'opt> AstEmitter<'alloc, 'opt> {
.map(|key| *function_map.get(key).expect("function should exist"))
.collect();
for fun in &top_level_functions {
self.note_top_level_function(fun);
}
ScriptEmitter {
top_level_functions: top_level_functions.iter(),
top_level_function: |emitter, fun| emitter.emit_top_level_function_declaration(fun),
@ -97,20 +133,24 @@ impl<'alloc, 'opt> AstEmitter<'alloc, 'opt> {
}
.emit(&mut self)?;
Ok(self.scripts.push(self.emit.into()))
self.scripts.populate(script_index, self.emit.into());
Ok(script_index)
}
fn emit_top_level_function_declaration(&mut self, fun: &Function) -> Result<(), EmitError> {
let _name = fun
let name = fun
.name
.as_ref()
.expect("function declaration should have name")
.name
.value;
Err(EmitError::NotImplemented(
"TODO: top level FunctionDeclaration",
))
let fun_index = DummyFunctionScriptEmitter { name }.emit(self)?;
FunctionDeclarationEmitter { fun: fun_index }.emit(self);
Ok(())
}
fn emit_statement(&mut self, ast: &Statement) -> Result<(), EmitError> {
@ -128,29 +168,22 @@ impl<'alloc, 'opt> AstEmitter<'alloc, 'opt> {
}
Statement::BreakStatement { label, .. } => {
BreakEmitter {
jump: JumpKind::Goto,
label: label.as_ref().map(|x| x.value),
}
.emit(self);
return Err(EmitError::NotImplemented(
"TODO: scope handling for BreakStatement",
));
}
Statement::ContinueStatement { label, .. } => {
ContinueEmitter {
jump: JumpKind::Goto,
label: label.as_ref().map(|x| x.value),
}
.emit(self);
return Err(EmitError::NotImplemented(
"TODO: scope handling for ContinueStatement",
));
}
Statement::DebuggerStatement { .. } => {
return Err(EmitError::NotImplemented("TODO: DebuggerStatement"));
}
Statement::DoWhileStatement { block, test, .. } => {
DoWhileEmitter {
enclosing_emitter_scope_depth: self.scope_stack.current_depth(),
block: |emitter| emitter.emit_statement(block),
test: |emitter| emitter.emit_expression(test),
}
@ -177,6 +210,7 @@ impl<'alloc, 'opt> AstEmitter<'alloc, 'opt> {
..
} => {
CForEmitter {
enclosing_emitter_scope_depth: self.scope_stack.current_depth(),
maybe_init: init,
maybe_test: test,
maybe_update: update,
@ -205,6 +239,7 @@ impl<'alloc, 'opt> AstEmitter<'alloc, 'opt> {
}
Statement::LabelledStatement { label, body, .. } => {
LabelEmitter {
enclosing_emitter_scope_depth: self.scope_stack.current_depth(),
name: label.value,
body: |emitter| emitter.emit_statement(body),
}
@ -236,6 +271,7 @@ impl<'alloc, 'opt> AstEmitter<'alloc, 'opt> {
}
Statement::WhileStatement { test, block, .. } => {
WhileEmitter {
enclosing_emitter_scope_depth: self.scope_stack.current_depth(),
test: |emitter| emitter.emit_expression(test),
block: |emitter| emitter.emit_statement(block),
}
@ -244,14 +280,26 @@ impl<'alloc, 'opt> AstEmitter<'alloc, 'opt> {
Statement::WithStatement { .. } => {
return Err(EmitError::NotImplemented("TODO: WithStatement"));
}
Statement::FunctionDeclaration(_) => {
return Err(EmitError::NotImplemented("TODO: FunctionDeclaration"));
Statement::FunctionDeclaration(fun) => {
if !self.is_top_level_function(fun) {
return Err(EmitError::NotImplemented(
"TODO: non-top-level FunctionDeclaration",
));
}
}
};
Ok(())
}
fn note_top_level_function(&mut self, fun: &Function) {
self.top_level_function_offsets.insert(fun.loc.start);
}
fn is_top_level_function(&self, fun: &Function) -> bool {
self.top_level_function_offsets.contains(&fun.loc.start)
}
fn emit_variable_declaration_statement(
&mut self,
ast: &VariableDeclaration,
@ -376,7 +424,7 @@ impl<'alloc, 'opt> AstEmitter<'alloc, 'opt> {
}
Expression::LiteralStringExpression { value, .. } => {
let str_index = self.emit.get_atom_index(*value);
let str_index = self.emit.get_atom_gcthing_index(*value);
self.emit.string(str_index);
}

Просмотреть файл

@ -2,6 +2,7 @@ use crate::ast_emitter::AstEmitter;
use crate::bytecode_offset::{BytecodeOffset, BytecodeOffsetDiff};
use crate::emitter::EmitError;
use crate::emitter::InstructionWriter;
use crate::emitter_scope::EmitterScopeDepth;
use ast::source_atom_set::SourceAtomSetIndex;
// Control structures
@ -122,7 +123,9 @@ pub trait Continuable {
fn emit_continue_target_and_patch(&mut self, emit: &mut InstructionWriter);
}
#[derive(Debug, PartialEq)]
pub struct LoopControl {
enclosing_emitter_scope_depth: EmitterScopeDepth,
breaks: Vec<BytecodeOffset>,
continues: Vec<BytecodeOffset>,
head: BytecodeOffset,
@ -153,9 +156,14 @@ impl Continuable for LoopControl {
}
impl LoopControl {
pub fn new(emit: &mut InstructionWriter, depth: u8) -> Self {
pub fn new(
emit: &mut InstructionWriter,
depth: u8,
enclosing_emitter_scope_depth: EmitterScopeDepth,
) -> Self {
let offset = LoopControl::open_loop(emit, depth);
Self {
enclosing_emitter_scope_depth,
breaks: Vec::new(),
continues: Vec::new(),
head: offset,
@ -184,8 +192,9 @@ impl LoopControl {
}
}
#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub struct LabelControl {
enclosing_emitter_scope_depth: EmitterScopeDepth,
name: SourceAtomSetIndex,
breaks: Vec<BytecodeOffset>,
head: BytecodeOffset,
@ -199,14 +208,21 @@ impl Breakable for LabelControl {
}
fn emit_break_target_and_patch(&mut self, emit: &mut InstructionWriter) {
emit.emit_jump_target_and_patch(&self.breaks);
if !self.breaks.is_empty() {
emit.emit_jump_target_and_patch(&self.breaks);
}
}
}
impl LabelControl {
pub fn new(name: SourceAtomSetIndex, emit: &mut InstructionWriter) -> Self {
pub fn new(
name: SourceAtomSetIndex,
emit: &mut InstructionWriter,
enclosing_emitter_scope_depth: EmitterScopeDepth,
) -> Self {
let offset = emit.bytecode_offset();
Self {
enclosing_emitter_scope_depth,
name,
head: offset,
breaks: Vec::new(),
@ -214,11 +230,21 @@ impl LabelControl {
}
}
#[derive(Debug, PartialEq)]
pub enum Control {
Loop(LoopControl),
Label(LabelControl),
}
impl Control {
fn enclosing_emitter_scope_depth(&self) -> EmitterScopeDepth {
match self {
Control::Loop(control) => control.enclosing_emitter_scope_depth,
Control::Label(control) => control.enclosing_emitter_scope_depth,
}
}
}
// Compared to C++ impl, this uses explicit stack struct,
// given Rust cannot store a reference of stack-allocated object into
// another object that has longer-lifetime.
@ -233,21 +259,31 @@ impl ControlStructureStack {
}
}
pub fn open_loop(&mut self, emit: &mut InstructionWriter) {
pub fn open_loop(
&mut self,
emit: &mut InstructionWriter,
enclosing_emitter_scope_depth: EmitterScopeDepth,
) {
let depth = (self.control_stack.len() + 1) as u8;
let new_loop = Control::Loop(LoopControl::new(emit, depth));
let new_loop = Control::Loop(LoopControl::new(emit, depth, enclosing_emitter_scope_depth));
self.control_stack.push(new_loop);
}
pub fn open_label(&mut self, name: SourceAtomSetIndex, emit: &mut InstructionWriter) {
let new_label = LabelControl::new(name, emit);
pub fn open_label(
&mut self,
name: SourceAtomSetIndex,
emit: &mut InstructionWriter,
enclosing_emitter_scope_depth: EmitterScopeDepth,
) {
let new_label = LabelControl::new(name, emit, enclosing_emitter_scope_depth);
self.control_stack.push(Control::Label(new_label));
}
pub fn register_break(&mut self, offset: BytecodeOffset) {
let innermost = self.innermost();
match innermost {
Control::Label(control) => control.register_break(offset),
Control::Loop(control) => control.register_break(offset),
@ -265,12 +301,9 @@ impl ControlStructureStack {
}
pub fn register_labelled_break(&mut self, label: SourceAtomSetIndex, offset: BytecodeOffset) {
if let Some(control) = self.find_labelled_loop(label) {
control.register_break(offset);
} else {
panic!(
"A labelled break was passed, but no label was found. This should be caught by early errors"
)
match self.find_labelled_control(label) {
Control::Label(control) => control.register_break(offset),
Control::Loop(control) => control.register_break(offset),
}
}
@ -289,7 +322,7 @@ impl ControlStructureStack {
}
pub fn find_labelled_loop(&mut self, label: SourceAtomSetIndex) -> Option<&mut LoopControl> {
let label_index = self.find_labelled_index(label)?;
let label_index = self.find_labelled_index(label);
// To find the associated loop for a label, we can take the label's index + 1, as the
// associated loop should always be in the position after the label.
let control = self.control_stack.get_mut(label_index + 1);
@ -299,16 +332,34 @@ impl ControlStructureStack {
}
}
pub fn find_labelled_index(&mut self, label: SourceAtomSetIndex) -> Option<usize> {
self.control_stack.iter().position(|control| match control {
Control::Label(control) => {
if control.name == label {
return true;
pub fn find_labelled_control(&mut self, label: SourceAtomSetIndex) -> &mut Control {
self.control_stack
.iter_mut()
.find(|control| match control {
Control::Label(control) => {
if control.name == label {
return true;
}
false
}
false
}
_ => false,
})
_ => false,
})
.expect("there should be a control with this label")
}
pub fn find_labelled_index(&mut self, label: SourceAtomSetIndex) -> usize {
self.control_stack
.iter()
.position(|control| match control {
Control::Label(control) => {
if control.name == label {
return true;
}
false
}
_ => false,
})
.expect("there should be a control with this label")
}
pub fn emit_continue_target_and_patch(&mut self, emit: &mut InstructionWriter) {
@ -353,74 +404,74 @@ impl ControlStructureStack {
}
}
// Struct for multiple jumps that point to the same target. Examples are breaks and loop conditions.
pub struct BreakEmitter {
pub jump: JumpKind,
pub label: Option<SourceAtomSetIndex>,
struct RegisteredJump<F1>
where
F1: Fn(&mut AstEmitter, BytecodeOffset),
{
kind: JumpKind,
// This callback registers the bytecode offset of the jump in a list of bytecode offsets
// associated with a loop or a label.
register_offset: F1,
}
impl Jump for BreakEmitter {
impl<F1> Jump for RegisteredJump<F1>
where
F1: Fn(&mut AstEmitter, BytecodeOffset),
{
fn jump_kind(&mut self) -> &JumpKind {
&self.jump
&self.kind
}
}
impl<F1> RegisteredJump<F1>
where
F1: Fn(&mut AstEmitter, BytecodeOffset),
{
pub fn emit(&mut self, emitter: &mut AstEmitter) {
let offset = emitter.emit.bytecode_offset();
self.emit_jump(emitter);
(self.register_offset)(emitter, offset);
}
}
// Struct for multiple jumps that point to the same target. Examples are breaks and loop conditions.
pub struct BreakEmitter {
pub label: Option<SourceAtomSetIndex>,
}
impl BreakEmitter {
pub fn emit(&mut self, emitter: &mut AstEmitter) {
// TODO: For 'break' statements in non local loops, we need to emit some extra bytecode.
// see https://searchfox.org/mozilla-central/rev/a707541ff423ade0d81cef6488e6ecfa09273886/js/src/frontend/BytecodeEmitter.cpp#702-840
let offset = emitter.emit.bytecode_offset();
match self.label {
Some(label) => emitter.control_stack.register_labelled_break(label, offset),
None => emitter.control_stack.register_break(offset),
NonLocalExitControl {
registered_jump: RegisteredJump {
kind: JumpKind::Goto,
register_offset: |emitter, offset| match self.label {
Some(label) => emitter.control_stack.register_labelled_break(label, offset),
None => emitter.control_stack.register_break(offset),
},
},
}
self.emit_jump(emitter);
}
}
// Struct for multiple jumps that point to the same target. Examples are breaks and loop conditions.
pub struct InternalBreakEmitter {
pub jump: JumpKind,
}
impl Jump for InternalBreakEmitter {
fn jump_kind(&mut self) -> &JumpKind {
&self.jump
}
}
impl InternalBreakEmitter {
pub fn emit(&mut self, emitter: &mut AstEmitter) {
let offset = emitter.emit.bytecode_offset();
emitter.control_stack.register_break(offset);
self.emit_jump(emitter);
.emit(emitter, self.label);
}
}
pub struct ContinueEmitter {
pub jump: JumpKind,
pub label: Option<SourceAtomSetIndex>,
}
impl Jump for ContinueEmitter {
fn jump_kind(&mut self) -> &JumpKind {
&self.jump
}
}
impl ContinueEmitter {
pub fn emit(&mut self, emitter: &mut AstEmitter) {
// TODO: For 'continue' statements in non local loops, we need to emit some extra bytecode.
// see https://searchfox.org/mozilla-central/rev/a707541ff423ade0d81cef6488e6ecfa09273886/js/src/frontend/BytecodeEmitter.cpp#702-840
let offset = emitter.emit.bytecode_offset();
match self.label {
Some(label) => emitter
.control_stack
.register_labelled_continue(label, offset),
None => emitter.control_stack.register_continue(offset),
NonLocalExitControl {
registered_jump: RegisteredJump {
kind: JumpKind::Goto,
register_offset: |emitter, offset| match self.label {
Some(label) => emitter
.control_stack
.register_labelled_continue(label, offset),
None => emitter.control_stack.register_continue(offset),
},
},
}
self.emit_jump(emitter);
.emit(emitter, self.label);
}
}
@ -429,6 +480,7 @@ where
F1: Fn(&mut AstEmitter) -> Result<(), EmitError>,
F2: Fn(&mut AstEmitter) -> Result<(), EmitError>,
{
pub enclosing_emitter_scope_depth: EmitterScopeDepth,
pub test: F1,
pub block: F2,
}
@ -438,12 +490,16 @@ where
F2: Fn(&mut AstEmitter) -> Result<(), EmitError>,
{
pub fn emit(&mut self, emitter: &mut AstEmitter) -> Result<(), EmitError> {
emitter.control_stack.open_loop(&mut emitter.emit);
emitter
.control_stack
.open_loop(&mut emitter.emit, self.enclosing_emitter_scope_depth);
(self.test)(emitter)?;
InternalBreakEmitter {
jump: JumpKind::IfEq,
// add a registered jump for the conditional statement
RegisteredJump {
kind: JumpKind::IfEq,
register_offset: |emitter, offset| emitter.control_stack.register_break(offset),
}
.emit(emitter);
@ -464,6 +520,7 @@ where
F1: Fn(&mut AstEmitter) -> Result<(), EmitError>,
F2: Fn(&mut AstEmitter) -> Result<(), EmitError>,
{
pub enclosing_emitter_scope_depth: EmitterScopeDepth,
pub block: F2,
pub test: F1,
}
@ -473,7 +530,9 @@ where
F2: Fn(&mut AstEmitter) -> Result<(), EmitError>,
{
pub fn emit(&mut self, emitter: &mut AstEmitter) -> Result<(), EmitError> {
emitter.control_stack.open_loop(&mut emitter.emit);
emitter
.control_stack
.open_loop(&mut emitter.emit, self.enclosing_emitter_scope_depth);
(self.block)(emitter)?;
@ -483,8 +542,10 @@ where
(self.test)(emitter)?;
InternalBreakEmitter {
jump: JumpKind::IfEq,
// add a registered jump for the conditional statement
RegisteredJump {
kind: JumpKind::IfEq,
register_offset: |emitter, offset| emitter.control_stack.register_break(offset),
}
.emit(emitter);
@ -501,6 +562,7 @@ where
UpdateFn: Fn(&mut AstEmitter, &ExprT) -> Result<(), EmitError>,
BlockFn: Fn(&mut AstEmitter) -> Result<(), EmitError>,
{
pub enclosing_emitter_scope_depth: EmitterScopeDepth,
pub maybe_init: &'a Option<CondT>,
pub maybe_test: &'a Option<ExprT>,
pub maybe_update: &'a Option<ExprT>,
@ -525,14 +587,18 @@ where
}
// Emit loop head
emitter.control_stack.open_loop(&mut emitter.emit);
emitter
.control_stack
.open_loop(&mut emitter.emit, self.enclosing_emitter_scope_depth);
// if there is a test condition (ie x < 3) emit it
if let Some(test) = self.maybe_test {
(self.test)(emitter, &test)?;
InternalBreakEmitter {
jump: JumpKind::IfEq,
// add a registered jump for the conditional statement
RegisteredJump {
kind: JumpKind::IfEq,
register_offset: |emitter, offset| emitter.control_stack.register_break(offset),
}
.emit(emitter);
}
@ -560,6 +626,7 @@ pub struct LabelEmitter<F1>
where
F1: Fn(&mut AstEmitter) -> Result<(), EmitError>,
{
pub enclosing_emitter_scope_depth: EmitterScopeDepth,
pub name: SourceAtomSetIndex,
pub body: F1,
}
@ -569,9 +636,11 @@ where
F1: Fn(&mut AstEmitter) -> Result<(), EmitError>,
{
pub fn emit(&mut self, emitter: &mut AstEmitter) -> Result<(), EmitError> {
emitter
.control_stack
.open_label(self.name, &mut emitter.emit);
emitter.control_stack.open_label(
self.name,
&mut emitter.emit,
self.enclosing_emitter_scope_depth,
);
(self.body)(emitter)?;
@ -579,3 +648,57 @@ where
Ok(())
}
}
pub struct NonLocalExitControl<F1>
where
F1: Fn(&mut AstEmitter, BytecodeOffset),
{
registered_jump: RegisteredJump<F1>,
}
impl<F1> NonLocalExitControl<F1>
where
F1: Fn(&mut AstEmitter, BytecodeOffset),
{
pub fn emit(&mut self, emitter: &mut AstEmitter, label: Option<SourceAtomSetIndex>) {
// Step 1: find the enclosing emitter scope
let enclosing_emitter_scope_depth = match label {
Some(label) => emitter
.control_stack
.find_labelled_control(label)
.enclosing_emitter_scope_depth(),
None => emitter
.control_stack
.innermost()
.enclosing_emitter_scope_depth(),
};
// Step 2: find the current emitter scope
let current_scope_index = emitter.scope_stack.current_depth();
// Step 3: iterate over scopes that have been entered since the enclosing scope,
// add a scope note hole for each one as we exit
let mut holes = Vec::new();
let scope_indicies = emitter
.scope_stack
.scope_note_indices_from_to(&enclosing_emitter_scope_depth, &current_scope_index);
let mut parent_scope_note_index = emitter
.scope_stack
.get_scope_note_index_for(current_scope_index);
for maybe_scope_note_index in scope_indicies.iter().rev() {
let scope_note_index = emitter
.emit
.enter_scope_hole(maybe_scope_note_index, parent_scope_note_index);
holes.push(scope_note_index);
parent_scope_note_index = Some(scope_note_index);
}
// Step 4: perform the jump
self.registered_jump.emit(emitter);
// Step 5: close each scope hole after the jump
for scope_note_hole_index in holes.iter() {
emitter.emit.leave_scope_hole(*scope_note_hole_index);
}
}
}

Просмотреть файл

@ -6,11 +6,13 @@ use std::fmt::Write;
pub fn dis(bc: &[u8]) -> String {
let mut result = String::new();
let mut iter = bc.iter();
let mut offset = 0;
loop {
let len = match iter.next() {
Some(byte) => match Opcode::try_from(*byte) {
Ok(op) => {
write!(&mut result, "{:?}", op).unwrap();
write!(&mut result, "{}", format!("{:05}: {:?}", offset, op)).unwrap();
offset = offset + op.instruction_length();
op.instruction_length()
}
Err(()) => {

Просмотреть файл

@ -11,13 +11,13 @@ use crate::gcthings::{GCThingIndex, GCThingList};
use crate::opcode::Opcode;
use crate::regexp::{RegExpItem, RegExpList};
use crate::scope_notes::{ScopeNoteIndex, ScopeNoteList};
use crate::script_atom_set::{ScriptAtomSet, ScriptAtomSetIndex};
use crate::stencil::ScriptStencil;
use ast::source_atom_set::SourceAtomSetIndex;
use byteorder::{ByteOrder, LittleEndian};
use scope::data::ScopeIndex;
use scope::frame_slot::FrameSlot;
use std::cmp;
use std::collections::HashMap;
use std::convert::TryFrom;
use std::convert::TryInto;
use std::fmt;
@ -113,7 +113,9 @@ pub type u24 = u32;
/// Low-level bytecode emitter.
pub struct InstructionWriter {
bytecode: Vec<u8>,
atoms: ScriptAtomSet,
/// To de-duplicate atoms in gcthings list, note the index for each atom.
atom_to_gcindex_map: HashMap<SourceAtomSetIndex, GCThingIndex>,
gcthings: GCThingList,
scope_notes: ScopeNoteList,
@ -173,8 +175,8 @@ impl InstructionWriter {
pub fn new() -> Self {
Self {
bytecode: Vec::new(),
atoms: ScriptAtomSet::new(),
gcthings: GCThingList::new(),
atom_to_gcindex_map: HashMap::new(),
scope_notes: ScopeNoteList::new(),
inner_functions: FunctionCreationDataList::new(),
regexps: RegExpList::new(),
@ -219,10 +221,6 @@ impl InstructionWriter {
self.write_u32(usize::from(value) as u32);
}
fn write_script_atom_set_index(&mut self, atom_index: ScriptAtomSetIndex) {
self.write_u32(atom_index.into());
}
fn write_offset(&mut self, offset: i32) {
self.write_i32(offset);
}
@ -313,10 +311,6 @@ impl InstructionWriter {
offset.offset + target_opcode.instruction_length()
}
pub fn get_atom_index(&mut self, value: SourceAtomSetIndex) -> ScriptAtomSetIndex {
self.atoms.insert(value)
}
pub fn emit_jump_target_and_patch(&mut self, jumplist: &Vec<BytecodeOffset>) {
let mut target = self.bytecode_offset();
let last_jump = self.last_jump_target_offset;
@ -467,9 +461,9 @@ impl InstructionWriter {
self.write_u32(big_int_index);
}
pub fn string(&mut self, atom_index: ScriptAtomSetIndex) {
pub fn string(&mut self, atom_index: GCThingIndex) {
self.emit_op(Opcode::String);
self.write_script_atom_set_index(atom_index);
self.write_g_c_thing_index(atom_index);
}
pub fn symbol(&mut self, symbol: u8) {
@ -544,19 +538,19 @@ impl InstructionWriter {
self.emit_op(Opcode::ObjWithProto);
}
pub fn init_prop(&mut self, name_index: ScriptAtomSetIndex) {
pub fn init_prop(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::InitProp);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn init_hidden_prop(&mut self, name_index: ScriptAtomSetIndex) {
pub fn init_hidden_prop(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::InitHiddenProp);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn init_locked_prop(&mut self, name_index: ScriptAtomSetIndex) {
pub fn init_locked_prop(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::InitLockedProp);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn init_elem(&mut self) {
@ -567,14 +561,14 @@ impl InstructionWriter {
self.emit_op(Opcode::InitHiddenElem);
}
pub fn init_prop_getter(&mut self, name_index: ScriptAtomSetIndex) {
pub fn init_prop_getter(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::InitPropGetter);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn init_hidden_prop_getter(&mut self, name_index: ScriptAtomSetIndex) {
pub fn init_hidden_prop_getter(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::InitHiddenPropGetter);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn init_elem_getter(&mut self) {
@ -585,14 +579,14 @@ impl InstructionWriter {
self.emit_op(Opcode::InitHiddenElemGetter);
}
pub fn init_prop_setter(&mut self, name_index: ScriptAtomSetIndex) {
pub fn init_prop_setter(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::InitPropSetter);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn init_hidden_prop_setter(&mut self, name_index: ScriptAtomSetIndex) {
pub fn init_hidden_prop_setter(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::InitHiddenPropSetter);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn init_elem_setter(&mut self) {
@ -603,14 +597,14 @@ impl InstructionWriter {
self.emit_op(Opcode::InitHiddenElemSetter);
}
pub fn get_prop(&mut self, name_index: ScriptAtomSetIndex) {
pub fn get_prop(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::GetProp);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn call_prop(&mut self, name_index: ScriptAtomSetIndex) {
pub fn call_prop(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::CallProp);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn get_elem(&mut self) {
@ -621,19 +615,19 @@ impl InstructionWriter {
self.emit_op(Opcode::CallElem);
}
pub fn length(&mut self, name_index: ScriptAtomSetIndex) {
pub fn length(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::Length);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn set_prop(&mut self, name_index: ScriptAtomSetIndex) {
pub fn set_prop(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::SetProp);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn strict_set_prop(&mut self, name_index: ScriptAtomSetIndex) {
pub fn strict_set_prop(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::StrictSetProp);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn set_elem(&mut self) {
@ -644,14 +638,14 @@ impl InstructionWriter {
self.emit_op(Opcode::StrictSetElem);
}
pub fn del_prop(&mut self, name_index: ScriptAtomSetIndex) {
pub fn del_prop(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::DelProp);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn strict_del_prop(&mut self, name_index: ScriptAtomSetIndex) {
pub fn strict_del_prop(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::StrictDelProp);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn del_elem(&mut self) {
@ -670,23 +664,23 @@ impl InstructionWriter {
self.emit_op(Opcode::SuperBase);
}
pub fn get_prop_super(&mut self, name_index: ScriptAtomSetIndex) {
pub fn get_prop_super(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::GetPropSuper);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn get_elem_super(&mut self) {
self.emit_op(Opcode::GetElemSuper);
}
pub fn set_prop_super(&mut self, name_index: ScriptAtomSetIndex) {
pub fn set_prop_super(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::SetPropSuper);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn strict_set_prop_super(&mut self, name_index: ScriptAtomSetIndex) {
pub fn strict_set_prop_super(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::StrictSetPropSuper);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn set_elem_super(&mut self) {
@ -859,14 +853,14 @@ impl InstructionWriter {
self.emit_op(Opcode::StrictSpreadEval);
}
pub fn implicit_this(&mut self, name_index: ScriptAtomSetIndex) {
pub fn implicit_this(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::ImplicitThis);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn g_implicit_this(&mut self, name_index: ScriptAtomSetIndex) {
pub fn g_implicit_this(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::GImplicitThis);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn call_site_obj(&mut self, object_index: GCThingIndex) {
@ -1042,9 +1036,9 @@ impl InstructionWriter {
self.write_u8(msg_number as u8);
}
pub fn throw_set_const(&mut self, name_index: ScriptAtomSetIndex) {
pub fn throw_set_const(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::ThrowSetConst);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn try_(&mut self, jump_at_end_offset: i32) {
@ -1087,9 +1081,9 @@ impl InstructionWriter {
self.write_u24(localno);
}
pub fn init_g_lexical(&mut self, name_index: ScriptAtomSetIndex) {
pub fn init_g_lexical(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::InitGLexical);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn init_aliased_lexical(&mut self, hops: u8, slot: u24) {
@ -1113,24 +1107,24 @@ impl InstructionWriter {
self.emit_op(Opcode::CheckThis);
}
pub fn bind_g_name(&mut self, name_index: ScriptAtomSetIndex) {
pub fn bind_g_name(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::BindGName);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn bind_name(&mut self, name_index: ScriptAtomSetIndex) {
pub fn bind_name(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::BindName);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn get_name(&mut self, name_index: ScriptAtomSetIndex) {
pub fn get_name(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::GetName);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn get_g_name(&mut self, name_index: ScriptAtomSetIndex) {
pub fn get_g_name(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::GetGName);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn get_arg(&mut self, argno: u16) {
@ -1149,19 +1143,19 @@ impl InstructionWriter {
self.write_u24(slot);
}
pub fn get_import(&mut self, name_index: ScriptAtomSetIndex) {
pub fn get_import(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::GetImport);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn get_bound_name(&mut self, name_index: ScriptAtomSetIndex) {
pub fn get_bound_name(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::GetBoundName);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn get_intrinsic(&mut self, name_index: ScriptAtomSetIndex) {
pub fn get_intrinsic(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::GetIntrinsic);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn callee(&mut self) {
@ -1173,24 +1167,24 @@ impl InstructionWriter {
self.write_u8(num_hops);
}
pub fn set_name(&mut self, name_index: ScriptAtomSetIndex) {
pub fn set_name(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::SetName);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn strict_set_name(&mut self, name_index: ScriptAtomSetIndex) {
pub fn strict_set_name(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::StrictSetName);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn set_g_name(&mut self, name_index: ScriptAtomSetIndex) {
pub fn set_g_name(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::SetGName);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn strict_set_g_name(&mut self, name_index: ScriptAtomSetIndex) {
pub fn strict_set_g_name(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::StrictSetGName);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn set_arg(&mut self, argno: u16) {
@ -1209,9 +1203,9 @@ impl InstructionWriter {
self.write_u24(slot);
}
pub fn set_intrinsic(&mut self, name_index: ScriptAtomSetIndex) {
pub fn set_intrinsic(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::SetIntrinsic);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn push_lexical_env(&mut self, lexical_scope_index: u32) {
@ -1253,32 +1247,32 @@ impl InstructionWriter {
self.emit_op(Opcode::BindVar);
}
pub fn def_var(&mut self, name_index: ScriptAtomSetIndex) {
pub fn def_var(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::DefVar);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn def_fun(&mut self) {
self.emit_op(Opcode::DefFun);
}
pub fn def_let(&mut self, name_index: ScriptAtomSetIndex) {
pub fn def_let(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::DefLet);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn def_const(&mut self, name_index: ScriptAtomSetIndex) {
pub fn def_const(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::DefConst);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn check_global_or_eval_decl(&mut self) {
self.emit_op(Opcode::CheckGlobalOrEvalDecl);
}
pub fn del_name(&mut self, name_index: ScriptAtomSetIndex) {
pub fn del_name(&mut self, name_index: GCThingIndex) {
self.emit_op(Opcode::DelName);
self.write_script_atom_set_index(name_index);
self.write_g_c_thing_index(name_index);
}
pub fn arguments(&mut self) {
@ -1368,6 +1362,17 @@ impl InstructionWriter {
// @@@@ END METHODS @@@@
pub fn get_atom_gcthing_index(&mut self, atom: SourceAtomSetIndex) -> GCThingIndex {
match self.atom_to_gcindex_map.get(&atom) {
Some(index) => *index,
None => {
let index = self.gcthings.push_atom(atom);
self.atom_to_gcindex_map.insert(atom, index);
index
}
}
}
pub fn get_function_gcthing_index(&mut self, fun_data: FunctionCreationData) -> GCThingIndex {
let fun_data_index = self.inner_functions.push(fun_data);
self.gcthings.push_function(fun_data_index)
@ -1411,6 +1416,33 @@ impl InstructionWriter {
self.scope_notes.leave_scope(index, offset);
}
pub fn enter_scope_hole(
&mut self,
maybe_scope_note_index: &Option<ScopeNoteIndex>,
parent_scope_note_index: Option<ScopeNoteIndex>,
) -> ScopeNoteIndex {
// TODO: the bytecode sequence before leaving scope (entering hole) depends on the kind
// of scope (and also controls). This is currently only debug_leave_lexical_env because
// there's only simple lexical scope.
self.debug_leave_lexical_env();
let offset = self.bytecode_offset();
let gcthing_index = match maybe_scope_note_index {
Some(index) => self.scope_notes.get_scope_hole_gcthing_index(index),
None => self
.body_scope_index
.expect("we should have a body scope index"),
};
self.scope_notes
.enter_scope(gcthing_index, offset, parent_scope_note_index)
}
pub fn leave_scope_hole(&mut self, index: ScopeNoteIndex) {
let offset = self.bytecode_offset();
self.scope_notes.leave_scope(index, offset);
}
pub fn switch_to_main(&mut self) {
self.main_offset = self.bytecode_offset();
}
@ -1420,7 +1452,6 @@ impl From<InstructionWriter> for ScriptStencil {
fn from(emit: InstructionWriter) -> Self {
Self {
bytecode: emit.bytecode,
atoms: emit.atoms.into(),
regexps: emit.regexps.into(),
gcthings: emit.gcthings.into(),
scope_notes: emit.scope_notes.into(),

Просмотреть файл

@ -22,6 +22,11 @@ pub enum NameLocation {
FrameSlot(FrameSlot, BindingKind),
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct EmitterScopeDepth {
index: usize,
}
// --- EmitterScope types
//
// These types are the variants of enum EmitterScope.
@ -118,7 +123,7 @@ impl EmitterScope {
}
}
fn scope_note_index(&self) -> Option<ScopeNoteIndex> {
pub fn scope_note_index(&self) -> Option<ScopeNoteIndex> {
match self {
EmitterScope::Global(scope) => scope.scope_note_index(),
EmitterScope::Lexical(scope) => scope.scope_note_index(),
@ -167,12 +172,16 @@ impl EmitterScopeStack {
let scope_index = scope_data_map.get_global_index();
let scope_data = scope_data_map.get_global_at(scope_index);
// The outermost scope should be the first item in the GC things list.
// Enter global scope here, before emitting any name ops below.
emit.enter_global_scope(scope_index);
if scope_data.bindings.len() > 0 {
emit.check_global_or_eval_decl();
}
for item in scope_data.iter() {
let name_index = emit.get_atom_index(item.name());
let name_index = emit.get_atom_gcthing_index(item.name());
match item.kind() {
BindingKind::Var => {
@ -193,8 +202,6 @@ impl EmitterScopeStack {
let scope = EmitterScope::Global(GlobalEmitterScope::new(scope_data));
self.scope_stack.push(scope);
emit.enter_global_scope(scope_index);
}
/// Leave the global scope. Call this once at the end of a top-level
@ -285,4 +292,34 @@ impl EmitterScopeStack {
NameLocation::Dynamic
}
pub fn current_depth(&mut self) -> EmitterScopeDepth {
EmitterScopeDepth {
index: self.scope_stack.len() - 1,
}
}
pub fn scope_note_indices_from_to(
&self,
from: &EmitterScopeDepth,
to: &EmitterScopeDepth,
) -> Vec<Option<ScopeNoteIndex>> {
let mut indices = Vec::new();
for scope in self
.scope_stack
.iter()
.skip(from.index)
.take(to.index - from.index)
{
indices.push(scope.scope_note_index());
}
indices
}
pub fn get_scope_note_index_for(&self, index: EmitterScopeDepth) -> Option<ScopeNoteIndex> {
self.scope_stack
.get(index.index)
.expect("scope should exist")
.scope_note_index()
}
}

Просмотреть файл

@ -25,18 +25,6 @@ pub enum FunctionKind {
FunctionKindLimit = 8,
}
#[derive(Debug)]
pub enum GeneratorKind {
NotGenerator = 0,
Generator = 1,
}
#[derive(Debug)]
pub enum FunctionAsyncKind {
SyncFunction = 0,
AsyncFunction = 1,
}
#[allow(dead_code)]
const FUNCTION_KIND_SHIFT: u16 = 0;
#[allow(dead_code)]
@ -122,7 +110,7 @@ const STABLE_ACROSS_CLONES: u16 = CONSTRUCTOR | LAMBDA | SELF_HOSTED | FUNCTION_
// @@@@ END TYPES @@@@
impl FunctionFlags {
pub fn new(flags: u16) -> Self {
fn new(flags: u16) -> Self {
debug_assert!(
(((FunctionKind::FunctionKindLimit as u16) - 1) << FUNCTION_KIND_SHIFT)
<= FUNCTION_KIND_MASK
@ -130,6 +118,10 @@ impl FunctionFlags {
Self { flags }
}
pub fn interpreted_normal() -> Self {
Self::new(INTERPRETED_NORMAL)
}
}
#[derive(Debug)]
@ -156,8 +148,6 @@ pub enum FunctionScript {
pub struct FunctionCreationData {
name: Option<SourceAtomSetIndex>,
script: FunctionScript,
generator_kind: GeneratorKind,
async_kind: FunctionAsyncKind,
flags: FunctionFlags,
// FIXME: add more fields
}
@ -167,25 +157,16 @@ impl FunctionCreationData {
pub fn non_lazy(
name: Option<SourceAtomSetIndex>,
script: ScriptStencilIndex,
generator_kind: GeneratorKind,
async_kind: FunctionAsyncKind,
flags: FunctionFlags,
) -> Self {
Self {
name,
script: FunctionScript::NonLazy(NonLazyFunctionScript { script }),
generator_kind,
async_kind,
flags,
}
}
pub fn lazy(
name: Option<SourceAtomSetIndex>,
generator_kind: GeneratorKind,
async_kind: FunctionAsyncKind,
flags: FunctionFlags,
) -> Self {
pub fn lazy(name: Option<SourceAtomSetIndex>, flags: FunctionFlags) -> Self {
Self {
name,
script: FunctionScript::Lazy(LazyFunctionScript {
@ -194,8 +175,6 @@ impl FunctionCreationData {
force_strict: false,
strict: false,
}),
generator_kind,
async_kind,
flags,
}
}

Просмотреть файл

@ -0,0 +1,58 @@
use crate::ast_emitter::AstEmitter;
use crate::emitter::EmitError;
use crate::function::{FunctionCreationData, FunctionFlags};
use crate::gcthings::GCThingIndex;
use ast::source_atom_set::SourceAtomSetIndex;
/// Create a dummy function with empty script, to implement
/// FunctionDeclarationEmitter without implementing FunctionScriptEmitter.
pub struct DummyFunctionScriptEmitter {
pub name: SourceAtomSetIndex,
}
impl DummyFunctionScriptEmitter {
pub fn emit(self, emitter: &mut AstEmitter) -> Result<GCThingIndex, EmitError> {
let script_index = emitter.with_inner(|_emitter| {
Err(EmitError::NotImplemented("TODO: FunctionDeclaration"))
// The following implementing is just a dummy to pass the
// emitter part. The generated bytecode is completely wrong.
//
// Uncomment the following to check the behavior of
// FunctionDeclarationEmitter in the enclosing script.
/*
let scope_data_map = &emitter.compilation_info.scope_data_map;
emitter
.scope_stack
.enter_global(&mut emitter.emit, scope_data_map);
emitter.emit.undefined();
emitter.emit.set_rval();
emitter.emit.ret_rval();
emitter.scope_stack.leave_global(&mut emitter.emit);
Ok(())
*/
})?;
let fun_data = FunctionCreationData::non_lazy(
Some(self.name),
script_index,
FunctionFlags::interpreted_normal(),
);
Ok(emitter.emit.get_function_gcthing_index(fun_data))
}
}
pub struct FunctionDeclarationEmitter {
pub fun: GCThingIndex,
}
impl FunctionDeclarationEmitter {
pub fn emit(self, emitter: &mut AstEmitter) {
emitter.emit.lambda(self.fun);
emitter.emit.def_fun();
}
}

Просмотреть файл

@ -1,18 +1,20 @@
use crate::function::FunctionCreationDataIndex;
use crate::regexp::RegExpIndex;
use ast::source_atom_set::SourceAtomSetIndex;
use scope::data::ScopeIndex;
/// Corresponds to js::frontend::GCThingList::ListType
/// in m-c/js/src/frontend/BytecodeSection.h.
#[derive(Debug)]
pub enum GCThing {
Atom(SourceAtomSetIndex),
Function(FunctionCreationDataIndex),
RegExp(RegExpIndex),
Scope(ScopeIndex),
}
/// Index into GCThingList.things.
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct GCThingIndex {
index: usize,
}
@ -42,6 +44,12 @@ impl GCThingList {
Self { things: Vec::new() }
}
pub fn push_atom(&mut self, atom_index: SourceAtomSetIndex) -> GCThingIndex {
let index = self.things.len();
self.things.push(GCThing::Atom(atom_index));
GCThingIndex::new(index)
}
pub fn push_function(&mut self, fun_index: FunctionCreationDataIndex) -> GCThingIndex {
let index = self.things.len();
self.things.push(GCThing::Function(fun_index));

Просмотреть файл

@ -9,6 +9,7 @@ mod emitter;
mod emitter_scope;
mod expression_emitter;
mod function;
mod function_declaration_emitter;
mod gcthings;
mod object_emitter;
pub mod opcode;
@ -16,7 +17,6 @@ pub mod opcode_info;
mod reference_op_emitter;
mod regexp;
mod scope_notes;
mod script_atom_set;
mod script_emitter;
mod stencil;
@ -112,12 +112,12 @@ mod tests {
bytecode("dis()"),
vec![
Opcode::GetGName as u8,
0,
1,
0,
0,
0,
Opcode::GImplicitThis as u8,
0,
1,
0,
0,
0,

Просмотреть файл

@ -34,7 +34,7 @@ where
// [stack] OBJ
}
None => {
let name_index = emitter.emit.get_atom_index(self.key);
let name_index = emitter.emit.get_atom_gcthing_index(self.key);
(self.value)(emitter)?;
// [stack] OBJ VALUE

Просмотреть файл

@ -1,19 +1,20 @@
use crate::ast_emitter::AstEmitter;
use crate::emitter::EmitError;
use crate::emitter_scope::NameLocation;
use crate::script_atom_set::ScriptAtomSetIndex;
use crate::gcthings::GCThingIndex;
use ast::source_atom_set::SourceAtomSetIndex;
use scope::data::BindingKind;
use scope::frame_slot::FrameSlot;
#[derive(Debug, PartialEq)]
enum AssignmentReferenceKind {
GlobalVar(ScriptAtomSetIndex),
GlobalLexical(ScriptAtomSetIndex),
FrameSlot(FrameSlot),
Dynamic(ScriptAtomSetIndex),
GlobalVar(GCThingIndex),
GlobalLexical(GCThingIndex),
FrameSlotLexical(FrameSlot),
FrameSlotNonLexical(FrameSlot),
Dynamic(GCThingIndex),
#[allow(dead_code)]
Prop(ScriptAtomSetIndex),
Prop(GCThingIndex),
#[allow(dead_code)]
Elem,
}
@ -34,7 +35,8 @@ impl AssignmentReference {
match self.kind {
AssignmentReferenceKind::GlobalVar(_) => 1,
AssignmentReferenceKind::GlobalLexical(_) => 1,
AssignmentReferenceKind::FrameSlot(_) => 0,
AssignmentReferenceKind::FrameSlotLexical(_) => 0,
AssignmentReferenceKind::FrameSlotNonLexical(_) => 0,
AssignmentReferenceKind::Dynamic(_) => 1,
AssignmentReferenceKind::Prop(_) => 1,
AssignmentReferenceKind::Elem => 2,
@ -44,8 +46,8 @@ impl AssignmentReference {
#[derive(Debug, PartialEq)]
enum DeclarationReferenceKind {
GlobalVar(ScriptAtomSetIndex),
GlobalLexical(ScriptAtomSetIndex),
GlobalVar(GCThingIndex),
GlobalLexical(GCThingIndex),
FrameSlot(FrameSlot),
}
@ -68,6 +70,38 @@ enum CallKind {
// FIXME: Support eval, Function#call, Function#apply etc.
}
#[derive(Debug, PartialEq)]
enum ValueIsOnStack {
No,
Yes,
}
fn check_temporary_dead_zone(
emitter: &mut AstEmitter,
slot: FrameSlot,
is_on_stack: ValueIsOnStack,
) {
// FIXME: Use cache to avoid emitting check_lexical twice or more.
// FIXME: Support aliased lexical.
// [stack] VAL?
if is_on_stack == ValueIsOnStack::No {
emitter.emit.get_local(slot.into());
// [stack] VAL
}
emitter.emit.check_lexical(slot.into());
// [stack] VAL
if is_on_stack == ValueIsOnStack::No {
emitter.emit.pop();
// [stack]
}
// [stack] VAL?
}
// See *ReferenceEmitter.
// This uses struct to hide the details from the consumer.
#[derive(Debug)]
@ -87,7 +121,7 @@ pub struct GetNameEmitter {
}
impl GetNameEmitter {
pub fn emit(self, emitter: &mut AstEmitter) {
let name_index = emitter.emit.get_atom_index(self.name);
let name_index = emitter.emit.get_atom_gcthing_index(self.name);
let loc = emitter.lookup_name(self.name);
// [stack]
@ -101,9 +135,14 @@ impl GetNameEmitter {
emitter.emit.get_name(name_index);
// [stack] VAL
}
NameLocation::FrameSlot(slot, _kind) => {
NameLocation::FrameSlot(slot, kind) => {
emitter.emit.get_local(slot.into());
// [stack] VAL
if kind == BindingKind::Let || kind == BindingKind::Const {
check_temporary_dead_zone(emitter, slot, ValueIsOnStack::Yes);
// [stack] VAL
}
}
}
}
@ -122,7 +161,7 @@ where
F: Fn(&mut AstEmitter) -> Result<(), EmitError>,
{
pub fn emit(self, emitter: &mut AstEmitter) -> Result<(), EmitError> {
let key_index = emitter.emit.get_atom_index(self.key);
let key_index = emitter.emit.get_atom_gcthing_index(self.key);
// [stack]
@ -151,7 +190,7 @@ where
F: Fn(&mut AstEmitter) -> Result<(), EmitError>,
{
pub fn emit(self, emitter: &mut AstEmitter) -> Result<(), EmitError> {
let key_index = emitter.emit.get_atom_index(self.key);
let key_index = emitter.emit.get_atom_gcthing_index(self.key);
// [stack]
@ -253,7 +292,7 @@ pub struct NameReferenceEmitter {
}
impl NameReferenceEmitter {
pub fn emit_for_call(self, emitter: &mut AstEmitter) -> CallReference {
let name_index = emitter.emit.get_atom_index(self.name);
let name_index = emitter.emit.get_atom_gcthing_index(self.name);
let loc = emitter.lookup_name(self.name);
// [stack]
@ -273,10 +312,15 @@ impl NameReferenceEmitter {
emitter.emit.g_implicit_this(name_index);
// [stack] CALLEE THIS
}
NameLocation::FrameSlot(slot, _kind) => {
NameLocation::FrameSlot(slot, kind) => {
emitter.emit.get_local(slot.into());
// [stack] CALLEE
if kind == BindingKind::Let || kind == BindingKind::Const {
check_temporary_dead_zone(emitter, slot, ValueIsOnStack::Yes);
// [stack] CALLEE
}
emitter.emit.undefined();
// [stack] CALLEE THIS
}
@ -286,7 +330,7 @@ impl NameReferenceEmitter {
}
pub fn emit_for_assignment(self, emitter: &mut AstEmitter) -> AssignmentReference {
let name_index = emitter.emit.get_atom_index(self.name);
let name_index = emitter.emit.get_atom_gcthing_index(self.name);
let loc = emitter.lookup_name(self.name);
// [stack]
@ -310,14 +354,18 @@ impl NameReferenceEmitter {
AssignmentReference::new(AssignmentReferenceKind::Dynamic(name_index))
}
NameLocation::FrameSlot(slot, _kind) => {
AssignmentReference::new(AssignmentReferenceKind::FrameSlot(slot))
NameLocation::FrameSlot(slot, kind) => {
if kind == BindingKind::Let || kind == BindingKind::Const {
AssignmentReference::new(AssignmentReferenceKind::FrameSlotLexical(slot))
} else {
AssignmentReference::new(AssignmentReferenceKind::FrameSlotNonLexical(slot))
}
}
}
}
pub fn emit_for_declaration(self, emitter: &mut AstEmitter) -> DeclarationReference {
let name_index = emitter.emit.get_atom_index(self.name);
let name_index = emitter.emit.get_atom_gcthing_index(self.name);
let loc = emitter.lookup_name(self.name);
// [stack]
@ -356,7 +404,7 @@ where
F: Fn(&mut AstEmitter) -> Result<(), EmitError>,
{
pub fn emit_for_call(self, emitter: &mut AstEmitter) -> Result<CallReference, EmitError> {
let key_index = emitter.emit.get_atom_index(self.key);
let key_index = emitter.emit.get_atom_gcthing_index(self.key);
// [stack]
@ -383,7 +431,7 @@ where
self,
emitter: &mut AstEmitter,
) -> Result<AssignmentReference, EmitError> {
let key_index = emitter.emit.get_atom_index(self.key);
let key_index = emitter.emit.get_atom_gcthing_index(self.key);
// [stack]
@ -585,7 +633,16 @@ where
emitter.emit.set_name(name_index);
// [stack] VAL
}
AssignmentReferenceKind::FrameSlot(slot) => {
AssignmentReferenceKind::FrameSlotLexical(slot) => {
// [stack] VAL
check_temporary_dead_zone(emitter, slot, ValueIsOnStack::No);
// [stack] VAL
emitter.emit.set_local(slot.into());
// [stack] VAL
}
AssignmentReferenceKind::FrameSlotNonLexical(slot) => {
// [stack] VAL
emitter.emit.set_local(slot.into());

Просмотреть файл

@ -62,6 +62,13 @@ impl ScopeNoteList {
ScopeNoteIndex::new(note_index)
}
pub fn get_scope_hole_gcthing_index(&self, scope_note_index: &ScopeNoteIndex) -> GCThingIndex {
self.notes
.get(scope_note_index.index)
.expect("Scope note should exist")
.index
}
pub fn leave_scope(&mut self, index: ScopeNoteIndex, offset: BytecodeOffset) {
self.notes[usize::from(index)].end = offset;
}

Просмотреть файл

@ -1,46 +0,0 @@
use ast::source_atom_set::SourceAtomSetIndex;
use indexmap::set::IndexSet;
/// Index into ScriptAtomSet.atoms.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct ScriptAtomSetIndex {
index: u32,
}
impl ScriptAtomSetIndex {
fn new(index: u32) -> Self {
Self { index }
}
}
impl From<ScriptAtomSetIndex> for u32 {
fn from(index: ScriptAtomSetIndex) -> u32 {
index.index
}
}
/// List of atoms referred from bytecode.
///
/// Maps to JSScript::atoms() in js/src/vm/JSScript.h.
pub struct ScriptAtomSet {
// This keeps the insertion order.
atoms: IndexSet<SourceAtomSetIndex>,
}
impl ScriptAtomSet {
pub fn new() -> Self {
Self {
atoms: IndexSet::new(),
}
}
pub fn insert(&mut self, value: SourceAtomSetIndex) -> ScriptAtomSetIndex {
let (index, _) = self.atoms.insert_full(value);
ScriptAtomSetIndex::new(index as u32)
}
}
impl From<ScriptAtomSet> for Vec<SourceAtomSetIndex> {
fn from(set: ScriptAtomSet) -> Vec<SourceAtomSetIndex> {
set.atoms.into_iter().collect()
}
}

Просмотреть файл

@ -6,7 +6,6 @@ use crate::gcthings::GCThing;
use crate::regexp::RegExpItem;
use crate::scope_notes::ScopeNote;
use ast::source_atom_set::SourceAtomSetIndex;
use scope::data::ScopeData;
use scope::frame_slot::FrameSlot;
@ -38,7 +37,6 @@ impl<'alloc> EmitResult<'alloc> {
#[derive(Debug)]
pub struct ScriptStencil {
pub bytecode: Vec<u8>,
pub atoms: Vec<SourceAtomSetIndex>,
pub regexps: Vec<RegExpItem>,
pub gcthings: Vec<GCThing>,
pub scope_notes: Vec<ScopeNote>,
@ -87,7 +85,9 @@ impl From<ScriptStencilIndex> for usize {
/// List of stencil scripts.
#[derive(Debug)]
pub struct ScriptStencilList {
scripts: Vec<ScriptStencil>,
/// Uses Option to allow `allocate()` and `populate()` to be called
/// separately.
scripts: Vec<Option<ScriptStencil>>,
}
impl ScriptStencilList {
@ -99,13 +99,26 @@ impl ScriptStencilList {
pub fn push(&mut self, script: ScriptStencil) -> ScriptStencilIndex {
let index = self.scripts.len();
self.scripts.push(script);
self.scripts.push(Some(script));
ScriptStencilIndex::new(index)
}
pub fn allocate(&mut self) -> ScriptStencilIndex {
let index = self.scripts.len();
self.scripts.push(None);
ScriptStencilIndex::new(index)
}
pub fn populate(&mut self, index: ScriptStencilIndex, script: ScriptStencil) {
self.scripts[usize::from(index)].replace(script);
}
}
impl From<ScriptStencilList> for Vec<ScriptStencil> {
fn from(list: ScriptStencilList) -> Vec<ScriptStencil> {
list.scripts
.into_iter()
.map(|g| g.expect("Should be populated"))
.collect()
}
}

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"8e424d01abd384e3d5f13bf921c8f4bc58306b3f41825dc821e60c5220efb7e0","src/ast_builder.rs":"1c7f5bd154d626ca560091764bf13c480e84295a2003ecd5d3157f242d03cfe3","src/context_stack.rs":"29331d03cd4c8ee9283cb426ebe893b7ba6ad6d8a69016399c4d92a81cb1363b","src/declaration_kind.rs":"fdfda2fe408cce1c637d17fee0813160619450472c6de9befc36ebeed892cc3c","src/early_error_checker.rs":"04b5e8dfc2db295c073cd97abd0e8a96ce641ab46ba9a06338f5154ff72377b0","src/early_errors.rs":"8674454af7ac5efe51eb6a8e2abe088aad5560e0a0bd88a3eae66c90f1527149","src/error.rs":"507e4dd9c66720f3da2db135c3024392d8aaac5ccdb90c7f7463ccb2eff7efa8","src/lib.rs":"a40b11e1dda1afcccef5fc86a2030c326d38feb31e24596e602930dcad28f1ec","src/parser_tables_generated.rs":"8a15ec6a66b92884f00a6d6616dd537d36e5135c6ba6f72f1b3def692bd6103d","src/stack_value_generated.rs":"d8696a671368e2565d589922e3a46d20667ed3e17e29953e69b970470e9639ee","src/token.rs":"479f4cb97d2e6bc654a70634f3809817cc73eaf749c845643beb3556b9ead383","src/traits/mod.rs":"bcc2fa63444ba4c763dc996f410a6871f2cdc3bde54e1924ca8cc25cba92674a"},"package":null}
{"files":{"Cargo.toml":"8e424d01abd384e3d5f13bf921c8f4bc58306b3f41825dc821e60c5220efb7e0","src/ast_builder.rs":"8b10743ebbc3390d1158cb44ff5c87fbb653d62521f3e1274565d0061eebe095","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":"a40b11e1dda1afcccef5fc86a2030c326d38feb31e24596e602930dcad28f1ec","src/parser_tables_generated.rs":"a99bc928a0ac9ffc44564e5c086fee1b195c6be5e05cfc4bf92946fdc963631e","src/stack_value_generated.rs":"d8696a671368e2565d589922e3a46d20667ed3e17e29953e69b970470e9639ee","src/token.rs":"479f4cb97d2e6bc654a70634f3809817cc73eaf749c845643beb3556b9ead383","src/traits/mod.rs":"bcc2fa63444ba4c763dc996f410a6871f2cdc3bde54e1924ca8cc25cba92674a"},"package":null}

Просмотреть файл

@ -2223,6 +2223,25 @@ impl<'alloc> AstBuilder<'alloc> {
CompoundAssignmentOperator::And { loc: token.loc }
}
pub fn logical_or_assign_op(
&self,
token: arena::Box<'alloc, Token>,
) -> CompoundAssignmentOperator {
CompoundAssignmentOperator::LogicalOr { loc: token.loc }
}
pub fn logical_and_assign_op(
&self,
token: arena::Box<'alloc, Token>,
) -> CompoundAssignmentOperator {
CompoundAssignmentOperator::LogicalAnd { loc: token.loc }
}
pub fn coalesce_assign_op(
&self,
token: arena::Box<'alloc, Token>,
) -> CompoundAssignmentOperator {
CompoundAssignmentOperator::Coalesce { loc: token.loc }
}
pub fn box_assign_op(
&self,
op: CompoundAssignmentOperator,
@ -2231,6 +2250,7 @@ impl<'alloc> AstBuilder<'alloc> {
}
// AssignmentExpression : LeftHandSideExpression AssignmentOperator AssignmentExpression
// AssignmentExpression : LeftHandSideExpression LogicalAssignmentOperator AssignmentExpression
pub fn compound_assignment_expr(
&self,
left_hand_side: arena::Box<'alloc, Expression<'alloc>>,

Просмотреть файл

@ -565,8 +565,12 @@ pub trait EarlyErrorChecker<'alloc> {
CatchParameterEarlyErrorsContext::new_with_binding_pattern()
};
let param_index = self.context_metadata_mut().find_first_binding(start_of_bindings_offset);
let body_index = self.context_metadata_mut().find_first_binding(end_of_bindings_offset);
let param_index = self
.context_metadata_mut()
.find_first_binding(start_of_bindings_offset);
let body_index = self
.context_metadata_mut()
.find_first_binding(end_of_bindings_offset);
declare_param(
self.context_metadata(),
self.atoms(),
@ -589,8 +593,13 @@ pub trait EarlyErrorChecker<'alloc> {
}
// Check bindings in Catch with no parameter and Block.
fn check_catch_no_param_bindings(&mut self, start_of_catch_offset: usize) -> Result<'alloc, ()> {
let body_index = self.context_metadata_mut().find_first_binding(start_of_catch_offset);
fn check_catch_no_param_bindings(
&mut self,
start_of_catch_offset: usize,
) -> Result<'alloc, ()> {
let body_index = self
.context_metadata_mut()
.find_first_binding(start_of_catch_offset);
let param_context = CatchParameterEarlyErrorsContext::new_with_binding_identifier();
let mut block_context = CatchBlockEarlyErrorsContext::new(param_context);
@ -614,8 +623,12 @@ pub trait EarlyErrorChecker<'alloc> {
) -> Result<'alloc, ()> {
let mut head_context = LexicalForHeadEarlyErrorsContext::new();
let head_index = self.context_metadata_mut().find_first_binding(start_of_bindings_offset);
let body_index = self.context_metadata_mut().find_first_binding(end_of_bindings_offset);
let head_index = self
.context_metadata_mut()
.find_first_binding(start_of_bindings_offset);
let body_index = self
.context_metadata_mut()
.find_first_binding(end_of_bindings_offset);
declare_lexical_for_head(
self.context_metadata(),
self.atoms(),

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"8bb197a613ba0328d4295fdbd824e54f2dc1ae7cf688abb9f0650d39733ef4f2","benches/__finStreamer-proto.js":"44edc00a99a8904f8c6bb0c42c7ba4f96ad611e61191d2702ecb228ae6d7b35d","benches/parser.rs":"6cb13b135513e86b94e1bbe1470156f182355078c2e34bf8d9deba1c67daf4b9","benches/simple.js":"fbb50c1c49c0b1e3740a79407a834248c1f8ebdb1b72530c0fc6df57d079f252","src/lexer.rs":"9648e0d88f490f446965ddb444220f270f571199cfff5e63a0ccf3dc07be63c6","src/lib.rs":"87a6a2bb77088574422ecd6598bcdb2838a676d34ce557fe1503abdce941fcf2","src/numeric_value.rs":"f429c50640eb35a53aa5ffdf71de305da30747e568dc10219c54b766372f6eca","src/parser.rs":"6735dd5b4241287a06dedf52f867d35da782e618542f35b1c0a5f579117878f5","src/queue_stack.rs":"d1826d4ef0b0cf3c4e6d5d83a3b5cb1b9ea3e2eda25d8bb0d13fce50d6062d37","src/simulator.rs":"4018f71a08900df11f407a3ccee1f6ca68059a0e922260a1bc2dd808b78dbc2f","src/tests.rs":"a48030a0b0e5c5a9c75916bb63de3d3524e66733dbb86c1526ec55bdf25787a4"},"package":null}
{"files":{"Cargo.toml":"8bb197a613ba0328d4295fdbd824e54f2dc1ae7cf688abb9f0650d39733ef4f2","benches/__finStreamer-proto.js":"44edc00a99a8904f8c6bb0c42c7ba4f96ad611e61191d2702ecb228ae6d7b35d","benches/parser.rs":"6cb13b135513e86b94e1bbe1470156f182355078c2e34bf8d9deba1c67daf4b9","benches/simple.js":"fbb50c1c49c0b1e3740a79407a834248c1f8ebdb1b72530c0fc6df57d079f252","src/lexer.rs":"a2c942415a6dba5a768da71ddfec32eb194b482679b0a0edf10c949b8d386c63","src/lib.rs":"ef17c34e95e05724e8772280172042b065c57883d7a043cb427840456982f9bd","src/numeric_value.rs":"f429c50640eb35a53aa5ffdf71de305da30747e568dc10219c54b766372f6eca","src/parser.rs":"c8c7903248a565f79bf642641d4c95d5d4838ba1ae38294f583721ce6ba2bafd","src/queue_stack.rs":"d1826d4ef0b0cf3c4e6d5d83a3b5cb1b9ea3e2eda25d8bb0d13fce50d6062d37","src/simulator.rs":"829102c7f5cec8ab79179115630175cfa7c865269e8ef99e7896cbbad3678e96","src/tests.rs":"ea5df36f73d74692a6f26f4148d3d0b541a9e4baae16479100d54d2898602c3f"},"package":null}

738
third_party/rust/jsparagus-parser/src/lexer.rs поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -81,7 +81,7 @@ fn parse<'alloc>(
if t.terminal_id == TerminalId::End {
break;
}
parser.write_token(&t)?;
parser.write_token(t)?;
}
parser.close(tokens.offset())
}
@ -102,7 +102,7 @@ pub fn is_partial_script<'alloc>(
if t.terminal_id == TerminalId::End {
break;
}
parser.write_token(&t)?;
parser.write_token(t)?;
}
Ok(!parser.can_close())
}

Просмотреть файл

@ -1,5 +1,6 @@
use crate::queue_stack::QueueStack;
use crate::simulator::Simulator;
use ast::arena;
use ast::SourceLocation;
use generated_parser::{
full_actions, AstBuilder, AstBuilderDelegate, ErrorCode, ParseError, ParserTrait, Result,
@ -118,7 +119,7 @@ impl<'alloc> Parser<'alloc> {
*self.state_stack.last().unwrap()
}
pub fn write_token(&mut self, token: &Token) -> Result<'alloc, ()> {
pub fn write_token(&mut self, token: arena::Box<'alloc, Token>) -> Result<'alloc, ()> {
json_trace!({
"method": "write_token",
"is_on_new_line": token.is_on_new_line,
@ -126,9 +127,10 @@ impl<'alloc> Parser<'alloc> {
"end": token.loc.end,
});
// Shift the token with the associated StackValue.
let term = Term::Terminal(token.terminal_id);
let accept = self.shift(TermValue {
term: Term::Terminal(token.terminal_id),
value: StackValue::Token(self.handler.alloc(token.clone())),
term,
value: StackValue::Token(token),
})?;
// JavaScript grammar accepts empty inputs, therefore we can never
// accept any program before receiving a TerminalId::End.
@ -146,7 +148,7 @@ impl<'alloc> Parser<'alloc> {
let token = Token::basic_token(TerminalId::End, loc);
let accept = self.shift(TermValue {
term: Term::Terminal(TerminalId::End),
value: StackValue::Token(self.handler.alloc(token.clone())),
value: StackValue::Token(self.handler.alloc(token)),
})?;
// Adding a TerminalId::End would either lead to a parse error, or to
// accepting the current input. In which case we return matching node
@ -232,11 +234,7 @@ impl<'alloc> Parser<'alloc> {
}
pub fn can_accept_terminal(&self, t: TerminalId) -> bool {
let bogus_loc = SourceLocation::new(0, 0);
let result = self
.simulator()
.write_token(&Token::basic_token(t, bogus_loc))
.is_ok();
let result = self.simulator().write_token(t).is_ok();
json_trace!({
"can_accept": result,
"terminal": format!("{:?}", t),

Просмотреть файл

@ -126,10 +126,10 @@ impl<'alloc, 'parser> Simulator<'alloc, 'parser> {
}
}
pub fn write_token(&mut self, token: &Token) -> Result<'alloc, ()> {
pub fn write_token(&mut self, t: TerminalId) -> Result<'alloc, ()> {
// Shift the token with the associated StackValue.
let accept = self.shift(TermValue {
term: Term::Terminal(token.terminal_id),
term: Term::Terminal(t),
value: (),
})?;
// JavaScript grammar accepts empty inputs, therefore we can never

Просмотреть файл

@ -181,8 +181,8 @@ fn assert_same_tokens<'alloc>(left: &str, right: &str) {
if left_token.terminal_id == TerminalId::End {
break;
}
left_parser.write_token(&left_token).unwrap();
right_parser.write_token(&right_token).unwrap();
left_parser.write_token(left_token).unwrap();
right_parser.write_token(right_token).unwrap();
}
left_parser.close(left_lexer.offset()).unwrap();
right_parser.close(left_lexer.offset()).unwrap();
@ -203,7 +203,7 @@ fn assert_can_close_after<'alloc, T: IntoChunks<'alloc>>(code: T) {
if t.terminal_id == TerminalId::End {
break;
}
parser.write_token(&t).unwrap();
parser.write_token(t).unwrap();
}
assert!(parser.can_close());
}

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -527,6 +527,8 @@ AssignmentExpression[In, Yield, Await] :
=> assignment_expr($0, $2)
LeftHandSideExpression[?Yield, ?Await] AssignmentOperator AssignmentExpression[?In, ?Yield, ?Await]
=> compound_assignment_expr($0, $1, $2)
LeftHandSideExpression[?Yield, ?Await] LogicalAssignmentOperator AssignmentExpression[?In, ?Yield, ?Await]
=> compound_assignment_expr($0, $1, $2)
@returns CompoundAssignmentOperator
AssignmentOperator :
@ -555,6 +557,14 @@ AssignmentOperator :
`**=`
=> box_assign_op(pow_assign_op($0))
@returns CompoundAssignmentOperator
LogicalAssignmentOperator :
`&&=`
=> box_assign_op(logical_and_assign_op($0))
`||=`
=> box_assign_op(logical_or_assign_op($0))
`??=`
=> box_assign_op(coalesce_assign_op($0))
AssignmentPattern[Yield, Await] :
ObjectAssignmentPattern[?Yield, ?Await]

Просмотреть файл

@ -26,6 +26,7 @@ import jsparagus.lexer
def _get_punctuators():
punctuators = '''
&&= ||= ??=
{ ( ) [ ] . ... ; , < > <= >= == != === !== + - * % ** ++ --
<< >> >>> & | ^ ! ~ && || ? : = += -= *= %=
**= ><<= >>= >>>= &= |= ^= =>

Просмотреть файл

@ -17,6 +17,9 @@ from .. import types
TERMINAL_NAMES = {
'&&=': 'LogicalAndAssign',
'||=': 'LogicalOrAssign',
'??=': 'CoalesceAssign',
'{': 'OpenBrace',
'}': 'CloseBrace',
'(': 'OpenParenthesis',

2
third_party/rust/nom/.cargo-checksum.json поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

101
third_party/rust/nom/.travis.yml поставляемый
Просмотреть файл

@ -1,101 +0,0 @@
language: rust
# sudo is required to enable kcov to use the personality syscall
sudo: required
dist: trusty
cache: cargo
rust:
- nightly
- beta
- stable
- 1.31.0
env:
matrix:
- FEATURES='--features "regexp regexp_macros"'
before_script:
- eval git pull --rebase https://github.com/Geal/nom master
- eval git log --pretty=oneline HEAD~5..HEAD
matrix:
include:
- rust: nightly
env: FEATURES='--no-default-features'
- rust: nightly
env: FEATURES='--no-default-features --features "alloc"'
- rust: stable
env: FEATURES=''
- rust: nightly
env: DOC_FEATURES='--features "std lexical regexp regexp_macros" --no-default-features'
before_script:
- export PATH=$HOME/.cargo/bin:$PATH
script:
- eval cargo doc --verbose $DOC_FEATURES
- rust: nightly
env: FEATURES=''
before_script:
- export PATH=$HOME/.cargo/bin:$PATH
- cargo install cargo-update || echo "cargo-update already installed"
- cargo install cargo-travis || echo "cargo-travis already installed"
- cargo install-update -a
- mkdir -p target/kcov-master
script:
cargo coveralls --verbose --all-features
allow_failures:
- rust: stable
env: FEATURES=''
before_script:
- export PATH=$HOME/.cargo/bin:$PATH
- rustup component add rustfmt-preview
script:
- eval cargo fmt -- --write-mode=diff
notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/9c035a194ac4fd4cc061
on_success: change
on_failure: always
on_start: false
addons:
apt:
packages:
- libcurl4-openssl-dev
- libelf-dev
- libdw-dev
- binutils-dev
- cmake
sources:
- kalakris-cmake
cache:
directories:
- /home/travis/.cargo
before_cache:
- rm -rf /home/travis/.cargo/registry
script:
- eval cargo build --verbose $FEATURES
- eval cargo test --verbose $FEATURES
after_success: |
case "$TRAVIS_RUST_VERSION" in
nightly)
if [ "${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}" != "master" ]; then
git fetch &&
git checkout master &&
cargo bench --verbose
fi
if [ "$FEATURES" == '--features "regexp regexp_macros"' ]; then
cargo bench --verbose
fi
;;
*)
;;
esac