Skip to content

Commit

Permalink
Add code doc
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat committed Jul 27, 2023
1 parent d2b2a1a commit ef099f0
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 11 deletions.
8 changes: 0 additions & 8 deletions boa_engine/src/bytecompiler/declarations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -805,11 +805,6 @@ impl ByteCompiler<'_, '_> {
strict: bool,
generator: bool,
) -> (Option<Label>, bool) {
if self.in_async() && !self.in_generator() {
self.emit_opcode(Opcode::CreatePromiseCapability);
self.async_handler = Some(self.push_handler());
}

let mut env_label = None;
let mut additional_env = false;

Expand Down Expand Up @@ -1016,9 +1011,6 @@ impl ByteCompiler<'_, '_> {
self.emit_opcode(Opcode::RestParameterPop);
}

if self.async_handler.is_none() && self.in_async() {
self.async_handler = Some(self.push_handler());
}
if generator {
self.emit_opcode(Opcode::Generator);
self.emit_u8(self.in_async().into());
Expand Down
39 changes: 38 additions & 1 deletion boa_engine/src/bytecompiler/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
builtins::function::ThisMode,
bytecompiler::ByteCompiler,
environments::CompileTimeEnvironment,
vm::{CodeBlock, CodeBlockFlags},
vm::{CodeBlock, CodeBlockFlags, Opcode},
Context,
};
use boa_ast::function::{FormalParameterList, FunctionBody};
Expand Down Expand Up @@ -120,6 +120,31 @@ impl FunctionCompiler {
// Function environment
compiler.push_compile_environment(true);

// Taken from:
// - 15.9.3 Runtime Semantics: EvaluateAsyncConciseBody: <https://tc39.es/ecma262/#sec-runtime-semantics-evaluateasyncconcisebody>
// - 15.8.4 Runtime Semantics: EvaluateAsyncFunctionBody: <https://tc39.es/ecma262/#sec-runtime-semantics-evaluateasyncfunctionbody>
//
// Note: In `EvaluateAsyncGeneratorBody` unlike the async non-generator functions we don't handle exceptions thrown by
// `FunctionDeclarationInstantiation` (so they are propagated).
//
// See: 15.6.2 Runtime Semantics: EvaluateAsyncGeneratorBody: https://tc39.es/ecma262/#sec-runtime-semantics-evaluateasyncgeneratorbody
if compiler.in_async() && !compiler.in_generator() {
// 1. Let promiseCapability be ! NewPromiseCapability(%Promise%).
//
// Note: If the promise capability is already set, then we do nothing.
// This is a deviation from the spec, but it allows to set the promise capability by
// ExecuteAsyncModule ( module ): <https://tc39.es/ecma262/#sec-execute-async-module>
compiler.emit_opcode(Opcode::CreatePromiseCapability);

// 2. Let declResult be Completion(FunctionDeclarationInstantiation(functionObject, argumentsList)).
//
// Note: We push an exception handler so we catch exceptions that are thrown by the
// `FunctionDeclarationInstantiation` abstract function.
//
// Patched in `ByteCompiler::finish()`.
compiler.async_handler = Some(compiler.push_handler());
}

let (env_label, additional_env) = compiler.function_declaration_instantiation(
body,
parameters,
Expand All @@ -128,6 +153,18 @@ impl FunctionCompiler {
self.generator,
);

// Taken from:
// - 27.6.3.2 AsyncGeneratorStart ( generator, generatorBody ): <https://tc39.es/ecma262/#sec-asyncgeneratorstart>
//
// Note: We do handle exceptions thrown by generator body in `AsyncGeneratorStart`.
if compiler.in_generator() {
assert!(compiler.async_handler.is_none());
if compiler.in_async() {
// Patched in `ByteCompiler::finish()`.
compiler.async_handler = Some(compiler.push_handler());
}
}

compiler.compile_statement_list(body.statements(), false, false);

if let Some(env_labels) = env_label {
Expand Down
9 changes: 9 additions & 0 deletions boa_engine/src/bytecompiler/jump_control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,16 @@ impl JumpRecord {
JumpRecordKind::Continue => compiler.patch_jump_with_target(self.label, start_address),
JumpRecordKind::Return => {
match (compiler.in_async(), compiler.in_generator()) {
// Taken from:
// - 27.6.3.2 AsyncGeneratorStart ( generator, generatorBody ): https://tc39.es/ecma262/#sec-asyncgeneratorstart
//
// Note: If we are returning we have to close the async generator function.
(true, true) => compiler.emit_opcode(Opcode::AsyncGeneratorClose),

// Taken from:
// - 27.7.5.2 AsyncBlockStart ( promiseCapability, asyncBody, asyncContext ): <https://tc39.es/ecma262/#sec-asyncblockstart>
//
// Note: If there is promise capability resolve or reject it based on pending exception.
(true, false) => compiler.emit_opcode(Opcode::CompletePromiseCapability),
(_, _) => {}
}
Expand Down
4 changes: 4 additions & 0 deletions boa_engine/src/bytecompiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,10 @@ pub struct ByteCompiler<'ctx, 'host> {
jump_info: Vec<JumpControlInfo>,
pub(crate) in_async: bool,
in_generator: bool,

/// Used to handle exception throws that escape the async function types.
///
/// Async functions and async generator functions, need to be closed and resolved.
pub(crate) async_handler: Option<u32>,
json_parse: bool,

Expand Down
2 changes: 0 additions & 2 deletions boa_engine/src/vm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@ impl Context<'_> {
const OPERAND_COLUMN_WIDTH: usize = Self::COLUMN_WIDTH;
const NUMBER_OF_COLUMNS: usize = 4;

#[inline(never)]
fn trace_call_frame(&self) {
let msg = if self.vm.frames.last().is_some() {
format!(
Expand Down Expand Up @@ -232,7 +231,6 @@ impl Context<'_> {
);
}

#[inline(never)]
fn trace_execute_instruction(&mut self) -> JsResult<CompletionType> {
let mut pc = self.vm.frame().pc as usize;
let opcode: Opcode = self.vm.frame().code_block.read::<u8>(pc).into();
Expand Down

0 comments on commit ef099f0

Please sign in to comment.