Skip to content

Commit

Permalink
Merge branch 'main' into error-rework
Browse files Browse the repository at this point in the history
# Conflicts:
#	core/modules/map.rs
  • Loading branch information
crowlKats committed Oct 12, 2024
2 parents 0d4e7a1 + 7258aa3 commit c5f85ad
Show file tree
Hide file tree
Showing 41 changed files with 672 additions and 189 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/ci-test-valgrind/suppressions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,19 @@
fun:Builtins_CEntry_Return1_ArgvOnStack_NoBuiltinExit
fun:Builtins_CompileLazy
}
{
<insert_a_suppression_name_here>
Memcheck:Value8
fun:_ZN2v88internal18MacroAssemblerBase12BuiltinEntryENS0_7BuiltinE
fun:_ZN2v88internal14MacroAssembler11CallBuiltinENS0_7BuiltinE
fun:_ZZN2v88internal6maglev15MaglevAssembler32CheckAndEmitDeferredWriteBarrierILNS2_9StoreModeE1EEEvNS0_8RegisterENSt4__Cr11conditionalIXeqT_LS4_0EEiS5_E4typeES5_NS1_16RegisterSnapshotENS2_17ValueIsCompressedENS2_13ValueCanBeSmiEENKUlPS2_NS1_12ZoneLabelRefES5_S5_S5_SA_SB_E_clESD_SE_S5_S5_S5_SA_SB_
fun:_ZZN2v88internal6maglev15MaglevAssembler32CheckAndEmitDeferredWriteBarrierILNS2_9StoreModeE1EEEvNS0_8RegisterENSt4__Cr11conditionalIXeqT_LS4_0EEiS5_E4typeES5_NS1_16RegisterSnapshotENS2_17ValueIsCompressedENS2_13ValueCanBeSmiEENUlPS2_NS1_12ZoneLabelRefES5_S5_S5_SA_SB_E_8__invokeESD_SE_S5_S5_S5_SA_SB_
fun:_ZN2v88internal6maglev6detail20DeferredCodeInfoImplIZNS1_15MaglevAssembler32CheckAndEmitDeferredWriteBarrierILNS4_9StoreModeE1EEEvNS0_8RegisterENSt4__Cr11conditionalIXeqT_LS6_0EEiS7_E4typeES7_NS1_16RegisterSnapshotENS4_17ValueIsCompressedENS4_13ValueCanBeSmiEEUlPS4_NS1_12ZoneLabelRefES7_S7_S7_SC_SD_E_E8GenerateESF_
fun:_ZN2v88internal6maglev19MaglevCodeGenerator8EmitCodeEv
fun:_ZN2v88internal6maglev19MaglevCodeGenerator8AssembleEv
fun:_ZN2v88internal6maglev14MaglevCompiler7CompileEPNS0_12LocalIsolateEPNS1_21MaglevCompilationInfoE
fun:_ZN2v88internal6maglev20MaglevCompilationJob14ExecuteJobImplEPNS0_16RuntimeCallStatsEPNS0_12LocalIsolateE
fun:_ZN2v88internal12_GLOBAL__N_113CompileMaglevEPNS0_7IsolateENS0_6HandleINS0_10JSFunctionEEENS0_15ConcurrencyModeENS0_14BytecodeOffsetENS1_21CompileResultBehaviorE
fun:_ZN2v88internal12_GLOBAL__N_121GetOrCompileOptimizedEPNS0_7IsolateENS0_6HandleINS0_10JSFunctionEEENS0_15ConcurrencyModeENS0_8CodeKindENS0_14BytecodeOffsetENS1_21CompileResultBehaviorE
fun:_ZN2v88internal8Compiler16CompileOptimizedEPNS0_7IsolateENS0_6HandleINS0_10JSFunctionEEENS0_15ConcurrencyModeENS0_8CodeKindE
}
19 changes: 14 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
resolver = "2"
members = [
"core",
"core/examples/snapshot",
"dcore",
"ops",
"ops/compile_test_runner",
Expand All @@ -19,12 +20,12 @@ repository = "https://github.com/denoland/deno_core"

[workspace.dependencies]
# Local dependencies
deno_core = { version = "0.306.0", path = "./core" }
deno_ops = { version = "0.182.0", path = "./ops" }
serde_v8 = { version = "0.215.0", path = "./serde_v8" }
deno_core = { version = "0.311.0", path = "./core" }
deno_ops = { version = "0.187.0", path = "./ops" }
serde_v8 = { version = "0.220.0", path = "./serde_v8" }
deno_core_testing = { path = "./testing" }

v8 = { version = "0.104.0", default-features = false }
v8 = { version = "0.106.0", default-features = false }
deno_ast = { version = "=0.40.0", features = ["transpiling"] }
deno_unsync = "0.4.0"
deno_core_icudata = "0.0.73"
Expand Down
33 changes: 7 additions & 26 deletions core/01_core.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,24 +260,6 @@
return ObjectFromEntries(op_resources());
}

function metrics() {
// TODO(mmastrac): we should replace this with a newer API
return {
opsDispatched: 0,
opsDispatchedSync: 0,
opsDispatchedAsync: 0,
opsDispatchedAsyncUnref: 0,
opsCompleted: 0,
opsCompletedSync: 0,
opsCompletedAsync: 0,
opsCompletedAsyncUnref: 0,
bytesSentControl: 0,
bytesSentData: 0,
bytesReceived: 0,
ops: {},
};
}

let reportExceptionCallback = (error) => {
op_dispatch_exception(error, false);
};
Expand Down Expand Up @@ -313,7 +295,7 @@
});
}

// Some "extensions" rely on "BadResource", "Interrupted", "PermissionDenied"
// Some "extensions" rely on "BadResource", "Interrupted", "NotCapable"
// errors in the JS code (eg. "deno_net") so they are provided in "Deno.core"
// but later reexported on "Deno.errors"
class BadResource extends Error {
Expand All @@ -332,17 +314,17 @@
}
const InterruptedPrototype = Interrupted.prototype;

class PermissionDenied extends Error {
class NotCapable extends Error {
constructor(msg) {
super(msg);
this.name = "PermissionDenied";
this.name = "NotCapable";
}
}
const PermissionDeniedPrototype = PermissionDenied.prototype;
const NotCapablePrototype = NotCapable.prototype;

registerErrorClass("BadResource", BadResource);
registerErrorClass("Interrupted", Interrupted);
registerErrorClass("PermissionDenied", PermissionDenied);
registerErrorClass("NotCapable", NotCapable);

const promiseHooks = [
[], // init
Expand Down Expand Up @@ -650,14 +632,13 @@
const core = ObjectAssign(globalThis.Deno.core, {
internalRidSymbol: Symbol("Deno.internal.rid"),
resources,
metrics,
eventLoopTick,
BadResource,
BadResourcePrototype,
Interrupted,
InterruptedPrototype,
PermissionDenied,
PermissionDeniedPrototype,
NotCapable,
NotCapablePrototype,
refOpPromise,
unrefOpPromise,
setReportExceptionCallback,
Expand Down
2 changes: 1 addition & 1 deletion core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[package]
name = "deno_core"
version = "0.306.0"
version = "0.311.0"
authors.workspace = true
edition.workspace = true
license.workspace = true
Expand Down
4 changes: 2 additions & 2 deletions core/core.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,8 @@ export namespace core {
export const BadResourcePrototype: typeof BadResource.prototype;
export class Interrupted extends Error {}
export const InterruptedPrototype: typeof Interrupted.prototype;
export class PermissionDenied extends Error {}
export const PermissionDeniedPrototype: typeof PermissionDenied.prototype;
export class NotCapable extends Error {}
export const NotCapablePrototype: typeof NotCapable.prototype;

function serialize(
value: any,
Expand Down
12 changes: 7 additions & 5 deletions core/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub type AnyError = anyhow::Error;
#[derive(Debug, thiserror::Error)]
pub enum CoreError {
#[error("Top-level await is not allowed in extensions")]
TLA(#[source] JsError),
TLA,
#[error(transparent)]
Js(#[from] JsError),
#[error(transparent)]
Expand Down Expand Up @@ -194,7 +194,7 @@ impl JsErrorClass for anyhow::Error {
impl JsErrorClass for CoreError {
fn get_class(&self) -> &'static str {
match self {
CoreError::TLA(js_error) | CoreError::Js(js_error) => {
CoreError::Js(js_error) => {
unreachable!("JsError's should not be reachable: {}", js_error)
}
CoreError::Io(err) => err.get_class(),
Expand All @@ -207,7 +207,8 @@ impl JsErrorClass for CoreError {
CoreError::DataError(err) => err.get_class(),
CoreError::Other(err) => err.get_class(),
CoreError::FutureCanceled(_) => "Interrupted",
CoreError::Parse(_)
CoreError::TLA
| CoreError::Parse(_)
| CoreError::Execute(_)
| CoreError::UnusedModules(_)
| CoreError::NonEvaluatedModules(_)
Expand All @@ -220,7 +221,7 @@ impl JsErrorClass for CoreError {

fn get_message(&self) -> Cow<'static, str> {
match self {
CoreError::TLA(js_error) | CoreError::Js(js_error) => {
CoreError::Js(js_error) => {
unreachable!("JsError's should not be reachable: {}", js_error)
}
CoreError::Io(err) => err.get_message(),
Expand All @@ -232,7 +233,8 @@ impl JsErrorClass for CoreError {
CoreError::Module(err) => err.get_message(),
CoreError::DataError(err) => err.get_message(),
CoreError::Other(err) => err.get_message(),
CoreError::Parse(_)
CoreError::TLA
| CoreError::Parse(_)
| CoreError::Execute(_)
| CoreError::UnusedModules(_)
| CoreError::NonEvaluatedModules(_)
Expand Down
19 changes: 19 additions & 0 deletions core/examples/snapshot/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
# Note: Since Cargo "example" targets don't discover/use `build.rs` files, this
# example is a member of the root `deno_core` workspace. That means it will
# compile with `cargo build` in the root, so that this example/documentation
# stays in-sync with development.

[package]
name = "build-your-own-js-snapshot"
version = "0.1.0"
edition = "2021"
build = "build.rs"


[dependencies]
deno_core.workspace = true
tokio.workspace = true

[build-dependencies]
deno_core.workspace = true
32 changes: 32 additions & 0 deletions core/examples/snapshot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Snapshot Example

This example roughly follows the blog post
[Roll Your Own JavaScript Runtime: Part 3][blog] to create a `JsRuntime` with an
embedded startup snapshot.

That blog post and the two that preceded it were no longer accurate. By
including this example in the repository, it will continually be built, so it
will hopefully stay up-to-date.

## Running

The example can be run by changing to the `core/examples/snapshot` directory and
running `cargo run`.

## Differences

Differences from those blog posts:

- The `create_snapshot()` API has changed in various ways.
- New API features for extensions:
- `#[op2]` ([read more][op2])
- `extension!(...)` macro replaces `Extension::builder()`
- ESM-based extensions.

Missing features vs. those blog posts:

- Does not implement [TsModuleLoader], to keep this example more concise.

[blog]: https://deno.com/blog/roll-your-own-javascript-runtime-pt3#creating-a-snapshot-in-buildrs
[op2]: https://github.com/denoland/deno_core/tree/main/ops/op2#readme
[TsModuleLoader]: https://deno.com/blog/roll-your-own-javascript-runtime-pt2#supporting-typescript
42 changes: 42 additions & 0 deletions core/examples/snapshot/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use deno_core::{
extension,
snapshot::{create_snapshot, CreateSnapshotOptions},
};
use std::path::PathBuf;
use std::{env, fs};

fn main() {
extension!(
runjs_extension,
// Must specify an entrypoint so that our module gets loaded while snapshotting:
esm_entry_point = "my:runtime",
esm = [
dir "src",
"my:runtime" = "runtime.js",
],
);

let options = CreateSnapshotOptions {
cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"),
startup_snapshot: None,
extensions: vec![runjs_extension::init_ops_and_esm()],
with_runtime_cb: None,
skip_op_registration: false,
extension_transpiler: None,
};
let warmup_script = None;

let snapshot =
create_snapshot(options, warmup_script).expect("Error creating snapshot");

// Save the snapshot for use by our source code:
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let file_path = out_dir.join("RUNJS_SNAPSHOT.bin");
fs::write(file_path, snapshot.output).expect("Failed to write snapshot");

// Let cargo know that builds depend on these files:
for path in snapshot.files_loaded_during_snapshot {
println!("cargo:rerun-if-changed={}", path.display());
}
}
6 changes: 6 additions & 0 deletions core/examples/snapshot/example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// Run this script with `cargo run`.

import { callRust } from "my:runtime";

callRust("Hello from example.js");
47 changes: 47 additions & 0 deletions core/examples/snapshot/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use std::{env::current_dir, rc::Rc};

use deno_core::{
error::AnyError, extension, op2, FsModuleLoader, JsRuntime,
PollEventLoopOptions, RuntimeOptions,
};

fn main() {
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();
if let Err(error) = runtime.block_on(run_js("./example.js")) {
eprintln!("error: {}", error);
}
}

#[op2(fast)]
fn op_call_rust(#[string] value: String) {
println!("Received this value from JS: {value}");
}

extension!(runjs_extension, ops = [op_call_rust,],);

async fn run_js(file_path: &str) -> Result<(), AnyError> {
let cwd = current_dir()?;
let main_module = deno_core::resolve_path(file_path, &cwd)?;

let mut js_runtime = JsRuntime::new(RuntimeOptions {
module_loader: Some(Rc::new(FsModuleLoader)),
startup_snapshot: Some(RUNTIME_SNAPSHOT),
extensions: vec![runjs_extension::init_ops()],
..Default::default()
});

let mod_id = js_runtime.load_main_es_module(&main_module).await?;
let result = js_runtime.mod_evaluate(mod_id);
js_runtime
.run_event_loop(PollEventLoopOptions::default())
.await?;
result.await
}

// Load the snapshot generated by build.rs:
static RUNTIME_SNAPSHOT: &[u8] =
include_bytes!(concat!(env!("OUT_DIR"), "/RUNJS_SNAPSHOT.bin"));
Loading

0 comments on commit c5f85ad

Please sign in to comment.