Skip to content

Commit

Permalink
Use SourceSliceIndex for string literal (fixes mozilla-spidermonkey#624)
Browse files Browse the repository at this point in the history
  • Loading branch information
arai-a committed Aug 7, 2020
1 parent c4c4446 commit c40ca24
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 11 deletions.
2 changes: 1 addition & 1 deletion crates/ast/ast.json
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@
"unicode": "bool"
},
"LiteralStringExpression": {
"value": "SourceAtomSetIndex"
"value": "SourceSliceIndex"
},
"ArrayExpression": "ArrayExpression",
"ArrowExpression": {
Expand Down
1 change: 0 additions & 1 deletion crates/ast/generate_ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -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, "")
Expand Down
1 change: 0 additions & 1 deletion crates/ast/src/source_atom_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
);
}
Expand Down
2 changes: 1 addition & 1 deletion crates/emitter/src/ast_emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
5 changes: 5 additions & 0 deletions crates/emitter/src/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
}
Expand Down
10 changes: 7 additions & 3 deletions crates/generated_parser/src/ast_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}

Expand Down Expand Up @@ -1050,7 +1051,10 @@ impl<'alloc> AstBuilder<'alloc> {
&self,
token: arena::Box<'alloc, Token>,
) -> Result<'alloc, arena::Box<'alloc, PropertyName<'alloc>>> {
let value = token.value.as_atom();
let name = self.slices.borrow().get(token.value.as_slice());

let value = self.atoms.borrow_mut().insert(name);

if value == CommonSourceAtomSetIndices::__proto__() {
return Err(ParseError::NotImplemented("__proto__ as property name").into());
}
Expand Down
23 changes: 21 additions & 2 deletions crates/interpreter/src/evaluate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ trait Helpers<'alloc> {
fn read_offset(&self, offset: usize) -> isize;
fn read_atom(&self, offset: usize, gcthings: &Vec<GCThing>, atoms: &Vec<&'alloc str>)
-> String;
fn read_slice(
&self,
offset: usize,
gcthings: &Vec<GCThing>,
slices: &Vec<&'alloc str>,
) -> String;
}

impl<'alloc> Helpers<'alloc> for ImmutableScriptData {
Expand Down Expand Up @@ -77,6 +83,18 @@ impl<'alloc> Helpers<'alloc> for ImmutableScriptData {
_ => panic!("Unexpected GC things for string"),
}
}

fn read_slice(
&self,
offset: usize,
gcthings: &Vec<GCThing>,
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.
Expand All @@ -96,6 +114,7 @@ pub fn evaluate(result: &EmitResult, global: Rc<RefCell<Object>>) -> Result<JSVa
let immutable_script_data = &result.script_data_list[script_data_index];
let gcthings = &script.gcthings;
let atoms = &result.atoms;
let slices = &result.slices;

loop {
let op = match Opcode::try_from(immutable_script_data.bytecode[pc]) {
Expand Down Expand Up @@ -424,10 +443,10 @@ pub fn evaluate(result: &EmitResult, global: Rc<RefCell<Object>>) -> Result<JSVa
}

Opcode::String => {
stack.push(JSValue::String(immutable_script_data.read_atom(
stack.push(JSValue::String(immutable_script_data.read_slice(
pc + 1,
gcthings,
atoms,
slices,
)));
}

Expand Down
2 changes: 1 addition & 1 deletion crates/parser/src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()),
Expand Down
8 changes: 8 additions & 0 deletions crates/stencil/src/gcthings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ 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.
#[derive(Debug)]
pub enum GCThing {
Null,
Atom(SourceAtomSetIndex),
Slice(SourceSliceIndex),
Function(ScriptStencilIndex),
RegExp(RegExpIndex),
Scope(ScopeIndex),
Expand Down Expand Up @@ -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));
Expand Down
2 changes: 1 addition & 1 deletion gecko-patches.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
D85363:1648574
D86376:1657937

0 comments on commit c40ca24

Please sign in to comment.