Skip to content

Commit

Permalink
Restore deno_core update and fix stack frames (#100)
Browse files Browse the repository at this point in the history
* Revert "Revert "build: update deno dependencies (not the latest version) to reduce th…" (#99)"

This reverts commit c41bd20.

* Fix `Error.prepareStackTrace` getting set incorrectly

* Add test case for `op_brioche_stack_frames_from_exception`

* Mark `op_brioche_stack_frames_from_exception` as reentrant

Fixes a panic in test (thanks to @jaudiger, see
#98 (comment))
  • Loading branch information
kylewlacy authored Jul 19, 2024
1 parent c41bd20 commit 98c29da
Show file tree
Hide file tree
Showing 9 changed files with 379 additions and 311 deletions.
485 changes: 215 additions & 270 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions crates/brioche-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ bstr = { version = "1.8.0", features = ["serde"] }
cfg-if = "1.0.0"
console-subscriber = "0.3.0"
debug-ignore = "1.0.5"
deno_ast = { version = "0.28.0", features = ["transpiling"] }
deno_core = "0.201.0"
deno_ast = { version = "0.32.1", features = ["transpiling"] }
deno_core = "0.237.0"
directories = "5.0.1"
futures = "0.3.29"
globset = "0.4.14"
Expand All @@ -40,7 +40,7 @@ reqwest-retry = "0.6.0"
rust-embed = { version = "8.1.0", features = ["debug-embed", "interpolate-folder-path", "include-exclude"] }
serde = { version = "1.0.193", features = ["derive"] }
serde_json = "1.0.108"
serde_v8 = "0.112.0"
serde_v8 = "0.146.0"
serde_with = { version = "3.4.0", features = ["hex"] }
sha2 = "0.10.8"
sqlx = { version = "0.7.3", features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate", "json"] }
Expand Down
30 changes: 17 additions & 13 deletions crates/brioche-core/src/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,12 @@ deno_core::extension!(brioche_rt,
},
);

#[deno_core::op]
#[deno_core::op2(async)]
#[serde]
pub async fn op_brioche_bake_all(
state: Rc<RefCell<OpState>>,
recipes: Vec<WithMeta<Recipe>>,
) -> anyhow::Result<Vec<Artifact>> {
#[serde] recipes: Vec<WithMeta<Recipe>>,
) -> Result<Vec<Artifact>, deno_core::error::AnyError> {
let brioche = {
let state = state.try_borrow()?;
state
Expand All @@ -197,11 +198,12 @@ pub async fn op_brioche_bake_all(
Ok(results)
}

#[deno_core::op]
#[deno_core::op2(async)]
#[serde]
pub async fn op_brioche_create_proxy(
state: Rc<RefCell<OpState>>,
recipe: Recipe,
) -> anyhow::Result<Recipe> {
#[serde] recipe: Recipe,
) -> Result<Recipe, deno_core::error::AnyError> {
let brioche = {
let state = state.try_borrow()?;
state
Expand All @@ -215,11 +217,12 @@ pub async fn op_brioche_create_proxy(
}

// TODO: Return a Uint8Array instead of tick-encoding
#[deno_core::op]
#[deno_core::op2(async)]
#[serde]
pub async fn op_brioche_read_blob(
state: Rc<RefCell<OpState>>,
blob_hash: BlobHash,
) -> anyhow::Result<crate::encoding::TickEncode<Vec<u8>>> {
#[serde] blob_hash: BlobHash,
) -> Result<crate::encoding::TickEncode<Vec<u8>>, deno_core::error::AnyError> {
let brioche = {
let state = state.try_borrow()?;
state
Expand All @@ -237,12 +240,13 @@ pub async fn op_brioche_read_blob(
Ok(crate::encoding::TickEncode(bytes))
}

#[deno_core::op]
#[deno_core::op2(async)]
#[serde]
pub async fn op_brioche_get_static(
state: Rc<RefCell<OpState>>,
url: String,
static_: StaticQuery,
) -> anyhow::Result<Recipe> {
#[string] url: String,
#[serde] static_: StaticQuery,
) -> Result<Recipe, deno_core::error::AnyError> {
let (brioche, projects) = {
let state = state.try_borrow()?;
let brioche = state
Expand Down
2 changes: 1 addition & 1 deletion crates/brioche-core/src/script/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub async fn check(
let module_id = js_runtime.load_main_module(&main_module, None).await?;
let result = js_runtime.mod_evaluate(module_id);
js_runtime.run_event_loop(false).await?;
result.await??;
result.await?;

let module_namespace = js_runtime.get_module_namespace(module_id)?;

Expand Down
28 changes: 17 additions & 11 deletions crates/brioche-core/src/script/compiler_host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,11 +271,12 @@ fn brioche_compiler_host_state(state: Rc<RefCell<OpState>>) -> anyhow::Result<Br
Ok(compiler_host)
}

#[deno_core::op]
#[deno_core::op2]
#[serde]
pub fn op_brioche_file_read(
state: Rc<RefCell<OpState>>,
path: &str,
) -> anyhow::Result<Option<Arc<String>>> {
#[string] path: &str,
) -> Result<Option<Arc<String>>, deno_core::error::AnyError> {
let compiler_host = brioche_compiler_host_state(state)?;

let specifier: BriocheModuleSpecifier = path.parse()?;
Expand All @@ -284,8 +285,11 @@ pub fn op_brioche_file_read(
Ok(contents)
}

#[deno_core::op]
pub fn op_brioche_file_exists(state: Rc<RefCell<OpState>>, path: &str) -> anyhow::Result<bool> {
#[deno_core::op2(fast)]
pub fn op_brioche_file_exists(
state: Rc<RefCell<OpState>>,
#[string] path: &str,
) -> Result<bool, deno_core::error::AnyError> {
let compiler_host = brioche_compiler_host_state(state)?;

let specifier: BriocheModuleSpecifier = path.parse()?;
Expand All @@ -294,11 +298,12 @@ pub fn op_brioche_file_exists(state: Rc<RefCell<OpState>>, path: &str) -> anyhow
Ok(result.is_some())
}

#[deno_core::op]
#[deno_core::op2]
#[bigint]
pub fn op_brioche_file_version(
state: Rc<RefCell<OpState>>,
path: &str,
) -> anyhow::Result<Option<u64>> {
#[string] path: &str,
) -> Result<Option<u64>, deno_core::error::AnyError> {
let compiler_host = brioche_compiler_host_state(state)?;

let specifier: BriocheModuleSpecifier = path.parse()?;
Expand All @@ -307,11 +312,12 @@ pub fn op_brioche_file_version(
Ok(version)
}

#[deno_core::op]
#[deno_core::op2]
#[string]
pub fn op_brioche_resolve_module(
state: Rc<RefCell<OpState>>,
specifier: &str,
referrer: &str,
#[string] specifier: &str,
#[string] referrer: &str,
) -> Option<String> {
let compiler_host = brioche_compiler_host_state(state).ok()?;

Expand Down
10 changes: 1 addition & 9 deletions crates/brioche-core/src/script/evaluate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,6 @@ pub async fn evaluate(
..Default::default()
});

js_runtime.execute_script_static(
"[brioche_init]",
r#"
// Use Deno's stack trace routine, which resolves sourcemaps
Error.prepareStackTrace = Deno.core.prepareStackTrace;
"#,
)?;

let main_module = projects.project_root_module_specifier(project_hash)?;
let main_module: deno_core::ModuleSpecifier = main_module.into();

Expand All @@ -49,7 +41,7 @@ pub async fn evaluate(
let module_id = js_runtime.load_main_module(&main_module, None).await?;
let result = js_runtime.mod_evaluate(module_id);
js_runtime.run_event_loop(false).await?;
result.await??;
result.await?;

let module_namespace = js_runtime.get_module_namespace(module_id)?;

Expand Down
6 changes: 3 additions & 3 deletions crates/brioche-core/src/script/js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ fn op_brioche_version() -> String {
crate::VERSION.to_string()
}

#[deno_core::op]
fn op_brioche_console(level: ConsoleLevel, message: String) {
#[deno_core::op2]
fn op_brioche_console(#[serde] level: ConsoleLevel, #[string] message: String) {
match level {
ConsoleLevel::Log => tracing::info!("{}", message),
ConsoleLevel::Debug => tracing::debug!("{}", message),
Expand All @@ -43,7 +43,7 @@ fn op_brioche_console(level: ConsoleLevel, message: String) {
}
}

#[deno_core::op2]
#[deno_core::op2(reentrant)]
#[serde]
fn op_brioche_stack_frames_from_exception(
scope: &mut v8::HandleScope,
Expand Down
2 changes: 1 addition & 1 deletion crates/brioche-core/src/script/lsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ fn js_lsp_task(
let module_id = js_runtime.load_main_module(&main_module, None).await?;
let result = js_runtime.mod_evaluate(module_id);
js_runtime.run_event_loop(false).await?;
result.await??;
result.await?;

let module_namespace = js_runtime.get_module_namespace(module_id)?;

Expand Down
121 changes: 121 additions & 0 deletions crates/brioche-core/tests/script_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,124 @@ async fn test_script_ops_version() -> anyhow::Result<()> {

Ok(())
}

#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct TestStackFrame {
file_name: String,
line_number: i32,
}

#[tokio::test]
async fn test_script_osp_stack_frames_from_exception() -> anyhow::Result<()> {
let (brioche, context) = brioche_test::brioche_test().await;

let project_dir = context.mkdir("myproject").await;

context
.write_file(
"myproject/project.bri",
r#"
import { foo } from "./foo.bri";
export default () => {
return {
briocheSerialize: () => {
return {
type: "create_file",
content: JSON.stringify(foo()),
executable: false,
resources: {
type: "directory",
entries: {},
},
};
},
};
};
"#,
)
.await;
context
.write_file(
"myproject/foo.bri",
r#"
import { bar } from "./bar.bri";
export function foo(): unknown {
return bar();
}
"#,
)
.await;
context
.write_file(
"myproject/bar.bri",
r#"
import { getStackFrames } from "./stack_frames.bri";
export function bar(): unknown {
return getStackFrames();
}
"#,
)
.await;
context
.write_file(
"myproject/stack_frames.bri",
r#"
export function getStackFrames(): unknown {
const error = new Error();
const frames = (globalThis as any).Deno.core.ops.op_brioche_stack_frames_from_exception(error);
// Get just the filename and line number
return frames.map((frame: any) => {
return {
fileName: frame.fileName.split("/").at(-1),
lineNumber: frame.lineNumber,
};
});
return frames;
}
"#,
)
.await;

let (projects, project_hash) = brioche_test::load_project(&brioche, &project_dir).await?;

let recipe = evaluate(&brioche, &projects, project_hash, "default")
.await?
.value;
let artifact = brioche_test::bake_without_meta(&brioche, recipe).await?;

let file = match artifact {
brioche_core::recipe::Artifact::File(file) => file,
_ => panic!("expected file artifact"),
};
let blob_path = brioche_core::blob::local_blob_path(&brioche, file.content_blob);
let content = tokio::fs::read_to_string(&blob_path).await?;

let stack_frames = serde_json::from_str::<Vec<TestStackFrame>>(&content)?;

assert_eq!(
stack_frames,
vec![
TestStackFrame {
file_name: "stack_frames.bri".to_string(),
line_number: 3,
},
TestStackFrame {
file_name: "bar.bri".to_string(),
line_number: 4,
},
TestStackFrame {
file_name: "foo.bri".to_string(),
line_number: 4,
},
TestStackFrame {
file_name: "project.bri".to_string(),
line_number: 9,
},
]
);

Ok(())
}

0 comments on commit 98c29da

Please sign in to comment.