1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-25 15:29:32 -05:00

perf(core): js errors as unions vs tuples to reduce allocs (#9947)

This commit is contained in:
Aaron O'Mullan 2021-04-01 13:24:30 +02:00 committed by GitHub
parent f8aff8edcd
commit 6eace4de5c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 19 deletions

View file

@ -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);
@ -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));
}
}

View file

@ -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,
}
@ -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(),
}),
}))
}