Skip to content

Commit

Permalink
perf(core): js errors as unions vs tuples to reduce allocs (denoland#…
Browse files Browse the repository at this point in the history
  • Loading branch information
AaronO committed Apr 1, 2021
1 parent f8aff8e commit 6eace4d
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 19 deletions.
24 changes: 14 additions & 10 deletions core/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,23 @@
}

function processResponse(res) {
// const [ok, err] = res;
if (res[1] === null) {
return res[0];
if (!isErr(res)) {
return res;
}
throw processErr(res[1]);
throw processErr(res);
}

// .$err_class_name is a special key that should only exist on errors
function isErr(res) {
return !!(res && res.$err_class_name);
}

function processErr(err) {
const [ErrorClass, args] = getErrorClassAndArgs(err.className);
const className = err.$err_class_name;
const [ErrorClass, args] = getErrorClassAndArgs(className);
if (!ErrorClass) {
return new Error(
`Unregistered error class: "${err.className}"\n ${err.message}\n Classes of errors returned from ops should be registered via Deno.core.registerErrorClass().`,
`Unregistered error class: "${className}"\n ${err.message}\n Classes of errors returned from ops should be registered via Deno.core.registerErrorClass().`,
);
}
return new ErrorClass(err.message, ...args);
Expand All @@ -82,13 +87,12 @@
}

function opAsyncHandler(promiseId, res) {
// const [ok, err] = res;
const promise = promiseTable.get(promiseId);
promiseTable.delete(promiseId);
if (!res[1]) {
promise.resolve(res[0]);
if (!isErr(res)) {
promise.resolve(res);
} else {
promise.reject(processErr(res[1]));
promise.reject(processErr(res));
}
}

Expand Down
20 changes: 11 additions & 9 deletions core/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,16 @@ pub enum Op {
}

#[derive(Serialize)]
pub struct OpResult<R>(Option<R>, Option<OpError>);
#[serde(untagged)]
pub enum OpResult<R> {
Ok(R),
Err(OpError),
}

#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct OpError {
#[serde(rename = "$err_class_name")]
class_name: &'static str,
message: String,
}
Expand All @@ -88,14 +93,11 @@ pub fn serialize_op_result<R: Serialize + 'static>(
state: Rc<RefCell<OpState>>,
) -> OpResponse {
OpResponse::Value(Box::new(match result {
Ok(v) => OpResult::<R>(Some(v), None),
Err(err) => OpResult::<R>(
None,
Some(OpError {
class_name: (state.borrow().get_error_class_fn)(&err),
message: err.to_string(),
}),
),
Ok(v) => OpResult::Ok(v),
Err(err) => OpResult::Err(OpError {
class_name: (state.borrow().get_error_class_fn)(&err),
message: err.to_string(),
}),
}))
}

Expand Down

0 comments on commit 6eace4d

Please sign in to comment.