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

refactor: add 'setup' module, move isolate creation code #499

Merged
merged 50 commits into from
Jan 29, 2024

Conversation

bartlomieju
Copy link
Member

@bartlomieju bartlomieju commented Jan 26, 2024

This commit add "deno_core::runtime::setup" module and factors
out some non-trivial pieces of logic into standalone functions.

A lot of this code has been organically added over the years and it
becomes harder and harder to reason about op registration as well
as OpState setup.

In preparation for #489
Towards #52

core/runtime/setup.rs Outdated Show resolved Hide resolved
Comment on lines +32 to +34
// TODO(bartlomieju): `deno_core_ext` ops should be returned as a separate
// vector - they need to be special cased and attached to `Deno.core.ops`,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

core/ops.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@mmastrac mmastrac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, some minor feedback.

@@ -89,6 +89,9 @@ pub(crate) fn external_references(
let refs = v8::ExternalReferences::new(&references);
// Leak, V8 takes ownership of the references.
std::mem::forget(references);

// V8 takes ownership of external_references.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually something we need to fix eventually. It should be dropped along with the runtime.

additional_references
.extend_from_slice(extension.get_external_references());
}
let mut op_state = OpState::new(options.feature_checker.take());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For later: we should move a lot of this opstate setup into the core extension itself. I started adding the task spawners there as well.

.expect("Failed to evaluate extension JS");

// TODO(bartlomieju): clean this up - we shouldn't need to store extensions
// on the `js_runtime` as they are mutable.
js_runtime.extensions = extensions;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was previously done for realms support. It might not be required any more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only required because of snapshot_util using it to print Cargo directives. I opened #502.

)
.unwrap();
module_map.instantiate_module(scope, mod_id).unwrap();
let mut receiver = module_map.mod_evaluate(scope, mod_id);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move this to a mod_evaluate_sync method in ModuleMap? Polling an async function with a noop-waker is not a great pattern as it should require extra scrutiny every time we see it. The extension sync loader code could mostly be hoisted into the ModuleMap as mod_evaluate_sync:

        match receiver.poll_unpin(&mut Context::from_waker(noop_waker_ref())) {
          Poll::Ready(result) => {
            result
              .with_context(|| format!("Couldn't execute '{specifier}'"))?;
          }
          Poll::Pending => {
            // Find the TLA location and return it as an error
            let scope = &mut realm.handle_scope(self.v8_isolate());
            let messages = module_map.find_stalled_top_level_await(scope);
            assert!(!messages.is_empty());
            let msg = v8::Local::new(scope, &messages[0]);
            let js_error = JsError::from_v8_message(scope, msg);
            return Err(Error::from(js_error))
              .with_context(|| "Top-level await is not allowed in extensions");
          }
        }

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I will do it in a follow up PR.

core/runtime/jsruntime.rs Outdated Show resolved Hide resolved
bartlomieju added a commit that referenced this pull request Jan 29, 2024
This commit removes entanglement between "OpCtx" and "ContextState"
structs.

"OpCtx" no longer requires "ContextState" to be passed as an argument.
Instead it accepts "op_driver" arg which is "OpDriverImpl" (renamed from
"DefaultOpDriver").

This allows us to fully set up "OpCtx" for every op and only then create
"ContextState".
This unlocks a lock of further clean ups that are done in
#499.
@bartlomieju bartlomieju enabled auto-merge (squash) January 29, 2024 16:41
@bartlomieju bartlomieju merged commit 5f265b3 into denoland:main Jan 29, 2024
13 checks passed
@bartlomieju bartlomieju deleted the cleanup_jsruntime_creation branch January 29, 2024 16:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants