Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix remaining static module bugs #2955

Merged
merged 3 commits into from
May 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,32 @@
{
"type": "lldb",
"request": "launch",
"name": "Launch",
"name": "Launch (Script)",
"windows": {
"program": "${workspaceFolder}/target/debug/boa.exe"
},
"program": "${workspaceFolder}/target/debug/boa",
"args": ["${workspaceFolder}/tests/js/test.js", "--debug-object"],
"sourceLanguages": ["rust"],
"preLaunchTask": "Cargo Build"
},
{
"type": "lldb",
"request": "launch",
"name": "Launch (Module)",
"windows": {
"program": "${workspaceFolder}/target/debug/boa.exe"
},
"program": "${workspaceFolder}/target/debug/boa",
"args": [
"${workspaceFolder}/tests/js/test.js",
"--debug-object",
"-m",
"-r",
"tests/js"
],
"sourceLanguages": ["rust"],
"preLaunchTask": "Cargo Build"
}
]
}
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions boa_ast/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ bitflags = "2.3.1"
num-bigint = "0.4.3"
serde = { version = "1.0.163", features = ["derive"], optional = true }
arbitrary = { version = "1", features = ["derive"], optional = true }
indexmap = "1.9.3"
11 changes: 10 additions & 1 deletion boa_ast/src/declaration/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,16 +174,18 @@ impl VisitWith for ExportDeclaration {
pub struct ExportSpecifier {
alias: Sym,
private_name: Sym,
string_literal: bool,
}

impl ExportSpecifier {
/// Creates a new [`ExportSpecifier`].
#[inline]
#[must_use]
pub const fn new(alias: Sym, private_name: Sym) -> Self {
pub const fn new(alias: Sym, private_name: Sym, string_literal: bool) -> Self {
Self {
alias,
private_name,
string_literal,
}
}

Expand All @@ -200,6 +202,13 @@ impl ExportSpecifier {
pub const fn private_name(self) -> Sym {
self.private_name
}

/// Returns `true` if the private name of the specifier was a `StringLiteral`.
#[inline]
#[must_use]
pub const fn string_literal(&self) -> bool {
self.string_literal
}
}

impl VisitWith for ExportSpecifier {
Expand Down
11 changes: 6 additions & 5 deletions boa_ast/src/module_item_list/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
//!
//! [spec]: https://tc39.es/ecma262/#sec-modules

use std::{convert::Infallible, ops::ControlFlow};
use std::{convert::Infallible, hash::BuildHasherDefault, ops::ControlFlow};

use boa_interner::Sym;
use rustc_hash::FxHashSet;
use indexmap::IndexSet;
use rustc_hash::{FxHashSet, FxHasher};

use crate::{
declaration::{
Expand Down Expand Up @@ -205,9 +206,9 @@ impl ModuleItemList {
/// [spec]: https://tc39.es/ecma262/#sec-static-semantics-modulerequests
#[inline]
#[must_use]
pub fn requests(&self) -> FxHashSet<Sym> {
pub fn requests(&self) -> IndexSet<Sym, BuildHasherDefault<FxHasher>> {
#[derive(Debug)]
struct RequestsVisitor<'vec>(&'vec mut FxHashSet<Sym>);
struct RequestsVisitor<'vec>(&'vec mut IndexSet<Sym, BuildHasherDefault<FxHasher>>);

impl<'ast> Visitor<'ast> for RequestsVisitor<'_> {
type BreakTy = Infallible;
Expand All @@ -227,7 +228,7 @@ impl ModuleItemList {
}
}

let mut requests = FxHashSet::default();
let mut requests = IndexSet::default();

RequestsVisitor(&mut requests).visit_module_item_list(self);

Expand Down
10 changes: 5 additions & 5 deletions boa_engine/src/bytecompiler/declarations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,16 +351,16 @@ impl ByteCompiler<'_, '_> {
for d in &declarations {
match d {
LexicallyScopedDeclaration::Function(function) => {
self.function(function.into(), NodeKind::Declaration, false);
self.function_with_binding(function.into(), NodeKind::Declaration, false);
}
LexicallyScopedDeclaration::Generator(function) => {
self.function(function.into(), NodeKind::Declaration, false);
self.function_with_binding(function.into(), NodeKind::Declaration, false);
}
LexicallyScopedDeclaration::AsyncFunction(function) => {
self.function(function.into(), NodeKind::Declaration, false);
self.function_with_binding(function.into(), NodeKind::Declaration, false);
}
LexicallyScopedDeclaration::AsyncGenerator(function) => {
self.function(function.into(), NodeKind::Declaration, false);
self.function_with_binding(function.into(), NodeKind::Declaration, false);
}
_ => {}
}
Expand Down Expand Up @@ -1147,7 +1147,7 @@ impl ByteCompiler<'_, '_> {
// a. Let fn be the sole element of the BoundNames of f.
// b. Let fo be InstantiateFunctionObject of f with arguments lexEnv and privateEnv.
// c. Perform ! varEnv.SetMutableBinding(fn, fo, false).
self.function(function, NodeKind::Declaration, false);
self.function_with_binding(function, NodeKind::Declaration, false);
}

// 37. Return unused.
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/bytecompiler/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ impl ByteCompiler<'_, '_> {
.create_mutable_binding(name, function_scope));
}

/// Initialize a mutable binding at bytecode compile time and return it's binding locator.
/// Initialize a mutable binding at bytecode compile time and return its binding locator.
pub(crate) fn initialize_mutable_binding(
&self,
name: Identifier,
Expand Down
12 changes: 6 additions & 6 deletions boa_engine/src/bytecompiler/expression/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,22 +124,22 @@ impl ByteCompiler<'_, '_> {
}
Expression::Spread(spread) => self.compile_expr(spread.target(), true),
Expression::Function(function) => {
self.function(function.into(), NodeKind::Expression, use_expr);
self.function_with_binding(function.into(), NodeKind::Expression, use_expr);
}
Expression::ArrowFunction(function) => {
self.function(function.into(), NodeKind::Expression, use_expr);
self.function_with_binding(function.into(), NodeKind::Expression, use_expr);
}
Expression::AsyncArrowFunction(function) => {
self.function(function.into(), NodeKind::Expression, use_expr);
self.function_with_binding(function.into(), NodeKind::Expression, use_expr);
}
Expression::Generator(function) => {
self.function(function.into(), NodeKind::Expression, use_expr);
self.function_with_binding(function.into(), NodeKind::Expression, use_expr);
}
Expression::AsyncFunction(function) => {
self.function(function.into(), NodeKind::Expression, use_expr);
self.function_with_binding(function.into(), NodeKind::Expression, use_expr);
}
Expression::AsyncGenerator(function) => {
self.function(function.into(), NodeKind::Expression, use_expr);
self.function_with_binding(function.into(), NodeKind::Expression, use_expr);
}
Expression::Call(call) => self.call(Callable::Call(call), use_expr),
Expression::New(new) => self.call(Callable::New(new), use_expr),
Expand Down
86 changes: 48 additions & 38 deletions boa_engine/src/bytecompiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub(crate) enum NodeKind {

/// Describes the type of a function.
#[derive(Debug, Clone, Copy, PartialEq)]
enum FunctionKind {
pub(crate) enum FunctionKind {
Ordinary,
Arrow,
AsyncArrow,
Expand All @@ -57,37 +57,31 @@ enum FunctionKind {
AsyncGenerator,
}

impl FunctionKind {
pub(crate) const fn is_arrow(self) -> bool {
matches!(self, Self::Arrow | Self::AsyncArrow)
}

pub(crate) const fn is_async(self) -> bool {
matches!(self, Self::Async | Self::AsyncGenerator | Self::AsyncArrow)
}

pub(crate) const fn is_generator(self) -> bool {
matches!(self, Self::Generator | Self::AsyncGenerator)
}
}

/// Describes the complete specification of a function node.
#[derive(Debug, Clone, Copy, PartialEq)]
#[allow(single_use_lifetimes)]
pub(crate) struct FunctionSpec<'a> {
kind: FunctionKind,
pub(crate) kind: FunctionKind,
pub(crate) name: Option<Identifier>,
parameters: &'a FormalParameterList,
body: &'a FunctionBody,
has_binding_identifier: bool,
}

impl FunctionSpec<'_> {
const fn is_arrow(&self) -> bool {
matches!(self.kind, FunctionKind::Arrow | FunctionKind::AsyncArrow)
}

const fn is_async(&self) -> bool {
matches!(
self.kind,
FunctionKind::Async | FunctionKind::AsyncGenerator | FunctionKind::AsyncArrow
)
}

const fn is_generator(&self) -> bool {
matches!(
self.kind,
FunctionKind::Generator | FunctionKind::AsyncGenerator
)
}
}

impl<'a> From<&'a Function> for FunctionSpec<'a> {
fn from(function: &'a Function) -> Self {
FunctionSpec {
Expand Down Expand Up @@ -1070,17 +1064,13 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
}
}

/// Compile a function AST Node into bytecode.
pub(crate) fn function(
&mut self,
function: FunctionSpec<'_>,
node_kind: NodeKind,
use_expr: bool,
) {
/// Compiles a function AST Node into bytecode, and returns its index into
/// the `functions` array.
pub(crate) fn function(&mut self, function: FunctionSpec<'_>) -> u32 {
let (generator, r#async, arrow) = (
function.is_generator(),
function.is_async(),
function.is_arrow(),
function.kind.is_generator(),
function.kind.is_async(),
function.kind.is_arrow(),
);
let FunctionSpec {
name,
Expand Down Expand Up @@ -1117,6 +1107,26 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
let index = self.functions.len() as u32;
self.functions.push(code);

index
}

/// Compiles a function AST Node into bytecode, setting its corresponding binding or
/// pushing it to the stack if necessary.
pub(crate) fn function_with_binding(
&mut self,
function: FunctionSpec<'_>,
node_kind: NodeKind,
use_expr: bool,
) {
let name = function.name;
let (generator, r#async, arrow) = (
function.kind.is_generator(),
function.kind.is_async(),
function.kind.is_arrow(),
);

let index = self.function(function);

if r#async && generator {
self.emit(Opcode::GetGeneratorAsync, &[index]);
} else if generator {
Expand Down Expand Up @@ -1152,9 +1162,9 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
/// Compile an object method AST Node into bytecode.
pub(crate) fn object_method(&mut self, function: FunctionSpec<'_>) {
let (generator, r#async, arrow) = (
function.is_generator(),
function.is_async(),
function.is_arrow(),
function.kind.is_generator(),
function.kind.is_async(),
function.kind.is_arrow(),
);
let FunctionSpec {
name,
Expand Down Expand Up @@ -1212,9 +1222,9 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
/// Compile a class method AST Node into bytecode.
fn method(&mut self, function: FunctionSpec<'_>, class_name: Sym) {
let (generator, r#async, arrow) = (
function.is_generator(),
function.is_async(),
function.is_arrow(),
function.kind.is_generator(),
function.kind.is_async(),
function.kind.is_arrow(),
);
let FunctionSpec {
name,
Expand Down
16 changes: 14 additions & 2 deletions boa_engine/src/bytecompiler/module.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::vm::BindingOpcode;
use crate::vm::{BindingOpcode, Opcode};

use super::ByteCompiler;
use super::{ByteCompiler, Literal};
use boa_ast::{declaration::ExportDeclaration, expression::Identifier, ModuleItem, ModuleItemList};
use boa_interner::Sym;

Expand Down Expand Up @@ -55,6 +55,18 @@ impl ByteCompiler<'_, '_> {
let name = Identifier::from(Sym::DEFAULT_EXPORT);
self.create_mutable_binding(name, false);
self.compile_expr(expr, true);

if expr.is_anonymous_function_definition() {
let default = self
.interner()
.resolve_expect(Sym::DEFAULT)
.into_common(false);
self.emit_push_literal(Literal::String(default));
self.emit_opcode(Opcode::Swap);
self.emit_opcode(Opcode::SetFunctionName);
self.emit_u8(0);
}

self.emit_binding(BindingOpcode::InitLet, name);
}
}
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/bytecompiler/statement/labelled.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl ByteCompiler<'_, '_> {
stmt => self.compile_stmt(stmt, use_expr),
},
LabelledItem::Function(f) => {
self.function(f.into(), NodeKind::Declaration, false);
self.function_with_binding(f.into(), NodeKind::Declaration, false);
}
}

Expand Down
Loading