Skip to content

Commit

Permalink
Refactor environment, exception handling and jumping in VM
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat committed Jul 15, 2023
1 parent b51e7cf commit e7c8330
Show file tree
Hide file tree
Showing 37 changed files with 953 additions and 1,595 deletions.
5 changes: 4 additions & 1 deletion boa_engine/src/builtins/eval/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,10 @@ impl Eval {
context.vm.environments.extend_outer_function_environment();
}

context.vm.push_frame(CallFrame::new(code_block));
let env_fp = context.vm.environments.len() as u32;
context
.vm
.push_frame(CallFrame::new(code_block).with_env_fp(env_fp));
context.realm().resize_global_env();
let record = context.run();
context.vm.pop_frame();
Expand Down
5 changes: 4 additions & 1 deletion boa_engine/src/builtins/json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,10 @@ impl Json {
Gc::new(compiler.finish())
};

context.vm.push_frame(CallFrame::new(code_block));
let env_fp = context.vm.environments.len() as u32;
context
.vm
.push_frame(CallFrame::new(code_block).with_env_fp(env_fp));
context.realm().resize_global_env();
let record = context.run();
context.vm.pop_frame();
Expand Down
48 changes: 41 additions & 7 deletions boa_engine/src/bytecompiler/declaration/declaration_pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,45 @@ impl ByteCompiler<'_, '_> {
self.emit_opcode(Opcode::ValueNotNullOrUndefined);
self.emit_opcode(Opcode::GetIterator);

// TODO: maybe, refactor this to be more condensed.
let handler_index = self.push_handler();
for element in pattern.bindings() {
self.compile_array_pattern_element(element, def);
}
let handler_end_address = self.next_opcode_location();

self.emit_opcode(Opcode::PushFalse);

let exit = self.jump();
let handler_address = self.next_opcode_location();
self.emit_opcode(Opcode::Exception);
self.emit_opcode(Opcode::PushTrue);
self.patch_jump(exit);

self.handlers[handler_index as usize].handler = handler_address;
self.handlers[handler_index as usize].range.end = handler_end_address;

let iterator_close_handler = self.push_handler();
self.iterator_close(false);

let exit = self.jump();
let iterator_close_handler_address = self.next_opcode_location();
{
let jump = self.jump_if_false();
self.emit_opcode(Opcode::Throw);
self.patch_jump(jump);
}
self.emit_opcode(Opcode::ReThrow);
self.patch_jump(exit);

let jump = self.jump_if_false();
self.emit_opcode(Opcode::Throw);
self.patch_jump(jump);

self.handlers[iterator_close_handler as usize].handler =
iterator_close_handler_address;
self.handlers[iterator_close_handler as usize].range.end =
iterator_close_handler_address;
}
}
}
Expand All @@ -198,15 +232,15 @@ impl ByteCompiler<'_, '_> {
match element {
// ArrayBindingPattern : [ Elision ]
Elision => {
self.emit_opcode(Opcode::IteratorNext);
self.emit_opcode(Opcode::IteratorNextWithoutPop);
}
// SingleNameBinding : BindingIdentifier Initializer[opt]
SingleName {
ident,
default_init,
} => {
self.emit_opcode(Opcode::IteratorNext);
self.emit_opcode(Opcode::IteratorValue);
self.emit_opcode(Opcode::IteratorNextWithoutPop);
self.emit_opcode(Opcode::IteratorValueWithoutPop);
if let Some(init) = default_init {
let skip = self.emit_opcode_with_operand(Opcode::JumpIfNotUndefined);
self.compile_expr(init, true);
Expand All @@ -216,17 +250,17 @@ impl ByteCompiler<'_, '_> {
}
PropertyAccess { access } => {
self.access_set(Access::Property { access }, false, |compiler, _level| {
compiler.emit_opcode(Opcode::IteratorNext);
compiler.emit_opcode(Opcode::IteratorValue);
compiler.emit_opcode(Opcode::IteratorNextWithoutPop);
compiler.emit_opcode(Opcode::IteratorValueWithoutPop);
});
}
// BindingElement : BindingPattern Initializer[opt]
Pattern {
pattern,
default_init,
} => {
self.emit_opcode(Opcode::IteratorNext);
self.emit_opcode(Opcode::IteratorValue);
self.emit_opcode(Opcode::IteratorNextWithoutPop);
self.emit_opcode(Opcode::IteratorValueWithoutPop);

if let Some(init) = default_init {
let skip = self.emit_opcode_with_operand(Opcode::JumpIfNotUndefined);
Expand Down
2 changes: 2 additions & 0 deletions boa_engine/src/bytecompiler/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use boa_ast::expression::Identifier;
impl ByteCompiler<'_, '_> {
/// Push either a new declarative or function environment on the compile time environment stack.
pub(crate) fn push_compile_environment(&mut self, function_scope: bool) {
self.current_open_environments_count += 1;
self.current_environment = Rc::new(CompileTimeEnvironment::new(
self.current_environment.clone(),
function_scope,
Expand All @@ -16,6 +17,7 @@ impl ByteCompiler<'_, '_> {
/// Pops the top compile time environment and returns its index in the compile time environments array.
#[track_caller]
pub(crate) fn pop_compile_environment(&mut self) -> u32 {
self.current_open_environments_count -= 1;
let index = self.compile_environments.len() as u32;
self.compile_environments
.push(self.current_environment.clone());
Expand Down
Loading

0 comments on commit e7c8330

Please sign in to comment.