Skip to content

Commit

Permalink
Add a HostHooks and JobQueue API
Browse files Browse the repository at this point in the history
  • Loading branch information
jedel1043 committed Jan 11, 2023
1 parent db88097 commit ae8aeb1
Show file tree
Hide file tree
Showing 14 changed files with 620 additions and 453 deletions.
32 changes: 29 additions & 3 deletions boa_cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,15 @@ mod helper;

use boa_ast::StatementList;
use boa_engine::{
context::ContextBuilder,
job::{JobQueue, NativeJob},
vm::flowgraph::{Direction, Graph},
Context, JsResult,
};
use clap::{Parser, ValueEnum, ValueHint};
use colored::{Color, Colorize};
use rustyline::{config::Config, error::ReadlineError, EditMode, Editor};
use std::{fs::read, fs::OpenOptions, io, path::PathBuf};
use std::{cell::RefCell, collections::VecDeque, fs::read, fs::OpenOptions, io, path::PathBuf};

#[cfg(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu"))]
#[cfg_attr(
Expand Down Expand Up @@ -253,7 +255,8 @@ fn generate_flowgraph(
fn main() -> Result<(), io::Error> {
let args = Opt::parse();

let mut context = Context::default();
let queue = Jobs::default();
let mut context = ContextBuilder::new().job_queue(&queue).build();

// Trace Output
context.set_trace(args.trace);
Expand All @@ -280,6 +283,7 @@ fn main() -> Result<(), io::Error> {
Ok(v) => println!("{}", v.display()),
Err(v) => eprintln!("Uncaught {v}"),
}
context.run_jobs();
}
}

Expand Down Expand Up @@ -333,11 +337,14 @@ fn main() -> Result<(), io::Error> {
}
} else {
match context.eval(line.trim_end()) {
Ok(v) => println!("{}", v.display()),
Ok(v) => {
println!("{}", v.display());
}
Err(v) => {
eprintln!("{}: {}", "Uncaught".red(), v.to_string().red());
}
}
context.run_jobs();
}
}

Expand All @@ -355,3 +362,22 @@ fn main() -> Result<(), io::Error> {

Ok(())
}

#[derive(Default)]
struct Jobs(RefCell<VecDeque<NativeJob>>);

impl JobQueue for Jobs {
fn enqueue_promise_job(&self, job: NativeJob, _: &mut Context<'_>) {
self.0.borrow_mut().push_front(job);
}

fn run_jobs(&self, context: &mut Context<'_>) {
let mut next_job = self.0.borrow_mut().pop_front();
while let Some(job) = next_job {
if let Err(e) = job.call(context) {
eprintln!("Uncaught {e}");
}
next_job = self.0.borrow_mut().pop_front();
}
}
}
18 changes: 10 additions & 8 deletions boa_engine/src/builtins/async_generator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -632,20 +632,22 @@ impl AsyncGenerator {
context,
NativeFunction::from_copy_closure_with_captures(
|_this, args, generator, context| {
let mut generator_borrow_mut = generator.borrow_mut();
let gen = generator_borrow_mut
.as_async_generator_mut()
.expect("already checked before");
let next = {
let mut generator_borrow_mut = generator.borrow_mut();
let gen = generator_borrow_mut
.as_async_generator_mut()
.expect("already checked before");

// a. Set generator.[[AsyncGeneratorState]] to completed.
gen.state = AsyncGeneratorState::Completed;
// a. Set generator.[[AsyncGeneratorState]] to completed.
gen.state = AsyncGeneratorState::Completed;

gen.queue.pop_front().expect("must have one entry")
};

// b. Let result be NormalCompletion(value).
let result = Ok(args.get_or_undefined(0).clone());

// c. Perform AsyncGeneratorCompleteStep(generator, result, true).
let next = gen.queue.pop_front().expect("must have one entry");
drop(generator_borrow_mut);
Self::complete_step(&next, result, true, context);

// d. Perform AsyncGeneratorDrainQueue(generator).
Expand Down
10 changes: 6 additions & 4 deletions boa_engine/src/builtins/eval/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,17 @@ impl Eval {
// Because of implementation details the following code differs from the spec.

// 5. Perform ? HostEnsureCanCompileStrings(evalRealm).
let mut parser = Parser::new(x.as_bytes());
if strict {
parser.set_strict();
}
context.host_hooks.ensure_can_compile_strings(context)?;

// 11. Perform the following substeps in an implementation-defined order, possibly interleaving parsing and error detection:
// a. Let script be ParseText(StringToCodePoints(x), Script).
// b. If script is a List of errors, throw a SyntaxError exception.
// c. If script Contains ScriptBody is false, return undefined.
// d. Let body be the ScriptBody of script.
let mut parser = Parser::new(x.as_bytes());
if strict {
parser.set_strict();
}
let body = parser.parse_eval(direct, context.interner_mut())?;

// 6. Let inFunction be false.
Expand Down
Loading

0 comments on commit ae8aeb1

Please sign in to comment.