diff options
author | Linus Groh <mail@linusgroh.de> | 2022-08-28 17:09:31 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-08-28 19:34:10 +0100 |
commit | e3804e6426e9a483df23382fe4d6876315b1f7ff (patch) | |
tree | 945c57588217da8d5cd68911d6f8fdc13cb192a8 | |
parent | 3d5300a25eeaef1e328a973dc13645c1cf948db3 (diff) | |
download | serenity-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.cpp | 27 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/GlobalObject.h | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/Intrinsics.cpp | 13 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/Intrinsics.h | 33 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/NumberConstructor.cpp | 6 |
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); |