boa icon indicating copy to clipboard operation
boa copied to clipboard

Split WebAPI (environment) built-in objects from the ES builtin objects.

Open croraf opened this issue 4 years ago • 5 comments

Split WebAPI (environment) objects from the ES builtin objects.

Perhaps delegate the implementation of environment objects to some other library.

croraf avatar Sep 26 '20 17:09 croraf

I understand that things like console shouldn’t be in the engine, but it is used for debugging purposes and is making lives easier right now.

This will most likely be a low priority issue as I think Console is the only object that is external from the spec, and we benefit more from having it right now than we do by getting rid of it. I also don’t know if many are embedding Boa right now for it to be a problem

jasonwilliams avatar Sep 26 '20 19:09 jasonwilliams

OK, but I would at least think of separating the Console from the "/boa" JS engine folder, and would inject it somehow into the environment (for example from the "boa_cli" or something)?

Doing this would also as a prerequisite require an API for putting external builtin objects into the execution context (or whatever is the proper terminology).

croraf avatar Sep 26 '20 20:09 croraf

Proposed changes:

  • We put our implementation of the console object in an feature flags (maybe console/console-object flag) this will on by default or not, not sure.

  • Later on once we implement #551

    • We will have a builder struct called ContextBuilder with will impl:
impl ContextBuilder {
	#[cfg(feature = "console")]
	pub fn console<T>(&mut self, value: T) -> &mut Self
	where
		T: Into<Console>,
	{
	}

	fn build() -> &mut Self {
		// ...	
	}
}

so we can do something like this:

let mut context = Context::builder()
	.console(MyConsole) // MyConsole implements Console as described in #551
	.build();

// ...

later on we will be able to extend the ContextBuilder struct to maybe disable/enable some builtin objects like Map/Set/Proxy/...

HalidOdat avatar Sep 27 '20 19:09 HalidOdat

The way I see it, console is different in boa_wasm and boa_cli, for example. The first should print in the browser while the second one should print in the OS console.

JavaScript has no notion of console or anything, so something we could do here is to use a register hook to add this. We don't have a register_global_variable hook, right? maybe we should, and we could use that to add stuff if needed.

Note that the hook itself is needed for full test262 executor compliance, since we need to add some global variables + functions.

Once we have that, we can move the console implementation to its own crate, something like boa_console, that accepts a printer as described in #551. This would be used in the boa_cli crate, while the boa_wasm could inject its own implementation, I think, right?

Razican avatar Oct 02 '20 16:10 Razican

If we go with "the inject on context creation" route, perhaps the following can be used.


The current flow goes like this:

boa_cli/src/main.rs let mut engine = Context::new(); calls boa/src/context.rs

pub fn new() -> Self {
   Default::default()
}

which calls impl Default for Context { which initializes the given builtins (which are mostly ES builtins).


Through this path I would pass a parameter which would contain the list of external structs with init callback method. Each instance from the list will have its init called, which will receive the global_object that it will be able to inject into.

Or use some other injection strategy through this path.

croraf avatar Oct 06 '20 21:10 croraf