|
1 | 1 | //! All methods for deserializing a [`JsValueStore`] into a [`JsValue`]. |
2 | 2 | use crate::store::{JsValueStore, StringStore, ValueStoreInner, unsupported_type}; |
3 | 3 | use boa_engine::builtins::array_buffer::{AlignedVec, SharedArrayBuffer}; |
| 4 | +use boa_engine::builtins::error::ErrorKind; |
4 | 5 | use boa_engine::builtins::typed_array::TypedArrayKind; |
5 | 6 | use boa_engine::object::builtins::{ |
6 | 7 | JsArray, JsArrayBuffer, JsDataView, JsDate, JsMap, JsRegExp, JsSet, JsSharedArrayBuffer, |
7 | 8 | js_typed_array_from_kind, |
8 | 9 | }; |
9 | | -use boa_engine::{Context, JsBigInt, JsObject, JsResult, JsString, JsValue, js_error}; |
| 10 | +use boa_engine::{ |
| 11 | + Context, JsBigInt, JsNativeError, JsObject, JsResult, JsString, JsValue, js_string, |
| 12 | +}; |
10 | 13 | use std::collections::HashMap; |
11 | 14 |
|
12 | 15 | #[derive(Default)] |
13 | 16 | pub(super) struct ReverseSeenMap(HashMap<usize, JsObject>); |
14 | 17 |
|
| 18 | +type ErrorStoreFields<'a> = ( |
| 19 | + &'a ErrorKind, |
| 20 | + &'a StringStore, |
| 21 | + &'a StringStore, |
| 22 | + &'a StringStore, |
| 23 | + &'a StringStore, |
| 24 | +); |
| 25 | + |
15 | 26 | impl ReverseSeenMap { |
16 | 27 | fn get(&self, object: &JsValueStore) -> Option<JsObject> { |
17 | 28 | let addr = std::ptr::from_ref(object.0.as_ref()).addr(); |
@@ -150,6 +161,47 @@ fn try_into_js_date( |
150 | 161 | Ok(JsValue::from(date)) |
151 | 162 | } |
152 | 163 |
|
| 164 | +fn try_into_js_error( |
| 165 | + store: &JsValueStore, |
| 166 | + error_data: ErrorStoreFields<'_>, |
| 167 | + seen: &mut ReverseSeenMap, |
| 168 | + context: &mut Context, |
| 169 | +) -> JsResult<JsValue> { |
| 170 | + let (kind, name, message, stack, cause) = error_data; |
| 171 | + let message = message.to_js_string().to_std_string_escaped(); |
| 172 | + let native = match kind { |
| 173 | + ErrorKind::Aggregate => JsNativeError::aggregate(Vec::new()), |
| 174 | + ErrorKind::Eval => JsNativeError::eval(), |
| 175 | + ErrorKind::Type => JsNativeError::typ(), |
| 176 | + ErrorKind::Range => JsNativeError::range(), |
| 177 | + ErrorKind::Reference => JsNativeError::reference(), |
| 178 | + ErrorKind::Syntax => JsNativeError::syntax(), |
| 179 | + ErrorKind::Uri => JsNativeError::uri(), |
| 180 | + _ => JsNativeError::error(), |
| 181 | + } |
| 182 | + .with_message(message); |
| 183 | + |
| 184 | + let error = native.into_opaque(context); |
| 185 | + seen.insert(store, error.clone()); |
| 186 | + |
| 187 | + let name = name.to_js_string(); |
| 188 | + if !name.is_empty() { |
| 189 | + error.set(js_string!("name"), name, true, context)?; |
| 190 | + } |
| 191 | + |
| 192 | + let stack = stack.to_js_string(); |
| 193 | + if !stack.is_empty() { |
| 194 | + error.set(js_string!("stack"), stack, true, context)?; |
| 195 | + } |
| 196 | + |
| 197 | + let cause = cause.to_js_string(); |
| 198 | + if !cause.is_empty() { |
| 199 | + error.set(js_string!("cause"), cause, true, context)?; |
| 200 | + } |
| 201 | + |
| 202 | + Ok(JsValue::from(error)) |
| 203 | +} |
| 204 | + |
153 | 205 | fn try_into_regexp( |
154 | 206 | store: &JsValueStore, |
155 | 207 | source: &str, |
@@ -207,7 +259,13 @@ pub(super) fn try_value_into_js( |
207 | 259 | ValueStoreInner::Set(values) => try_into_js_set(store, values, seen, context), |
208 | 260 | ValueStoreInner::Array(items) => try_items_into_js_array(store, items, seen, context), |
209 | 261 | ValueStoreInner::Date(msec) => try_into_js_date(store, *msec, seen, context), |
210 | | - ValueStoreInner::Error { .. } => Err(js_error!("Not yet implemented.")), |
| 262 | + ValueStoreInner::Error { |
| 263 | + kind, |
| 264 | + name, |
| 265 | + message, |
| 266 | + stack, |
| 267 | + cause, |
| 268 | + } => try_into_js_error(store, (kind, name, message, stack, cause), seen, context), |
211 | 269 | ValueStoreInner::RegExp { source, flags } => { |
212 | 270 | try_into_regexp(store, source, flags, seen, context) |
213 | 271 | } |
|
0 commit comments