mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 06:17:34 +00:00
LibJS: Make Interpreter::throw_exception() a void function
The motivation for this change is twofold: - Returning a JS::Value is misleading as one would expect it to carry some meaningful information, like maybe the error object that's being created, but in fact it is always empty. Supposedly to serve as a shortcut for the common case of "throw and return empty value", but that's just leading us to my second point. - Inconsistent usage / coding style: as of this commit there are 114 uses of throw_exception() discarding its return value and 55 uses directly returning the call result (in LibJS, not counting LibWeb); with the first style often having a more explicit empty value (or nullptr in some cases) return anyway. One more line to always make the return value obvious is should be worth it. So now it's basically always these steps, which is already being used in the majority of cases (as outlined above): - Throw an exception. This mutates interpreter state by updating m_exception and unwinding, but doesn't return anything. - Let the caller explicitly return an empty value, nullptr or anything else itself.
This commit is contained in:
parent
98dd034c29
commit
9ea6ef4ed1
21 changed files with 281 additions and 171 deletions
|
@ -88,13 +88,15 @@ public:
|
|||
|
||||
static JS_DEFINE_NATIVE_FUNCTION(parse_cell_name)
|
||||
{
|
||||
if (interpreter.argument_count() != 1)
|
||||
return interpreter.throw_exception<JS::TypeError>("Expected exactly one argument to parse_cell_name()");
|
||||
|
||||
if (interpreter.argument_count() != 1) {
|
||||
interpreter.throw_exception<JS::TypeError>("Expected exactly one argument to parse_cell_name()");
|
||||
return {};
|
||||
}
|
||||
auto name_value = interpreter.argument(0);
|
||||
if (!name_value.is_string())
|
||||
return interpreter.throw_exception<JS::TypeError>("Expected a String argument to parse_cell_name()");
|
||||
|
||||
if (!name_value.is_string()) {
|
||||
interpreter.throw_exception<JS::TypeError>("Expected a String argument to parse_cell_name()");
|
||||
return {};
|
||||
}
|
||||
auto position = Sheet::parse_cell_name(name_value.as_string().string());
|
||||
if (!position.has_value())
|
||||
return JS::js_undefined();
|
||||
|
|
|
@ -147,10 +147,11 @@ Value CallExpression::execute(Interpreter& interpreter, GlobalObject& global_obj
|
|||
} else {
|
||||
expression_string = static_cast<const MemberExpression&>(*m_callee).to_string_approximation();
|
||||
}
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::IsNotAEvaluatedFrom, callee.to_string_without_side_effects().characters(), call_type, expression_string.characters());
|
||||
interpreter.throw_exception<TypeError>(ErrorType::IsNotAEvaluatedFrom, callee.to_string_without_side_effects().characters(), call_type, expression_string.characters());
|
||||
} else {
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::IsNotA, callee.to_string_without_side_effects().characters(), call_type);
|
||||
interpreter.throw_exception<TypeError>(ErrorType::IsNotA, callee.to_string_without_side_effects().characters(), call_type);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
auto& function = callee.as_function();
|
||||
|
@ -184,9 +185,10 @@ Value CallExpression::execute(Interpreter& interpreter, GlobalObject& global_obj
|
|||
} else if (m_callee->is_super_expression()) {
|
||||
auto* super_constructor = interpreter.current_environment()->current_function()->prototype();
|
||||
// FIXME: Functions should track their constructor kind.
|
||||
if (!super_constructor || !super_constructor->is_function())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NotAConstructor, "Super constructor");
|
||||
|
||||
if (!super_constructor || !super_constructor->is_function()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NotAConstructor, "Super constructor");
|
||||
return {};
|
||||
}
|
||||
result = interpreter.construct(static_cast<Function&>(*super_constructor), function, move(arguments), global_object);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
|
@ -668,9 +670,10 @@ Value ClassExpression::execute(Interpreter& interpreter, GlobalObject& global_ob
|
|||
super_constructor = m_super_class->execute(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
if (!super_constructor.is_function() && !super_constructor.is_null())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::ClassDoesNotExtendAConstructorOrNull, super_constructor.to_string_without_side_effects().characters());
|
||||
|
||||
if (!super_constructor.is_function() && !super_constructor.is_null()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::ClassDoesNotExtendAConstructorOrNull, super_constructor.to_string_without_side_effects().characters());
|
||||
return {};
|
||||
}
|
||||
class_constructor->set_constructor_kind(Function::ConstructorKind::Derived);
|
||||
Object* prototype = Object::create_empty(global_object);
|
||||
|
||||
|
@ -695,9 +698,10 @@ Value ClassExpression::execute(Interpreter& interpreter, GlobalObject& global_ob
|
|||
if (interpreter.exception())
|
||||
return {};
|
||||
|
||||
if (!class_prototype.is_object())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NotAnObject, "Class prototype");
|
||||
|
||||
if (!class_prototype.is_object()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NotAnObject, "Class prototype");
|
||||
return {};
|
||||
}
|
||||
for (const auto& method : m_methods) {
|
||||
auto method_value = method.execute(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
|
@ -1137,8 +1141,10 @@ void ForOfStatement::dump(int indent) const
|
|||
Value Identifier::execute(Interpreter& interpreter, GlobalObject& global_object) const
|
||||
{
|
||||
auto value = interpreter.get_variable(string(), global_object);
|
||||
if (value.is_empty())
|
||||
return interpreter.throw_exception<ReferenceError>(ErrorType::UnknownIdentifier, string().characters());
|
||||
if (value.is_empty()) {
|
||||
interpreter.throw_exception<ReferenceError>(ErrorType::UnknownIdentifier, string().characters());
|
||||
return {};
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -1259,9 +1265,10 @@ Value AssignmentExpression::execute(Interpreter& interpreter, GlobalObject& glob
|
|||
if (interpreter.exception())
|
||||
return {};
|
||||
|
||||
if (reference.is_unresolvable())
|
||||
return interpreter.throw_exception<ReferenceError>(ErrorType::InvalidLeftHandAssignment);
|
||||
|
||||
if (reference.is_unresolvable()) {
|
||||
interpreter.throw_exception<ReferenceError>(ErrorType::InvalidLeftHandAssignment);
|
||||
return {};
|
||||
}
|
||||
update_function_name(rhs_result, get_function_name(interpreter, reference.name().to_value(interpreter)));
|
||||
reference.put(interpreter, global_object, rhs_result);
|
||||
|
||||
|
@ -1797,7 +1804,8 @@ Value ThrowStatement::execute(Interpreter& interpreter, GlobalObject& global_obj
|
|||
auto value = m_argument->execute(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
return interpreter.throw_exception(value);
|
||||
interpreter.throw_exception(value);
|
||||
return {};
|
||||
}
|
||||
|
||||
Value SwitchStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const
|
||||
|
|
|
@ -324,7 +324,7 @@ Value Interpreter::construct(Function& function, Function& new_target, Optional<
|
|||
return this_value;
|
||||
}
|
||||
|
||||
Value Interpreter::throw_exception(Exception* exception)
|
||||
void Interpreter::throw_exception(Exception* exception)
|
||||
{
|
||||
#ifdef INTERPRETER_DEBUG
|
||||
if (exception->value().is_object() && exception->value().as_object().is_error()) {
|
||||
|
@ -341,7 +341,6 @@ Value Interpreter::throw_exception(Exception* exception)
|
|||
#endif
|
||||
m_exception = exception;
|
||||
unwind(ScopeType::Try);
|
||||
return {};
|
||||
}
|
||||
|
||||
GlobalObject& Interpreter::global_object()
|
||||
|
|
|
@ -176,19 +176,19 @@ public:
|
|||
void clear_exception() { m_exception = nullptr; }
|
||||
|
||||
template<typename T, typename... Args>
|
||||
Value throw_exception(Args&&... args)
|
||||
void throw_exception(Args&&... args)
|
||||
{
|
||||
return throw_exception(T::create(global_object(), forward<Args>(args)...));
|
||||
}
|
||||
|
||||
Value throw_exception(Exception*);
|
||||
Value throw_exception(Value value)
|
||||
void throw_exception(Exception*);
|
||||
void throw_exception(Value value)
|
||||
{
|
||||
return throw_exception(heap().allocate<Exception>(global_object(), value));
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
Value throw_exception(ErrorType type, Args&&... args)
|
||||
void throw_exception(ErrorType type, Args&&... args)
|
||||
{
|
||||
return throw_exception(T::create(global_object(), String::format(type.message(), forward<Args>(args)...)));
|
||||
}
|
||||
|
|
|
@ -53,11 +53,11 @@ ArrayIteratorPrototype::~ArrayIteratorPrototype()
|
|||
JS_DEFINE_NATIVE_FUNCTION(ArrayIteratorPrototype::next)
|
||||
{
|
||||
auto this_value = interpreter.this_value(global_object);
|
||||
if (!this_value.is_object() || !this_value.as_object().is_array_iterator_object())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NotAn, "Array Iterator");
|
||||
|
||||
if (!this_value.is_object() || !this_value.as_object().is_array_iterator_object()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NotAn, "Array Iterator");
|
||||
return {};
|
||||
}
|
||||
auto& this_object = this_value.as_object();
|
||||
|
||||
auto& iterator = static_cast<ArrayIterator&>(this_object);
|
||||
auto target_array = iterator.array();
|
||||
if (target_array.is_undefined())
|
||||
|
|
|
@ -204,8 +204,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::push)
|
|||
return {};
|
||||
auto argument_count = interpreter.argument_count();
|
||||
auto new_length = length + argument_count;
|
||||
if (new_length > MAX_ARRAY_LIKE_INDEX)
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::ArrayMaxSize);
|
||||
if (new_length > MAX_ARRAY_LIKE_INDEX) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::ArrayMaxSize);
|
||||
return {};
|
||||
}
|
||||
for (size_t i = 0; i < argument_count; ++i) {
|
||||
this_object->put(length + i, interpreter.argument(i));
|
||||
if (interpreter.exception())
|
||||
|
@ -744,8 +746,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::splice)
|
|||
|
||||
size_t new_length = initial_length + insert_count - actual_delete_count;
|
||||
|
||||
if (new_length > MAX_ARRAY_LIKE_INDEX)
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::ArrayMaxSize);
|
||||
if (new_length > MAX_ARRAY_LIKE_INDEX) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::ArrayMaxSize);
|
||||
return {};
|
||||
}
|
||||
|
||||
auto removed_elements = Array::create(global_object);
|
||||
|
||||
|
|
|
@ -58,8 +58,10 @@ JS_DEFINE_NATIVE_GETTER(ErrorPrototype::name_getter)
|
|||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (!this_object->is_error())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NotAn, "Error");
|
||||
if (!this_object->is_error()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NotAn, "Error");
|
||||
return {};
|
||||
}
|
||||
return js_string(interpreter, static_cast<const Error*>(this_object)->name());
|
||||
}
|
||||
|
||||
|
@ -83,15 +85,19 @@ JS_DEFINE_NATIVE_GETTER(ErrorPrototype::message_getter)
|
|||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (!this_object->is_error())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NotAn, "Error");
|
||||
if (!this_object->is_error()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NotAn, "Error");
|
||||
return {};
|
||||
}
|
||||
return js_string(interpreter, static_cast<const Error*>(this_object)->message());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ErrorPrototype::to_string)
|
||||
{
|
||||
if (!interpreter.this_value(global_object).is_object())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NotAnObject, interpreter.this_value(global_object).to_string_without_side_effects().characters());
|
||||
if (!interpreter.this_value(global_object).is_object()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NotAnObject, interpreter.this_value(global_object).to_string_without_side_effects().characters());
|
||||
return {};
|
||||
}
|
||||
auto& this_object = interpreter.this_value(global_object).as_object();
|
||||
|
||||
String name = "Error";
|
||||
|
@ -126,7 +132,7 @@ JS_DEFINE_NATIVE_FUNCTION(ErrorPrototype::to_string)
|
|||
: Object(*global_object.error_prototype()) \
|
||||
{ \
|
||||
} \
|
||||
PrototypeName::~PrototypeName() { }
|
||||
PrototypeName::~PrototypeName() {}
|
||||
|
||||
JS_ENUMERATE_ERROR_SUBCLASSES
|
||||
#undef __JS_ENUMERATE
|
||||
|
|
|
@ -65,15 +65,19 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::apply)
|
|||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (!this_object->is_function())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NotA, "Function");
|
||||
if (!this_object->is_function()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NotA, "Function");
|
||||
return {};
|
||||
}
|
||||
auto& function = static_cast<Function&>(*this_object);
|
||||
auto this_arg = interpreter.argument(0);
|
||||
auto arg_array = interpreter.argument(1);
|
||||
if (arg_array.is_null() || arg_array.is_undefined())
|
||||
return interpreter.call(function, this_arg);
|
||||
if (!arg_array.is_object())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::FunctionArgsNotObject);
|
||||
if (!arg_array.is_object()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::FunctionArgsNotObject);
|
||||
return {};
|
||||
}
|
||||
auto length_property = arg_array.as_object().get("length");
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
|
@ -95,9 +99,10 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::bind)
|
|||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (!this_object->is_function())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NotA, "Function");
|
||||
|
||||
if (!this_object->is_function()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NotA, "Function");
|
||||
return {};
|
||||
}
|
||||
auto& this_function = static_cast<Function&>(*this_object);
|
||||
auto bound_this_arg = interpreter.argument(0);
|
||||
|
||||
|
@ -115,8 +120,10 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::call)
|
|||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (!this_object->is_function())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NotA, "Function");
|
||||
if (!this_object->is_function()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NotA, "Function");
|
||||
return {};
|
||||
}
|
||||
auto& function = static_cast<Function&>(*this_object);
|
||||
auto this_arg = interpreter.argument(0);
|
||||
MarkedValueList arguments(interpreter.heap());
|
||||
|
@ -132,9 +139,10 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::to_string)
|
|||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (!this_object->is_function())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NotA, "Function");
|
||||
|
||||
if (!this_object->is_function()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NotA, "Function");
|
||||
return {};
|
||||
}
|
||||
String function_name = static_cast<Function*>(this_object)->name();
|
||||
String function_parameters = "";
|
||||
String function_body;
|
||||
|
@ -173,9 +181,10 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::symbol_has_instance)
|
|||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (!this_object->is_function())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NotA, "Function");
|
||||
|
||||
if (!this_object->is_function()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NotA, "Function");
|
||||
return {};
|
||||
}
|
||||
return ordinary_has_instance(interpreter, interpreter.argument(0), this_object);
|
||||
}
|
||||
|
||||
|
|
|
@ -112,9 +112,10 @@ bool LexicalEnvironment::has_this_binding() const
|
|||
Value LexicalEnvironment::get_this_binding() const
|
||||
{
|
||||
ASSERT(has_this_binding());
|
||||
if (this_binding_status() == ThisBindingStatus::Uninitialized)
|
||||
return interpreter().throw_exception<ReferenceError>(ErrorType::ThisHasNotBeenInitialized);
|
||||
|
||||
if (this_binding_status() == ThisBindingStatus::Uninitialized) {
|
||||
interpreter().throw_exception<ReferenceError>(ErrorType::ThisHasNotBeenInitialized);
|
||||
return {};
|
||||
}
|
||||
return m_this_value;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,7 +67,8 @@ JS_DEFINE_NATIVE_FUNCTION(NumberPrototype::to_string)
|
|||
} else if (this_value.is_object() && this_value.as_object().is_number_object()) {
|
||||
number_value = static_cast<NumberObject&>(this_value.as_object()).value_of();
|
||||
} else {
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NumberIncompatibleThis, "toString");
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NumberIncompatibleThis, "toString");
|
||||
return {};
|
||||
}
|
||||
|
||||
int radix;
|
||||
|
@ -78,8 +79,10 @@ JS_DEFINE_NATIVE_FUNCTION(NumberPrototype::to_string)
|
|||
radix = argument.to_i32(interpreter);
|
||||
}
|
||||
|
||||
if (interpreter.exception() || radix < 2 || radix > 36)
|
||||
return interpreter.throw_exception<RangeError>(ErrorType::InvalidRadix);
|
||||
if (interpreter.exception() || radix < 2 || radix > 36) {
|
||||
interpreter.throw_exception<RangeError>(ErrorType::InvalidRadix);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (number_value.is_positive_infinity())
|
||||
return js_string(interpreter, "Infinity");
|
||||
|
|
|
@ -105,8 +105,10 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_prototype_of)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::set_prototype_of)
|
||||
{
|
||||
if (interpreter.argument_count() < 2)
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::ObjectSetPrototypeOfTwoArgs);
|
||||
if (interpreter.argument_count() < 2) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::ObjectSetPrototypeOfTwoArgs);
|
||||
return {};
|
||||
}
|
||||
auto* object = interpreter.argument(0).to_object(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
|
@ -162,10 +164,14 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptor)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::define_property_)
|
||||
{
|
||||
if (!interpreter.argument(0).is_object())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NotAnObject, "Object argument");
|
||||
if (!interpreter.argument(2).is_object())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NotAnObject, "Descriptor argument");
|
||||
if (!interpreter.argument(0).is_object()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NotAnObject, "Object argument");
|
||||
return {};
|
||||
}
|
||||
if (!interpreter.argument(2).is_object()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NotAnObject, "Descriptor argument");
|
||||
return {};
|
||||
}
|
||||
auto& object = interpreter.argument(0).as_object();
|
||||
auto property_key = StringOrSymbol::from_value(interpreter, interpreter.argument(1));
|
||||
if (interpreter.exception())
|
||||
|
@ -191,8 +197,10 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::is)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::keys)
|
||||
{
|
||||
if (!interpreter.argument_count())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::ConvertUndefinedToObject);
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::ConvertUndefinedToObject);
|
||||
return {};
|
||||
}
|
||||
|
||||
auto* obj_arg = interpreter.argument(0).to_object(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
|
@ -203,9 +211,10 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::keys)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::values)
|
||||
{
|
||||
if (!interpreter.argument_count())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::ConvertUndefinedToObject);
|
||||
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::ConvertUndefinedToObject);
|
||||
return {};
|
||||
}
|
||||
auto* obj_arg = interpreter.argument(0).to_object(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
|
@ -215,9 +224,10 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::values)
|
|||
|
||||
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::entries)
|
||||
{
|
||||
if (!interpreter.argument_count())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::ConvertUndefinedToObject);
|
||||
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::ConvertUndefinedToObject);
|
||||
return {};
|
||||
}
|
||||
auto* obj_arg = interpreter.argument(0).to_object(interpreter, global_object);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
|
|
|
@ -51,22 +51,28 @@ ProxyConstructor::~ProxyConstructor()
|
|||
|
||||
Value ProxyConstructor::call(Interpreter& interpreter)
|
||||
{
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::ProxyCallWithNew);
|
||||
interpreter.throw_exception<TypeError>(ErrorType::ProxyCallWithNew);
|
||||
return {};
|
||||
}
|
||||
|
||||
Value ProxyConstructor::construct(Interpreter& interpreter, Function&)
|
||||
{
|
||||
if (interpreter.argument_count() < 2)
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::ProxyTwoArguments);
|
||||
if (interpreter.argument_count() < 2) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::ProxyTwoArguments);
|
||||
return {};
|
||||
}
|
||||
|
||||
auto target = interpreter.argument(0);
|
||||
auto handler = interpreter.argument(1);
|
||||
|
||||
if (!target.is_object())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::ProxyConstructorBadType, "target", target.to_string_without_side_effects().characters());
|
||||
if (!handler.is_object())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::ProxyConstructorBadType, "handler", handler.to_string_without_side_effects().characters());
|
||||
|
||||
if (!target.is_object()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::ProxyConstructorBadType, "target", target.to_string_without_side_effects().characters());
|
||||
return {};
|
||||
}
|
||||
if (!handler.is_object()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::ProxyConstructorBadType, "handler", handler.to_string_without_side_effects().characters());
|
||||
return {};
|
||||
}
|
||||
return ProxyObject::create(global_object(), target.as_object(), handler.as_object());
|
||||
}
|
||||
|
||||
|
|
|
@ -375,8 +375,10 @@ Value ProxyObject::get(const PropertyName& name, Value) const
|
|||
return {};
|
||||
if (trap.is_empty() || trap.is_undefined() || trap.is_null())
|
||||
return m_target.get(name);
|
||||
if (!trap.is_function())
|
||||
return interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "get");
|
||||
if (!trap.is_function()) {
|
||||
interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "get");
|
||||
return {};
|
||||
}
|
||||
MarkedValueList arguments(interpreter().heap());
|
||||
arguments.append(Value(&m_target));
|
||||
arguments.append(js_string(interpreter(), name.to_string()));
|
||||
|
@ -388,10 +390,14 @@ Value ProxyObject::get(const PropertyName& name, Value) const
|
|||
if (target_desc.has_value()) {
|
||||
if (interpreter().exception())
|
||||
return {};
|
||||
if (target_desc.value().is_data_descriptor() && !target_desc.value().attributes.is_writable() && !same_value(interpreter(), trap_result, target_desc.value().value))
|
||||
return interpreter().throw_exception<TypeError>(ErrorType::ProxyGetImmutableDataProperty);
|
||||
if (target_desc.value().is_accessor_descriptor() && target_desc.value().getter == nullptr && !trap_result.is_undefined())
|
||||
return interpreter().throw_exception<TypeError>(ErrorType::ProxyGetNonConfigurableAccessor);
|
||||
if (target_desc.value().is_data_descriptor() && !target_desc.value().attributes.is_writable() && !same_value(interpreter(), trap_result, target_desc.value().value)) {
|
||||
interpreter().throw_exception<TypeError>(ErrorType::ProxyGetImmutableDataProperty);
|
||||
return {};
|
||||
}
|
||||
if (target_desc.value().is_accessor_descriptor() && target_desc.value().getter == nullptr && !trap_result.is_undefined()) {
|
||||
interpreter().throw_exception<TypeError>(ErrorType::ProxyGetNonConfigurableAccessor);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
return trap_result;
|
||||
}
|
||||
|
@ -445,8 +451,10 @@ Value ProxyObject::delete_property(const PropertyName& name)
|
|||
return {};
|
||||
if (trap.is_empty() || trap.is_undefined() || trap.is_null())
|
||||
return m_target.delete_property(name);
|
||||
if (!trap.is_function())
|
||||
return interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "deleteProperty");
|
||||
if (!trap.is_function()) {
|
||||
interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "deleteProperty");
|
||||
return {};
|
||||
}
|
||||
MarkedValueList arguments(interpreter().heap());
|
||||
arguments.append(Value(&m_target));
|
||||
arguments.append(js_string(interpreter(), name.to_string()));
|
||||
|
@ -460,8 +468,10 @@ Value ProxyObject::delete_property(const PropertyName& name)
|
|||
return {};
|
||||
if (!target_desc.has_value())
|
||||
return Value(true);
|
||||
if (!target_desc.value().attributes.is_configurable())
|
||||
return interpreter().throw_exception<TypeError>(ErrorType::ProxyDeleteNonConfigurable);
|
||||
if (!target_desc.value().attributes.is_configurable()) {
|
||||
interpreter().throw_exception<TypeError>(ErrorType::ProxyDeleteNonConfigurable);
|
||||
return {};
|
||||
}
|
||||
return Value(true);
|
||||
}
|
||||
|
||||
|
@ -472,10 +482,12 @@ void ProxyObject::visit_children(Cell::Visitor& visitor)
|
|||
visitor.visit(&m_handler);
|
||||
}
|
||||
|
||||
Value ProxyObject::call(Interpreter& interpreter) {
|
||||
if (!is_function())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NotAFunction, Value(this).to_string_without_side_effects().characters());
|
||||
|
||||
Value ProxyObject::call(Interpreter& interpreter)
|
||||
{
|
||||
if (!is_function()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NotAFunction, Value(this).to_string_without_side_effects().characters());
|
||||
return {};
|
||||
}
|
||||
if (m_is_revoked) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::ProxyRevoked);
|
||||
return {};
|
||||
|
@ -485,9 +497,10 @@ Value ProxyObject::call(Interpreter& interpreter) {
|
|||
return {};
|
||||
if (trap.is_empty() || trap.is_undefined() || trap.is_null())
|
||||
return static_cast<Function&>(m_target).call(interpreter);
|
||||
if (!trap.is_function())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "apply");
|
||||
|
||||
if (!trap.is_function()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "apply");
|
||||
return {};
|
||||
}
|
||||
MarkedValueList arguments(interpreter.heap());
|
||||
arguments.append(Value(&m_target));
|
||||
arguments.append(Value(&m_handler));
|
||||
|
@ -501,10 +514,12 @@ Value ProxyObject::call(Interpreter& interpreter) {
|
|||
return interpreter.call(trap.as_function(), Value(&m_handler), move(arguments));
|
||||
}
|
||||
|
||||
Value ProxyObject::construct(Interpreter& interpreter, Function& new_target) {
|
||||
if (!is_function())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NotAConstructor, Value(this).to_string_without_side_effects().characters());
|
||||
|
||||
Value ProxyObject::construct(Interpreter& interpreter, Function& new_target)
|
||||
{
|
||||
if (!is_function()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NotAConstructor, Value(this).to_string_without_side_effects().characters());
|
||||
return {};
|
||||
}
|
||||
if (m_is_revoked) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::ProxyRevoked);
|
||||
return {};
|
||||
|
@ -514,8 +529,10 @@ Value ProxyObject::construct(Interpreter& interpreter, Function& new_target) {
|
|||
return {};
|
||||
if (trap.is_empty() || trap.is_undefined() || trap.is_null())
|
||||
return static_cast<Function&>(m_target).construct(interpreter, new_target);
|
||||
if (!trap.is_function())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "construct");
|
||||
if (!trap.is_function()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "construct");
|
||||
return {};
|
||||
}
|
||||
|
||||
MarkedValueList arguments(interpreter.heap());
|
||||
arguments.append(Value(&m_target));
|
||||
|
@ -526,8 +543,10 @@ Value ProxyObject::construct(Interpreter& interpreter, Function& new_target) {
|
|||
arguments.append(arguments_array);
|
||||
arguments.append(Value(&new_target));
|
||||
auto result = interpreter.call(trap.as_function(), Value(&m_handler), move(arguments));
|
||||
if (!result.is_object())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::ProxyConstructBadReturnType);
|
||||
if (!result.is_object()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::ProxyConstructBadReturnType);
|
||||
return {};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -143,8 +143,10 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::define_property)
|
|||
auto* target = get_target_object_from(interpreter, "defineProperty");
|
||||
if (!target)
|
||||
return {};
|
||||
if (!interpreter.argument(2).is_object())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::ReflectBadDescriptorArgument);
|
||||
if (!interpreter.argument(2).is_object()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::ReflectBadDescriptorArgument);
|
||||
return {};
|
||||
}
|
||||
auto property_key = StringOrSymbol::from_value(interpreter, interpreter.argument(1));
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
|
|
|
@ -135,8 +135,10 @@ Value ScriptFunction::call(Interpreter& interpreter)
|
|||
|
||||
Value ScriptFunction::construct(Interpreter& interpreter, Function&)
|
||||
{
|
||||
if (m_is_arrow_function)
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NotAConstructor, m_name.characters());
|
||||
if (m_is_arrow_function) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NotAConstructor, m_name.characters());
|
||||
return {};
|
||||
}
|
||||
return call(interpreter);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,8 +53,10 @@ StringIteratorPrototype::~StringIteratorPrototype()
|
|||
JS_DEFINE_NATIVE_FUNCTION(StringIteratorPrototype::next)
|
||||
{
|
||||
auto this_value = interpreter.this_value(global_object);
|
||||
if (!this_value.is_object() || !this_value.as_object().is_string_iterator_object())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NotA, "String Iterator");
|
||||
if (!this_value.is_object() || !this_value.as_object().is_string_iterator_object()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NotA, "String Iterator");
|
||||
return {};
|
||||
}
|
||||
|
||||
auto& this_object = this_value.as_object();
|
||||
auto& iterator = static_cast<StringIterator&>(this_object);
|
||||
|
|
|
@ -140,10 +140,14 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::repeat)
|
|||
auto count_value = interpreter.argument(0).to_number(interpreter);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
if (count_value.as_double() < 0)
|
||||
return interpreter.throw_exception<RangeError>(ErrorType::StringRepeatCountMustBe, "positive");
|
||||
if (count_value.is_infinity())
|
||||
return interpreter.throw_exception<RangeError>(ErrorType::StringRepeatCountMustBe, "finite");
|
||||
if (count_value.as_double() < 0) {
|
||||
interpreter.throw_exception<RangeError>(ErrorType::StringRepeatCountMustBe, "positive");
|
||||
return {};
|
||||
}
|
||||
if (count_value.is_infinity()) {
|
||||
interpreter.throw_exception<RangeError>(ErrorType::StringRepeatCountMustBe, "finite");
|
||||
return {};
|
||||
}
|
||||
auto count = count_value.to_size_t(interpreter);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
|
@ -455,8 +459,10 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::last_index_of)
|
|||
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::symbol_iterator)
|
||||
{
|
||||
auto this_object = interpreter.this_value(global_object);
|
||||
if (this_object.is_undefined() || this_object.is_null())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::ToObjectNullOrUndef);
|
||||
if (this_object.is_undefined() || this_object.is_null()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::ToObjectNullOrUndef);
|
||||
return {};
|
||||
}
|
||||
|
||||
auto string = this_object.to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
|
|
|
@ -58,8 +58,10 @@ JS_DEFINE_NATIVE_GETTER(Uint8ClampedArray::length_getter)
|
|||
auto* this_object = interpreter.this_value(global_object).to_object(interpreter, global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (StringView(this_object->class_name()) != "Uint8ClampedArray")
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NotA, "Uint8ClampedArray");
|
||||
if (StringView(this_object->class_name()) != "Uint8ClampedArray") {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NotA, "Uint8ClampedArray");
|
||||
return {};
|
||||
}
|
||||
return Value(static_cast<const Uint8ClampedArray*>(this_object)->length());
|
||||
}
|
||||
|
||||
|
|
|
@ -686,8 +686,10 @@ Value exp(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
|
||||
Value in(Interpreter& interpreter, Value lhs, Value rhs)
|
||||
{
|
||||
if (!rhs.is_object())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::InOperatorWithObject);
|
||||
if (!rhs.is_object()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::InOperatorWithObject);
|
||||
return {};
|
||||
}
|
||||
auto lhs_string = lhs.to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
|
@ -696,22 +698,25 @@ Value in(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
|
||||
Value instance_of(Interpreter& interpreter, Value lhs, Value rhs)
|
||||
{
|
||||
if (!rhs.is_object())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NotAnObject, rhs.to_string_without_side_effects().characters());
|
||||
|
||||
if (!rhs.is_object()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NotAnObject, rhs.to_string_without_side_effects().characters());
|
||||
return {};
|
||||
}
|
||||
auto has_instance_method = rhs.as_object().get(interpreter.well_known_symbol_has_instance());
|
||||
if (!has_instance_method.is_empty()) {
|
||||
if (!has_instance_method.is_function())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NotAFunction, has_instance_method.to_string_without_side_effects().characters());
|
||||
|
||||
if (!has_instance_method.is_function()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NotAFunction, has_instance_method.to_string_without_side_effects().characters());
|
||||
return {};
|
||||
}
|
||||
MarkedValueList arguments(interpreter.heap());
|
||||
arguments.append(lhs);
|
||||
return Value(interpreter.call(has_instance_method.as_function(), rhs, move(arguments)).to_boolean());
|
||||
}
|
||||
|
||||
if (!rhs.is_function())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::NotAFunction, rhs.to_string_without_side_effects().characters());
|
||||
|
||||
if (!rhs.is_function()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::NotAFunction, rhs.to_string_without_side_effects().characters());
|
||||
return {};
|
||||
}
|
||||
return ordinary_has_instance(interpreter, lhs, rhs);
|
||||
}
|
||||
|
||||
|
@ -734,9 +739,10 @@ Value ordinary_has_instance(Interpreter& interpreter, Value lhs, Value rhs)
|
|||
if (interpreter.exception())
|
||||
return {};
|
||||
|
||||
if (!rhs_prototype.is_object())
|
||||
return interpreter.throw_exception<TypeError>(ErrorType::InstanceOfOperatorBadPrototype, rhs_prototype.to_string_without_side_effects().characters());
|
||||
|
||||
if (!rhs_prototype.is_object()) {
|
||||
interpreter.throw_exception<TypeError>(ErrorType::InstanceOfOperatorBadPrototype, rhs_prototype.to_string_without_side_effects().characters());
|
||||
return {};
|
||||
}
|
||||
while (true) {
|
||||
lhs_object = lhs_object->prototype();
|
||||
if (interpreter.exception())
|
||||
|
|
|
@ -139,14 +139,17 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::set_interval)
|
|||
auto* impl = impl_from(interpreter, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
if (!interpreter.argument_count())
|
||||
return interpreter.throw_exception<JS::TypeError>(JS::ErrorType::BadArgCountAtLeastOne, "setInterval");
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.throw_exception<JS::TypeError>(JS::ErrorType::BadArgCountAtLeastOne, "setInterval");
|
||||
return {};
|
||||
}
|
||||
auto* callback_object = interpreter.argument(0).to_object(interpreter, global_object);
|
||||
if (!callback_object)
|
||||
return {};
|
||||
if (!callback_object->is_function())
|
||||
return interpreter.throw_exception<JS::TypeError>(JS::ErrorType::NotAFunctionNoParam);
|
||||
|
||||
if (!callback_object->is_function()) {
|
||||
interpreter.throw_exception<JS::TypeError>(JS::ErrorType::NotAFunctionNoParam);
|
||||
return {};
|
||||
}
|
||||
i32 interval = 0;
|
||||
if (interpreter.argument_count() >= 2) {
|
||||
interval = interpreter.argument(1).to_i32(interpreter);
|
||||
|
@ -165,14 +168,17 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::set_timeout)
|
|||
auto* impl = impl_from(interpreter, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
if (!interpreter.argument_count())
|
||||
return interpreter.throw_exception<JS::TypeError>(JS::ErrorType::BadArgCountAtLeastOne, "setTimeout");
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.throw_exception<JS::TypeError>(JS::ErrorType::BadArgCountAtLeastOne, "setTimeout");
|
||||
return {};
|
||||
}
|
||||
auto* callback_object = interpreter.argument(0).to_object(interpreter, global_object);
|
||||
if (!callback_object)
|
||||
return {};
|
||||
if (!callback_object->is_function())
|
||||
return interpreter.throw_exception<JS::TypeError>(JS::ErrorType::NotAFunctionNoParam);
|
||||
|
||||
if (!callback_object->is_function()) {
|
||||
interpreter.throw_exception<JS::TypeError>(JS::ErrorType::NotAFunctionNoParam);
|
||||
return {};
|
||||
}
|
||||
i32 interval = 0;
|
||||
if (interpreter.argument_count() >= 2) {
|
||||
interval = interpreter.argument(1).to_i32(interpreter);
|
||||
|
@ -191,8 +197,10 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::clear_timeout)
|
|||
auto* impl = impl_from(interpreter, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
if (!interpreter.argument_count())
|
||||
return interpreter.throw_exception<JS::TypeError>(JS::ErrorType::BadArgCountAtLeastOne, "clearTimeout");
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.throw_exception<JS::TypeError>(JS::ErrorType::BadArgCountAtLeastOne, "clearTimeout");
|
||||
return {};
|
||||
}
|
||||
i32 timer_id = interpreter.argument(0).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
|
@ -205,8 +213,10 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::clear_interval)
|
|||
auto* impl = impl_from(interpreter, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
if (!interpreter.argument_count())
|
||||
return interpreter.throw_exception<JS::TypeError>(JS::ErrorType::BadArgCountAtLeastOne, "clearInterval");
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.throw_exception<JS::TypeError>(JS::ErrorType::BadArgCountAtLeastOne, "clearInterval");
|
||||
return {};
|
||||
}
|
||||
i32 timer_id = interpreter.argument(0).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
|
@ -219,13 +229,17 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::request_animation_frame)
|
|||
auto* impl = impl_from(interpreter, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
if (!interpreter.argument_count())
|
||||
return interpreter.throw_exception<JS::TypeError>(JS::ErrorType::BadArgCountOne, "requestAnimationFrame");
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.throw_exception<JS::TypeError>(JS::ErrorType::BadArgCountOne, "requestAnimationFrame");
|
||||
return {};
|
||||
}
|
||||
auto* callback_object = interpreter.argument(0).to_object(interpreter, global_object);
|
||||
if (!callback_object)
|
||||
return {};
|
||||
if (!callback_object->is_function())
|
||||
return interpreter.throw_exception<JS::TypeError>(JS::ErrorType::NotAFunctionNoParam);
|
||||
if (!callback_object->is_function()) {
|
||||
interpreter.throw_exception<JS::TypeError>(JS::ErrorType::NotAFunctionNoParam);
|
||||
return {};
|
||||
}
|
||||
return JS::Value(impl->request_animation_frame(*static_cast<JS::Function*>(callback_object)));
|
||||
}
|
||||
|
||||
|
@ -234,8 +248,10 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::cancel_animation_frame)
|
|||
auto* impl = impl_from(interpreter, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
if (!interpreter.argument_count())
|
||||
return interpreter.throw_exception<JS::TypeError>(JS::ErrorType::BadArgCountOne, "cancelAnimationFrame");
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.throw_exception<JS::TypeError>(JS::ErrorType::BadArgCountOne, "cancelAnimationFrame");
|
||||
return {};
|
||||
}
|
||||
auto id = interpreter.argument(0).to_i32(interpreter);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
|
@ -248,8 +264,10 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::atob)
|
|||
auto* impl = impl_from(interpreter, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
if (!interpreter.argument_count())
|
||||
return interpreter.throw_exception<JS::TypeError>(JS::ErrorType::BadArgCountOne, "atob");
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.throw_exception<JS::TypeError>(JS::ErrorType::BadArgCountOne, "atob");
|
||||
return {};
|
||||
}
|
||||
auto string = interpreter.argument(0).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
|
@ -264,8 +282,10 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::btoa)
|
|||
auto* impl = impl_from(interpreter, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
if (!interpreter.argument_count())
|
||||
return interpreter.throw_exception<JS::TypeError>(JS::ErrorType::BadArgCountOne, "btoa");
|
||||
if (!interpreter.argument_count()) {
|
||||
interpreter.throw_exception<JS::TypeError>(JS::ErrorType::BadArgCountOne, "btoa");
|
||||
return {};
|
||||
}
|
||||
auto string = interpreter.argument(0).to_string(interpreter);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
|
@ -273,8 +293,10 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::btoa)
|
|||
Vector<u8> byte_string;
|
||||
byte_string.ensure_capacity(string.length());
|
||||
for (u32 code_point : Utf8View(string)) {
|
||||
if (code_point > 0xff)
|
||||
return interpreter.throw_exception<JS::InvalidCharacterError>(JS::ErrorType::NotAByteString, "btoa");
|
||||
if (code_point > 0xff) {
|
||||
interpreter.throw_exception<JS::InvalidCharacterError>(JS::ErrorType::NotAByteString, "btoa");
|
||||
return {};
|
||||
}
|
||||
byte_string.append(code_point);
|
||||
}
|
||||
|
||||
|
|
|
@ -645,12 +645,13 @@ void generate_implementation(const IDL::Interface& interface)
|
|||
out() << " if (!impl)";
|
||||
out() << " return {};";
|
||||
if (function.length() > 0) {
|
||||
out() << " if (interpreter.argument_count() < " << function.length() << ")";
|
||||
|
||||
out() << " if (interpreter.argument_count() < " << function.length() << ") {";
|
||||
if (function.length() == 1)
|
||||
out() << " return interpreter.throw_exception<JS::TypeError>(JS::ErrorType::BadArgCountOne, \"" << function.name << "\");";
|
||||
out() << " interpreter.throw_exception<JS::TypeError>(JS::ErrorType::BadArgCountOne, \"" << function.name << "\");";
|
||||
else
|
||||
out() << " return interpreter.throw_exception<JS::TypeError>(JS::ErrorType::BadArgCountMany, \"" << function.name << "\", \"" << function.length() << "\");";
|
||||
out() << " interpreter.throw_exception<JS::TypeError>(JS::ErrorType::BadArgCountMany, \"" << function.name << "\", \"" << function.length() << "\");";
|
||||
out() << " return {};";
|
||||
out() << " }";
|
||||
}
|
||||
|
||||
StringBuilder arguments_builder;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue