mirror of
https://github.com/RGBCube/serenity
synced 2025-05-22 19:45:08 +00:00
LibJS: Add Value::{is, as}_function()
This commit is contained in:
parent
419bce6915
commit
eea62dd365
6 changed files with 26 additions and 15 deletions
|
@ -114,8 +114,7 @@ Value CallExpression::execute(Interpreter& interpreter) const
|
|||
|
||||
ASSERT(!callee.is_empty());
|
||||
|
||||
if (!callee.is_object()
|
||||
|| !callee.as_object().is_function()
|
||||
if (!callee.is_function()
|
||||
|| (is_new_expression() && (callee.as_object().is_native_function() && !static_cast<NativeFunction&>(callee.as_object()).has_constructor()))) {
|
||||
String error_message;
|
||||
auto call_type = is_new_expression() ? "constructor" : "function";
|
||||
|
@ -132,7 +131,7 @@ Value CallExpression::execute(Interpreter& interpreter) const
|
|||
return interpreter.throw_exception<TypeError>(error_message);
|
||||
}
|
||||
|
||||
auto& function = static_cast<Function&>(callee.as_object());
|
||||
auto& function = callee.as_function();
|
||||
|
||||
MarkedValueList arguments(interpreter.heap());
|
||||
arguments.values().append(function.bound_arguments());
|
||||
|
@ -469,7 +468,7 @@ Value UnaryExpression::execute(Interpreter& interpreter) const
|
|||
case Value::Type::String:
|
||||
return js_string(interpreter, "string");
|
||||
case Value::Type::Object:
|
||||
if (lhs_result.as_object().is_function())
|
||||
if (lhs_result.is_function())
|
||||
return js_string(interpreter, "function");
|
||||
return js_string(interpreter, "object");
|
||||
case Value::Type::Boolean:
|
||||
|
|
|
@ -76,11 +76,11 @@ static Function* callback_from_args(Interpreter& interpreter, const String& name
|
|||
return nullptr;
|
||||
}
|
||||
auto callback = interpreter.argument(0);
|
||||
if (!callback.is_object() || !callback.as_object().is_function()) {
|
||||
if (!callback.is_function()) {
|
||||
interpreter.throw_exception<TypeError>(String::format("%s is not a function", callback.to_string().characters()));
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<Function*>(&callback.as_object());
|
||||
return &callback.as_function();
|
||||
}
|
||||
|
||||
Value ArrayPrototype::filter(Interpreter& interpreter)
|
||||
|
|
|
@ -477,10 +477,8 @@ Value Object::to_primitive(PreferredType preferred_type) const
|
|||
Value Object::to_string() const
|
||||
{
|
||||
auto to_string_property = get("toString");
|
||||
if (!to_string_property.is_empty()
|
||||
&& to_string_property.is_object()
|
||||
&& to_string_property.as_object().is_function()) {
|
||||
auto& to_string_function = static_cast<Function&>(to_string_property.as_object());
|
||||
if (!to_string_property.is_empty() && to_string_property.is_function()) {
|
||||
auto& to_string_function = to_string_property.as_function();
|
||||
auto& interpreter = const_cast<Object*>(this)->interpreter();
|
||||
auto to_string_result = interpreter.call(to_string_function, const_cast<Object*>(this));
|
||||
if (to_string_result.is_object())
|
||||
|
|
|
@ -47,11 +47,11 @@ static Object* get_target_object_from(Interpreter& interpreter, const String& na
|
|||
static Function* get_target_function_from(Interpreter& interpreter, const String& name)
|
||||
{
|
||||
auto target = interpreter.argument(0);
|
||||
if (!target.is_object() || !target.as_object().is_function()) {
|
||||
if (!target.is_function()) {
|
||||
interpreter.throw_exception<TypeError>(String::format("First argument of Reflect.%s() must be a function", name.characters()));
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<Function*>(&target.as_object());
|
||||
return &target.as_function();
|
||||
}
|
||||
|
||||
static void prepare_arguments_list(Interpreter& interpreter, Value value, MarkedValueList* arguments)
|
||||
|
@ -121,13 +121,12 @@ Value ReflectObject::construct(Interpreter& interpreter)
|
|||
auto* new_target = target;
|
||||
if (interpreter.argument_count() > 2) {
|
||||
auto new_target_value = interpreter.argument(2);
|
||||
if (!new_target_value.is_object()
|
||||
|| !new_target_value.as_object().is_function()
|
||||
if (!new_target_value.is_function()
|
||||
|| (new_target_value.as_object().is_native_function() && !static_cast<NativeFunction&>(new_target_value.as_object()).has_constructor())) {
|
||||
interpreter.throw_exception<TypeError>("Optional third argument of Reflect.construct() must be a constructor");
|
||||
return {};
|
||||
}
|
||||
new_target = static_cast<Function*>(&new_target_value.as_object());
|
||||
new_target = &new_target_value.as_function();
|
||||
}
|
||||
return interpreter.construct(*target, *new_target, move(arguments));
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <LibJS/Runtime/Array.h>
|
||||
#include <LibJS/Runtime/BooleanObject.h>
|
||||
#include <LibJS/Runtime/Error.h>
|
||||
#include <LibJS/Runtime/Function.h>
|
||||
#include <LibJS/Runtime/NumberObject.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
#include <LibJS/Runtime/PrimitiveString.h>
|
||||
|
@ -48,6 +49,17 @@ bool Value::is_array() const
|
|||
return is_object() && as_object().is_array();
|
||||
}
|
||||
|
||||
bool Value::is_function() const
|
||||
{
|
||||
return is_object() && as_object().is_function();
|
||||
}
|
||||
|
||||
Function& Value::as_function()
|
||||
{
|
||||
ASSERT(is_function());
|
||||
return static_cast<Function&>(as_object());
|
||||
}
|
||||
|
||||
String Value::to_string() const
|
||||
{
|
||||
if (is_boolean())
|
||||
|
|
|
@ -54,6 +54,7 @@ public:
|
|||
bool is_boolean() const { return m_type == Type::Boolean; }
|
||||
bool is_cell() const { return is_string() || is_object(); }
|
||||
bool is_array() const;
|
||||
bool is_function() const;
|
||||
|
||||
bool is_nan() const { return is_number() && __builtin_isnan(as_double()); }
|
||||
bool is_infinity() const { return is_number() && __builtin_isinf(as_double()); }
|
||||
|
@ -157,6 +158,8 @@ public:
|
|||
return m_value.as_cell;
|
||||
}
|
||||
|
||||
Function& as_function();
|
||||
|
||||
String to_string() const;
|
||||
bool to_boolean() const;
|
||||
Value to_number() const;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue