mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 11:28:12 +00:00
LibJS: Return Optional<T> from Completion::{value,target}(), not T
In the end this is a nicer API than having separate has_{value,target}() and having to check those first, and then making another Optional from the unwrapped value: completion.has_value() ? completion.value() : Optional<Value> {} // ^^^^^^^^^^^^^^^^^^ // Implicit creation of non-empty Optional<Value> This way we need to unwrap the optional ourselves, but can easily pass it to something else as well. This is in anticipation of the AST using completions :^)
This commit is contained in:
parent
b39aede8fe
commit
85f0fc2b83
15 changed files with 55 additions and 57 deletions
|
@ -51,7 +51,7 @@ GUI::Variant SheetModel::data(const GUI::ModelIndex& index, GUI::ModelRole role)
|
||||||
auto error_message = value.to_string(cell->sheet().global_object());
|
auto error_message = value.to_string(cell->sheet().global_object());
|
||||||
|
|
||||||
if (error_message.is_throw_completion())
|
if (error_message.is_throw_completion())
|
||||||
return to_string_as_exception(error_message.release_error().value());
|
return to_string_as_exception(*error_message.release_error().value());
|
||||||
|
|
||||||
builder.append(error_message.release_value());
|
builder.append(error_message.release_value());
|
||||||
return builder.to_string();
|
return builder.to_string();
|
||||||
|
@ -64,7 +64,7 @@ GUI::Variant SheetModel::data(const GUI::ModelIndex& index, GUI::ModelRole role)
|
||||||
|
|
||||||
auto display = cell->typed_display();
|
auto display = cell->typed_display();
|
||||||
if (display.is_error())
|
if (display.is_error())
|
||||||
return to_string_as_exception(display.release_error().value());
|
return to_string_as_exception(*display.release_error().value());
|
||||||
|
|
||||||
return display.release_value();
|
return display.release_value();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1629,10 +1629,10 @@ ThrowCompletionOr<Value> ClassExpression::class_definition_evaluation(Interprete
|
||||||
instance_fields.append(move(*class_field_definition_ptr));
|
instance_fields.append(move(*class_field_definition_ptr));
|
||||||
} else if (element.class_element_kind() == ClassElement::ElementKind::StaticInitializer) {
|
} else if (element.class_element_kind() == ClassElement::ElementKind::StaticInitializer) {
|
||||||
// We use Completion to hold the ClassStaticBlockDefinition Record.
|
// We use Completion to hold the ClassStaticBlockDefinition Record.
|
||||||
VERIFY(element_value.has<Completion>() && element_value.get<Completion>().has_value());
|
VERIFY(element_value.has<Completion>() && element_value.get<Completion>().value().has_value());
|
||||||
auto element_object = element_value.get<Completion>().value();
|
auto& element_object = element_value.get<Completion>().value()->as_object();
|
||||||
VERIFY(is<ECMAScriptFunctionObject>(element_object.as_object()));
|
VERIFY(is<ECMAScriptFunctionObject>(element_object));
|
||||||
static_elements.append(static_cast<ECMAScriptFunctionObject*>(&element_object.as_object()));
|
static_elements.append(static_cast<ECMAScriptFunctionObject*>(&element_object));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -254,7 +254,7 @@ void GetVariable::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||||
|
|
||||||
auto reference_or_error = interpreter.vm().resolve_binding(string);
|
auto reference_or_error = interpreter.vm().resolve_binding(string);
|
||||||
if (reference_or_error.is_throw_completion()) {
|
if (reference_or_error.is_throw_completion()) {
|
||||||
interpreter.vm().throw_exception(interpreter.global_object(), reference_or_error.release_error().value());
|
interpreter.vm().throw_exception(interpreter.global_object(), *reference_or_error.release_error().value());
|
||||||
return Reference {};
|
return Reference {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +278,7 @@ void SetVariable::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||||
auto& vm = interpreter.vm();
|
auto& vm = interpreter.vm();
|
||||||
auto reference_or_error = vm.resolve_binding(interpreter.current_executable().get_identifier(m_identifier));
|
auto reference_or_error = vm.resolve_binding(interpreter.current_executable().get_identifier(m_identifier));
|
||||||
if (reference_or_error.is_throw_completion()) {
|
if (reference_or_error.is_throw_completion()) {
|
||||||
interpreter.vm().throw_exception(interpreter.global_object(), reference_or_error.release_error().value());
|
interpreter.vm().throw_exception(interpreter.global_object(), *reference_or_error.release_error().value());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ ThrowCompletionOr<Object*> ArrayBufferConstructor::construct(FunctionObject& new
|
||||||
auto byte_length_or_error = vm.argument(0).to_index(global_object());
|
auto byte_length_or_error = vm.argument(0).to_index(global_object());
|
||||||
if (byte_length_or_error.is_error()) {
|
if (byte_length_or_error.is_error()) {
|
||||||
auto error = byte_length_or_error.release_error();
|
auto error = byte_length_or_error.release_error();
|
||||||
if (error.value().is_object() && is<RangeError>(error.value().as_object())) {
|
if (error.value()->is_object() && is<RangeError>(error.value()->as_object())) {
|
||||||
// Re-throw more specific RangeError
|
// Re-throw more specific RangeError
|
||||||
vm.clear_exception();
|
vm.clear_exception();
|
||||||
return vm.throw_completion<RangeError>(global_object(), ErrorType::InvalidLength, "array buffer");
|
return vm.throw_completion<RangeError>(global_object(), ErrorType::InvalidLength, "array buffer");
|
||||||
|
|
|
@ -41,7 +41,7 @@ ThrowCompletionOr<Value> AsyncFunctionDriverWrapper::react_to_async_task_complet
|
||||||
vm.clear_exception();
|
vm.clear_exception();
|
||||||
vm.stop_unwind();
|
vm.stop_unwind();
|
||||||
auto promise = Promise::create(global_object);
|
auto promise = Promise::create(global_object);
|
||||||
promise->reject(generator_result.throw_completion().value());
|
promise->reject(*generator_result.throw_completion().value());
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,12 +60,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] Type type() const { return m_type; }
|
[[nodiscard]] Type type() const { return m_type; }
|
||||||
|
[[nodiscard]] Optional<Value>& value() { return m_value; }
|
||||||
[[nodiscard]] bool has_value() const { return m_value.has_value(); }
|
[[nodiscard]] Optional<Value> const& value() const { return m_value; }
|
||||||
[[nodiscard]] Value value() const { return *m_value; }
|
[[nodiscard]] Optional<FlyString>& target() { return m_target; }
|
||||||
|
[[nodiscard]] Optional<FlyString> const& target() const { return m_target; }
|
||||||
[[nodiscard]] bool has_target() const { return m_target.has_value(); }
|
|
||||||
[[nodiscard]] FlyString const& target() const { return *m_target; }
|
|
||||||
|
|
||||||
// "abrupt completion refers to any completion with a [[Type]] value other than normal"
|
// "abrupt completion refers to any completion with a [[Type]] value other than normal"
|
||||||
[[nodiscard]] bool is_abrupt() const { return m_type != Type::Normal; }
|
[[nodiscard]] bool is_abrupt() const { return m_type != Type::Normal; }
|
||||||
|
|
|
@ -246,23 +246,23 @@ ThrowCompletionOr<Object*> ECMAScriptFunctionObject::internal_construct(MarkedVa
|
||||||
if (result.type() == Completion::Type::Return) {
|
if (result.type() == Completion::Type::Return) {
|
||||||
// FIXME: This is leftover from untangling the call/construct mess - doesn't belong here in any way, but removing it breaks derived classes.
|
// FIXME: This is leftover from untangling the call/construct mess - doesn't belong here in any way, but removing it breaks derived classes.
|
||||||
// Likely fixed by making ClassDefinitionEvaluation fully spec compliant.
|
// Likely fixed by making ClassDefinitionEvaluation fully spec compliant.
|
||||||
if (kind == ConstructorKind::Derived && result.value().is_object()) {
|
if (kind == ConstructorKind::Derived && result.value()->is_object()) {
|
||||||
auto prototype = TRY(new_target.get(vm.names.prototype));
|
auto prototype = TRY(new_target.get(vm.names.prototype));
|
||||||
if (prototype.is_object())
|
if (prototype.is_object())
|
||||||
TRY(result.value().as_object().internal_set_prototype_of(&prototype.as_object()));
|
TRY(result.value()->as_object().internal_set_prototype_of(&prototype.as_object()));
|
||||||
}
|
}
|
||||||
// EOF (End of FIXME)
|
// EOF (End of FIXME)
|
||||||
|
|
||||||
// a. If Type(result.[[Value]]) is Object, return NormalCompletion(result.[[Value]]).
|
// a. If Type(result.[[Value]]) is Object, return NormalCompletion(result.[[Value]]).
|
||||||
if (result.value().is_object())
|
if (result.value()->is_object())
|
||||||
return &result.value().as_object();
|
return &result.value()->as_object();
|
||||||
|
|
||||||
// b. If kind is base, return NormalCompletion(thisArgument).
|
// b. If kind is base, return NormalCompletion(thisArgument).
|
||||||
if (kind == ConstructorKind::Base)
|
if (kind == ConstructorKind::Base)
|
||||||
return this_argument;
|
return this_argument;
|
||||||
|
|
||||||
// c. If result.[[Value]] is not undefined, throw a TypeError exception.
|
// c. If result.[[Value]] is not undefined, throw a TypeError exception.
|
||||||
if (!result.value().is_undefined())
|
if (!result.value()->is_undefined())
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::DerivedConstructorReturningInvalidValue);
|
return vm.throw_completion<TypeError>(global_object, ErrorType::DerivedConstructorReturningInvalidValue);
|
||||||
}
|
}
|
||||||
// 11. Else, ReturnIfAbrupt(result).
|
// 11. Else, ReturnIfAbrupt(result).
|
||||||
|
@ -788,7 +788,7 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
|
||||||
|
|
||||||
VERIFY(result_and_frame.frame != nullptr);
|
VERIFY(result_and_frame.frame != nullptr);
|
||||||
if (result_and_frame.value.is_error()) {
|
if (result_and_frame.value.is_error()) {
|
||||||
vm.throw_exception(bytecode_interpreter->global_object(), result_and_frame.value.release_error().value());
|
vm.throw_exception(bytecode_interpreter->global_object(), *result_and_frame.value.release_error().value());
|
||||||
return throw_completion(vm.exception()->value());
|
return throw_completion(vm.exception()->value());
|
||||||
}
|
}
|
||||||
auto result = result_and_frame.value.release_value();
|
auto result = result_and_frame.value.release_value();
|
||||||
|
@ -844,7 +844,7 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
|
||||||
// 4. Else,
|
// 4. Else,
|
||||||
else {
|
else {
|
||||||
// a. Perform ! Call(promiseCapability.[[Reject]], undefined, « declResult.[[Value]] »).
|
// a. Perform ! Call(promiseCapability.[[Reject]], undefined, « declResult.[[Value]] »).
|
||||||
MUST(call(global_object(), promise_capability.reject, js_undefined(), declaration_result.throw_completion().value()));
|
MUST(call(global_object(), promise_capability.reject, js_undefined(), *declaration_result.throw_completion().value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. Return Completion { [[Type]]: return, [[Value]]: promiseCapability.[[Promise]], [[Target]]: empty }.
|
// 5. Return Completion { [[Type]]: return, [[Value]]: promiseCapability.[[Promise]], [[Target]]: empty }.
|
||||||
|
|
|
@ -116,7 +116,7 @@ Promise::ResolvingFunctions Promise::create_resolving_functions()
|
||||||
dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Exception while getting 'then' property, rejecting with error", &promise);
|
dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Exception while getting 'then' property, rejecting with error", &promise);
|
||||||
vm.clear_exception();
|
vm.clear_exception();
|
||||||
vm.stop_unwind();
|
vm.stop_unwind();
|
||||||
return promise.reject(then.throw_completion().value());
|
return promise.reject(*then.throw_completion().value());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 11. Let thenAction be then.[[Value]].
|
// 11. Let thenAction be then.[[Value]].
|
||||||
|
|
|
@ -89,14 +89,14 @@ ThrowCompletionOr<Value> PromiseReactionJob::call()
|
||||||
// i. Let status be Call(promiseCapability.[[Reject]], undefined, « handlerResult.[[Value]] »).
|
// i. Let status be Call(promiseCapability.[[Reject]], undefined, « handlerResult.[[Value]] »).
|
||||||
auto* reject_function = promise_capability.value().reject;
|
auto* reject_function = promise_capability.value().reject;
|
||||||
dbgln_if(PROMISE_DEBUG, "[PromiseReactionJob @ {}]: Calling PromiseCapability's reject function @ {}", this, reject_function);
|
dbgln_if(PROMISE_DEBUG, "[PromiseReactionJob @ {}]: Calling PromiseCapability's reject function @ {}", this, reject_function);
|
||||||
return vm.call(*reject_function, js_undefined(), handler_result.value());
|
return vm.call(*reject_function, js_undefined(), *handler_result.value());
|
||||||
}
|
}
|
||||||
// i. Else,
|
// i. Else,
|
||||||
else {
|
else {
|
||||||
// i. Let status be Call(promiseCapability.[[Resolve]], undefined, « handlerResult.[[Value]] »).
|
// i. Let status be Call(promiseCapability.[[Resolve]], undefined, « handlerResult.[[Value]] »).
|
||||||
auto* resolve_function = promise_capability.value().resolve;
|
auto* resolve_function = promise_capability.value().resolve;
|
||||||
dbgln_if(PROMISE_DEBUG, "[PromiseReactionJob @ {}]: Calling PromiseCapability's resolve function @ {}", this, resolve_function);
|
dbgln_if(PROMISE_DEBUG, "[PromiseReactionJob @ {}]: Calling PromiseCapability's resolve function @ {}", this, resolve_function);
|
||||||
return vm.call(*resolve_function, js_undefined(), handler_result.value());
|
return vm.call(*resolve_function, js_undefined(), *handler_result.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
// j. Return Completion(status).
|
// j. Return Completion(status).
|
||||||
|
@ -142,8 +142,8 @@ ThrowCompletionOr<Value> PromiseResolveThenableJob::call()
|
||||||
vm.stop_unwind();
|
vm.stop_unwind();
|
||||||
|
|
||||||
// i. Let status be Call(resolvingFunctions.[[Reject]], undefined, « thenCallResult.[[Value]] »).
|
// i. Let status be Call(resolvingFunctions.[[Reject]], undefined, « thenCallResult.[[Value]] »).
|
||||||
dbgln_if(PROMISE_DEBUG, "[PromiseResolveThenableJob @ {}]: then_call_result is an abrupt completion, calling reject function with value {}", this, then_call_result.throw_completion().value());
|
dbgln_if(PROMISE_DEBUG, "[PromiseResolveThenableJob @ {}]: then_call_result is an abrupt completion, calling reject function with value {}", this, *then_call_result.throw_completion().value());
|
||||||
auto status = JS::call(global_object, &reject_function, js_undefined(), then_call_result.throw_completion().value());
|
auto status = JS::call(global_object, &reject_function, js_undefined(), *then_call_result.throw_completion().value());
|
||||||
|
|
||||||
// ii. Return Completion(status).
|
// ii. Return Completion(status).
|
||||||
return status;
|
return status;
|
||||||
|
|
|
@ -20,23 +20,23 @@ struct PromiseCapability {
|
||||||
};
|
};
|
||||||
|
|
||||||
// 27.2.1.1.1 IfAbruptRejectPromise ( value, capability ), https://tc39.es/ecma262/#sec-ifabruptrejectpromise
|
// 27.2.1.1.1 IfAbruptRejectPromise ( value, capability ), https://tc39.es/ecma262/#sec-ifabruptrejectpromise
|
||||||
#define TRY_OR_REJECT(vm, capability, expression) \
|
#define TRY_OR_REJECT(vm, capability, expression) \
|
||||||
({ \
|
({ \
|
||||||
auto _temporary_try_or_reject_result = (expression); \
|
auto _temporary_try_or_reject_result = (expression); \
|
||||||
/* 1. If value is an abrupt completion, then */ \
|
/* 1. If value is an abrupt completion, then */ \
|
||||||
if (_temporary_try_or_reject_result.is_error()) { \
|
if (_temporary_try_or_reject_result.is_error()) { \
|
||||||
vm.clear_exception(); \
|
vm.clear_exception(); \
|
||||||
vm.stop_unwind(); \
|
vm.stop_unwind(); \
|
||||||
\
|
\
|
||||||
/* a. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »). */ \
|
/* a. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »). */ \
|
||||||
TRY(vm.call(*capability.reject, js_undefined(), _temporary_try_or_reject_result.release_error().value())); \
|
TRY(vm.call(*capability.reject, js_undefined(), *_temporary_try_or_reject_result.release_error().value())); \
|
||||||
\
|
\
|
||||||
/* b. Return capability.[[Promise]]. */ \
|
/* b. Return capability.[[Promise]]. */ \
|
||||||
return capability.promise; \
|
return capability.promise; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
/* 2. Else if value is a Completion Record, set value to value.[[Value]]. */ \
|
/* 2. Else if value is a Completion Record, set value to value.[[Value]]. */ \
|
||||||
_temporary_try_or_reject_result.release_value(); \
|
_temporary_try_or_reject_result.release_value(); \
|
||||||
})
|
})
|
||||||
|
|
||||||
// 27.2.1.5 NewPromiseCapability ( C ), https://tc39.es/ecma262/#sec-newpromisecapability
|
// 27.2.1.5 NewPromiseCapability ( C ), https://tc39.es/ecma262/#sec-newpromisecapability
|
||||||
|
|
|
@ -127,7 +127,7 @@ ThrowCompletionOr<Value> perform_shadow_realm_eval(GlobalObject& global_object,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 21. If result.[[Type]] is normal and result.[[Value]] is empty, then
|
// 21. If result.[[Type]] is normal and result.[[Value]] is empty, then
|
||||||
if (result.type() == Completion::Type::Normal && !result.has_value()) {
|
if (result.type() == Completion::Type::Normal && !result.value().has_value()) {
|
||||||
// a. Set result to NormalCompletion(undefined).
|
// a. Set result to NormalCompletion(undefined).
|
||||||
result = normal_completion(js_undefined());
|
result = normal_completion(js_undefined());
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ ThrowCompletionOr<Value> perform_shadow_realm_eval(GlobalObject& global_object,
|
||||||
return vm.throw_completion<TypeError>(global_object, ErrorType::ShadowRealmEvaluateAbruptCompletion);
|
return vm.throw_completion<TypeError>(global_object, ErrorType::ShadowRealmEvaluateAbruptCompletion);
|
||||||
|
|
||||||
// 25. Return ? GetWrappedValue(callerRealm, result.[[Value]]).
|
// 25. Return ? GetWrappedValue(callerRealm, result.[[Value]]).
|
||||||
return get_wrapped_value(global_object, caller_realm, result.value());
|
return get_wrapped_value(global_object, caller_realm, *result.value());
|
||||||
|
|
||||||
// NOTE: Also see "Editor's Note" in the spec regarding the TypeError above.
|
// NOTE: Also see "Editor's Note" in the spec regarding the TypeError above.
|
||||||
}
|
}
|
||||||
|
|
|
@ -469,7 +469,7 @@ void TypedArrayBase::visit_edges(Visitor& visitor)
|
||||||
auto array_length_or_error = first_argument.to_index(global_object()); \
|
auto array_length_or_error = first_argument.to_index(global_object()); \
|
||||||
if (array_length_or_error.is_error()) { \
|
if (array_length_or_error.is_error()) { \
|
||||||
auto error = array_length_or_error.release_error(); \
|
auto error = array_length_or_error.release_error(); \
|
||||||
if (error.value().is_object() && is<RangeError>(error.value().as_object())) { \
|
if (error.value()->is_object() && is<RangeError>(error.value()->as_object())) { \
|
||||||
/* Re-throw more specific RangeError */ \
|
/* Re-throw more specific RangeError */ \
|
||||||
vm.clear_exception(); \
|
vm.clear_exception(); \
|
||||||
return vm.throw_completion<RangeError>(global_object(), ErrorType::InvalidLength, "typed array"); \
|
return vm.throw_completion<RangeError>(global_object(), ErrorType::InvalidLength, "typed array"); \
|
||||||
|
|
|
@ -361,7 +361,7 @@ ThrowCompletionOr<void> VM::iterator_binding_initialization(BindingPattern const
|
||||||
auto next_object_or_error = iterator_next(*iterator);
|
auto next_object_or_error = iterator_next(*iterator);
|
||||||
if (next_object_or_error.is_throw_completion()) {
|
if (next_object_or_error.is_throw_completion()) {
|
||||||
iterator_done = true;
|
iterator_done = true;
|
||||||
return JS::throw_completion(next_object_or_error.release_error().value());
|
return JS::throw_completion(*next_object_or_error.release_error().value());
|
||||||
}
|
}
|
||||||
auto* next_object = next_object_or_error.release_value();
|
auto* next_object = next_object_or_error.release_value();
|
||||||
|
|
||||||
|
@ -380,7 +380,7 @@ ThrowCompletionOr<void> VM::iterator_binding_initialization(BindingPattern const
|
||||||
auto next_object_or_error = iterator_next(*iterator);
|
auto next_object_or_error = iterator_next(*iterator);
|
||||||
if (next_object_or_error.is_throw_completion()) {
|
if (next_object_or_error.is_throw_completion()) {
|
||||||
iterator_done = true;
|
iterator_done = true;
|
||||||
return JS::throw_completion(next_object_or_error.release_error().value());
|
return JS::throw_completion(*next_object_or_error.release_error().value());
|
||||||
}
|
}
|
||||||
auto* next_object = next_object_or_error.release_value();
|
auto* next_object = next_object_or_error.release_value();
|
||||||
|
|
||||||
|
@ -392,7 +392,7 @@ ThrowCompletionOr<void> VM::iterator_binding_initialization(BindingPattern const
|
||||||
auto value_or_error = next_object->get(names.value);
|
auto value_or_error = next_object->get(names.value);
|
||||||
if (value_or_error.is_throw_completion()) {
|
if (value_or_error.is_throw_completion()) {
|
||||||
iterator_done = true;
|
iterator_done = true;
|
||||||
return JS::throw_completion(value_or_error.release_error().value());
|
return JS::throw_completion(*value_or_error.release_error().value());
|
||||||
}
|
}
|
||||||
value = value_or_error.release_value();
|
value = value_or_error.release_value();
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,7 +160,7 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyObject::compile)
|
||||||
auto buffer_or_error = vm.argument(0).to_object(global_object);
|
auto buffer_or_error = vm.argument(0).to_object(global_object);
|
||||||
JS::Value rejection_value;
|
JS::Value rejection_value;
|
||||||
if (buffer_or_error.is_error()) {
|
if (buffer_or_error.is_error()) {
|
||||||
rejection_value = buffer_or_error.throw_completion().value();
|
rejection_value = *buffer_or_error.throw_completion().value();
|
||||||
vm.clear_exception();
|
vm.clear_exception();
|
||||||
vm.stop_unwind();
|
vm.stop_unwind();
|
||||||
}
|
}
|
||||||
|
@ -172,7 +172,7 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyObject::compile)
|
||||||
auto* buffer = buffer_or_error.release_value();
|
auto* buffer = buffer_or_error.release_value();
|
||||||
auto result = parse_module(global_object, buffer);
|
auto result = parse_module(global_object, buffer);
|
||||||
if (result.is_error())
|
if (result.is_error())
|
||||||
promise->reject(result.release_error().value());
|
promise->reject(*result.release_error().value());
|
||||||
else
|
else
|
||||||
promise->fulfill(vm.heap().allocate<WebAssemblyModuleObject>(global_object, global_object, result.release_value()));
|
promise->fulfill(vm.heap().allocate<WebAssemblyModuleObject>(global_object, global_object, result.release_value()));
|
||||||
return promise;
|
return promise;
|
||||||
|
@ -325,7 +325,7 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyObject::instantiate)
|
||||||
auto promise = JS::Promise::create(global_object);
|
auto promise = JS::Promise::create(global_object);
|
||||||
bool should_return_module = false;
|
bool should_return_module = false;
|
||||||
if (buffer_or_error.is_error()) {
|
if (buffer_or_error.is_error()) {
|
||||||
auto rejection_value = buffer_or_error.throw_completion().value();
|
auto rejection_value = *buffer_or_error.throw_completion().value();
|
||||||
vm.clear_exception();
|
vm.clear_exception();
|
||||||
vm.stop_unwind();
|
vm.stop_unwind();
|
||||||
promise->reject(rejection_value);
|
promise->reject(rejection_value);
|
||||||
|
@ -337,7 +337,7 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyObject::instantiate)
|
||||||
if (is<JS::ArrayBuffer>(buffer) || is<JS::TypedArrayBase>(buffer)) {
|
if (is<JS::ArrayBuffer>(buffer) || is<JS::TypedArrayBase>(buffer)) {
|
||||||
auto result = parse_module(global_object, buffer);
|
auto result = parse_module(global_object, buffer);
|
||||||
if (result.is_error()) {
|
if (result.is_error()) {
|
||||||
promise->reject(result.release_error().value());
|
promise->reject(*result.release_error().value());
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
module = &WebAssemblyObject::s_compiled_modules.at(result.release_value()).module;
|
module = &WebAssemblyObject::s_compiled_modules.at(result.release_value()).module;
|
||||||
|
@ -353,7 +353,7 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyObject::instantiate)
|
||||||
|
|
||||||
auto result = instantiate_module(*module, vm, global_object);
|
auto result = instantiate_module(*module, vm, global_object);
|
||||||
if (result.is_error()) {
|
if (result.is_error()) {
|
||||||
promise->reject(result.release_error().value());
|
promise->reject(*result.release_error().value());
|
||||||
} else {
|
} else {
|
||||||
auto instance_object = vm.heap().allocate<WebAssemblyInstanceObject>(global_object, global_object, result.release_value());
|
auto instance_object = vm.heap().allocate<WebAssemblyInstanceObject>(global_object, global_object, result.release_value());
|
||||||
if (should_return_module) {
|
if (should_return_module) {
|
||||||
|
|
|
@ -942,7 +942,7 @@ static bool parse_and_run(JS::Interpreter& interpreter, StringView source, Strin
|
||||||
auto result = bytecode_interpreter.run(executable);
|
auto result = bytecode_interpreter.run(executable);
|
||||||
// Since all the error handling code uses vm.exception() we just rethrow any exception we got here.
|
// Since all the error handling code uses vm.exception() we just rethrow any exception we got here.
|
||||||
if (result.is_error())
|
if (result.is_error())
|
||||||
vm->throw_exception(interpreter.global_object(), result.throw_completion().value());
|
vm->throw_exception(interpreter.global_object(), *result.throw_completion().value());
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue