mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 16:22:43 +00:00 
			
		
		
		
	LibJS: Move builtin prototypes to the global object
This moves us towards being able to run JavaScript in different global objects without allocating a separate GC heap.
This commit is contained in:
		
							parent
							
								
									cbcf317e76
								
							
						
					
					
						commit
						fca08bd000
					
				
					 40 changed files with 131 additions and 101 deletions
				
			
		|  | @ -27,20 +27,12 @@ | |||
| #include <AK/Badge.h> | ||||
| #include <LibJS/AST.h> | ||||
| #include <LibJS/Interpreter.h> | ||||
| #include <LibJS/Runtime/ArrayPrototype.h> | ||||
| #include <LibJS/Runtime/BooleanPrototype.h> | ||||
| #include <LibJS/Runtime/DatePrototype.h> | ||||
| #include <LibJS/Runtime/Error.h> | ||||
| #include <LibJS/Runtime/ErrorPrototype.h> | ||||
| #include <LibJS/Runtime/FunctionPrototype.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <LibJS/Runtime/LexicalEnvironment.h> | ||||
| #include <LibJS/Runtime/NativeFunction.h> | ||||
| #include <LibJS/Runtime/NumberPrototype.h> | ||||
| #include <LibJS/Runtime/Object.h> | ||||
| #include <LibJS/Runtime/ObjectPrototype.h> | ||||
| #include <LibJS/Runtime/Shape.h> | ||||
| #include <LibJS/Runtime/StringPrototype.h> | ||||
| #include <LibJS/Runtime/Value.h> | ||||
| 
 | ||||
| namespace JS { | ||||
|  | @ -49,19 +41,6 @@ Interpreter::Interpreter() | |||
|     : m_heap(*this) | ||||
| { | ||||
|     m_empty_object_shape = heap().allocate<Shape>(); | ||||
| 
 | ||||
|     // These are done first since other prototypes depend on their presence.
 | ||||
|     m_object_prototype = heap().allocate<ObjectPrototype>(); | ||||
|     m_function_prototype = heap().allocate<FunctionPrototype>(); | ||||
| 
 | ||||
|     static_cast<FunctionPrototype*>(m_function_prototype)->initialize(); | ||||
|     static_cast<ObjectPrototype*>(m_object_prototype)->initialize(); | ||||
| 
 | ||||
| #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ | ||||
|     if (!m_##snake_name##_prototype)                                          \ | ||||
|         m_##snake_name##_prototype = heap().allocate<PrototypeName>(); | ||||
|     JS_ENUMERATE_BUILTIN_TYPES | ||||
| #undef __JS_ENUMERATE | ||||
| } | ||||
| 
 | ||||
| Interpreter::~Interpreter() | ||||
|  | @ -186,11 +165,6 @@ void Interpreter::gather_roots(Badge<Heap>, HashTable<Cell*>& roots) | |||
|     roots.set(m_global_object); | ||||
|     roots.set(m_exception); | ||||
| 
 | ||||
| #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ | ||||
|     roots.set(m_##snake_name##_prototype); | ||||
|     JS_ENUMERATE_BUILTIN_TYPES | ||||
| #undef __JS_ENUMERATE | ||||
| 
 | ||||
|     if (m_last_value.is_cell()) | ||||
|         roots.set(m_last_value.as_cell()); | ||||
| 
 | ||||
|  |  | |||
|  | @ -74,6 +74,7 @@ public: | |||
|     { | ||||
|         auto interpreter = adopt_own(*new Interpreter); | ||||
|         interpreter->m_global_object = interpreter->heap().allocate<GlobalObjectType>(forward<Args>(args)...); | ||||
|         static_cast<GlobalObjectType*>(interpreter->m_global_object)->initialize(); | ||||
|         return interpreter; | ||||
|     } | ||||
| 
 | ||||
|  | @ -140,11 +141,6 @@ public: | |||
| 
 | ||||
|     Shape* empty_object_shape() { return m_empty_object_shape; } | ||||
| 
 | ||||
| #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ | ||||
|     Object* snake_name##_prototype() { return m_##snake_name##_prototype; } | ||||
|     JS_ENUMERATE_BUILTIN_TYPES | ||||
| #undef __JS_ENUMERATE | ||||
| 
 | ||||
|     Exception* exception() | ||||
|     { | ||||
|         return m_exception; | ||||
|  | @ -176,12 +172,6 @@ private: | |||
|     Vector<CallFrame> m_call_stack; | ||||
| 
 | ||||
|     Shape* m_empty_object_shape { nullptr }; | ||||
| 
 | ||||
| #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ | ||||
|     Object* m_##snake_name##_prototype { nullptr }; | ||||
|     JS_ENUMERATE_BUILTIN_TYPES | ||||
| #undef __JS_ENUMERATE | ||||
| 
 | ||||
|     Object* m_global_object { nullptr }; | ||||
| 
 | ||||
|     Exception* m_exception { nullptr }; | ||||
|  |  | |||
|  | @ -36,7 +36,7 @@ namespace JS { | |||
| Array* Array::create(GlobalObject& global_object) | ||||
| { | ||||
|     auto& interpreter = global_object.interpreter(); | ||||
|     return interpreter.heap().allocate<Array>(*interpreter.array_prototype()); | ||||
|     return interpreter.heap().allocate<Array>(*global_object.array_prototype()); | ||||
| } | ||||
| 
 | ||||
| Array::Array(Object& prototype) | ||||
|  |  | |||
|  | @ -29,14 +29,15 @@ | |||
| #include <LibJS/Interpreter.h> | ||||
| #include <LibJS/Runtime/Array.h> | ||||
| #include <LibJS/Runtime/ArrayConstructor.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <LibJS/Runtime/Shape.h> | ||||
| 
 | ||||
| namespace JS { | ||||
| 
 | ||||
| ArrayConstructor::ArrayConstructor() | ||||
|     : NativeFunction("Array", *interpreter().function_prototype()) | ||||
|     : NativeFunction("Array", *interpreter().global_object().function_prototype()) | ||||
| { | ||||
|     put("prototype", interpreter().array_prototype()); | ||||
|     put("prototype", interpreter().global_object().array_prototype()); | ||||
|     put("length", Value(1)); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -33,12 +33,13 @@ | |||
| #include <LibJS/Runtime/ArrayPrototype.h> | ||||
| #include <LibJS/Runtime/Error.h> | ||||
| #include <LibJS/Runtime/Function.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <LibJS/Runtime/Value.h> | ||||
| 
 | ||||
| namespace JS { | ||||
| 
 | ||||
| ArrayPrototype::ArrayPrototype() | ||||
|     : Object(interpreter().object_prototype()) | ||||
|     : Object(interpreter().global_object().object_prototype()) | ||||
| { | ||||
|     put_native_function("filter", filter, 1); | ||||
|     put_native_function("forEach", for_each, 1); | ||||
|  |  | |||
|  | @ -29,13 +29,14 @@ | |||
| #include <LibJS/Runtime/BooleanConstructor.h> | ||||
| #include <LibJS/Runtime/BooleanObject.h> | ||||
| #include <LibJS/Runtime/BooleanPrototype.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| 
 | ||||
| namespace JS { | ||||
| 
 | ||||
| BooleanConstructor::BooleanConstructor() | ||||
|     : NativeFunction("Boolean", *interpreter().function_prototype()) | ||||
|     : NativeFunction("Boolean", *interpreter().global_object().function_prototype()) | ||||
| { | ||||
|     put("prototype", Value(interpreter().boolean_prototype())); | ||||
|     put("prototype", Value(interpreter().global_object().boolean_prototype())); | ||||
|     put("length", Value(1)); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -33,7 +33,7 @@ namespace JS { | |||
| BooleanObject* BooleanObject::create(GlobalObject& global_object, bool value) | ||||
| { | ||||
|     auto& interpreter = global_object.interpreter(); | ||||
|     return interpreter.heap().allocate<BooleanObject>(value, *interpreter.boolean_prototype()); | ||||
|     return interpreter.heap().allocate<BooleanObject>(value, *global_object.boolean_prototype()); | ||||
| } | ||||
| 
 | ||||
| BooleanObject::BooleanObject(bool value, Object& prototype) | ||||
|  |  | |||
|  | @ -28,11 +28,12 @@ | |||
| #include <LibJS/Interpreter.h> | ||||
| #include <LibJS/Runtime/BooleanPrototype.h> | ||||
| #include <LibJS/Runtime/Error.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| 
 | ||||
| namespace JS { | ||||
| 
 | ||||
| BooleanPrototype::BooleanPrototype() | ||||
|     : BooleanObject(false, *interpreter().object_prototype()) | ||||
|     : BooleanObject(false, *interpreter().global_object().object_prototype()) | ||||
| { | ||||
|     put_native_function("toString", to_string); | ||||
|     put_native_function("valueOf", value_of); | ||||
|  |  | |||
|  | @ -29,6 +29,7 @@ | |||
| #include <AK/Function.h> | ||||
| #include <LibJS/Interpreter.h> | ||||
| #include <LibJS/Runtime/ConsoleObject.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| namespace JS { | ||||
|  | @ -44,7 +45,7 @@ static void print_args(Interpreter& interpreter) | |||
| } | ||||
| 
 | ||||
| ConsoleObject::ConsoleObject() | ||||
|     : Object(interpreter().object_prototype()) | ||||
|     : Object(interpreter().global_object().object_prototype()) | ||||
| { | ||||
|     put_native_function("log", log); | ||||
|     put_native_function("debug", debug); | ||||
|  |  | |||
|  | @ -34,7 +34,7 @@ namespace JS { | |||
| 
 | ||||
| Date* Date::create(GlobalObject& global_object, Core::DateTime datetime, u16 milliseconds) | ||||
| { | ||||
|     return global_object.heap().allocate<Date>(datetime, milliseconds, *global_object.interpreter().date_prototype()); | ||||
|     return global_object.heap().allocate<Date>(datetime, milliseconds, *global_object.date_prototype()); | ||||
| } | ||||
| 
 | ||||
| Date::Date(Core::DateTime datetime, u16 milliseconds, Object& prototype) | ||||
|  |  | |||
|  | @ -28,15 +28,16 @@ | |||
| #include <LibJS/Interpreter.h> | ||||
| #include <LibJS/Runtime/Date.h> | ||||
| #include <LibJS/Runtime/DateConstructor.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <sys/time.h> | ||||
| #include <time.h> | ||||
| 
 | ||||
| namespace JS { | ||||
| 
 | ||||
| DateConstructor::DateConstructor() | ||||
|     : NativeFunction("Date", *interpreter().function_prototype()) | ||||
|     : NativeFunction("Date", *interpreter().global_object().function_prototype()) | ||||
| { | ||||
|     put("prototype", interpreter().date_prototype()); | ||||
|     put("prototype", interpreter().global_object().date_prototype()); | ||||
|     put("length", Value(7)); | ||||
| 
 | ||||
|     put_native_function("now", now); | ||||
|  |  | |||
|  | @ -31,6 +31,7 @@ | |||
| #include <LibJS/Runtime/Date.h> | ||||
| #include <LibJS/Runtime/DatePrototype.h> | ||||
| #include <LibJS/Runtime/Error.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <LibJS/Runtime/Value.h> | ||||
| 
 | ||||
| namespace JS { | ||||
|  | @ -48,7 +49,7 @@ static Date* this_date_from_interpreter(Interpreter& interpreter) | |||
| } | ||||
| 
 | ||||
| DatePrototype::DatePrototype() | ||||
|     : Object(interpreter().object_prototype()) | ||||
|     : Object(interpreter().global_object().object_prototype()) | ||||
| { | ||||
|     put_native_function("getDate", get_date); | ||||
|     put_native_function("getDay", get_day); | ||||
|  |  | |||
|  | @ -33,7 +33,7 @@ namespace JS { | |||
| Error* Error::create(GlobalObject& global_object, const FlyString& name, const String& message) | ||||
| { | ||||
|     auto& interpreter = global_object.interpreter(); | ||||
|     return interpreter.heap().allocate<Error>(name, message, *interpreter.error_prototype()); | ||||
|     return interpreter.heap().allocate<Error>(name, message, *global_object.error_prototype()); | ||||
| } | ||||
| 
 | ||||
| Error::Error(const FlyString& name, const String& message, Object& prototype) | ||||
|  | @ -51,8 +51,7 @@ Error::~Error() | |||
| #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName)                          \ | ||||
|     ClassName* ClassName::create(GlobalObject& global_object, const String& message)                   \ | ||||
|     {                                                                                                  \ | ||||
|         auto& interpreter = global_object.interpreter();                                               \ | ||||
|         return interpreter.heap().allocate<ClassName>(message, *interpreter.snake_name##_prototype()); \ | ||||
|         return global_object.heap().allocate<ClassName>(message, *global_object.snake_name##_prototype()); \ | ||||
|     }                                                                                                  \ | ||||
|     ClassName::ClassName(const String& message, Object& prototype)                                     \ | ||||
|         : Error(#ClassName, message, prototype)                                                        \ | ||||
|  |  | |||
|  | @ -27,13 +27,14 @@ | |||
| #include <LibJS/Interpreter.h> | ||||
| #include <LibJS/Runtime/Error.h> | ||||
| #include <LibJS/Runtime/ErrorConstructor.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| 
 | ||||
| namespace JS { | ||||
| 
 | ||||
| ErrorConstructor::ErrorConstructor() | ||||
|     : NativeFunction("Error", *interpreter().function_prototype()) | ||||
|     : NativeFunction("Error", *interpreter().global_object().function_prototype()) | ||||
| { | ||||
|     put("prototype", interpreter().error_prototype()); | ||||
|     put("prototype", interpreter().global_object().error_prototype()); | ||||
|     put("length", Value(1)); | ||||
| } | ||||
| 
 | ||||
|  | @ -56,9 +57,9 @@ Value ErrorConstructor::construct(Interpreter& interpreter) | |||
| 
 | ||||
| #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName)                                        \ | ||||
|     ConstructorName::ConstructorName()                                                                               \ | ||||
|         : NativeFunction(*interpreter().function_prototype())                                                        \ | ||||
|         : NativeFunction(*interpreter().global_object().function_prototype())                                        \ | ||||
|     {                                                                                                                \ | ||||
|         put("prototype", interpreter().snake_name##_prototype());                                                    \ | ||||
|         put("prototype", interpreter().global_object().snake_name##_prototype());                                    \ | ||||
|         put("length", Value(1));                                                                                     \ | ||||
|     }                                                                                                                \ | ||||
|     ConstructorName::~ConstructorName() {}                                                                           \ | ||||
|  |  | |||
|  | @ -29,13 +29,14 @@ | |||
| #include <LibJS/Interpreter.h> | ||||
| #include <LibJS/Runtime/Error.h> | ||||
| #include <LibJS/Runtime/ErrorPrototype.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <LibJS/Runtime/PrimitiveString.h> | ||||
| #include <LibJS/Runtime/Value.h> | ||||
| 
 | ||||
| namespace JS { | ||||
| 
 | ||||
| ErrorPrototype::ErrorPrototype() | ||||
|     : Object(interpreter().object_prototype()) | ||||
|     : Object(interpreter().global_object().object_prototype()) | ||||
| { | ||||
|     put_native_property("name", name_getter, name_setter); | ||||
|     put_native_property("message", message_getter, nullptr); | ||||
|  | @ -104,7 +105,7 @@ Value ErrorPrototype::to_string(Interpreter& interpreter) | |||
| 
 | ||||
| #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ | ||||
|     PrototypeName::PrototypeName()                                            \ | ||||
|         : Object(interpreter().error_prototype())                             \ | ||||
|         : Object(interpreter().global_object().error_prototype())             \ | ||||
|     {                                                                         \ | ||||
|     }                                                                         \ | ||||
|     PrototypeName::~PrototypeName() {}                                        \ | ||||
|  |  | |||
|  | @ -30,14 +30,15 @@ | |||
| #include <LibJS/Parser.h> | ||||
| #include <LibJS/Runtime/Error.h> | ||||
| #include <LibJS/Runtime/FunctionConstructor.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <LibJS/Runtime/ScriptFunction.h> | ||||
| 
 | ||||
| namespace JS { | ||||
| 
 | ||||
| FunctionConstructor::FunctionConstructor() | ||||
|     : NativeFunction("Function", *interpreter().function_prototype()) | ||||
|     : NativeFunction("Function", *interpreter().global_object().function_prototype()) | ||||
| { | ||||
|     put("prototype", interpreter().function_prototype()); | ||||
|     put("prototype", interpreter().global_object().function_prototype()); | ||||
|     put("length", Value(1)); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -31,12 +31,13 @@ | |||
| #include <LibJS/Runtime/Error.h> | ||||
| #include <LibJS/Runtime/Function.h> | ||||
| #include <LibJS/Runtime/FunctionPrototype.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <LibJS/Runtime/ScriptFunction.h> | ||||
| 
 | ||||
| namespace JS { | ||||
| 
 | ||||
| FunctionPrototype::FunctionPrototype() | ||||
|     : Object(interpreter().object_prototype()) | ||||
|     : Object(interpreter().global_object().object_prototype()) | ||||
| { | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -29,17 +29,29 @@ | |||
| #include <LibJS/Heap/Heap.h> | ||||
| #include <LibJS/Interpreter.h> | ||||
| #include <LibJS/Runtime/ArrayConstructor.h> | ||||
| #include <LibJS/Runtime/ArrayPrototype.h> | ||||
| #include <LibJS/Runtime/BooleanConstructor.h> | ||||
| #include <LibJS/Runtime/BooleanPrototype.h> | ||||
| #include <LibJS/Runtime/ConsoleObject.h> | ||||
| #include <LibJS/Runtime/DateConstructor.h> | ||||
| #include <LibJS/Runtime/DatePrototype.h> | ||||
| #include <LibJS/Runtime/Error.h> | ||||
| #include <LibJS/Runtime/ErrorConstructor.h> | ||||
| #include <LibJS/Runtime/ErrorPrototype.h> | ||||
| #include <LibJS/Runtime/FunctionConstructor.h> | ||||
| #include <LibJS/Runtime/FunctionPrototype.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <LibJS/Runtime/LexicalEnvironment.h> | ||||
| #include <LibJS/Runtime/MathObject.h> | ||||
| #include <LibJS/Runtime/NativeFunction.h> | ||||
| #include <LibJS/Runtime/NumberConstructor.h> | ||||
| #include <LibJS/Runtime/NumberPrototype.h> | ||||
| #include <LibJS/Runtime/Object.h> | ||||
| #include <LibJS/Runtime/ObjectConstructor.h> | ||||
| #include <LibJS/Runtime/ObjectPrototype.h> | ||||
| #include <LibJS/Runtime/Shape.h> | ||||
| #include <LibJS/Runtime/StringConstructor.h> | ||||
| #include <LibJS/Runtime/StringPrototype.h> | ||||
| #include <LibJS/Runtime/Value.h> | ||||
| 
 | ||||
| namespace JS { | ||||
|  | @ -53,8 +65,25 @@ void GlobalObject::add_constructor(const FlyString& property_name, ConstructorTy | |||
| } | ||||
| 
 | ||||
| GlobalObject::GlobalObject() | ||||
|     : Object(interpreter().object_prototype()) | ||||
|     : Object(nullptr) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void GlobalObject::initialize() | ||||
| { | ||||
|     // These are done first since other prototypes depend on their presence.
 | ||||
|     m_object_prototype = heap().allocate<ObjectPrototype>(); | ||||
|     m_function_prototype = heap().allocate<FunctionPrototype>(); | ||||
| 
 | ||||
|     static_cast<FunctionPrototype*>(m_function_prototype)->initialize(); | ||||
|     static_cast<ObjectPrototype*>(m_object_prototype)->initialize(); | ||||
| 
 | ||||
| #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ | ||||
|     if (!m_##snake_name##_prototype)                                          \ | ||||
|         m_##snake_name##_prototype = heap().allocate<PrototypeName>(); | ||||
|     JS_ENUMERATE_BUILTIN_TYPES | ||||
| #undef __JS_ENUMERATE | ||||
| 
 | ||||
|     put_native_function("gc", gc); | ||||
|     put_native_function("isNaN", is_nan, 1); | ||||
| 
 | ||||
|  | @ -67,17 +96,17 @@ GlobalObject::GlobalObject() | |||
|     put("console", heap().allocate<ConsoleObject>()); | ||||
|     put("Math", heap().allocate<MathObject>()); | ||||
| 
 | ||||
|     add_constructor("Array", m_array_constructor, *interpreter().array_prototype()); | ||||
|     add_constructor("Boolean", m_boolean_constructor, *interpreter().boolean_prototype()); | ||||
|     add_constructor("Date", m_date_constructor, *interpreter().date_prototype()); | ||||
|     add_constructor("Error", m_error_constructor, *interpreter().error_prototype()); | ||||
|     add_constructor("Function", m_function_constructor, *interpreter().function_prototype()); | ||||
|     add_constructor("Number", m_number_constructor, *interpreter().number_prototype()); | ||||
|     add_constructor("Object", m_object_constructor, *interpreter().object_prototype()); | ||||
|     add_constructor("String", m_string_constructor, *interpreter().string_prototype()); | ||||
|     add_constructor("Array", m_array_constructor, *m_array_prototype); | ||||
|     add_constructor("Boolean", m_boolean_constructor, *m_boolean_prototype); | ||||
|     add_constructor("Date", m_date_constructor, *m_date_prototype); | ||||
|     add_constructor("Error", m_error_constructor, *m_error_prototype); | ||||
|     add_constructor("Function", m_function_constructor, *m_function_prototype); | ||||
|     add_constructor("Number", m_number_constructor, *m_number_prototype); | ||||
|     add_constructor("Object", m_object_constructor, *m_object_prototype); | ||||
|     add_constructor("String", m_string_constructor, *m_string_prototype); | ||||
| 
 | ||||
| #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ | ||||
|     add_constructor(#ClassName, m_##snake_name##_constructor, *interpreter().snake_name##_prototype()); | ||||
|     add_constructor(#ClassName, m_##snake_name##_constructor, *m_##snake_name##_prototype); | ||||
|     JS_ENUMERATE_ERROR_SUBCLASSES | ||||
| #undef __JS_ENUMERATE | ||||
| } | ||||
|  |  | |||
|  | @ -33,10 +33,13 @@ namespace JS { | |||
| class GlobalObject : public Object { | ||||
| public: | ||||
|     explicit GlobalObject(); | ||||
|     virtual void initialize(); | ||||
| 
 | ||||
|     virtual ~GlobalObject() override; | ||||
| 
 | ||||
| #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ | ||||
|     ConstructorName* snake_name##_constructor() { return m_##snake_name##_constructor; } | ||||
| #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName)            \ | ||||
|     ConstructorName* snake_name##_constructor() { return m_##snake_name##_constructor; } \ | ||||
|     Object* snake_name##_prototype() { return m_##snake_name##_prototype; } | ||||
|     JS_ENUMERATE_BUILTIN_TYPES | ||||
| #undef __JS_ENUMERATE | ||||
| 
 | ||||
|  | @ -53,7 +56,8 @@ private: | |||
|     void add_constructor(const FlyString& property_name, ConstructorType*&, Object& prototype); | ||||
| 
 | ||||
| #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \ | ||||
|     ConstructorName* m_##snake_name##_constructor { nullptr }; | ||||
|     ConstructorName* m_##snake_name##_constructor { nullptr };                \ | ||||
|     Object* m_##snake_name##_prototype { nullptr }; | ||||
|     JS_ENUMERATE_BUILTIN_TYPES | ||||
| #undef __JS_ENUMERATE | ||||
| }; | ||||
|  |  | |||
|  | @ -27,13 +27,14 @@ | |||
| #include <AK/FlyString.h> | ||||
| #include <AK/Function.h> | ||||
| #include <LibJS/Interpreter.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <LibJS/Runtime/MathObject.h> | ||||
| #include <math.h> | ||||
| 
 | ||||
| namespace JS { | ||||
| 
 | ||||
| MathObject::MathObject() | ||||
|     : Object(interpreter().object_prototype()) | ||||
|     : Object(interpreter().global_object().object_prototype()) | ||||
| { | ||||
|     put_native_function("abs", abs, 1); | ||||
|     put_native_function("random", random); | ||||
|  |  | |||
|  | @ -31,9 +31,9 @@ | |||
| 
 | ||||
| namespace JS { | ||||
| 
 | ||||
| NativeFunction* NativeFunction::create(Interpreter& interpreter, GlobalObject&, const FlyString& name, AK::Function<Value(Interpreter&)> function) | ||||
| NativeFunction* NativeFunction::create(Interpreter&, GlobalObject& global_object, const FlyString& name, AK::Function<Value(Interpreter&)> function) | ||||
| { | ||||
|     return interpreter.heap().allocate<NativeFunction>(name, move(function), *interpreter.function_prototype()); | ||||
|     return global_object.heap().allocate<NativeFunction>(name, move(function), *global_object.function_prototype()); | ||||
| } | ||||
| 
 | ||||
| NativeFunction::NativeFunction(Object& prototype) | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ | |||
| 
 | ||||
| #include <LibJS/Interpreter.h> | ||||
| #include <LibJS/Runtime/Error.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <LibJS/Runtime/NumberConstructor.h> | ||||
| #include <LibJS/Runtime/NumberObject.h> | ||||
| #include <math.h> | ||||
|  | @ -37,11 +38,11 @@ | |||
| namespace JS { | ||||
| 
 | ||||
| NumberConstructor::NumberConstructor() | ||||
|     : NativeFunction("Number", *interpreter().function_prototype()) | ||||
|     : NativeFunction("Number", *interpreter().global_object().function_prototype()) | ||||
| { | ||||
|     put_native_function("isSafeInteger", is_safe_integer, 1); | ||||
| 
 | ||||
|     put("prototype", interpreter().number_prototype()); | ||||
|     put("prototype", interpreter().global_object().number_prototype()); | ||||
|     put("length", Value(1)); | ||||
|     put("EPSILON", Value(EPSILON)); | ||||
|     put("MAX_SAFE_INTEGER", Value(MAX_SAFE_INTEGER)); | ||||
|  |  | |||
|  | @ -35,8 +35,7 @@ namespace JS { | |||
| 
 | ||||
| NumberObject* NumberObject::create(GlobalObject& global_object, double value) | ||||
| { | ||||
|     auto& interpreter = global_object.interpreter(); | ||||
|     return interpreter.heap().allocate<NumberObject>(value, *interpreter.number_prototype()); | ||||
|     return global_object.heap().allocate<NumberObject>(value, *global_object.number_prototype()); | ||||
| } | ||||
| 
 | ||||
| NumberObject::NumberObject(double value, Object& prototype) | ||||
|  |  | |||
|  | @ -25,12 +25,13 @@ | |||
|  */ | ||||
| 
 | ||||
| #include <LibJS/Interpreter.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <LibJS/Runtime/NumberPrototype.h> | ||||
| 
 | ||||
| namespace JS { | ||||
| 
 | ||||
| NumberPrototype::NumberPrototype() | ||||
|     : NumberObject(0, *interpreter().object_prototype()) | ||||
|     : NumberObject(0, *interpreter().global_object().object_prototype()) | ||||
| { | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -38,9 +38,9 @@ | |||
| 
 | ||||
| namespace JS { | ||||
| 
 | ||||
| Object* Object::create_empty(Interpreter& interpreter, GlobalObject&) | ||||
| Object* Object::create_empty(Interpreter&, GlobalObject& global_object) | ||||
| { | ||||
|     return interpreter.heap().allocate<Object>(interpreter.object_prototype()); | ||||
|     return global_object.heap().allocate<Object>(global_object.object_prototype()); | ||||
| } | ||||
| 
 | ||||
| Object::Object(Object* prototype) | ||||
|  |  | |||
|  | @ -29,15 +29,16 @@ | |||
| #include <LibJS/Interpreter.h> | ||||
| #include <LibJS/Runtime/Array.h> | ||||
| #include <LibJS/Runtime/Error.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <LibJS/Runtime/ObjectConstructor.h> | ||||
| #include <LibJS/Runtime/Shape.h> | ||||
| 
 | ||||
| namespace JS { | ||||
| 
 | ||||
| ObjectConstructor::ObjectConstructor() | ||||
|     : NativeFunction("Object", *interpreter().function_prototype()) | ||||
|     : NativeFunction("Object", *interpreter().global_object().function_prototype()) | ||||
| { | ||||
|     put("prototype", interpreter().object_prototype()); | ||||
|     put("prototype", interpreter().global_object().object_prototype()); | ||||
| 
 | ||||
|     put_native_function("defineProperty", define_property, 3); | ||||
|     put_native_function("getOwnPropertyDescriptor", get_own_property_descriptor, 2); | ||||
|  |  | |||
|  | @ -36,8 +36,7 @@ namespace JS { | |||
| 
 | ||||
| ScriptFunction* ScriptFunction::create(GlobalObject& global_object, const FlyString& name, const Statement& body, Vector<FlyString> parameters, LexicalEnvironment* parent_environment) | ||||
| { | ||||
|     auto& interpreter = global_object.interpreter(); | ||||
|     return interpreter.heap().allocate<ScriptFunction>(name, body, move(parameters), parent_environment, *interpreter.function_prototype()); | ||||
|     return global_object.heap().allocate<ScriptFunction>(name, body, move(parameters), parent_environment, *global_object.function_prototype()); | ||||
| } | ||||
| 
 | ||||
| ScriptFunction::ScriptFunction(const FlyString& name, const Statement& body, Vector<FlyString> parameters, LexicalEnvironment* parent_environment, Object& prototype) | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ | |||
| 
 | ||||
| #include <LibJS/Interpreter.h> | ||||
| #include <LibJS/Runtime/Error.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <LibJS/Runtime/StringConstructor.h> | ||||
| #include <LibJS/Runtime/StringObject.h> | ||||
| #include <math.h> | ||||
|  | @ -33,9 +34,9 @@ | |||
| namespace JS { | ||||
| 
 | ||||
| StringConstructor::StringConstructor() | ||||
|     : NativeFunction("String", *interpreter().function_prototype()) | ||||
|     : NativeFunction("String", *interpreter().global_object().function_prototype()) | ||||
| { | ||||
|     put("prototype", interpreter().string_prototype()); | ||||
|     put("prototype", interpreter().global_object().string_prototype()); | ||||
|     put("length", Value(1)); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -36,8 +36,7 @@ namespace JS { | |||
| 
 | ||||
| StringObject* StringObject::create(GlobalObject& global_object, PrimitiveString& primitive_string) | ||||
| { | ||||
|     auto& interpreter = global_object.interpreter(); | ||||
|     return interpreter.heap().allocate<StringObject>(primitive_string, *interpreter.string_prototype()); | ||||
|     return global_object.heap().allocate<StringObject>(primitive_string, *global_object.string_prototype()); | ||||
| } | ||||
| 
 | ||||
| StringObject::StringObject(PrimitiveString& string, Object& prototype) | ||||
|  |  | |||
|  | @ -29,6 +29,7 @@ | |||
| #include <LibJS/Heap/Heap.h> | ||||
| #include <LibJS/Interpreter.h> | ||||
| #include <LibJS/Runtime/Error.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <LibJS/Runtime/PrimitiveString.h> | ||||
| #include <LibJS/Runtime/StringObject.h> | ||||
| #include <LibJS/Runtime/StringPrototype.h> | ||||
|  | @ -38,7 +39,7 @@ | |||
| namespace JS { | ||||
| 
 | ||||
| StringPrototype::StringPrototype() | ||||
|     : StringObject(*js_string(interpreter(), String::empty()), *interpreter().object_prototype()) | ||||
|     : StringObject(*js_string(interpreter(), String::empty()), *interpreter().global_object().object_prototype()) | ||||
| { | ||||
|     put_native_property("length", length_getter, nullptr); | ||||
|     put_native_function("charAt", char_at, 1); | ||||
|  |  | |||
|  | @ -28,6 +28,7 @@ | |||
| #include <AK/Function.h> | ||||
| #include <LibJS/Interpreter.h> | ||||
| #include <LibJS/Runtime/Error.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <LibJS/Runtime/PrimitiveString.h> | ||||
| #include <LibJS/Runtime/Value.h> | ||||
| #include <LibWeb/Bindings/CanvasRenderingContext2DWrapper.h> | ||||
|  | @ -44,7 +45,7 @@ CanvasRenderingContext2DWrapper* wrap(JS::Heap& heap, CanvasRenderingContext2D& | |||
| } | ||||
| 
 | ||||
| CanvasRenderingContext2DWrapper::CanvasRenderingContext2DWrapper(CanvasRenderingContext2D& impl) | ||||
|     : Wrapper(*interpreter().object_prototype()) | ||||
|     : Wrapper(*interpreter().global_object().object_prototype()) | ||||
|     , m_impl(impl) | ||||
| { | ||||
|     put_native_property("fillStyle", fill_style_getter, fill_style_setter); | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ | |||
| 
 | ||||
| #include <LibJS/Interpreter.h> | ||||
| #include <LibJS/Runtime/Function.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <LibWeb/Bindings/EventListenerWrapper.h> | ||||
| #include <LibWeb/DOM/EventListener.h> | ||||
| 
 | ||||
|  | @ -33,7 +34,7 @@ namespace Web { | |||
| namespace Bindings { | ||||
| 
 | ||||
| EventListenerWrapper::EventListenerWrapper(EventListener& impl) | ||||
|     : Wrapper(*interpreter().object_prototype()) | ||||
|     : Wrapper(*interpreter().global_object().object_prototype()) | ||||
|     , m_impl(impl) | ||||
| { | ||||
| } | ||||
|  |  | |||
|  | @ -28,6 +28,7 @@ | |||
| #include <AK/Function.h> | ||||
| #include <LibJS/Interpreter.h> | ||||
| #include <LibJS/Runtime/Function.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <LibWeb/Bindings/EventListenerWrapper.h> | ||||
| #include <LibWeb/Bindings/EventTargetWrapper.h> | ||||
| #include <LibWeb/DOM/EventListener.h> | ||||
|  | @ -37,7 +38,7 @@ namespace Web { | |||
| namespace Bindings { | ||||
| 
 | ||||
| EventTargetWrapper::EventTargetWrapper(EventTarget& impl) | ||||
|     : Wrapper(*interpreter().object_prototype()) | ||||
|     : Wrapper(*interpreter().global_object().object_prototype()) | ||||
|     , m_impl(impl) | ||||
| { | ||||
|     put_native_function("addEventListener", add_event_listener, 2); | ||||
|  |  | |||
|  | @ -25,6 +25,7 @@ | |||
|  */ | ||||
| 
 | ||||
| #include <LibJS/Interpreter.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <LibWeb/Bindings/EventWrapper.h> | ||||
| #include <LibWeb/Bindings/MouseEventWrapper.h> | ||||
| #include <LibWeb/DOM/MouseEvent.h> | ||||
|  | @ -40,7 +41,7 @@ EventWrapper* wrap(JS::Heap& heap, Event& event) | |||
| } | ||||
| 
 | ||||
| EventWrapper::EventWrapper(Event& event) | ||||
|     : Wrapper(*interpreter().object_prototype()) | ||||
|     : Wrapper(*interpreter().global_object().object_prototype()) | ||||
|     , m_event(event) | ||||
| { | ||||
| } | ||||
|  |  | |||
|  | @ -26,13 +26,14 @@ | |||
| 
 | ||||
| #include <AK/FlyString.h> | ||||
| #include <LibJS/Interpreter.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <LibWeb/Bindings/NavigatorObject.h> | ||||
| 
 | ||||
| namespace Web { | ||||
| namespace Bindings { | ||||
| 
 | ||||
| NavigatorObject::NavigatorObject() | ||||
|     : Object(interpreter().object_prototype()) | ||||
|     : Object(interpreter().global_object().object_prototype()) | ||||
| { | ||||
|     put("appCodeName", js_string(heap(), "Mozilla")); | ||||
|     put("appName", js_string(heap(), "Netscape")); | ||||
|  |  | |||
|  | @ -43,6 +43,12 @@ namespace Bindings { | |||
| WindowObject::WindowObject(Window& impl) | ||||
|     : m_impl(impl) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void WindowObject::initialize() | ||||
| { | ||||
|     GlobalObject::initialize(); | ||||
| 
 | ||||
|     put("window", this); | ||||
|     put_native_property("document", document_getter, document_setter); | ||||
|     put_native_function("alert", alert); | ||||
|  |  | |||
|  | @ -35,6 +35,7 @@ namespace Bindings { | |||
| class WindowObject final : public JS::GlobalObject { | ||||
| public: | ||||
|     explicit WindowObject(Window&); | ||||
|     virtual void initialize() override; | ||||
|     virtual ~WindowObject() override; | ||||
| 
 | ||||
|     Window& impl() { return *m_impl; } | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ | |||
| 
 | ||||
| #include <LibJS/Heap/Heap.h> | ||||
| #include <LibJS/Interpreter.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <LibWeb/Bindings/WindowObject.h> | ||||
| #include <LibWeb/Bindings/XMLHttpRequestConstructor.h> | ||||
| #include <LibWeb/Bindings/XMLHttpRequestWrapper.h> | ||||
|  | @ -35,7 +36,7 @@ namespace Web { | |||
| namespace Bindings { | ||||
| 
 | ||||
| XMLHttpRequestConstructor::XMLHttpRequestConstructor() | ||||
|     : NativeFunction(*interpreter().function_prototype()) | ||||
|     : NativeFunction(*interpreter().global_object().function_prototype()) | ||||
| { | ||||
|     put("length", JS::Value(1)); | ||||
| } | ||||
|  |  | |||
|  | @ -27,6 +27,7 @@ | |||
| #include <AK/Function.h> | ||||
| #include <LibJS/Interpreter.h> | ||||
| #include <LibJS/Runtime/Error.h> | ||||
| #include <LibJS/Runtime/GlobalObject.h> | ||||
| #include <LibWeb/Bindings/XMLHttpRequestPrototype.h> | ||||
| #include <LibWeb/Bindings/XMLHttpRequestWrapper.h> | ||||
| #include <LibWeb/DOM/XMLHttpRequest.h> | ||||
|  | @ -35,7 +36,7 @@ namespace Web { | |||
| namespace Bindings { | ||||
| 
 | ||||
| XMLHttpRequestPrototype::XMLHttpRequestPrototype() | ||||
|     : Object(interpreter().object_prototype()) | ||||
|     : Object(interpreter().global_object().object_prototype()) | ||||
| { | ||||
|     put_native_function("open", open, 2); | ||||
|     put_native_function("send", send, 0); | ||||
|  |  | |||
|  | @ -50,6 +50,7 @@ Vector<String> repl_statements; | |||
| class ReplObject : public JS::GlobalObject { | ||||
| public: | ||||
|     ReplObject(); | ||||
|     virtual void initialize() override; | ||||
|     virtual ~ReplObject() override; | ||||
| 
 | ||||
|     static JS::Value load_file(JS::Interpreter&); | ||||
|  | @ -270,6 +271,11 @@ bool write_to_file(const StringView& path) | |||
| 
 | ||||
| ReplObject::ReplObject() | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void ReplObject::initialize() | ||||
| { | ||||
|     GlobalObject::initialize(); | ||||
|     put_native_function("exit", exit_interpreter); | ||||
|     put_native_function("help", repl_help); | ||||
|     put_native_function("load", load_file, 1); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling