Starting to mess with promises

Going to want async IO, I think. And it's a fun detail that I guess
I'm in charge of deciding when to run promise completion functions. :D
This commit is contained in:
John Doty 2023-06-28 15:54:13 -07:00
parent c1d86676c3
commit 5be0ffa08f
7 changed files with 251 additions and 74 deletions

View file

@ -8,6 +8,7 @@ mod class;
mod context;
mod conversion;
pub mod module;
mod promise;
mod runtime;
mod value;
@ -15,6 +16,7 @@ pub use atom::{Atom, AtomRef};
pub use class::{Class, ClassID};
pub use context::{Context, ContextRef, EvalFlags};
pub use conversion::*;
pub use promise::Promise;
pub use runtime::Runtime;
pub use value::{Value, ValueRef, ValueType};
@ -49,6 +51,20 @@ pub enum Error {
ParseError(String, String),
}
impl Error {
// Convert the error into an exception-type object which can be
// thrown. This is *different* from try_into_value which just propagates
// the error.
pub fn to_js_error(&self, context: &ContextRef) -> Value {
if let Error::Exception(e, _, _) = self {
e.clone()
} else {
let message = self.to_string();
context.new_error(&message)
}
}
}
impl From<NulError> for Error {
fn from(_: NulError) -> Self {
Error::UnexpectedNul
@ -75,35 +91,9 @@ pub(crate) fn throw_error(context: &ContextRef, error: Error) -> sys::JSValue {
}
pub(crate) fn throw_string(context: &ContextRef, message: String) -> sys::JSValue {
let ctx = context.ctx;
match context.new_string(&message) {
Ok(e) => unsafe {
// Because context.new_string yields an owned Value, and will
// clean it up on the way out, we need to explicitly DupValue a
// reference for the `Throw` to own.
let err = sys::JS_NewError(ctx);
if sys::JS_ValueGetTag(err) == sys::JS_TAG_EXCEPTION {
// GIVE UP; this is out of memory anyway things probably went
// wrong because of that.
return err;
}
sys::JS_DupValue(ctx, e.val); // SetProperty takes ownership.
let prop = CString::new("message").unwrap();
if sys::JS_SetPropertyStr(ctx, err, prop.as_ptr(), e.val) == -1 {
// Also an out of memory but we need to free the error object
// on our way out.
sys::JS_FreeValue(ctx, err);
return sys::JS_MakeException(); // JS_EXCEPTION
}
sys::JS_Throw(ctx, err)
},
Err(_) => unsafe {
sys::JS_Throw(
ctx,
sys::JS_NewString(ctx, "Errors within errors: embedded nulls in the description of the error that occurred".as_bytes().as_ptr() as *const i8),
)
},
let err = context.new_error(&message);
unsafe {
sys::JS_DupValue(context.ctx, err.val);
sys::JS_Throw(context.ctx, err.val)
}
}