LibJS: Remove Object::value_of()

Being really close to Object.prototype.valueOf() name wise makes this
unnecessarily confusing - while it sometimes serves as the
implementation of a valueOf() function, it's an abstraction which the
spec doesn't have.
Use the appropriate getters to retrieve specific internal slots instead,
most commonly [[FooData]] from the primitive wrapper objects.
For the Object class specifically, use the Value(Object*) ctor instead.
This commit is contained in:
Linus Groh 2021-12-10 22:50:02 +00:00
parent 07c5419a82
commit 038d354b5d
Notes: sideshowbarker 2024-07-17 22:59:47 +09:00
14 changed files with 20 additions and 38 deletions

View file

@ -364,7 +364,7 @@ Value SuperCall::execute(Interpreter& interpreter, GlobalObject& global_object)
return {};
// 5. If IsConstructor(func) is false, throw a TypeError exception.
if (!func || !func->value_of().is_constructor()) {
if (!func || !Value(func).is_constructor()) {
vm.throw_exception<TypeError>(global_object, ErrorType::NotAConstructor, "Super constructor");
return {};
}

View file

@ -23,11 +23,6 @@ public:
BigInt const& bigint() const { return m_bigint; }
BigInt& bigint() { return m_bigint; }
virtual Value value_of() const override
{
return Value(&m_bigint);
}
private:
virtual void visit_edges(Visitor&) override;

View file

@ -18,10 +18,7 @@ public:
BooleanObject(bool, Object& prototype);
virtual ~BooleanObject() override;
virtual Value value_of() const override
{
return Value(m_value);
}
bool boolean() const { return m_value; }
private:
bool m_value { false };

View file

@ -39,7 +39,7 @@ JS_DEFINE_NATIVE_FUNCTION(BooleanPrototype::to_string)
if (!this_value.is_object() || !is<BooleanObject>(this_value.as_object()))
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Boolean");
bool bool_value = static_cast<const BooleanObject&>(this_value.as_object()).value_of().as_bool();
bool bool_value = static_cast<const BooleanObject&>(this_value.as_object()).boolean();
return js_string(vm, bool_value ? "true" : "false");
}
@ -52,6 +52,6 @@ JS_DEFINE_NATIVE_FUNCTION(BooleanPrototype::value_of)
if (!this_value.is_object() || !is<BooleanObject>(this_value.as_object()))
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Boolean");
return static_cast<const BooleanObject&>(this_value.as_object()).value_of();
return Value(static_cast<const BooleanObject&>(this_value.as_object()).boolean());
}
}

View file

@ -73,9 +73,13 @@ public:
String locale_string() const { return m_datetime.to_string(); }
String locale_time_string() const { return m_datetime.to_string("%H:%M:%S"); }
virtual Value value_of() const override
// https://tc39.es/ecma262/#sec-properties-of-date-instances
// [[DateValue]]
double date_value() const
{
return Value(static_cast<double>(m_datetime.timestamp() * 1000 + m_milliseconds));
return m_is_invalid
? NAN
: static_cast<double>(m_datetime.timestamp() * 1000 + m_milliseconds);
}
private:

View file

@ -689,7 +689,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_date_string)
// 1. Let x be ? thisTimeValue(this value).
auto* this_object = TRY(typed_this_object(global_object));
auto time = this_object->is_invalid() ? js_nan() : this_object->value_of();
auto time = Value(this_object->date_value());
// 2. If x is NaN, return "Invalid Date".
if (time.is_nan())
@ -714,7 +714,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_string)
// 1. Let x be ? thisTimeValue(this value).
auto* this_object = TRY(typed_this_object(global_object));
auto time = this_object->is_invalid() ? js_nan() : this_object->value_of();
auto time = Value(this_object->date_value());
// 2. If x is NaN, return "Invalid Date".
if (time.is_nan())
@ -739,7 +739,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_time_string)
// 1. Let x be ? thisTimeValue(this value).
auto* this_object = TRY(typed_this_object(global_object));
auto time = this_object->is_invalid() ? js_nan() : this_object->value_of();
auto time = Value(this_object->date_value());
// 2. If x is NaN, return "Invalid Date".
if (time.is_nan())
@ -798,7 +798,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_temporal_instant)
{
// 1. Let t be ? thisTimeValue(this value).
auto* this_object = TRY(typed_this_object(global_object));
auto t = this_object->value_of();
auto t = Value(this_object->date_value());
// 2. Let ns be ? NumberToBigInt(t) × 10^6.
auto* ns = TRY(number_to_bigint(global_object, t));

View file

@ -145,9 +145,9 @@ ThrowCompletionOr<String> JSONObject::serialize_json_property(GlobalObject& glob
else if (is<StringObject>(value_object))
value = TRY(value.to_primitive_string(global_object));
else if (is<BooleanObject>(value_object))
value = static_cast<BooleanObject&>(value_object).value_of();
value = Value(static_cast<BooleanObject&>(value_object).boolean());
else if (is<BigIntObject>(value_object))
value = static_cast<BigIntObject&>(value_object).value_of();
value = Value(&static_cast<BigIntObject&>(value_object).bigint());
}
if (value.is_null())

View file

@ -19,8 +19,6 @@ public:
NumberObject(double, Object& prototype);
virtual ~NumberObject() override;
virtual Value value_of() const override { return Value(m_value); }
double number() const { return m_value; }
private:

View file

@ -55,7 +55,7 @@ static ThrowCompletionOr<Value> this_number_value(GlobalObject& global_object, V
if (value.is_number())
return value;
if (value.is_object() && is<NumberObject>(value.as_object()))
return static_cast<NumberObject&>(value.as_object()).value_of();
return Value(static_cast<NumberObject&>(value.as_object()).number());
auto& vm = global_object.vm();
return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Number");
}

View file

@ -167,7 +167,6 @@ public:
virtual const char* class_name() const override { return "Object"; }
virtual void visit_edges(Cell::Visitor&) override;
virtual Value value_of() const { return Value(const_cast<Object*>(this)); }
Value get_direct(size_t index) const { return m_storage[index]; }

View file

@ -23,11 +23,6 @@ public:
PrimitiveString const& primitive_string() const { return m_string; }
PrimitiveString& primitive_string() { return m_string; }
virtual Value value_of() const override
{
return Value(&m_string);
}
private:
virtual ThrowCompletionOr<Optional<PropertyDescriptor>> internal_get_own_property(PropertyKey const&) const override;
virtual ThrowCompletionOr<bool> internal_define_own_property(PropertyKey const&, PropertyDescriptor const&) override;

View file

@ -26,11 +26,6 @@ public:
String description() const { return m_symbol.description(); }
bool is_global() const { return m_symbol.is_global(); }
virtual Value value_of() const override
{
return Value(&m_symbol);
}
private:
virtual void visit_edges(Visitor&) override;

View file

@ -166,9 +166,8 @@ static JS::ThrowCompletionOr<DOM::Window*> impl_from(JS::VM& vm, JS::GlobalObjec
// the global object we make an exception here.
// This allows calls like `setTimeout(f, 10)` to work.
auto this_value = vm.this_value(global_object);
if (this_value.is_nullish()) {
this_value = global_object.value_of();
}
if (this_value.is_nullish())
this_value = &global_object;
auto* this_object = MUST(this_value.to_object(global_object));

View file

@ -760,7 +760,7 @@ static void print_primitive_wrapper_object(FlyString const& name, JS::Object con
// BooleanObject, NumberObject, StringObject
print_type(name);
js_out(" ");
print_value(object.value_of(), seen_objects);
print_value(&object, seen_objects);
}
static void print_value(JS::Value value, HashTable<JS::Object*>& seen_objects)