| 
									
										
										
										
											2020-04-06 11:09:01 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> | 
					
						
							| 
									
										
										
										
											2020-05-17 15:12:34 +01:00
										 |  |  |  * Copyright (c) 2020, Linus Groh <mail@linusgroh.de> | 
					
						
							| 
									
										
										
										
											2020-04-06 11:09:01 +02:00
										 |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Redistribution and use in source and binary forms, with or without | 
					
						
							|  |  |  |  * modification, are permitted provided that the following conditions are met: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 1. Redistributions of source code must retain the above copyright notice, this | 
					
						
							|  |  |  |  *    list of conditions and the following disclaimer. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 2. Redistributions in binary form must reproduce the above copyright notice, | 
					
						
							|  |  |  |  *    this list of conditions and the following disclaimer in the documentation | 
					
						
							|  |  |  |  *    and/or other materials provided with the distribution. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | 
					
						
							|  |  |  |  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
					
						
							|  |  |  |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 
					
						
							|  |  |  |  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | 
					
						
							|  |  |  |  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
					
						
							|  |  |  |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 
					
						
							|  |  |  |  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | 
					
						
							|  |  |  |  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | 
					
						
							|  |  |  |  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
					
						
							|  |  |  |  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-05 13:51:09 +01:00
										 |  |  | #include <AK/Utf8View.h>
 | 
					
						
							| 
									
										
										
										
											2020-09-29 21:15:06 +02:00
										 |  |  | #include <LibJS/Console.h>
 | 
					
						
							| 
									
										
										
										
											2020-09-20 19:24:44 +02:00
										 |  |  | #include <LibJS/Heap/DeferGC.h>
 | 
					
						
							| 
									
										
										
										
											2020-12-02 20:49:31 +00:00
										 |  |  | #include <LibJS/Runtime/ArrayBufferConstructor.h>
 | 
					
						
							|  |  |  | #include <LibJS/Runtime/ArrayBufferPrototype.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-04 22:28:21 +02:00
										 |  |  | #include <LibJS/Runtime/ArrayConstructor.h>
 | 
					
						
							| 
									
										
										
										
											2020-07-09 14:58:20 -07:00
										 |  |  | #include <LibJS/Runtime/ArrayIteratorPrototype.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-18 13:18:06 +02:00
										 |  |  | #include <LibJS/Runtime/ArrayPrototype.h>
 | 
					
						
							| 
									
										
										
										
											2020-06-06 01:14:10 +01:00
										 |  |  | #include <LibJS/Runtime/BigIntConstructor.h>
 | 
					
						
							|  |  |  | #include <LibJS/Runtime/BigIntPrototype.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-06 22:51:16 -05:00
										 |  |  | #include <LibJS/Runtime/BooleanConstructor.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-18 13:18:06 +02:00
										 |  |  | #include <LibJS/Runtime/BooleanPrototype.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-16 14:20:30 +01:00
										 |  |  | #include <LibJS/Runtime/ConsoleObject.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-30 00:21:56 +01:00
										 |  |  | #include <LibJS/Runtime/DateConstructor.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-18 13:18:06 +02:00
										 |  |  | #include <LibJS/Runtime/DatePrototype.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-01 19:42:07 +01:00
										 |  |  | #include <LibJS/Runtime/ErrorConstructor.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-18 13:18:06 +02:00
										 |  |  | #include <LibJS/Runtime/ErrorPrototype.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-04 14:34:31 +01:00
										 |  |  | #include <LibJS/Runtime/FunctionConstructor.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-18 13:18:06 +02:00
										 |  |  | #include <LibJS/Runtime/FunctionPrototype.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-16 14:20:30 +01:00
										 |  |  | #include <LibJS/Runtime/GlobalObject.h>
 | 
					
						
							| 
									
										
										
										
											2020-07-09 14:58:20 -07:00
										 |  |  | #include <LibJS/Runtime/IteratorPrototype.h>
 | 
					
						
							| 
									
										
										
										
											2020-06-10 11:01:00 -07:00
										 |  |  | #include <LibJS/Runtime/JSONObject.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-21 17:52:12 +01:00
										 |  |  | #include <LibJS/Runtime/MathObject.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-16 14:20:30 +01:00
										 |  |  | #include <LibJS/Runtime/NativeFunction.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-07 16:17:23 +01:00
										 |  |  | #include <LibJS/Runtime/NumberConstructor.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-18 13:18:06 +02:00
										 |  |  | #include <LibJS/Runtime/NumberPrototype.h>
 | 
					
						
							|  |  |  | #include <LibJS/Runtime/Object.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-28 17:23:54 +01:00
										 |  |  | #include <LibJS/Runtime/ObjectConstructor.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-18 13:18:06 +02:00
										 |  |  | #include <LibJS/Runtime/ObjectPrototype.h>
 | 
					
						
							| 
									
										
										
										
											2020-06-03 14:34:52 -07:00
										 |  |  | #include <LibJS/Runtime/ProxyConstructor.h>
 | 
					
						
							| 
									
										
										
										
											2020-05-01 11:06:27 +01:00
										 |  |  | #include <LibJS/Runtime/ReflectObject.h>
 | 
					
						
							| 
									
										
										
										
											2020-06-03 16:05:49 -07:00
										 |  |  | #include <LibJS/Runtime/RegExpConstructor.h>
 | 
					
						
							|  |  |  | #include <LibJS/Runtime/RegExpPrototype.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-18 13:18:06 +02:00
										 |  |  | #include <LibJS/Runtime/Shape.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-10 14:14:02 +02:00
										 |  |  | #include <LibJS/Runtime/StringConstructor.h>
 | 
					
						
							| 
									
										
										
										
											2020-07-11 20:23:01 -07:00
										 |  |  | #include <LibJS/Runtime/StringIteratorPrototype.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-18 13:18:06 +02:00
										 |  |  | #include <LibJS/Runtime/StringPrototype.h>
 | 
					
						
							| 
									
										
										
										
											2020-04-29 23:25:21 -07:00
										 |  |  | #include <LibJS/Runtime/SymbolConstructor.h>
 | 
					
						
							|  |  |  | #include <LibJS/Runtime/SymbolPrototype.h>
 | 
					
						
							| 
									
										
										
										
											2020-12-01 21:05:25 +01:00
										 |  |  | #include <LibJS/Runtime/TypedArray.h>
 | 
					
						
							| 
									
										
										
										
											2020-12-02 00:23:40 +00:00
										 |  |  | #include <LibJS/Runtime/TypedArrayConstructor.h>
 | 
					
						
							|  |  |  | #include <LibJS/Runtime/TypedArrayPrototype.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-16 14:20:30 +01:00
										 |  |  | #include <LibJS/Runtime/Value.h>
 | 
					
						
							| 
									
										
										
										
											2020-12-05 13:51:09 +01:00
										 |  |  | #include <ctype.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-12 20:11:35 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace JS { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-13 11:06:32 +01:00
										 |  |  | GlobalObject::GlobalObject() | 
					
						
							| 
									
										
										
										
											2020-11-28 16:02:27 +01:00
										 |  |  |     : ScopeObject(GlobalObjectTag::Tag) | 
					
						
							| 
									
										
										
										
											2020-09-29 21:15:06 +02:00
										 |  |  |     , m_console(make<Console>(*this)) | 
					
						
							| 
									
										
										
										
											2020-03-12 20:11:35 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-04-18 13:18:06 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GlobalObject::initialize() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-10-13 23:49:19 +02:00
										 |  |  |     auto& vm = this->vm(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-04 22:56:45 +02:00
										 |  |  |     ensure_shape_is_unique(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-18 13:18:06 +02:00
										 |  |  |     // These are done first since other prototypes depend on their presence.
 | 
					
						
							| 
									
										
										
										
											2020-10-17 23:47:07 +02:00
										 |  |  |     m_empty_object_shape = heap().allocate_without_global_object<Shape>(*this); | 
					
						
							| 
									
										
										
										
											2020-06-20 15:40:48 +02:00
										 |  |  |     m_object_prototype = heap().allocate_without_global_object<ObjectPrototype>(*this); | 
					
						
							|  |  |  |     m_function_prototype = heap().allocate_without_global_object<FunctionPrototype>(*this); | 
					
						
							| 
									
										
										
										
											2020-04-18 13:18:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-17 23:47:07 +02:00
										 |  |  |     m_new_object_shape = vm.heap().allocate_without_global_object<Shape>(*this); | 
					
						
							| 
									
										
										
										
											2020-10-17 23:13:37 +02:00
										 |  |  |     m_new_object_shape->set_prototype_without_transition(m_object_prototype); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-17 23:47:07 +02:00
										 |  |  |     m_new_script_function_prototype_object_shape = vm.heap().allocate_without_global_object<Shape>(*this); | 
					
						
							| 
									
										
										
										
											2020-10-17 23:13:37 +02:00
										 |  |  |     m_new_script_function_prototype_object_shape->set_prototype_without_transition(m_object_prototype); | 
					
						
							|  |  |  |     m_new_script_function_prototype_object_shape->add_property_without_transition(vm.names.constructor, Attribute::Writable | Attribute::Configurable); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-22 17:50:18 +02:00
										 |  |  |     static_cast<FunctionPrototype*>(m_function_prototype)->initialize(*this); | 
					
						
							|  |  |  |     static_cast<ObjectPrototype*>(m_object_prototype)->initialize(*this); | 
					
						
							| 
									
										
										
										
											2020-04-18 13:18:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-06 18:56:54 +00:00
										 |  |  |     set_prototype(m_object_prototype); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-01 21:05:25 +01:00
										 |  |  | #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType) \
 | 
					
						
							|  |  |  |     if (!m_##snake_name##_prototype)                                                     \ | 
					
						
							| 
									
										
										
										
											2020-06-20 15:40:48 +02:00
										 |  |  |         m_##snake_name##_prototype = heap().allocate<PrototypeName>(*this, *this); | 
					
						
							| 
									
										
										
										
											2020-04-18 13:18:06 +02:00
										 |  |  |     JS_ENUMERATE_BUILTIN_TYPES | 
					
						
							|  |  |  | #undef __JS_ENUMERATE
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-20 19:24:44 +02:00
										 |  |  | #define __JS_ENUMERATE(ClassName, snake_name) \
 | 
					
						
							|  |  |  |     if (!m_##snake_name##_prototype)          \ | 
					
						
							| 
									
										
										
										
											2020-07-09 14:58:20 -07:00
										 |  |  |         m_##snake_name##_prototype = heap().allocate<ClassName##Prototype>(*this, *this); | 
					
						
							|  |  |  |     JS_ENUMERATE_ITERATOR_PROTOTYPES | 
					
						
							|  |  |  | #undef __JS_ENUMERATE
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-27 23:05:02 -07:00
										 |  |  |     u8 attr = Attribute::Writable | Attribute::Configurable; | 
					
						
							| 
									
										
										
										
											2020-10-13 23:49:19 +02:00
										 |  |  |     define_native_function(vm.names.gc, gc, 0, attr); | 
					
						
							|  |  |  |     define_native_function(vm.names.isNaN, is_nan, 1, attr); | 
					
						
							|  |  |  |     define_native_function(vm.names.isFinite, is_finite, 1, attr); | 
					
						
							|  |  |  |     define_native_function(vm.names.parseFloat, parse_float, 1, attr); | 
					
						
							| 
									
										
										
										
											2020-12-05 13:51:09 +01:00
										 |  |  |     define_native_function(vm.names.parseInt, parse_int, 1, attr); | 
					
						
							| 
									
										
										
										
											2020-10-13 23:49:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     define_property(vm.names.NaN, js_nan(), 0); | 
					
						
							|  |  |  |     define_property(vm.names.Infinity, js_infinity(), 0); | 
					
						
							|  |  |  |     define_property(vm.names.undefined, js_undefined(), 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     define_property(vm.names.globalThis, this, attr); | 
					
						
							|  |  |  |     define_property(vm.names.console, heap().allocate<ConsoleObject>(*this, *this), attr); | 
					
						
							|  |  |  |     define_property(vm.names.Math, heap().allocate<MathObject>(*this, *this), attr); | 
					
						
							|  |  |  |     define_property(vm.names.JSON, heap().allocate<JSONObject>(*this, *this), attr); | 
					
						
							|  |  |  |     define_property(vm.names.Reflect, heap().allocate<ReflectObject>(*this, *this), attr); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-30 22:50:43 +00:00
										 |  |  |     add_constructor(vm.names.Array, m_array_constructor, m_array_prototype); | 
					
						
							| 
									
										
										
										
											2020-12-02 20:49:31 +00:00
										 |  |  |     add_constructor(vm.names.ArrayBuffer, m_array_buffer_constructor, m_array_buffer_prototype); | 
					
						
							| 
									
										
										
										
											2020-11-30 22:50:43 +00:00
										 |  |  |     add_constructor(vm.names.BigInt, m_bigint_constructor, m_bigint_prototype); | 
					
						
							|  |  |  |     add_constructor(vm.names.Boolean, m_boolean_constructor, m_boolean_prototype); | 
					
						
							|  |  |  |     add_constructor(vm.names.Date, m_date_constructor, m_date_prototype); | 
					
						
							|  |  |  |     add_constructor(vm.names.Error, m_error_constructor, m_error_prototype); | 
					
						
							|  |  |  |     add_constructor(vm.names.Function, m_function_constructor, m_function_prototype); | 
					
						
							|  |  |  |     add_constructor(vm.names.Number, m_number_constructor, m_number_prototype); | 
					
						
							|  |  |  |     add_constructor(vm.names.Object, m_object_constructor, m_object_prototype); | 
					
						
							|  |  |  |     add_constructor(vm.names.Proxy, m_proxy_constructor, nullptr); | 
					
						
							|  |  |  |     add_constructor(vm.names.RegExp, m_regexp_constructor, m_regexp_prototype); | 
					
						
							|  |  |  |     add_constructor(vm.names.String, m_string_constructor, m_string_prototype); | 
					
						
							|  |  |  |     add_constructor(vm.names.Symbol, m_symbol_constructor, m_symbol_prototype); | 
					
						
							| 
									
										
										
										
											2020-04-10 12:42:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-02 00:23:40 +00:00
										 |  |  |     initialize_constructor(vm.names.TypedArray, m_typed_array_constructor, m_typed_array_prototype); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-01 21:05:25 +01:00
										 |  |  | #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType) \
 | 
					
						
							| 
									
										
										
										
											2020-11-30 22:50:43 +00:00
										 |  |  |     add_constructor(vm.names.ClassName, m_##snake_name##_constructor, m_##snake_name##_prototype); | 
					
						
							| 
									
										
										
										
											2020-04-10 12:42:33 +02:00
										 |  |  |     JS_ENUMERATE_ERROR_SUBCLASSES | 
					
						
							| 
									
										
										
										
											2020-12-01 21:05:25 +01:00
										 |  |  |     JS_ENUMERATE_TYPED_ARRAYS | 
					
						
							| 
									
										
										
										
											2020-04-10 14:06:52 +02:00
										 |  |  | #undef __JS_ENUMERATE
 | 
					
						
							| 
									
										
										
										
											2020-03-12 20:11:35 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | GlobalObject::~GlobalObject() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-28 14:33:36 +01:00
										 |  |  | void GlobalObject::visit_edges(Visitor& visitor) | 
					
						
							| 
									
										
										
										
											2020-04-08 11:05:38 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-11-28 16:02:27 +01:00
										 |  |  |     Base::visit_edges(visitor); | 
					
						
							| 
									
										
										
										
											2020-04-08 11:05:38 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-18 13:56:13 +02:00
										 |  |  |     visitor.visit(m_empty_object_shape); | 
					
						
							| 
									
										
										
										
											2020-10-17 23:13:37 +02:00
										 |  |  |     visitor.visit(m_new_object_shape); | 
					
						
							|  |  |  |     visitor.visit(m_new_script_function_prototype_object_shape); | 
					
						
							| 
									
										
										
										
											2020-12-08 13:32:15 +01:00
										 |  |  |     visitor.visit(m_proxy_constructor); | 
					
						
							| 
									
										
										
										
											2020-04-18 13:56:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-01 21:05:25 +01:00
										 |  |  | #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType) \
 | 
					
						
							| 
									
										
										
										
											2020-04-18 11:02:05 +02:00
										 |  |  |     visitor.visit(m_##snake_name##_constructor); | 
					
						
							|  |  |  |     JS_ENUMERATE_ERROR_SUBCLASSES | 
					
						
							|  |  |  | #undef __JS_ENUMERATE
 | 
					
						
							| 
									
										
										
										
											2020-09-08 15:37:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define __JS_ENUMERATE(ClassName, snake_name) \
 | 
					
						
							|  |  |  |     visitor.visit(m_##snake_name##_prototype); | 
					
						
							|  |  |  |     JS_ENUMERATE_ITERATOR_PROTOTYPES | 
					
						
							|  |  |  | #undef __JS_ENUMERATE
 | 
					
						
							| 
									
										
										
										
											2020-04-08 11:05:38 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-20 13:55:34 +02:00
										 |  |  | JS_DEFINE_NATIVE_FUNCTION(GlobalObject::gc) | 
					
						
							| 
									
										
										
										
											2020-03-28 23:10:37 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-12-06 16:55:19 +00:00
										 |  |  |     dbgln("Forced garbage collection requested!"); | 
					
						
							| 
									
										
										
										
											2020-09-27 18:36:49 +02:00
										 |  |  |     vm.heap().collect_garbage(); | 
					
						
							| 
									
										
										
										
											2020-03-28 23:10:37 +01:00
										 |  |  |     return js_undefined(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-20 13:55:34 +02:00
										 |  |  | JS_DEFINE_NATIVE_FUNCTION(GlobalObject::is_nan) | 
					
						
							| 
									
										
										
										
											2020-03-28 23:10:37 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-27 18:36:49 +02:00
										 |  |  |     auto number = vm.argument(0).to_number(global_object); | 
					
						
							|  |  |  |     if (vm.exception()) | 
					
						
							| 
									
										
										
										
											2020-05-18 00:28:00 +01:00
										 |  |  |         return {}; | 
					
						
							|  |  |  |     return Value(number.is_nan()); | 
					
						
							| 
									
										
										
										
											2020-03-28 23:10:37 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-20 13:55:34 +02:00
										 |  |  | JS_DEFINE_NATIVE_FUNCTION(GlobalObject::is_finite) | 
					
						
							| 
									
										
										
										
											2020-04-22 18:07:24 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-27 18:36:49 +02:00
										 |  |  |     auto number = vm.argument(0).to_number(global_object); | 
					
						
							|  |  |  |     if (vm.exception()) | 
					
						
							| 
									
										
										
										
											2020-05-18 00:28:00 +01:00
										 |  |  |         return {}; | 
					
						
							|  |  |  |     return Value(number.is_finite_number()); | 
					
						
							| 
									
										
										
										
											2020-04-22 18:07:24 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-20 13:55:34 +02:00
										 |  |  | JS_DEFINE_NATIVE_FUNCTION(GlobalObject::parse_float) | 
					
						
							| 
									
										
										
										
											2020-05-17 15:12:34 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-27 18:36:49 +02:00
										 |  |  |     if (vm.argument(0).is_number()) | 
					
						
							|  |  |  |         return vm.argument(0); | 
					
						
							|  |  |  |     auto string = vm.argument(0).to_string(global_object); | 
					
						
							|  |  |  |     if (vm.exception()) | 
					
						
							| 
									
										
										
										
											2020-05-17 15:12:34 +01:00
										 |  |  |         return {}; | 
					
						
							|  |  |  |     for (size_t length = string.length(); length > 0; --length) { | 
					
						
							| 
									
										
										
										
											2020-05-18 00:28:00 +01:00
										 |  |  |         // This can't throw, so no exception check is fine.
 | 
					
						
							| 
									
										
										
										
											2020-09-27 18:36:49 +02:00
										 |  |  |         auto number = Value(js_string(vm, string.substring(0, length))).to_number(global_object); | 
					
						
							| 
									
										
										
										
											2020-05-17 15:12:34 +01:00
										 |  |  |         if (!number.is_nan()) | 
					
						
							|  |  |  |             return number; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return js_nan(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-05 13:51:09 +01:00
										 |  |  | JS_DEFINE_NATIVE_FUNCTION(GlobalObject::parse_int) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // 18.2.5 parseInt ( string, radix )
 | 
					
						
							|  |  |  |     auto input_string = vm.argument(0).to_string(global_object); | 
					
						
							|  |  |  |     if (vm.exception()) | 
					
						
							|  |  |  |         return {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // FIXME: There's a bunch of unnecessary string copying here.
 | 
					
						
							|  |  |  |     double sign = 1; | 
					
						
							|  |  |  |     auto s = input_string.trim_whitespace(TrimMode::Left); | 
					
						
							|  |  |  |     if (!s.is_empty() && s[0] == '-') | 
					
						
							|  |  |  |         sign = -1; | 
					
						
							|  |  |  |     if (!s.is_empty() && (s[0] == '+' || s[0] == '-')) | 
					
						
							|  |  |  |         s = s.substring(1, s.length() - 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto radix = vm.argument(1).to_i32(global_object); | 
					
						
							|  |  |  |     if (vm.exception()) | 
					
						
							|  |  |  |         return {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool strip_prefix = true; | 
					
						
							|  |  |  |     if (radix != 0) { | 
					
						
							|  |  |  |         if (radix < 2 || radix > 36) | 
					
						
							|  |  |  |             return js_nan(); | 
					
						
							|  |  |  |         if (radix != 16) | 
					
						
							|  |  |  |             strip_prefix = false; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         radix = 10; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (strip_prefix) { | 
					
						
							|  |  |  |         if (s.length() >= 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) { | 
					
						
							|  |  |  |             s = s.substring(2, s.length() - 2); | 
					
						
							|  |  |  |             radix = 16; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto parse_digit = [&](u32 codepoint, i32 radix) -> Optional<i32> { | 
					
						
							|  |  |  |         i32 digit = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (isdigit(codepoint)) | 
					
						
							|  |  |  |             digit = codepoint - '0'; | 
					
						
							|  |  |  |         else if (islower(codepoint)) | 
					
						
							|  |  |  |             digit = 10 + (codepoint - 'a'); | 
					
						
							|  |  |  |         else if (isupper(codepoint)) | 
					
						
							|  |  |  |             digit = 10 + (codepoint - 'A'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (digit == -1 || digit >= radix) | 
					
						
							|  |  |  |             return {}; | 
					
						
							|  |  |  |         return digit; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool had_digits = false; | 
					
						
							|  |  |  |     double number = 0; | 
					
						
							|  |  |  |     for (auto codepoint : Utf8View(s)) { | 
					
						
							|  |  |  |         auto digit = parse_digit(codepoint, radix); | 
					
						
							|  |  |  |         if (!digit.has_value()) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         had_digits = true; | 
					
						
							|  |  |  |         number *= radix; | 
					
						
							|  |  |  |         number += digit.value(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!had_digits) | 
					
						
							|  |  |  |         return js_nan(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return Value(sign * number); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-28 16:02:27 +01:00
										 |  |  | Optional<Variable> GlobalObject::get_from_scope(const FlyString& name) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto value = get(name); | 
					
						
							|  |  |  |     if (value.is_empty()) | 
					
						
							|  |  |  |         return {}; | 
					
						
							|  |  |  |     return Variable { value, DeclarationKind::Var }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GlobalObject::put_to_scope(const FlyString& name, Variable variable) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     put(name, variable.value); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool GlobalObject::has_this_binding() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Value GlobalObject::get_this_binding(GlobalObject&) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return Value(this); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-12 20:11:35 +01:00
										 |  |  | } |