From 2517721ca9bfa0f506f81e41a9bcb1b4a4a4ca27 Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Fri, 7 Aug 2020 23:48:00 +0900 Subject: [PATCH] Use SourceSliceIndex for string literal (fixes #624) --- crates/ast/ast.json | 2 +- crates/ast/generate_ast.py | 1 - crates/ast/src/source_atom_set.rs | 1 - crates/emitter/src/ast_emitter.rs | 2 +- crates/emitter/src/emitter.rs | 5 +++++ crates/generated_parser/src/ast_builder.rs | 5 +++-- crates/interpreter/src/evaluate.rs | 23 ++++++++++++++++++++-- crates/parser/src/lexer.rs | 2 +- crates/stencil/src/gcthings.rs | 8 ++++++++ gecko-patches.txt | 2 +- 10 files changed, 41 insertions(+), 10 deletions(-) diff --git a/crates/ast/ast.json b/crates/ast/ast.json index e02d91648..5fc0ac8a5 100644 --- a/crates/ast/ast.json +++ b/crates/ast/ast.json @@ -210,7 +210,7 @@ "unicode": "bool" }, "LiteralStringExpression": { - "value": "SourceAtomSetIndex" + "value": "SourceSliceIndex" }, "ArrayExpression": "ArrayExpression", "ArrowExpression": { diff --git a/crates/ast/generate_ast.py b/crates/ast/generate_ast.py index dab3f96aa..ba31aa30c 100755 --- a/crates/ast/generate_ast.py +++ b/crates/ast/generate_ast.py @@ -429,7 +429,6 @@ def emit_variant_none_call(indent, enum_name, variant_name): write(0, "#![allow(dead_code)]") write(0, "") write(0, "use crate::arena;") - write(0, "use crate::source_atom_set::SourceAtomSetIndex;") write(0, "use crate::source_slice_list::SourceSliceIndex;") write(0, "use crate::types::*;") write(0, "") diff --git a/crates/ast/src/source_atom_set.rs b/crates/ast/src/source_atom_set.rs index 25369c977..6240e1ff5 100644 --- a/crates/ast/src/source_atom_set.rs +++ b/crates/ast/src/source_atom_set.rs @@ -111,7 +111,6 @@ macro_rules! for_all_common_atoms { ("while", while_, While), ("with", with, With), ("yield", yield_, Yield), - ("use strict", use_strict, UseStrict), ("__proto__", __proto__, Proto), ); } diff --git a/crates/emitter/src/ast_emitter.rs b/crates/emitter/src/ast_emitter.rs index 1b3480b95..a2280be1e 100644 --- a/crates/emitter/src/ast_emitter.rs +++ b/crates/emitter/src/ast_emitter.rs @@ -453,7 +453,7 @@ impl<'alloc, 'opt> AstEmitter<'alloc, 'opt> { } Expression::LiteralStringExpression { value, .. } => { - let str_index = self.emit.get_atom_gcthing_index(*value); + let str_index = self.emit.get_slice_gcthing_index(*value); self.emit.string(str_index); } diff --git a/crates/emitter/src/emitter.rs b/crates/emitter/src/emitter.rs index 734e4da87..b9a77f1de 100644 --- a/crates/emitter/src/emitter.rs +++ b/crates/emitter/src/emitter.rs @@ -6,6 +6,7 @@ #![allow(dead_code)] use ast::source_atom_set::SourceAtomSetIndex; +use ast::source_slice_list::SourceSliceIndex; use byteorder::{ByteOrder, LittleEndian}; use std::cmp; use std::collections::HashMap; @@ -1384,6 +1385,10 @@ impl InstructionWriter { } } + pub fn get_slice_gcthing_index(&mut self, slice: SourceSliceIndex) -> GCThingIndex { + self.gcthings.push_slice(slice) + } + pub fn get_function_gcthing_index(&mut self, fun_index: ScriptStencilIndex) -> GCThingIndex { self.gcthings.push_function(fun_index) } diff --git a/crates/generated_parser/src/ast_builder.rs b/crates/generated_parser/src/ast_builder.rs index 6de757a96..13efaecf9 100644 --- a/crates/generated_parser/src/ast_builder.rs +++ b/crates/generated_parser/src/ast_builder.rs @@ -766,8 +766,9 @@ impl<'alloc> AstBuilder<'alloc> { let loc = token.loc; // Hack: Prevent emission for scripts with "use strict" // directive. - let value = token.value.as_atom(); - if value == CommonSourceAtomSetIndices::use_strict() { + let value = token.value.as_slice(); + let slice = self.slices.borrow().get(value); + if slice == "use strict" { return Err(ParseError::NotImplemented("use strict directive").into()); } diff --git a/crates/interpreter/src/evaluate.rs b/crates/interpreter/src/evaluate.rs index 0d70a6415..8e240bbe5 100644 --- a/crates/interpreter/src/evaluate.rs +++ b/crates/interpreter/src/evaluate.rs @@ -39,6 +39,12 @@ trait Helpers<'alloc> { fn read_offset(&self, offset: usize) -> isize; fn read_atom(&self, offset: usize, gcthings: &Vec, atoms: &Vec<&'alloc str>) -> String; + fn read_slice( + &self, + offset: usize, + gcthings: &Vec, + slices: &Vec<&'alloc str>, + ) -> String; } impl<'alloc> Helpers<'alloc> for ImmutableScriptData { @@ -77,6 +83,18 @@ impl<'alloc> Helpers<'alloc> for ImmutableScriptData { _ => panic!("Unexpected GC things for string"), } } + + fn read_slice( + &self, + offset: usize, + gcthings: &Vec, + slices: &Vec<&'alloc str>, + ) -> String { + match gcthings[self.read_i32(offset) as usize] { + GCThing::Slice(index) => slices[usize::from(index)].to_string(), + _ => panic!("Unexpected GC things for string"), + } + } } /// This functions can partially interpreter the bytecode shared with SpiderMonkey. @@ -96,6 +114,7 @@ pub fn evaluate(result: &EmitResult, global: Rc>) -> Result>) -> Result { - stack.push(JSValue::String(immutable_script_data.read_atom( + stack.push(JSValue::String(immutable_script_data.read_slice( pc + 1, gcthings, - atoms, + slices, ))); } diff --git a/crates/parser/src/lexer.rs b/crates/parser/src/lexer.rs index 109558c5c..224be0add 100644 --- a/crates/parser/src/lexer.rs +++ b/crates/parser/src/lexer.rs @@ -1378,7 +1378,7 @@ impl<'alloc> Lexer<'alloc> { Some(c @ '"') | Some(c @ '\'') => { if c == delimiter { - let value = self.string_to_token_value(builder.finish_without_push(&self)); + let value = self.slice_to_token_value(builder.finish_without_push(&self)); return self.set_result( TerminalId::StringLiteral, SourceLocation::new(offset, self.offset()), diff --git a/crates/stencil/src/gcthings.rs b/crates/stencil/src/gcthings.rs index bbe18fd20..e1c40791b 100644 --- a/crates/stencil/src/gcthings.rs +++ b/crates/stencil/src/gcthings.rs @@ -2,6 +2,7 @@ use crate::regexp::RegExpIndex; use crate::scope::ScopeIndex; use crate::script::ScriptStencilIndex; use ast::source_atom_set::SourceAtomSetIndex; +use ast::source_slice_list::SourceSliceIndex; /// Corresponds to js::frontend::GCThingList::ListType /// in m-c/js/src/frontend/BytecodeSection.h. @@ -9,6 +10,7 @@ use ast::source_atom_set::SourceAtomSetIndex; pub enum GCThing { Null, Atom(SourceAtomSetIndex), + Slice(SourceSliceIndex), Function(ScriptStencilIndex), RegExp(RegExpIndex), Scope(ScopeIndex), @@ -51,6 +53,12 @@ impl GCThingList { GCThingIndex::new(index) } + pub fn push_slice(&mut self, slice_index: SourceSliceIndex) -> GCThingIndex { + let index = self.things.len(); + self.things.push(GCThing::Slice(slice_index)); + GCThingIndex::new(index) + } + pub fn push_function(&mut self, fun_index: ScriptStencilIndex) -> GCThingIndex { let index = self.things.len(); self.things.push(GCThing::Function(fun_index)); diff --git a/gecko-patches.txt b/gecko-patches.txt index 17858e08f..f5de7a738 100644 --- a/gecko-patches.txt +++ b/gecko-patches.txt @@ -1 +1 @@ -D85363:1648574 +D86376:1657937