summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Groh <mail@linusgroh.de>2022-08-28 17:09:31 +0100
committerLinus Groh <mail@linusgroh.de>2022-08-28 19:34:10 +0100
commite3804e6426e9a483df23382fe4d6876315b1f7ff (patch)
tree945c57588217da8d5cd68911d6f8fdc13cb192a8
parent3d5300a25eeaef1e328a973dc13645c1cf948db3 (diff)
downloadserenity-e3804e6426e9a483df23382fe4d6876315b1f7ff.zip
LibJS: Move construction of GlobalObject native functions to Intrinsics
This will later allow global objects not inheriting from the regular JS::GlobalObject to pull in these functions without having to implement them from scratch. The primary use case here is, again, a wrapper-less HTML::Window in LibWeb :^) Allocating these upfront now allows us to get rid of two hacks: - The GlobalObject assigning Intrinsics private members after finishing its initialization - The GlobalObject defining the parseInt and parseFloat properties of the NumberConstructor object, as they are supposed to be identical with the global functions of the same name
-rw-r--r--Userland/Libraries/LibJS/Runtime/GlobalObject.cpp27
-rw-r--r--Userland/Libraries/LibJS/Runtime/GlobalObject.h2
-rw-r--r--Userland/Libraries/LibJS/Runtime/Intrinsics.cpp13
-rw-r--r--Userland/Libraries/LibJS/Runtime/Intrinsics.h33
-rw-r--r--Userland/Libraries/LibJS/Runtime/NumberConstructor.cpp6
5 files changed, 56 insertions, 25 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp b/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp
index 5d147d37eb..b1880e19fe 100644
--- a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp
+++ b/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp
@@ -100,15 +100,15 @@ void GlobalObject::initialize(Realm& realm)
u8 attr = Attribute::Writable | Attribute::Configurable;
// 19.2 Function Properties of the Global Object, https://tc39.es/ecma262/#sec-function-properties-of-the-global-object
- define_native_function(realm, vm.names.eval, eval, 1, attr);
- define_native_function(realm, vm.names.isFinite, is_finite, 1, attr);
- define_native_function(realm, vm.names.isNaN, is_nan, 1, attr);
- define_native_function(realm, vm.names.parseFloat, parse_float, 1, attr);
- define_native_function(realm, vm.names.parseInt, parse_int, 2, attr);
- define_native_function(realm, vm.names.decodeURI, decode_uri, 1, attr);
- define_native_function(realm, vm.names.decodeURIComponent, decode_uri_component, 1, attr);
- define_native_function(realm, vm.names.encodeURI, encode_uri, 1, attr);
- define_native_function(realm, vm.names.encodeURIComponent, encode_uri_component, 1, attr);
+ define_direct_property(vm.names.eval, realm.intrinsics().eval_function(), attr);
+ define_direct_property(vm.names.isFinite, realm.intrinsics().is_finite_function(), attr);
+ define_direct_property(vm.names.isNaN, realm.intrinsics().is_nan_function(), attr);
+ define_direct_property(vm.names.parseFloat, realm.intrinsics().parse_float_function(), attr);
+ define_direct_property(vm.names.parseInt, realm.intrinsics().parse_int_function(), attr);
+ define_direct_property(vm.names.decodeURI, realm.intrinsics().decode_uri_function(), attr);
+ define_direct_property(vm.names.decodeURIComponent, realm.intrinsics().decode_uri_component_function(), attr);
+ define_direct_property(vm.names.encodeURI, realm.intrinsics().encode_uri_function(), attr);
+ define_direct_property(vm.names.encodeURIComponent, realm.intrinsics().encode_uri_component_function(), attr);
// 19.1 Value Properties of the Global Object, https://tc39.es/ecma262/#sec-value-properties-of-the-global-object
define_direct_property(vm.names.globalThis, this, attr);
@@ -167,18 +167,13 @@ void GlobalObject::initialize(Realm& realm)
define_direct_property(vm.names.Temporal, heap().allocate<Temporal::Temporal>(realm, realm), attr);
// B.2.1 Additional Properties of the Global Object, https://tc39.es/ecma262/#sec-additional-properties-of-the-global-object
- define_native_function(realm, vm.names.escape, escape, 1, attr);
- define_native_function(realm, vm.names.unescape, unescape, 1, attr);
+ define_direct_property(vm.names.escape, realm.intrinsics().escape_function(), attr);
+ define_direct_property(vm.names.unescape, realm.intrinsics().unescape_function(), attr);
// Non-standard
define_direct_property(vm.names.InternalError, realm.intrinsics().internal_error_constructor(), attr);
define_direct_property(vm.names.console, realm.intrinsics().console_object(), attr);
define_native_function(realm, vm.names.gc, gc, 0, attr);
-
- // Assign intrinsics and functions that depend on the GlobalObject's native functions
- realm.intrinsics().m_eval_function = &get_without_side_effects(vm.names.eval).as_function();
- realm.intrinsics().m_number_constructor->define_direct_property(vm.names.parseInt, get_without_side_effects(vm.names.parseInt), attr);
- realm.intrinsics().m_number_constructor->define_direct_property(vm.names.parseFloat, get_without_side_effects(vm.names.parseFloat), attr);
}
GlobalObject::~GlobalObject() = default;
diff --git a/Userland/Libraries/LibJS/Runtime/GlobalObject.h b/Userland/Libraries/LibJS/Runtime/GlobalObject.h
index 94aa241d92..0529c32eea 100644
--- a/Userland/Libraries/LibJS/Runtime/GlobalObject.h
+++ b/Userland/Libraries/LibJS/Runtime/GlobalObject.h
@@ -16,6 +16,8 @@ namespace JS {
class GlobalObject : public Object {
JS_OBJECT(GlobalObject, Object);
+ friend class Intrinsics;
+
public:
explicit GlobalObject(Realm&);
virtual void initialize(Realm&) override;
diff --git a/Userland/Libraries/LibJS/Runtime/Intrinsics.cpp b/Userland/Libraries/LibJS/Runtime/Intrinsics.cpp
index 815f1c10c1..55db6493a0 100644
--- a/Userland/Libraries/LibJS/Runtime/Intrinsics.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Intrinsics.cpp
@@ -206,6 +206,19 @@ void Intrinsics::initialize_intrinsics(Realm& realm)
// Not included in JS_ENUMERATE_NATIVE_OBJECTS due to missing distinct prototype
m_proxy_constructor = heap().allocate<ProxyConstructor>(realm, realm);
+ // Global object functions
+ m_eval_function = NativeFunction::create(realm, GlobalObject::eval, 1, vm.names.eval, &realm);
+ m_is_finite_function = NativeFunction::create(realm, GlobalObject::is_finite, 1, vm.names.isFinite, &realm);
+ m_is_nan_function = NativeFunction::create(realm, GlobalObject::is_nan, 1, vm.names.isNaN, &realm);
+ m_parse_float_function = NativeFunction::create(realm, GlobalObject::parse_float, 1, vm.names.parseFloat, &realm);
+ m_parse_int_function = NativeFunction::create(realm, GlobalObject::parse_int, 2, vm.names.parseInt, &realm);
+ m_decode_uri_function = NativeFunction::create(realm, GlobalObject::decode_uri, 1, vm.names.decodeURI, &realm);
+ m_decode_uri_component_function = NativeFunction::create(realm, GlobalObject::decode_uri_component, 1, vm.names.decodeURIComponent, &realm);
+ m_encode_uri_function = NativeFunction::create(realm, GlobalObject::encode_uri, 1, vm.names.encodeURI, &realm);
+ m_encode_uri_component_function = NativeFunction::create(realm, GlobalObject::encode_uri_component, 1, vm.names.encodeURIComponent, &realm);
+ m_escape_function = NativeFunction::create(realm, GlobalObject::escape, 1, vm.names.escape, &realm);
+ m_unescape_function = NativeFunction::create(realm, GlobalObject::unescape, 1, vm.names.unescape, &realm);
+
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType) \
/* These are the prototypes allocated earlier, everything else must not yet exist.*/ \
if constexpr (!IsOneOf<PrototypeName, ErrorPrototype, FunctionPrototype, ObjectPrototype>) { \
diff --git a/Userland/Libraries/LibJS/Runtime/Intrinsics.h b/Userland/Libraries/LibJS/Runtime/Intrinsics.h
index 2ddaa566d8..ee57442569 100644
--- a/Userland/Libraries/LibJS/Runtime/Intrinsics.h
+++ b/Userland/Libraries/LibJS/Runtime/Intrinsics.h
@@ -14,9 +14,6 @@ namespace JS {
class Intrinsics final : public Cell {
public:
- // Allow the global object to set intrinsics, ugly but needed for now.
- friend class GlobalObject;
-
static Intrinsics* create(Realm&);
Intrinsics() = default;
@@ -42,9 +39,22 @@ public:
// Not included in JS_ENUMERATE_INTL_OBJECTS due to missing distinct constructor
Object* intl_segments_prototype() { return m_intl_segments_prototype; }
+ // Global object functions
+ FunctionObject* eval_function() const { return m_eval_function; }
+ FunctionObject* is_finite_function() const { return m_is_finite_function; }
+ FunctionObject* is_nan_function() const { return m_is_nan_function; }
+ FunctionObject* parse_float_function() const { return m_parse_float_function; }
+ FunctionObject* parse_int_function() const { return m_parse_int_function; }
+ FunctionObject* decode_uri_function() const { return m_decode_uri_function; }
+ FunctionObject* decode_uri_component_function() const { return m_decode_uri_component_function; }
+ FunctionObject* encode_uri_function() const { return m_encode_uri_function; }
+ FunctionObject* encode_uri_component_function() const { return m_encode_uri_component_function; }
+ FunctionObject* escape_function() const { return m_escape_function; }
+ FunctionObject* unescape_function() const { return m_unescape_function; }
+
+ // Namespace/constructor object functions
FunctionObject* array_prototype_values_function() const { return m_array_prototype_values_function; }
FunctionObject* date_constructor_now_function() const { return m_date_constructor_now_function; }
- FunctionObject* eval_function() const { return m_eval_function; }
FunctionObject* json_parse_function() const { return m_json_parse_function; }
FunctionObject* object_prototype_to_string_function() const { return m_object_prototype_to_string_function; }
FunctionObject* throw_type_error_function() const { return m_throw_type_error_function; }
@@ -122,9 +132,22 @@ private:
// Not included in JS_ENUMERATE_INTL_OBJECTS due to missing distinct constructor
Object* m_intl_segments_prototype { nullptr };
+ // Global object functions
+ FunctionObject* m_eval_function { nullptr };
+ FunctionObject* m_is_finite_function { nullptr };
+ FunctionObject* m_is_nan_function { nullptr };
+ FunctionObject* m_parse_float_function { nullptr };
+ FunctionObject* m_parse_int_function { nullptr };
+ FunctionObject* m_decode_uri_function { nullptr };
+ FunctionObject* m_decode_uri_component_function { nullptr };
+ FunctionObject* m_encode_uri_function { nullptr };
+ FunctionObject* m_encode_uri_component_function { nullptr };
+ FunctionObject* m_escape_function { nullptr };
+ FunctionObject* m_unescape_function { nullptr };
+
+ // Namespace/constructor object functions
FunctionObject* m_array_prototype_values_function { nullptr };
FunctionObject* m_date_constructor_now_function { nullptr };
- FunctionObject* m_eval_function { nullptr };
FunctionObject* m_json_parse_function { nullptr };
FunctionObject* m_object_prototype_to_string_function { nullptr };
FunctionObject* m_throw_type_error_function { nullptr };
diff --git a/Userland/Libraries/LibJS/Runtime/NumberConstructor.cpp b/Userland/Libraries/LibJS/Runtime/NumberConstructor.cpp
index 6e61b56c6a..a14921ce61 100644
--- a/Userland/Libraries/LibJS/Runtime/NumberConstructor.cpp
+++ b/Userland/Libraries/LibJS/Runtime/NumberConstructor.cpp
@@ -41,10 +41,8 @@ void NumberConstructor::initialize(Realm& realm)
define_native_function(realm, vm.names.isInteger, is_integer, 1, attr);
define_native_function(realm, vm.names.isNaN, is_nan, 1, attr);
define_native_function(realm, vm.names.isSafeInteger, is_safe_integer, 1, attr);
- // NOTE: These are set from the global object as at this point we don't have them allocated yet;
- // The native functions are part of the global object itself.
- define_direct_property(vm.names.parseInt, js_undefined(), attr);
- define_direct_property(vm.names.parseFloat, js_undefined(), attr);
+ define_direct_property(vm.names.parseInt, realm.intrinsics().parse_int_function(), attr);
+ define_direct_property(vm.names.parseFloat, realm.intrinsics().parse_float_function(), attr);
define_direct_property(vm.names.EPSILON, Value(EPSILON_VALUE), 0);
define_direct_property(vm.names.MAX_VALUE, Value(NumericLimits<double>::max()), 0);
define_direct_property(vm.names.MIN_VALUE, Value(NumericLimits<double>::min()), 0);