Bläddra i källkod

LibJS+LibWeb: Wrap raw JS::Cell*/& fields in GCPtr/NonnullGCPtr

Matthew Olsson 2 år sedan
förälder
incheckning
7c0c1c8f49
100 ändrade filer med 361 tillägg och 362 borttagningar
  1. 2 2
      Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp
  2. 16 16
      Userland/Libraries/LibJS/AST.cpp
  3. 1 1
      Userland/Libraries/LibJS/AST.h
  4. 5 5
      Userland/Libraries/LibJS/Bytecode/Interpreter.cpp
  5. 3 3
      Userland/Libraries/LibJS/Bytecode/Interpreter.h
  6. 2 2
      Userland/Libraries/LibJS/Bytecode/Op.cpp
  7. 1 1
      Userland/Libraries/LibJS/Console.h
  8. 2 2
      Userland/Libraries/LibJS/Contrib/Test262/$262Object.h
  9. 1 1
      Userland/Libraries/LibJS/Contrib/Test262/GlobalObject.h
  10. 4 5
      Userland/Libraries/LibJS/CyclicModule.cpp
  11. 11 11
      Userland/Libraries/LibJS/CyclicModule.h
  12. 1 1
      Userland/Libraries/LibJS/Heap/Handle.h
  13. 1 1
      Userland/Libraries/LibJS/Heap/Heap.h
  14. 2 2
      Userland/Libraries/LibJS/Heap/HeapBlock.h
  15. 1 1
      Userland/Libraries/LibJS/Module.h
  16. 1 1
      Userland/Libraries/LibJS/Print.cpp
  17. 2 2
      Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp
  18. 2 2
      Userland/Libraries/LibJS/Runtime/Accessor.h
  19. 1 1
      Userland/Libraries/LibJS/Runtime/ArgumentsObject.cpp
  20. 2 2
      Userland/Libraries/LibJS/Runtime/ArgumentsObject.h
  21. 2 2
      Userland/Libraries/LibJS/Runtime/AsyncFromSyncIteratorPrototype.cpp
  22. 1 1
      Userland/Libraries/LibJS/Runtime/BigIntObject.cpp
  23. 1 1
      Userland/Libraries/LibJS/Runtime/BigIntObject.h
  24. 3 3
      Userland/Libraries/LibJS/Runtime/BoundFunction.h
  25. 1 1
      Userland/Libraries/LibJS/Runtime/DataView.h
  26. 12 12
      Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp
  27. 4 4
      Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h
  28. 1 1
      Userland/Libraries/LibJS/Runtime/Environment.h
  29. 1 1
      Userland/Libraries/LibJS/Runtime/Error.cpp
  30. 7 7
      Userland/Libraries/LibJS/Runtime/ExecutionContext.h
  31. 2 2
      Userland/Libraries/LibJS/Runtime/FinalizationRegistry.h
  32. 1 1
      Userland/Libraries/LibJS/Runtime/FunctionEnvironment.h
  33. 1 1
      Userland/Libraries/LibJS/Runtime/GeneratorObject.h
  34. 4 4
      Userland/Libraries/LibJS/Runtime/GlobalEnvironment.h
  35. 8 8
      Userland/Libraries/LibJS/Runtime/Intl/Collator.h
  36. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/CollatorCompareFunction.cpp
  37. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/CollatorCompareFunction.h
  38. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.h
  39. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormatFunction.cpp
  40. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormatFunction.h
  41. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.h
  42. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/NumberFormatFunction.cpp
  43. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/NumberFormatFunction.h
  44. 2 2
      Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.h
  45. 2 2
      Userland/Libraries/LibJS/Runtime/Intl/SegmentIterator.cpp
  46. 2 2
      Userland/Libraries/LibJS/Runtime/Intl/SegmentIterator.h
  47. 1 1
      Userland/Libraries/LibJS/Runtime/Intl/Segments.cpp
  48. 2 2
      Userland/Libraries/LibJS/Runtime/Intl/Segments.h
  49. 2 2
      Userland/Libraries/LibJS/Runtime/Intrinsics.cpp
  50. 35 35
      Userland/Libraries/LibJS/Runtime/Intrinsics.h
  51. 3 3
      Userland/Libraries/LibJS/Runtime/Iterator.h
  52. 1 1
      Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp
  53. 2 2
      Userland/Libraries/LibJS/Runtime/JSONObject.h
  54. 10 10
      Userland/Libraries/LibJS/Runtime/Map.h
  55. 1 1
      Userland/Libraries/LibJS/Runtime/MapIterator.cpp
  56. 1 1
      Userland/Libraries/LibJS/Runtime/MapIterator.h
  57. 1 1
      Userland/Libraries/LibJS/Runtime/ModuleEnvironment.h
  58. 1 1
      Userland/Libraries/LibJS/Runtime/ModuleNamespaceObject.cpp
  59. 1 1
      Userland/Libraries/LibJS/Runtime/ModuleNamespaceObject.h
  60. 2 2
      Userland/Libraries/LibJS/Runtime/NativeFunction.cpp
  61. 1 1
      Userland/Libraries/LibJS/Runtime/NativeFunction.h
  62. 3 3
      Userland/Libraries/LibJS/Runtime/Object.cpp
  63. 1 1
      Userland/Libraries/LibJS/Runtime/Object.h
  64. 12 12
      Userland/Libraries/LibJS/Runtime/ObjectEnvironment.cpp
  65. 2 2
      Userland/Libraries/LibJS/Runtime/ObjectEnvironment.h
  66. 2 2
      Userland/Libraries/LibJS/Runtime/PrimitiveString.h
  67. 2 2
      Userland/Libraries/LibJS/Runtime/PrivateEnvironment.h
  68. 4 4
      Userland/Libraries/LibJS/Runtime/Promise.cpp
  69. 7 7
      Userland/Libraries/LibJS/Runtime/Promise.h
  70. 2 2
      Userland/Libraries/LibJS/Runtime/PromiseConstructor.cpp
  71. 3 3
      Userland/Libraries/LibJS/Runtime/PromiseJobs.cpp
  72. 1 1
      Userland/Libraries/LibJS/Runtime/PromiseJobs.h
  73. 14 14
      Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.cpp
  74. 2 2
      Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.h
  75. 2 2
      Userland/Libraries/LibJS/Runtime/PromiseResolvingFunction.cpp
  76. 2 2
      Userland/Libraries/LibJS/Runtime/PromiseResolvingFunction.h
  77. 4 4
      Userland/Libraries/LibJS/Runtime/PropertyDescriptor.h
  78. 63 63
      Userland/Libraries/LibJS/Runtime/ProxyObject.cpp
  79. 3 3
      Userland/Libraries/LibJS/Runtime/ProxyObject.h
  80. 4 4
      Userland/Libraries/LibJS/Runtime/Realm.h
  81. 1 1
      Userland/Libraries/LibJS/Runtime/Reference.cpp
  82. 1 1
      Userland/Libraries/LibJS/Runtime/RegExpStringIterator.cpp
  83. 1 1
      Userland/Libraries/LibJS/Runtime/RegExpStringIterator.h
  84. 1 1
      Userland/Libraries/LibJS/Runtime/SetIterator.cpp
  85. 1 1
      Userland/Libraries/LibJS/Runtime/SetIterator.h
  86. 2 2
      Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp
  87. 1 1
      Userland/Libraries/LibJS/Runtime/ShadowRealm.h
  88. 3 3
      Userland/Libraries/LibJS/Runtime/Shape.cpp
  89. 4 4
      Userland/Libraries/LibJS/Runtime/Shape.h
  90. 3 3
      Userland/Libraries/LibJS/Runtime/StringObject.cpp
  91. 1 1
      Userland/Libraries/LibJS/Runtime/StringObject.h
  92. 1 1
      Userland/Libraries/LibJS/Runtime/SymbolObject.cpp
  93. 1 1
      Userland/Libraries/LibJS/Runtime/SymbolObject.h
  94. 1 1
      Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.h
  95. 1 1
      Userland/Libraries/LibJS/Runtime/Temporal/Instant.cpp
  96. 1 1
      Userland/Libraries/LibJS/Runtime/Temporal/Instant.h
  97. 1 1
      Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp
  98. 4 4
      Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.h
  99. 1 1
      Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp
  100. 10 10
      Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.h

+ 2 - 2
Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp

@@ -1706,12 +1706,12 @@ static void generate_wrap_statement(SourceGenerator& generator, DeprecatedString
   if (!@value@) {
       @result_expression@ JS::js_null();
   } else {
-      @result_expression@ &@value@->callback;
+      @result_expression@ @value@->callback;
   }
 )~~~");
         } else {
             scoped_generator.append(R"~~~(
-  @result_expression@ &@value@->callback;
+  @result_expression@ @value@->callback;
 )~~~");
         }
     } else if (interface.dictionaries.contains(type.name())) {

+ 16 - 16
Userland/Libraries/LibJS/AST.cpp

@@ -273,10 +273,10 @@ Completion FunctionDeclaration::execute(Interpreter& interpreter) const
         // Perform special annexB steps see step 3 of: https://tc39.es/ecma262/#sec-web-compat-functiondeclarationinstantiation
 
         // i. Let genv be the running execution context's VariableEnvironment.
-        auto* variable_environment = interpreter.vm().running_execution_context().variable_environment;
+        auto variable_environment = interpreter.vm().running_execution_context().variable_environment;
 
         // ii. Let benv be the running execution context's LexicalEnvironment.
-        auto* lexical_environment = interpreter.vm().running_execution_context().lexical_environment;
+        auto lexical_environment = interpreter.vm().running_execution_context().lexical_environment;
 
         // iii. Let fobj be ! benv.GetBindingValue(F, false).
         auto function_object = MUST(lexical_environment->get_binding_value(vm, name(), false));
@@ -319,7 +319,7 @@ Value FunctionExpression::instantiate_ordinary_function_expression(Interpreter&
         MUST(environment->create_immutable_binding(vm, name(), false));
     }
 
-    auto* private_environment = vm.running_execution_context().private_environment;
+    auto private_environment = vm.running_execution_context().private_environment;
 
     auto closure = ECMAScriptFunctionObject::create(realm, used_name, source_text(), body(), parameters(), function_length(), environment, private_environment, kind(), is_strict_mode(), might_need_arguments_object(), contains_direct_call_to_eval(), is_arrow_function());
 
@@ -622,7 +622,7 @@ Completion WithStatement::execute(Interpreter& interpreter) const
     auto* object = TRY(value.to_object(vm));
 
     // 3. Let oldEnv be the running execution context's LexicalEnvironment.
-    auto* old_environment = vm.running_execution_context().lexical_environment;
+    auto old_environment = vm.running_execution_context().lexical_environment;
 
     // 4. Let newEnv be NewObjectEnvironment(obj, true, oldEnv).
     auto new_environment = new_object_environment(*object, true, old_environment);
@@ -1096,7 +1096,7 @@ static ThrowCompletionOr<ForInOfHeadState> for_in_of_head_execute(Interpreter& i
 
         if (new_environment) {
             // 2.d Set the running execution context's LexicalEnvironment to newEnv.
-            TemporaryChange<Environment*> scope_change(interpreter.vm().running_execution_context().lexical_environment, new_environment);
+            TemporaryChange<GCPtr<Environment>> scope_change(interpreter.vm().running_execution_context().lexical_environment, new_environment);
 
             // 3. Let exprRef be the result of evaluating expr.
             // 5. Let exprValue be ? GetValue(exprRef).
@@ -1177,9 +1177,9 @@ Completion ForInStatement::loop_evaluation(Interpreter& interpreter, Vector<Depr
         // NOTE: Because of optimizations we only create a new lexical environment if there are bindings
         //       so we should only dispose if that is the case.
         if (vm.running_execution_context().lexical_environment != old_environment) {
-            VERIFY(is<DeclarativeEnvironment>(vm.running_execution_context().lexical_environment));
+            VERIFY(is<DeclarativeEnvironment>(*vm.running_execution_context().lexical_environment));
             // m. Set result to DisposeResources(iterationEnv, result).
-            result = dispose_resources(vm, static_cast<DeclarativeEnvironment*>(vm.running_execution_context().lexical_environment), result);
+            result = dispose_resources(vm, static_cast<DeclarativeEnvironment*>(vm.running_execution_context().lexical_environment.ptr()), result);
         }
 
         // n. Set the running execution context's LexicalEnvironment to oldEnv.
@@ -1241,8 +1241,8 @@ Completion ForOfStatement::loop_evaluation(Interpreter& interpreter, Vector<Depr
         auto result = m_body->execute(interpreter);
 
         if (vm.running_execution_context().lexical_environment != old_environment) {
-            VERIFY(is<DeclarativeEnvironment>(vm.running_execution_context().lexical_environment));
-            result = dispose_resources(vm, static_cast<DeclarativeEnvironment*>(vm.running_execution_context().lexical_environment), result);
+            VERIFY(is<DeclarativeEnvironment>(*vm.running_execution_context().lexical_environment));
+            result = dispose_resources(vm, static_cast<DeclarativeEnvironment*>(vm.running_execution_context().lexical_environment.ptr()), result);
         }
 
         // m. Set the running execution context's LexicalEnvironment to oldEnv.
@@ -1378,7 +1378,7 @@ Completion BinaryExpression::execute(Interpreter& interpreter) const
         auto rhs_result = TRY(m_rhs->execute(interpreter)).release_value();
         if (!rhs_result.is_object())
             return interpreter.vm().throw_completion<TypeError>(ErrorType::InOperatorWithObject);
-        auto* private_environment = interpreter.vm().running_execution_context().private_environment;
+        auto private_environment = interpreter.vm().running_execution_context().private_environment;
         VERIFY(private_environment);
         auto private_name = private_environment->resolve_private_identifier(private_identifier);
         return Value(rhs_result.as_object().private_element_find(private_name) != nullptr);
@@ -1661,7 +1661,7 @@ static ThrowCompletionOr<ClassElementName> class_key_to_property_name(Interprete
 
     if (is<PrivateIdentifier>(key)) {
         auto& private_identifier = static_cast<PrivateIdentifier const&>(key);
-        auto* private_environment = interpreter.vm().running_execution_context().private_environment;
+        auto private_environment = interpreter.vm().running_execution_context().private_environment;
         VERIFY(private_environment);
         return ClassElementName { private_environment->resolve_private_identifier(private_identifier.string()) };
     }
@@ -1841,10 +1841,10 @@ ThrowCompletionOr<ClassElement::ClassValue> StaticInitializer::class_element_eva
     auto& realm = *vm.current_realm();
 
     // 1. Let lex be the running execution context's LexicalEnvironment.
-    auto* lexical_environment = interpreter.vm().running_execution_context().lexical_environment;
+    auto lexical_environment = interpreter.vm().running_execution_context().lexical_environment;
 
     // 2. Let privateEnv be the running execution context's PrivateEnvironment.
-    auto* private_environment = interpreter.vm().running_execution_context().private_environment;
+    auto private_environment = interpreter.vm().running_execution_context().private_environment;
 
     // 3. Let sourceText be the empty sequence of Unicode code points.
     // 4. Let formalParameters be an instance of the production FormalParameters : [empty] .
@@ -1946,7 +1946,7 @@ ThrowCompletionOr<ECMAScriptFunctionObject*> ClassExpression::class_definition_e
     if (!binding_name.is_null())
         MUST(class_environment->create_immutable_binding(vm, binding_name, true));
 
-    auto* outer_private_environment = vm.running_execution_context().private_environment;
+    auto outer_private_environment = vm.running_execution_context().private_environment;
     auto class_private_environment = new_private_environment(vm, outer_private_environment);
 
     for (auto const& element : m_elements) {
@@ -3976,7 +3976,7 @@ Completion TryStatement::execute(Interpreter& interpreter) const
     // 14.15.2 Runtime Semantics: CatchClauseEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-catchclauseevaluation
     auto catch_clause_evaluation = [&](Value thrown_value) {
         // 1. Let oldEnv be the running execution context's LexicalEnvironment.
-        auto* old_environment = vm.running_execution_context().lexical_environment;
+        auto old_environment = vm.running_execution_context().lexical_environment;
 
         // 2. Let catchEnv be NewDeclarativeEnvironment(oldEnv).
         auto catch_environment = new_declarative_environment(*old_environment);
@@ -4730,7 +4730,7 @@ void ScopeNode::block_declaration_instantiation(Interpreter& interpreter, Enviro
     auto& realm = *vm.current_realm();
 
     VERIFY(environment);
-    auto* private_environment = vm.running_execution_context().private_environment;
+    auto private_environment = vm.running_execution_context().private_environment;
     // Note: All the calls here are ! and thus we do not need to TRY this callback.
     //       We use MUST to ensure it does not throw and to avoid discarding the returned ThrowCompletionOr<void>.
     MUST(for_each_lexically_scoped_declaration([&](Declaration const& declaration) {

+ 1 - 1
Userland/Libraries/LibJS/AST.h

@@ -1863,7 +1863,7 @@ public:
 private:
     NonnullRefPtr<Expression const> const m_tag;
     NonnullRefPtr<TemplateLiteral const> const m_template_literal;
-    mutable HashMap<Realm*, Handle<Array>> m_cached_values;
+    mutable HashMap<GCPtr<Realm>, Handle<Array>> m_cached_values;
 };
 
 class MemberExpression final : public Expression {

+ 5 - 5
Userland/Libraries/LibJS/Bytecode/Interpreter.cpp

@@ -51,12 +51,12 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable const& e
     ExecutionContext execution_context(vm().heap());
     if (vm().execution_context_stack().is_empty() || !vm().running_execution_context().lexical_environment) {
         // The "normal" interpreter pushes an execution context without environment so in that case we also want to push one.
-        execution_context.this_value = &m_realm.global_object();
+        execution_context.this_value = &m_realm->global_object();
         static DeprecatedFlyString global_execution_context_name = "(*BC* global execution context)";
         execution_context.function_name = global_execution_context_name;
-        execution_context.lexical_environment = &m_realm.global_environment();
-        execution_context.variable_environment = &m_realm.global_environment();
-        execution_context.realm = &m_realm;
+        execution_context.lexical_environment = &m_realm->global_environment();
+        execution_context.variable_environment = &m_realm->global_environment();
+        execution_context.realm = m_realm;
         execution_context.is_strict_mode = executable.is_strict_mode;
         vm().push_execution_context(execution_context);
         pushed_execution_context = true;
@@ -67,7 +67,7 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable const& e
     if (in_frame)
         m_register_windows.append(in_frame);
     else
-        m_register_windows.append(make<RegisterWindow>(MarkedVector<Value>(vm().heap()), MarkedVector<Environment*>(vm().heap()), MarkedVector<Environment*>(vm().heap()), Vector<UnwindInfo> {}));
+        m_register_windows.append(make<RegisterWindow>(MarkedVector<Value>(vm().heap()), MarkedVector<GCPtr<Environment>>(vm().heap()), MarkedVector<GCPtr<Environment>>(vm().heap()), Vector<UnwindInfo> {}));
 
     registers().resize(executable.number_of_registers);
 

+ 3 - 3
Userland/Libraries/LibJS/Bytecode/Interpreter.h

@@ -20,8 +20,8 @@ namespace JS::Bytecode {
 
 struct RegisterWindow {
     MarkedVector<Value> registers;
-    MarkedVector<Environment*> saved_lexical_environments;
-    MarkedVector<Environment*> saved_variable_environments;
+    MarkedVector<GCPtr<Environment>> saved_lexical_environments;
+    MarkedVector<GCPtr<Environment>> saved_variable_environments;
     Vector<UnwindInfo> unwind_contexts;
 };
 
@@ -109,7 +109,7 @@ private:
     static AK::Array<OwnPtr<PassManager>, static_cast<UnderlyingType<Interpreter::OptimizationLevel>>(Interpreter::OptimizationLevel::__Count)> s_optimization_pipelines;
 
     VM& m_vm;
-    Realm& m_realm;
+    NonnullGCPtr<Realm> m_realm;
     Vector<Variant<NonnullOwnPtr<RegisterWindow>, RegisterWindow*>> m_register_windows;
     Optional<BasicBlock const*> m_pending_jump;
     BasicBlock const* m_scheduled_jump { nullptr };

+ 2 - 2
Userland/Libraries/LibJS/Bytecode/Op.cpp

@@ -413,8 +413,8 @@ ThrowCompletionOr<void> DeleteVariable::execute_impl(Bytecode::Interpreter& inte
 
 ThrowCompletionOr<void> CreateEnvironment::execute_impl(Bytecode::Interpreter& interpreter) const
 {
-    auto make_and_swap_envs = [&](auto*& old_environment) {
-        Environment* environment = new_declarative_environment(*old_environment).ptr();
+    auto make_and_swap_envs = [&](auto& old_environment) {
+        GCPtr<Environment> environment = new_declarative_environment(*old_environment).ptr();
         swap(old_environment, environment);
         return environment;
     };

+ 1 - 1
Userland/Libraries/LibJS/Console.h

@@ -89,7 +89,7 @@ private:
     ThrowCompletionOr<String> value_vector_to_string(MarkedVector<Value> const&);
     ThrowCompletionOr<String> format_time_since(Core::ElapsedTimer timer);
 
-    Realm& m_realm;
+    NonnullGCPtr<Realm> m_realm;
     ConsoleClient* m_client { nullptr };
 
     HashMap<String, unsigned> m_counters;

+ 2 - 2
Userland/Libraries/LibJS/Contrib/Test262/$262Object.h

@@ -25,8 +25,8 @@ private:
 
     virtual void visit_edges(Visitor&) override;
 
-    AgentObject* m_agent { nullptr };
-    IsHTMLDDA* m_is_htmldda { nullptr };
+    GCPtr<AgentObject> m_agent;
+    GCPtr<IsHTMLDDA> m_is_htmldda;
 
     JS_DECLARE_NATIVE_FUNCTION(clear_kept_objects);
     JS_DECLARE_NATIVE_FUNCTION(create_realm);

+ 1 - 1
Userland/Libraries/LibJS/Contrib/Test262/GlobalObject.h

@@ -28,7 +28,7 @@ private:
 
     virtual void visit_edges(Visitor&) override;
 
-    $262Object* m_$262 { nullptr };
+    GCPtr<$262Object> m_$262;
 
     JS_DECLARE_NATIVE_FUNCTION(print);
 };

+ 4 - 5
Userland/Libraries/LibJS/CyclicModule.cpp

@@ -25,7 +25,7 @@ void CyclicModule::visit_edges(Cell::Visitor& visitor)
 {
     Base::visit_edges(visitor);
     visitor.visit(m_cycle_root);
-    for (auto* module : m_async_parent_modules)
+    for (auto module : m_async_parent_modules)
         visitor.visit(module);
 }
 
@@ -204,7 +204,7 @@ ThrowCompletionOr<Promise*> CyclicModule::evaluate(VM& vm)
         VERIFY(m_cycle_root);
         VERIFY(this != m_cycle_root);
         VERIFY(m_cycle_root->m_status == ModuleStatus::Linked);
-        dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] evaluate[{}](vm) deferring to cycle root at {}", this, m_cycle_root);
+        dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] evaluate[{}](vm) deferring to cycle root at {}", this, m_cycle_root.ptr());
         return m_cycle_root->evaluate(vm);
     }
 
@@ -502,7 +502,7 @@ void CyclicModule::execute_async_module(VM& vm)
 void CyclicModule::gather_available_ancestors(Vector<CyclicModule*>& exec_list)
 {
     // 1. For each Cyclic Module Record m of module.[[AsyncParentModules]], do
-    for (auto* module : m_async_parent_modules) {
+    for (auto module : m_async_parent_modules) {
         // a. If execList does not contain m and m.[[CycleRoot]].[[EvaluationError]] is empty, then
         if (!exec_list.contains_slow(module) && !module->m_cycle_root->m_evaluation_error.is_error()) {
             // i. Assert: m.[[Status]] is evaluating-async.
@@ -653,8 +653,7 @@ void CyclicModule::async_module_execution_rejected(VM& vm, Value error)
     m_status = ModuleStatus::Evaluated;
 
     // 7. For each Cyclic Module Record m of module.[[AsyncParentModules]], do
-    for (auto* module : m_async_parent_modules) {
-
+    for (auto module : m_async_parent_modules) {
         // a. Perform AsyncModuleExecutionRejected(m, error).
         module->async_module_execution_rejected(vm, error);
     }

+ 11 - 11
Userland/Libraries/LibJS/CyclicModule.h

@@ -48,17 +48,17 @@ protected:
     void async_module_execution_fulfilled(VM& vm);
     void async_module_execution_rejected(VM& vm, Value error);
 
-    ModuleStatus m_status { ModuleStatus::Unlinked }; // [[Status]]
-    ThrowCompletionOr<void> m_evaluation_error;       // [[EvaluationError]]
-    Optional<u32> m_dfs_index;                        // [[DFSIndex]]
-    Optional<u32> m_dfs_ancestor_index;               // [[DFSAncestorIndex]]
-    Vector<ModuleRequest> m_requested_modules;        // [[RequestedModules]]
-    CyclicModule* m_cycle_root { nullptr };           // [[CycleRoot]]
-    bool m_has_top_level_await { false };             // [[HasTLA]]
-    bool m_async_evaluation { false };                // [[AsyncEvaluation]]
-    GCPtr<PromiseCapability> m_top_level_capability;  // [[TopLevelCapability]]
-    Vector<CyclicModule*> m_async_parent_modules;     // [[AsyncParentModules]]
-    Optional<u32> m_pending_async_dependencies;       // [[PendingAsyncDependencies]]
+    ModuleStatus m_status { ModuleStatus::Unlinked };   // [[Status]]
+    ThrowCompletionOr<void> m_evaluation_error;         // [[EvaluationError]]
+    Optional<u32> m_dfs_index;                          // [[DFSIndex]]
+    Optional<u32> m_dfs_ancestor_index;                 // [[DFSAncestorIndex]]
+    Vector<ModuleRequest> m_requested_modules;          // [[RequestedModules]]
+    GCPtr<CyclicModule> m_cycle_root;                   // [[CycleRoot]]
+    bool m_has_top_level_await { false };               // [[HasTLA]]
+    bool m_async_evaluation { false };                  // [[AsyncEvaluation]]
+    GCPtr<PromiseCapability> m_top_level_capability;    // [[TopLevelCapability]]
+    Vector<GCPtr<CyclicModule>> m_async_parent_modules; // [[AsyncParentModules]]
+    Optional<u32> m_pending_async_dependencies;         // [[PendingAsyncDependencies]]
 };
 
 }

+ 1 - 1
Userland/Libraries/LibJS/Heap/Handle.h

@@ -31,7 +31,7 @@ private:
     friend class Handle;
 
     explicit HandleImpl(Cell*);
-    Cell* m_cell { nullptr };
+    GCPtr<Cell> m_cell;
 
     IntrusiveListNode<HandleImpl> m_list_node;
 

+ 1 - 1
Userland/Libraries/LibJS/Heap/Heap.h

@@ -113,7 +113,7 @@ private:
     MarkedVectorBase::List m_marked_vectors;
     WeakContainer::List m_weak_containers;
 
-    Vector<Cell*> m_uprooted_cells;
+    Vector<GCPtr<Cell>> m_uprooted_cells;
 
     BlockAllocator m_block_allocator;
 

+ 2 - 2
Userland/Libraries/LibJS/Heap/HeapBlock.h

@@ -99,7 +99,7 @@ private:
     struct FreelistEntry final : public Cell {
         JS_CELL(FreelistEntry, Cell);
 
-        FreelistEntry* next { nullptr };
+        GCPtr<FreelistEntry> next;
     };
 
     Cell* cell(size_t index)
@@ -110,7 +110,7 @@ private:
     Heap& m_heap;
     size_t m_cell_size { 0 };
     size_t m_next_lazy_freelist_index { 0 };
-    FreelistEntry* m_freelist { nullptr };
+    GCPtr<FreelistEntry> m_freelist;
     alignas(Cell) u8 m_storage[];
 
 public:

+ 1 - 1
Userland/Libraries/LibJS/Module.h

@@ -36,7 +36,7 @@ struct ResolvedBinding {
     }
 
     Type type { Null };
-    Module* module { nullptr };
+    GCPtr<Module> module;
     DeprecatedFlyString export_name;
 
     bool is_valid() const

+ 1 - 1
Userland/Libraries/LibJS/Print.cpp

@@ -356,7 +356,7 @@ ErrorOr<void> print_weak_ref(JS::PrintContext& print_context, JS::WeakRef const&
 {
     TRY(print_type(print_context, "WeakRef"sv));
     TRY(js_out(print_context, " "));
-    TRY(print_value(print_context, weak_ref.value().visit([](Empty) -> JS::Value { return JS::js_undefined(); }, [](auto* value) -> JS::Value { return value; }), seen_objects));
+    TRY(print_value(print_context, weak_ref.value().visit([](Empty) -> JS::Value { return JS::js_undefined(); }, [](auto value) -> JS::Value { return value; }), seen_objects));
     return {};
 }
 

+ 2 - 2
Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp

@@ -345,8 +345,8 @@ bool validate_and_apply_property_descriptor(Object* object, PropertyKey const& p
             // i. For each field of Desc, set the corresponding attribute of the property named P of object O to the value of the field.
             Value value;
             if (descriptor.is_accessor_descriptor() || (current->is_accessor_descriptor() && !descriptor.is_data_descriptor())) {
-                auto* getter = descriptor.get.value_or(current->get.value_or(nullptr));
-                auto* setter = descriptor.set.value_or(current->set.value_or(nullptr));
+                auto getter = descriptor.get.value_or(current->get.value_or(nullptr));
+                auto setter = descriptor.set.value_or(current->set.value_or(nullptr));
                 value = Accessor::create(object->vm(), getter, setter);
             } else {
                 value = descriptor.value.value_or(current->value.value_or({}));

+ 2 - 2
Userland/Libraries/LibJS/Runtime/Accessor.h

@@ -41,8 +41,8 @@ private:
     {
     }
 
-    FunctionObject* m_getter { nullptr };
-    FunctionObject* m_setter { nullptr };
+    GCPtr<FunctionObject> m_getter;
+    GCPtr<FunctionObject> m_setter;
 };
 
 }

+ 1 - 1
Userland/Libraries/LibJS/Runtime/ArgumentsObject.cpp

@@ -28,7 +28,7 @@ ThrowCompletionOr<void> ArgumentsObject::initialize(Realm& realm)
 void ArgumentsObject::visit_edges(Cell::Visitor& visitor)
 {
     Base::visit_edges(visitor);
-    visitor.visit(&m_environment);
+    visitor.visit(m_environment);
     visitor.visit(m_parameter_map);
 }
 

+ 2 - 2
Userland/Libraries/LibJS/Runtime/ArgumentsObject.h

@@ -35,8 +35,8 @@ private:
 
     virtual void visit_edges(Cell::Visitor&) override;
 
-    Environment& m_environment;
-    Object* m_parameter_map { nullptr };
+    NonnullGCPtr<Environment> m_environment;
+    GCPtr<Object> m_parameter_map;
 };
 
 }

+ 2 - 2
Userland/Libraries/LibJS/Runtime/AsyncFromSyncIteratorPrototype.cpp

@@ -108,7 +108,7 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::return_)
     auto promise_capability = MUST(new_promise_capability(vm, realm.intrinsics().promise_constructor()));
 
     // 4. Let syncIterator be O.[[SyncIteratorRecord]].[[Iterator]].
-    auto* sync_iterator = this_object->sync_iterator_record().iterator;
+    auto sync_iterator = this_object->sync_iterator_record().iterator;
 
     // 5. Let return be Completion(GetMethod(syncIterator, "return")).
     // 6. IfAbruptRejectPromise(return, promiseCapability).
@@ -161,7 +161,7 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncFromSyncIteratorPrototype::throw_)
     auto promise_capability = MUST(new_promise_capability(vm, realm.intrinsics().promise_constructor()));
 
     // 4. Let syncIterator be O.[[SyncIteratorRecord]].[[Iterator]].
-    auto* sync_iterator = this_object->sync_iterator_record().iterator;
+    auto sync_iterator = this_object->sync_iterator_record().iterator;
 
     // 5. Let throw be Completion(GetMethod(syncIterator, "throw")).
     // 6. IfAbruptRejectPromise(throw, promiseCapability).

+ 1 - 1
Userland/Libraries/LibJS/Runtime/BigIntObject.cpp

@@ -23,7 +23,7 @@ BigIntObject::BigIntObject(BigInt& bigint, Object& prototype)
 void BigIntObject::visit_edges(Cell::Visitor& visitor)
 {
     Base::visit_edges(visitor);
-    visitor.visit(&m_bigint);
+    visitor.visit(m_bigint);
 }
 
 }

+ 1 - 1
Userland/Libraries/LibJS/Runtime/BigIntObject.h

@@ -27,7 +27,7 @@ private:
 
     virtual void visit_edges(Visitor&) override;
 
-    BigInt& m_bigint;
+    NonnullGCPtr<BigInt> m_bigint;
 };
 
 }

+ 3 - 3
Userland/Libraries/LibJS/Runtime/BoundFunction.h

@@ -35,9 +35,9 @@ private:
 
     virtual void visit_edges(Visitor&) override;
 
-    FunctionObject* m_bound_target_function { nullptr }; // [[BoundTargetFunction]]
-    Value m_bound_this;                                  // [[BoundThis]]
-    Vector<Value> m_bound_arguments;                     // [[BoundArguments]]
+    GCPtr<FunctionObject> m_bound_target_function; // [[BoundTargetFunction]]
+    Value m_bound_this;                            // [[BoundThis]]
+    Vector<Value> m_bound_arguments;               // [[BoundArguments]]
 
     DeprecatedFlyString m_name;
 };

+ 1 - 1
Userland/Libraries/LibJS/Runtime/DataView.h

@@ -29,7 +29,7 @@ private:
 
     virtual void visit_edges(Visitor& visitor) override;
 
-    ArrayBuffer* m_viewed_array_buffer { nullptr };
+    GCPtr<ArrayBuffer> m_viewed_array_buffer;
     size_t m_byte_length { 0 };
     size_t m_byte_offset { 0 };
 };

+ 12 - 12
Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp

@@ -247,7 +247,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> ECMAScriptFunctionObject::internal_const
     }
 
     // 7. Let constructorEnv be the LexicalEnvironment of calleeContext.
-    auto* constructor_env = callee_context.lexical_environment;
+    auto constructor_env = callee_context.lexical_environment;
 
     // 8. Let result be Completion(OrdinaryCallEvaluateBody(F, argumentsList)).
     auto result = ordinary_call_evaluate_body();
@@ -587,7 +587,7 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::function_declaration_instantia
         }));
     }
 
-    auto* private_environment = callee_context.private_environment;
+    auto private_environment = callee_context.private_environment;
     for (auto& declaration : functions_to_initialize) {
         auto function = ECMAScriptFunctionObject::create(realm, declaration.name(), declaration.source_text(), declaration.body(), declaration.parameters(), declaration.function_length(), lex_environment, private_environment, declaration.kind(), declaration.is_strict_mode(), declaration.might_need_arguments_object(), declaration.contains_direct_call_to_eval());
         MUST(var_environment->set_mutable_binding(vm, declaration.name(), function, false));
@@ -621,7 +621,7 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::prepare_for_ordinary_call(Exec
     callee_context.function_name = m_name;
 
     // 4. Let calleeRealm be F.[[Realm]].
-    auto* callee_realm = m_realm;
+    auto callee_realm = m_realm;
     // NOTE: This non-standard fallback is needed until we can guarantee that literally
     // every function has a realm - especially in LibWeb that's sometimes not the case
     // when a function is created while no JS is running, as we currently need to rely on
@@ -674,7 +674,7 @@ void ECMAScriptFunctionObject::ordinary_call_bind_this(ExecutionContext& callee_
         return;
 
     // 3. Let calleeRealm be F.[[Realm]].
-    auto* callee_realm = m_realm;
+    auto callee_realm = m_realm;
     // NOTE: This non-standard fallback is needed until we can guarantee that literally
     // every function has a realm - especially in LibWeb that's sometimes not the case
     // when a function is created while no JS is running, as we currently need to rely on
@@ -685,7 +685,7 @@ void ECMAScriptFunctionObject::ordinary_call_bind_this(ExecutionContext& callee_
     VERIFY(callee_realm);
 
     // 4. Let localEnv be the LexicalEnvironment of calleeContext.
-    auto* local_env = callee_context.lexical_environment;
+    auto local_env = callee_context.lexical_environment;
 
     Value this_value;
 
@@ -717,7 +717,7 @@ void ECMAScriptFunctionObject::ordinary_call_bind_this(ExecutionContext& callee_
     // 7. Assert: localEnv is a function Environment Record.
     // 8. Assert: The next step never returns an abrupt completion because localEnv.[[ThisBindingStatus]] is not initialized.
     // 9. Perform ! localEnv.BindThisValue(thisValue).
-    MUST(verify_cast<FunctionEnvironment>(local_env)->bind_this_value(vm, this_value));
+    MUST(verify_cast<FunctionEnvironment>(*local_env).bind_this_value(vm, this_value));
 
     // 10. Return unused.
 }
@@ -762,11 +762,11 @@ void async_block_start(VM& vm, NonnullRefPtr<Statement const> const& async_body,
         vm.pop_execution_context();
 
         // d. Let env be asyncContext's LexicalEnvironment.
-        auto* env = async_context.lexical_environment;
-        VERIFY(is<DeclarativeEnvironment>(env));
+        auto env = async_context.lexical_environment;
+        VERIFY(is<DeclarativeEnvironment>(*env));
 
         // e. Set result to DisposeResources(env, result).
-        result = dispose_resources(vm, static_cast<DeclarativeEnvironment*>(env), result);
+        result = dispose_resources(vm, static_cast<DeclarativeEnvironment*>(env.ptr()), result);
 
         // f. If result.[[Type]] is normal, then
         if (result.type() == Completion::Type::Normal) {
@@ -909,11 +909,11 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
             auto result = m_ecmascript_code->execute(*ast_interpreter);
 
             // 3. Let env be the running execution context's LexicalEnvironment.
-            auto* env = vm.running_execution_context().lexical_environment;
-            VERIFY(is<DeclarativeEnvironment>(env));
+            auto env = vm.running_execution_context().lexical_environment;
+            VERIFY(is<DeclarativeEnvironment>(*env));
 
             // 4. Return ? DisposeResources(env, result).
-            return dispose_resources(vm, static_cast<DeclarativeEnvironment*>(env), result);
+            return dispose_resources(vm, static_cast<DeclarativeEnvironment*>(env.ptr()), result);
         }
         // AsyncFunctionBody : FunctionBody
         else if (m_kind == FunctionKind::Async) {

+ 4 - 4
Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h

@@ -112,13 +112,13 @@ private:
     i32 m_function_length { 0 };
 
     // Internal Slots of ECMAScript Function Objects, https://tc39.es/ecma262/#table-internal-slots-of-ecmascript-function-objects
-    Environment* m_environment { nullptr };                                  // [[Environment]]
-    PrivateEnvironment* m_private_environment { nullptr };                   // [[PrivateEnvironment]]
+    GCPtr<Environment> m_environment;                                        // [[Environment]]
+    GCPtr<PrivateEnvironment> m_private_environment;                         // [[PrivateEnvironment]]
     Vector<FunctionParameter> const m_formal_parameters;                     // [[FormalParameters]]
     NonnullRefPtr<Statement const> m_ecmascript_code;                        // [[ECMAScriptCode]]
-    Realm* m_realm { nullptr };                                              // [[Realm]]
+    GCPtr<Realm> m_realm;                                                    // [[Realm]]
     ScriptOrModule m_script_or_module;                                       // [[ScriptOrModule]]
-    Object* m_home_object { nullptr };                                       // [[HomeObject]]
+    GCPtr<Object> m_home_object;                                             // [[HomeObject]]
     DeprecatedString m_source_text;                                          // [[SourceText]]
     Vector<ClassFieldDefinition> m_fields;                                   // [[Fields]]
     Vector<PrivateElement> m_private_methods;                                // [[PrivateMethods]]

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Environment.h

@@ -67,7 +67,7 @@ private:
 
     bool m_permanently_screwed_by_eval { false };
 
-    Environment* m_outer_environment { nullptr };
+    GCPtr<Environment> m_outer_environment;
 };
 
 }

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Error.cpp

@@ -65,7 +65,7 @@ void Error::populate_stack()
     auto& vm = this->vm();
     m_traceback.ensure_capacity(vm.execution_context_stack().size());
     for (ssize_t i = vm.execution_context_stack().size() - 1; i >= 0; i--) {
-        auto* context = vm.execution_context_stack()[i];
+        auto context = vm.execution_context_stack()[i];
         auto function_name = context->function_name;
         if (function_name.is_empty())
             function_name = "<unknown>"sv;

+ 7 - 7
Userland/Libraries/LibJS/Runtime/ExecutionContext.h

@@ -32,15 +32,15 @@ private:
     explicit ExecutionContext(MarkedVector<Value> existing_arguments);
 
 public:
-    FunctionObject* function { nullptr };                // [[Function]]
-    Realm* realm { nullptr };                            // [[Realm]]
-    ScriptOrModule script_or_module;                     // [[ScriptOrModule]]
-    Environment* lexical_environment { nullptr };        // [[LexicalEnvironment]]
-    Environment* variable_environment { nullptr };       // [[VariableEnvironment]]
-    PrivateEnvironment* private_environment { nullptr }; // [[PrivateEnvironment]]
+    GCPtr<FunctionObject> function;                // [[Function]]
+    GCPtr<Realm> realm;                            // [[Realm]]
+    ScriptOrModule script_or_module;               // [[ScriptOrModule]]
+    GCPtr<Environment> lexical_environment;        // [[LexicalEnvironment]]
+    GCPtr<Environment> variable_environment;       // [[VariableEnvironment]]
+    GCPtr<PrivateEnvironment> private_environment; // [[PrivateEnvironment]]
 
     // Non-standard: This points at something that owns this ExecutionContext, in case it needs to be protected from GC.
-    Cell* context_owner { nullptr };
+    GCPtr<Cell> context_owner;
 
     ASTNode const* current_node { nullptr };
     DeprecatedFlyString function_name;

+ 2 - 2
Userland/Libraries/LibJS/Runtime/FinalizationRegistry.h

@@ -46,9 +46,9 @@ private:
     JobCallback m_cleanup_callback;
 
     struct FinalizationRecord {
-        Cell* target { nullptr };
+        GCPtr<Cell> target;
         Value held_value;
-        Cell* unregister_token { nullptr };
+        GCPtr<Cell> unregister_token;
     };
     SinglyLinkedList<FinalizationRecord> m_records;
 };

+ 1 - 1
Userland/Libraries/LibJS/Runtime/FunctionEnvironment.h

@@ -52,7 +52,7 @@ private:
 
     Value m_this_value;                                                           // [[ThisValue]]
     ThisBindingStatus m_this_binding_status { ThisBindingStatus::Uninitialized }; // [[ThisBindingStatus]]
-    ECMAScriptFunctionObject* m_function_object { nullptr };                      // [[FunctionObject]]
+    GCPtr<ECMAScriptFunctionObject> m_function_object;                            // [[FunctionObject]]
     Value m_new_target { js_undefined() };                                        // [[NewTarget]]
 };
 

+ 1 - 1
Userland/Libraries/LibJS/Runtime/GeneratorObject.h

@@ -38,7 +38,7 @@ private:
     ThrowCompletionOr<Value> execute(VM&, JS::Completion const& completion);
 
     ExecutionContext m_execution_context;
-    ECMAScriptFunctionObject* m_generating_function { nullptr };
+    GCPtr<ECMAScriptFunctionObject> m_generating_function;
     Value m_previous_value;
     Optional<Bytecode::RegisterWindow> m_frame;
     GeneratorState m_generator_state { GeneratorState::SuspendedStart };

+ 4 - 4
Userland/Libraries/LibJS/Runtime/GlobalEnvironment.h

@@ -43,10 +43,10 @@ private:
     virtual bool is_global_environment() const override { return true; }
     virtual void visit_edges(Visitor&) override;
 
-    ObjectEnvironment* m_object_record { nullptr };           // [[ObjectRecord]]
-    Object* m_global_this_value { nullptr };                  // [[GlobalThisValue]]
-    DeclarativeEnvironment* m_declarative_record { nullptr }; // [[DeclarativeRecord]]
-    Vector<DeprecatedFlyString> m_var_names;                  // [[VarNames]]
+    GCPtr<ObjectEnvironment> m_object_record;           // [[ObjectRecord]]
+    GCPtr<Object> m_global_this_value;                  // [[GlobalThisValue]]
+    GCPtr<DeclarativeEnvironment> m_declarative_record; // [[DeclarativeRecord]]
+    Vector<DeprecatedFlyString> m_var_names;            // [[VarNames]]
 };
 
 template<>

+ 8 - 8
Userland/Libraries/LibJS/Runtime/Intl/Collator.h

@@ -77,14 +77,14 @@ private:
 
     virtual void visit_edges(Visitor&) override;
 
-    String m_locale;                                      // [[Locale]]
-    Usage m_usage { Usage::Sort };                        // [[Usage]]
-    Sensitivity m_sensitivity { Sensitivity::Variant };   // [[Sensitivity]]
-    CaseFirst m_case_first { CaseFirst::False };          // [[CaseFirst]]
-    String m_collation;                                   // [[Collation]]
-    bool m_ignore_punctuation { false };                  // [[IgnorePunctuation]]
-    bool m_numeric { false };                             // [[Numeric]]
-    CollatorCompareFunction* m_bound_compare { nullptr }; // [[BoundCompare]]
+    String m_locale;                                    // [[Locale]]
+    Usage m_usage { Usage::Sort };                      // [[Usage]]
+    Sensitivity m_sensitivity { Sensitivity::Variant }; // [[Sensitivity]]
+    CaseFirst m_case_first { CaseFirst::False };        // [[CaseFirst]]
+    String m_collation;                                 // [[Collation]]
+    bool m_ignore_punctuation { false };                // [[IgnorePunctuation]]
+    bool m_numeric { false };                           // [[Numeric]]
+    GCPtr<CollatorCompareFunction> m_bound_compare;     // [[BoundCompare]]
 };
 
 }

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/CollatorCompareFunction.cpp

@@ -71,7 +71,7 @@ ThrowCompletionOr<Value> CollatorCompareFunction::call()
 void CollatorCompareFunction::visit_edges(Visitor& visitor)
 {
     Base::visit_edges(visitor);
-    visitor.visit(&m_collator);
+    visitor.visit(m_collator);
 }
 
 }

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/CollatorCompareFunction.h

@@ -26,7 +26,7 @@ private:
 
     virtual void visit_edges(Visitor&) override;
 
-    Collator& m_collator; // [[Collator]]
+    NonnullGCPtr<Collator> m_collator; // [[Collator]]
 };
 
 double compare_strings(Collator&, Utf8View const& x, Utf8View const& y);

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.h

@@ -142,7 +142,7 @@ private:
     Optional<Style> m_date_style;                            // [[DateStyle]]
     Optional<Style> m_time_style;                            // [[TimeStyle]]
     Vector<::Locale::CalendarRangePattern> m_range_patterns; // [[RangePatterns]]
-    NativeFunction* m_bound_format { nullptr };              // [[BoundFormat]]
+    GCPtr<NativeFunction> m_bound_format;                    // [[BoundFormat]]
 
     String m_data_locale;
 };

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormatFunction.cpp

@@ -67,7 +67,7 @@ ThrowCompletionOr<Value> DateTimeFormatFunction::call()
 void DateTimeFormatFunction::visit_edges(Cell::Visitor& visitor)
 {
     Base::visit_edges(visitor);
-    visitor.visit(&m_date_time_format);
+    visitor.visit(m_date_time_format);
 }
 
 }

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormatFunction.h

@@ -28,7 +28,7 @@ private:
 
     virtual void visit_edges(Visitor&) override;
 
-    DateTimeFormat& m_date_time_format; // [[DateTimeFormat]]
+    NonnullGCPtr<DateTimeFormat> m_date_time_format; // [[DateTimeFormat]]
 };
 
 }

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.h

@@ -251,7 +251,7 @@ private:
     Notation m_notation { Notation::Invalid };           // [[Notation]]
     Optional<CompactDisplay> m_compact_display {};       // [[CompactDisplay]]
     SignDisplay m_sign_display { SignDisplay::Invalid }; // [[SignDisplay]]
-    NativeFunction* m_bound_format { nullptr };          // [[BoundFormat]]
+    GCPtr<NativeFunction> m_bound_format;                // [[BoundFormat]]
 
     // Non-standard. Stores the resolved currency display string based on [[Locale]], [[Currency]], and [[CurrencyDisplay]].
     Optional<StringView> m_resolved_currency_display;

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/NumberFormatFunction.cpp

@@ -54,7 +54,7 @@ ThrowCompletionOr<Value> NumberFormatFunction::call()
 void NumberFormatFunction::visit_edges(Cell::Visitor& visitor)
 {
     Base::visit_edges(visitor);
-    visitor.visit(&m_number_format);
+    visitor.visit(m_number_format);
 }
 
 }

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/NumberFormatFunction.h

@@ -28,7 +28,7 @@ private:
 
     virtual void visit_edges(Visitor&) override;
 
-    NumberFormat& m_number_format; // [[NumberFormat]]
+    NonnullGCPtr<NumberFormat> m_number_format; // [[NumberFormat]]
 };
 
 }

+ 2 - 2
Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.h

@@ -68,8 +68,8 @@ private:
     String m_numbering_system;                         // [[NumberingSystem]]
     ::Locale::Style m_style { ::Locale::Style::Long }; // [[Style]]
     Numeric m_numeric { Numeric::Always };             // [[Numeric]]
-    NumberFormat* m_number_format { nullptr };         // [[NumberFormat]]
-    PluralRules* m_plural_rules { nullptr };           // [[PluralRules]]
+    GCPtr<NumberFormat> m_number_format;               // [[NumberFormat]]
+    GCPtr<PluralRules> m_plural_rules;                 // [[PluralRules]]
 };
 
 struct PatternPartitionWithUnit : public PatternPartition {

+ 2 - 2
Userland/Libraries/LibJS/Runtime/Intl/SegmentIterator.cpp

@@ -34,8 +34,8 @@ SegmentIterator::SegmentIterator(Realm& realm, Segmenter& segmenter, Utf16View c
 void SegmentIterator::visit_edges(Cell::Visitor& visitor)
 {
     Base::visit_edges(visitor);
-    visitor.visit(&m_iterating_segmenter);
-    visitor.visit(&m_segments);
+    visitor.visit(m_iterating_segmenter);
+    visitor.visit(m_segments);
 }
 
 }

+ 2 - 2
Userland/Libraries/LibJS/Runtime/Intl/SegmentIterator.h

@@ -32,11 +32,11 @@ private:
 
     virtual void visit_edges(Cell::Visitor&) override;
 
-    Segmenter& m_iterating_segmenter;                            // [[IteratingSegmenter]]
+    NonnullGCPtr<Segmenter> m_iterating_segmenter;               // [[IteratingSegmenter]]
     Utf16View m_iterated_string;                                 // [[IteratedString]]
     size_t m_iterated_string_next_segment_code_unit_index { 0 }; // [[IteratedStringNextSegmentCodeUnitIndex]]
 
-    Segments const& m_segments;
+    NonnullGCPtr<Segments const> m_segments;
 };
 
 }

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/Segments.cpp

@@ -32,7 +32,7 @@ Segments::Segments(Realm& realm, Segmenter& segmenter, Utf16String string)
 void Segments::visit_edges(Cell::Visitor& visitor)
 {
     Base::visit_edges(visitor);
-    visitor.visit(&m_segments_segmenter);
+    visitor.visit(m_segments_segmenter);
 }
 
 }

+ 2 - 2
Userland/Libraries/LibJS/Runtime/Intl/Segments.h

@@ -29,8 +29,8 @@ private:
 
     virtual void visit_edges(Cell::Visitor&) override;
 
-    Segmenter& m_segments_segmenter; // [[SegmentsSegmenter]]
-    Utf16String m_segments_string;   // [[SegmentsString]]
+    NonnullGCPtr<Segmenter> m_segments_segmenter; // [[SegmentsSegmenter]]
+    Utf16String m_segments_string;                // [[SegmentsString]]
 };
 
 }

+ 2 - 2
Userland/Libraries/LibJS/Runtime/Intrinsics.cpp

@@ -184,8 +184,8 @@ ThrowCompletionOr<void> Intrinsics::initialize_intrinsics(Realm& realm)
     m_new_ordinary_function_prototype_object_shape->add_property_without_transition(vm.names.constructor, Attribute::Writable | Attribute::Configurable);
 
     // Normally Heap::allocate() takes care of this, but these are allocated via allocate_without_realm().
-    MUST_OR_THROW_OOM(static_cast<FunctionPrototype*>(m_function_prototype)->initialize(realm));
-    MUST_OR_THROW_OOM(static_cast<ObjectPrototype*>(m_object_prototype)->initialize(realm));
+    MUST_OR_THROW_OOM(m_function_prototype->initialize(realm));
+    MUST_OR_THROW_OOM(m_object_prototype->initialize(realm));
 
 #define __JS_ENUMERATE(ClassName, snake_name) \
     VERIFY(!m_##snake_name##_prototype);      \

+ 35 - 35
Userland/Libraries/LibJS/Runtime/Intrinsics.h

@@ -115,69 +115,69 @@ private:
     JS_ENUMERATE_TEMPORAL_OBJECTS
 #undef __JS_ENUMERATE
 
-    Realm& m_realm;
+    NonnullGCPtr<Realm> m_realm;
 
-    Shape* m_empty_object_shape { nullptr };
-    Shape* m_new_object_shape { nullptr };
-    Shape* m_new_ordinary_function_prototype_object_shape { nullptr };
+    GCPtr<Shape> m_empty_object_shape;
+    GCPtr<Shape> m_new_object_shape;
+    GCPtr<Shape> m_new_ordinary_function_prototype_object_shape;
 
     // Not included in JS_ENUMERATE_NATIVE_OBJECTS due to missing distinct prototype
-    ProxyConstructor* m_proxy_constructor { nullptr };
+    GCPtr<ProxyConstructor> m_proxy_constructor;
 
     // Not included in JS_ENUMERATE_NATIVE_OBJECTS due to missing distinct constructor
-    Object* m_async_from_sync_iterator_prototype { nullptr };
-    Object* m_async_generator_prototype { nullptr };
-    Object* m_generator_prototype { nullptr };
+    GCPtr<Object> m_async_from_sync_iterator_prototype;
+    GCPtr<Object> m_async_generator_prototype;
+    GCPtr<Object> m_generator_prototype;
 
     // Not included in JS_ENUMERATE_INTL_OBJECTS due to missing distinct constructor
-    Object* m_intl_segments_prototype { nullptr };
+    GCPtr<Object> m_intl_segments_prototype;
 
     // 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 };
+    GCPtr<FunctionObject> m_eval_function;
+    GCPtr<FunctionObject> m_is_finite_function;
+    GCPtr<FunctionObject> m_is_nan_function;
+    GCPtr<FunctionObject> m_parse_float_function;
+    GCPtr<FunctionObject> m_parse_int_function;
+    GCPtr<FunctionObject> m_decode_uri_function;
+    GCPtr<FunctionObject> m_decode_uri_component_function;
+    GCPtr<FunctionObject> m_encode_uri_function;
+    GCPtr<FunctionObject> m_encode_uri_component_function;
+    GCPtr<FunctionObject> m_escape_function;
+    GCPtr<FunctionObject> m_unescape_function;
 
     // Namespace/constructor object functions
-    FunctionObject* m_array_prototype_values_function { nullptr };
-    FunctionObject* m_date_constructor_now_function { nullptr };
-    FunctionObject* m_json_parse_function { nullptr };
-    FunctionObject* m_json_stringify_function { nullptr };
-    FunctionObject* m_object_prototype_to_string_function { nullptr };
-    FunctionObject* m_throw_type_error_function { nullptr };
+    GCPtr<FunctionObject> m_array_prototype_values_function;
+    GCPtr<FunctionObject> m_date_constructor_now_function;
+    GCPtr<FunctionObject> m_json_parse_function;
+    GCPtr<FunctionObject> m_json_stringify_function;
+    GCPtr<FunctionObject> m_object_prototype_to_string_function;
+    GCPtr<FunctionObject> m_throw_type_error_function;
 
 #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, ArrayType) \
-    ConstructorName* m_##snake_name##_constructor { nullptr };                           \
-    Object* m_##snake_name##_prototype { nullptr };
+    GCPtr<ConstructorName> m_##snake_name##_constructor;                                 \
+    GCPtr<Object> m_##snake_name##_prototype;
     JS_ENUMERATE_BUILTIN_TYPES
 #undef __JS_ENUMERATE
 
 #define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \
-    Intl::ConstructorName* m_intl_##snake_name##_constructor { nullptr };     \
-    Object* m_intl_##snake_name##_prototype { nullptr };
+    GCPtr<Intl::ConstructorName> m_intl_##snake_name##_constructor;           \
+    GCPtr<Object> m_intl_##snake_name##_prototype;
     JS_ENUMERATE_INTL_OBJECTS
 #undef __JS_ENUMERATE
 
-#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName)     \
-    Temporal::ConstructorName* m_temporal_##snake_name##_constructor { nullptr }; \
-    Object* m_temporal_##snake_name##_prototype { nullptr };
+#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \
+    GCPtr<Temporal::ConstructorName> m_temporal_##snake_name##_constructor;   \
+    GCPtr<Object> m_temporal_##snake_name##_prototype;
     JS_ENUMERATE_TEMPORAL_OBJECTS
 #undef __JS_ENUMERATE
 
 #define __JS_ENUMERATE(ClassName, snake_name) \
-    ClassName* m_##snake_name##_object { nullptr };
+    GCPtr<ClassName> m_##snake_name##_object;
     JS_ENUMERATE_BUILTIN_NAMESPACE_OBJECTS
 #undef __JS_ENUMERATE
 
 #define __JS_ENUMERATE(ClassName, snake_name) \
-    Object* m_##snake_name##_prototype { nullptr };
+    GCPtr<Object> m_##snake_name##_prototype;
     JS_ENUMERATE_ITERATOR_PROTOTYPES
 #undef __JS_ENUMERATE
 };

+ 3 - 3
Userland/Libraries/LibJS/Runtime/Iterator.h

@@ -13,9 +13,9 @@ namespace JS {
 
 // 7.4.1 Iterator Records, https://tc39.es/ecma262/#sec-iterator-records
 struct Iterator {
-    Object* iterator { nullptr }; // [[Iterator]]
-    Value next_method;            // [[NextMethod]]
-    bool done { false };          // [[Done]]
+    GCPtr<Object> iterator; // [[Iterator]]
+    Value next_method;      // [[NextMethod]]
+    bool done { false };    // [[Done]]
 };
 
 }

+ 1 - 1
Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp

@@ -128,7 +128,7 @@ static Completion iterator_close_impl(VM& vm, Iterator const& iterator_record, C
     // 1. Assert: Type(iteratorRecord.[[Iterator]]) is Object.
 
     // 2. Let iterator be iteratorRecord.[[Iterator]].
-    auto* iterator = iterator_record.iterator;
+    auto iterator = iterator_record.iterator;
 
     // 3. Let innerResult be Completion(GetMethod(iterator, "return")).
     auto inner_result = ThrowCompletionOr<Value> { js_undefined() };

+ 2 - 2
Userland/Libraries/LibJS/Runtime/JSONObject.h

@@ -27,8 +27,8 @@ private:
     explicit JSONObject(Realm&);
 
     struct StringifyState {
-        FunctionObject* replacer_function { nullptr };
-        HashTable<Object*> seen_objects;
+        GCPtr<FunctionObject> replacer_function;
+        HashTable<GCPtr<Object>> seen_objects;
         DeprecatedString indent { DeprecatedString::empty() };
         DeprecatedString gap;
         Optional<Vector<DeprecatedString>> property_list;

+ 10 - 10
Userland/Libraries/LibJS/Runtime/Map.h

@@ -37,8 +37,8 @@ public:
     struct IteratorImpl {
         bool is_end() const
         {
-            return m_map.m_keys.begin_from(m_index).is_end()
-                && m_map.m_keys.find_smallest_not_below_iterator(m_index).is_end();
+            return m_map->m_keys.begin_from(m_index).is_end()
+                && m_map->m_keys.find_smallest_not_below_iterator(m_index).is_end();
         }
 
         IteratorImpl& operator++()
@@ -50,13 +50,13 @@ public:
         decltype(auto) operator*()
         {
             ensure_next_element();
-            return *m_map.m_entries.find(*m_map.m_keys.begin_from(m_index));
+            return *m_map->m_entries.find(*m_map->m_keys.begin_from(m_index));
         }
 
         decltype(auto) operator*() const
         {
             ensure_next_element();
-            return *m_map.m_entries.find(*m_map.m_keys.begin_from(m_index));
+            return *m_map->m_entries.find(*m_map->m_keys.begin_from(m_index));
         }
 
         bool operator==(IteratorImpl const& other) const { return m_index == other.m_index && &m_map == &other.m_map; }
@@ -80,21 +80,21 @@ public:
 
         void ensure_index() const
         {
-            if (m_map.m_keys.is_empty())
-                m_index = m_map.m_next_insertion_id;
+            if (m_map->m_keys.is_empty())
+                m_index = m_map->m_next_insertion_id;
             else
-                m_index = m_map.m_keys.begin().key();
+                m_index = m_map->m_keys.begin().key();
         }
 
         void ensure_next_element() const
         {
-            if (auto it = m_map.m_keys.find_smallest_not_below_iterator(m_index); it.is_end())
-                m_index = m_map.m_next_insertion_id;
+            if (auto it = m_map->m_keys.find_smallest_not_below_iterator(m_index); it.is_end())
+                m_index = m_map->m_next_insertion_id;
             else
                 m_index = it.key();
         }
 
-        Conditional<IsConst, Map const&, Map&> m_map;
+        Conditional<IsConst, NonnullGCPtr<Map const>, NonnullGCPtr<Map>> m_map;
         mutable size_t m_index { 0 };
     };
 

+ 1 - 1
Userland/Libraries/LibJS/Runtime/MapIterator.cpp

@@ -25,7 +25,7 @@ MapIterator::MapIterator(Map& map, Object::PropertyKind iteration_kind, Object&
 void MapIterator::visit_edges(Cell::Visitor& visitor)
 {
     Base::visit_edges(visitor);
-    visitor.visit(&m_map);
+    visitor.visit(m_map);
 }
 
 }

+ 1 - 1
Userland/Libraries/LibJS/Runtime/MapIterator.h

@@ -31,7 +31,7 @@ private:
 
     virtual void visit_edges(Cell::Visitor&) override;
 
-    Map& m_map;
+    NonnullGCPtr<Map> m_map;
     bool m_done { false };
     Object::PropertyKind m_iteration_kind;
     Map::ConstIterator m_iterator;

+ 1 - 1
Userland/Libraries/LibJS/Runtime/ModuleEnvironment.h

@@ -34,7 +34,7 @@ private:
 
     struct IndirectBinding {
         DeprecatedFlyString name;
-        Module* module;
+        GCPtr<Module> module;
         DeprecatedFlyString binding_name;
     };
     IndirectBinding const* get_indirect_binding(DeprecatedFlyString const& name) const;

+ 1 - 1
Userland/Libraries/LibJS/Runtime/ModuleNamespaceObject.cpp

@@ -160,7 +160,7 @@ ThrowCompletionOr<Value> ModuleNamespaceObject::internal_get(PropertyKey const&
     VERIFY(binding.is_valid());
 
     // 7. Let targetModule be binding.[[Module]].
-    auto* target_module = binding.module;
+    auto target_module = binding.module;
 
     // 8. Assert: targetModule is not undefined.
     VERIFY(target_module);

+ 1 - 1
Userland/Libraries/LibJS/Runtime/ModuleNamespaceObject.h

@@ -35,7 +35,7 @@ private:
     ModuleNamespaceObject(Realm&, Module* module, Vector<DeprecatedFlyString> exports);
 
     // FIXME: UHHH how do we want to store this to avoid cycles but be safe??
-    Module* m_module;                      // [[Module]]
+    GCPtr<Module> m_module;                // [[Module]]
     Vector<DeprecatedFlyString> m_exports; // [[Exports]]
 };
 

+ 2 - 2
Userland/Libraries/LibJS/Runtime/NativeFunction.cpp

@@ -111,7 +111,7 @@ ThrowCompletionOr<Value> NativeFunction::internal_call(Value this_argument, Mark
     callee_context.function_name = m_name;
 
     // 5. Let calleeRealm be F.[[Realm]].
-    auto* callee_realm = m_realm;
+    auto callee_realm = m_realm;
     // NOTE: This non-standard fallback is needed until we can guarantee that literally
     // every function has a realm - especially in LibWeb that's sometimes not the case
     // when a function is created while no JS is running, as we currently need to rely on
@@ -178,7 +178,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> NativeFunction::internal_construct(Marke
     callee_context.function_name = m_name;
 
     // 5. Let calleeRealm be F.[[Realm]].
-    auto* callee_realm = m_realm;
+    auto callee_realm = m_realm;
     // NOTE: This non-standard fallback is needed until we can guarantee that literally
     // every function has a realm - especially in LibWeb that's sometimes not the case
     // when a function is created while no JS is running, as we currently need to rely on

+ 1 - 1
Userland/Libraries/LibJS/Runtime/NativeFunction.h

@@ -54,7 +54,7 @@ private:
     DeprecatedFlyString m_name;
     Optional<DeprecatedFlyString> m_initial_name; // [[InitialName]]
     SafeFunction<ThrowCompletionOr<Value>(VM&)> m_native_function;
-    Realm* m_realm { nullptr };
+    GCPtr<Realm> m_realm;
 };
 
 template<>

+ 3 - 3
Userland/Libraries/LibJS/Runtime/Object.cpp

@@ -24,7 +24,7 @@
 
 namespace JS {
 
-static HashMap<Object const*, HashMap<DeprecatedFlyString, Object::IntrinsicAccessor>> s_intrinsics;
+static HashMap<GCPtr<Object const>, HashMap<DeprecatedFlyString, Object::IntrinsicAccessor>> s_intrinsics;
 
 // 10.1.12 OrdinaryObjectCreate ( proto [ , additionalInternalSlotsList ] ), https://tc39.es/ecma262/#sec-ordinaryobjectcreate
 NonnullGCPtr<Object> Object::create(Realm& realm, Object* prototype)
@@ -813,7 +813,7 @@ ThrowCompletionOr<Value> Object::internal_get(PropertyKey const& property_key, V
     VERIFY(descriptor->is_accessor_descriptor());
 
     // 5. Let getter be desc.[[Get]].
-    auto* getter = *descriptor->get;
+    auto getter = *descriptor->get;
 
     // 6. If getter is undefined, return undefined.
     if (!getter)
@@ -911,7 +911,7 @@ ThrowCompletionOr<bool> Object::ordinary_set_with_own_descriptor(PropertyKey con
     VERIFY(own_descriptor->is_accessor_descriptor());
 
     // 4. Let setter be ownDesc.[[Set]].
-    auto* setter = *own_descriptor->set;
+    auto setter = *own_descriptor->set;
 
     // 5. If setter is undefined, return false.
     if (!setter)

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Object.h

@@ -213,7 +213,7 @@ private:
     Object* prototype() { return shape().prototype(); }
     Object const* prototype() const { return shape().prototype(); }
 
-    Shape* m_shape { nullptr };
+    GCPtr<Shape> m_shape;
     Vector<Value> m_storage;
     IndexedProperties m_indexed_properties;
     OwnPtr<Vector<PrivateElement>> m_private_elements; // [[PrivateElements]]

+ 12 - 12
Userland/Libraries/LibJS/Runtime/ObjectEnvironment.cpp

@@ -20,7 +20,7 @@ ObjectEnvironment::ObjectEnvironment(Object& binding_object, IsWithEnvironment i
 void ObjectEnvironment::visit_edges(Cell::Visitor& visitor)
 {
     Base::visit_edges(visitor);
-    visitor.visit(&m_binding_object);
+    visitor.visit(m_binding_object);
 }
 
 // 9.1.1.2.1 HasBinding ( N ), https://tc39.es/ecma262/#sec-object-environment-records-hasbinding-n
@@ -31,7 +31,7 @@ ThrowCompletionOr<bool> ObjectEnvironment::has_binding(DeprecatedFlyString const
     // 1. Let bindingObject be envRec.[[BindingObject]].
 
     // 2. Let foundBinding be ? HasProperty(bindingObject, N).
-    bool found_binding = TRY(m_binding_object.has_property(name));
+    bool found_binding = TRY(m_binding_object->has_property(name));
 
     // 3. If foundBinding is false, return false.
     if (!found_binding)
@@ -42,7 +42,7 @@ ThrowCompletionOr<bool> ObjectEnvironment::has_binding(DeprecatedFlyString const
         return true;
 
     // 5. Let unscopables be ? Get(bindingObject, @@unscopables).
-    auto unscopables = TRY(m_binding_object.get(*vm.well_known_symbol_unscopables()));
+    auto unscopables = TRY(m_binding_object->get(*vm.well_known_symbol_unscopables()));
 
     // 6. If Type(unscopables) is Object, then
     if (unscopables.is_object()) {
@@ -63,7 +63,7 @@ ThrowCompletionOr<void> ObjectEnvironment::create_mutable_binding(VM&, Deprecate
 {
     // 1. Let bindingObject be envRec.[[BindingObject]].
     // 2. Perform ? DefinePropertyOrThrow(bindingObject, N, PropertyDescriptor { [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D }).
-    TRY(m_binding_object.define_property_or_throw(name, { .value = js_undefined(), .writable = true, .enumerable = true, .configurable = can_be_deleted }));
+    TRY(m_binding_object->define_property_or_throw(name, { .value = js_undefined(), .writable = true, .enumerable = true, .configurable = can_be_deleted }));
 
     // 3. Return unused.
     return {};
@@ -99,22 +99,22 @@ ThrowCompletionOr<void> ObjectEnvironment::set_mutable_binding(VM&, DeprecatedFl
     //               We can't do this for with environments, since it would be observable (e.g via a Proxy)
     // FIXME: I think we could combine HasProperty and Set in strict mode if Set would return a bit more failure information.
     if (!m_with_environment && !strict)
-        return m_binding_object.set(name, value, Object::ShouldThrowExceptions::No);
+        return m_binding_object->set(name, value, Object::ShouldThrowExceptions::No);
 
     // 1. Let bindingObject be envRec.[[BindingObject]].
     // 2. Let stillExists be ? HasProperty(bindingObject, N).
-    auto still_exists = TRY(m_binding_object.has_property(name));
+    auto still_exists = TRY(m_binding_object->has_property(name));
 
     // 3. If stillExists is false and S is true, throw a ReferenceError exception.
     if (!still_exists && strict)
         return vm.throw_completion<ReferenceError>(ErrorType::UnknownIdentifier, name);
 
     // 4. Perform ? Set(bindingObject, N, V, S).
-    auto result_or_error = m_binding_object.set(name, value, strict ? Object::ShouldThrowExceptions::Yes : Object::ShouldThrowExceptions::No);
+    auto result_or_error = m_binding_object->set(name, value, strict ? Object::ShouldThrowExceptions::Yes : Object::ShouldThrowExceptions::No);
 
     // Note: Nothing like this in the spec, this is here to produce nicer errors instead of the generic one thrown by Object::set().
     if (result_or_error.is_error() && strict) {
-        auto property_or_error = m_binding_object.internal_get_own_property(name);
+        auto property_or_error = m_binding_object->internal_get_own_property(name);
         // Return the initial error instead of masking it with the new error
         if (property_or_error.is_error())
             return result_or_error.release_error();
@@ -142,11 +142,11 @@ ThrowCompletionOr<Value> ObjectEnvironment::get_binding_value(VM&, DeprecatedFly
     //               We can't do this for with environments, since it would be observable (e.g via a Proxy)
     // FIXME: We could combine HasProperty and Get in non-strict mode if Get would return a bit more failure information.
     if (!m_with_environment && !strict)
-        return m_binding_object.get(name);
+        return m_binding_object->get(name);
 
     // 1. Let bindingObject be envRec.[[BindingObject]].
     // 2. Let value be ? HasProperty(bindingObject, N).
-    auto value = TRY(m_binding_object.has_property(name));
+    auto value = TRY(m_binding_object->has_property(name));
 
     // 3. If value is false, then
     if (!value) {
@@ -157,7 +157,7 @@ ThrowCompletionOr<Value> ObjectEnvironment::get_binding_value(VM&, DeprecatedFly
     }
 
     // 4. Return ? Get(bindingObject, N).
-    return m_binding_object.get(name);
+    return m_binding_object->get(name);
 }
 
 // 9.1.1.2.7 DeleteBinding ( N ), https://tc39.es/ecma262/#sec-object-environment-records-deletebinding-n
@@ -165,7 +165,7 @@ ThrowCompletionOr<bool> ObjectEnvironment::delete_binding(VM&, DeprecatedFlyStri
 {
     // 1. Let bindingObject be envRec.[[BindingObject]].
     // 2. Return ? bindingObject.[[Delete]](N).
-    return m_binding_object.internal_delete(name);
+    return m_binding_object->internal_delete(name);
 }
 
 }

+ 2 - 2
Userland/Libraries/LibJS/Runtime/ObjectEnvironment.h

@@ -31,7 +31,7 @@ public:
     virtual Object* with_base_object() const override
     {
         if (is_with_environment())
-            return &m_binding_object;
+            return m_binding_object;
         return nullptr;
     }
 
@@ -46,7 +46,7 @@ private:
 
     virtual void visit_edges(Visitor&) override;
 
-    Object& m_binding_object;
+    NonnullGCPtr<Object> m_binding_object;
     bool m_with_environment { false };
 };
 

+ 2 - 2
Userland/Libraries/LibJS/Runtime/PrimitiveString.h

@@ -62,8 +62,8 @@ private:
 
     mutable bool m_is_rope { false };
 
-    mutable PrimitiveString* m_lhs { nullptr };
-    mutable PrimitiveString* m_rhs { nullptr };
+    mutable GCPtr<PrimitiveString> m_lhs;
+    mutable GCPtr<PrimitiveString> m_rhs;
 
     mutable Optional<String> m_utf8_string;
     mutable Optional<DeprecatedString> m_deprecated_string;

+ 2 - 2
Userland/Libraries/LibJS/Runtime/PrivateEnvironment.h

@@ -49,8 +49,8 @@ private:
 
     static u64 s_next_id;
 
-    PrivateEnvironment* m_outer_environment { nullptr }; // [[OuterEnv]]
-    Vector<PrivateName> m_private_names;                 // [[Names]]
+    GCPtr<PrivateEnvironment> m_outer_environment; // [[OuterEnv]]
+    Vector<PrivateName> m_private_names;           // [[Names]]
     u64 m_unique_id;
 };
 

+ 4 - 4
Userland/Libraries/LibJS/Runtime/Promise.cpp

@@ -151,7 +151,7 @@ Promise::ResolvingFunctions Promise::create_resolving_functions()
         auto job = create_promise_resolve_thenable_job(vm, promise, resolution, move(then_job_callback));
 
         // 15. Perform HostEnqueuePromiseJob(job.[[Job]], job.[[Realm]]).
-        dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Enqueuing job @ {} in realm {}", &promise, &job.job, job.realm);
+        dbgln_if(PROMISE_DEBUG, "[Promise @ {} / PromiseResolvingFunction]: Enqueuing job @ {} in realm {}", &promise, &job.job, job.realm.ptr());
         vm.host_enqueue_promise_job(move(job.job), job.realm);
 
         // 16. Return undefined.
@@ -275,7 +275,7 @@ void Promise::trigger_reactions() const
         auto [job, realm] = create_promise_reaction_job(vm, *reaction, m_result);
 
         // b. Perform HostEnqueuePromiseJob(job.[[Job]], job.[[Realm]]).
-        dbgln_if(PROMISE_DEBUG, "[Promise @ {} / trigger_reactions()]: Enqueuing job @ {} in realm {}", this, &job, realm);
+        dbgln_if(PROMISE_DEBUG, "[Promise @ {} / trigger_reactions()]: Enqueuing job @ {} in realm {}", this, &job, realm.ptr());
         vm.host_enqueue_promise_job(move(job), realm);
     }
 
@@ -345,7 +345,7 @@ Value Promise::perform_then(Value on_fulfilled, Value on_rejected, GCPtr<Promise
         auto [fulfill_job, realm] = create_promise_reaction_job(vm, fulfill_reaction, value);
 
         // c. Perform HostEnqueuePromiseJob(fulfillJob.[[Job]], fulfillJob.[[Realm]]).
-        dbgln_if(PROMISE_DEBUG, "[Promise @ {} / perform_then()]: Enqueuing job @ {} in realm {}", this, &fulfill_job, realm);
+        dbgln_if(PROMISE_DEBUG, "[Promise @ {} / perform_then()]: Enqueuing job @ {} in realm {}", this, &fulfill_job, realm.ptr());
         vm.host_enqueue_promise_job(move(fulfill_job), realm);
         break;
     }
@@ -365,7 +365,7 @@ Value Promise::perform_then(Value on_fulfilled, Value on_rejected, GCPtr<Promise
         auto [reject_job, realm] = create_promise_reaction_job(vm, *reject_reaction, reason);
 
         // e. Perform HostEnqueuePromiseJob(rejectJob.[[Job]], rejectJob.[[Realm]]).
-        dbgln_if(PROMISE_DEBUG, "[Promise @ {} / perform_then()]: Enqueuing job @ {} in realm {}", this, &reject_job, realm);
+        dbgln_if(PROMISE_DEBUG, "[Promise @ {} / perform_then()]: Enqueuing job @ {} in realm {}", this, &reject_job, realm.ptr());
         vm.host_enqueue_promise_job(move(reject_job), realm);
         break;
     }

+ 7 - 7
Userland/Libraries/LibJS/Runtime/Promise.h

@@ -35,8 +35,8 @@ public:
     Value result() const { return m_result; }
 
     struct ResolvingFunctions {
-        FunctionObject& resolve;
-        FunctionObject& reject;
+        NonnullGCPtr<FunctionObject> resolve;
+        NonnullGCPtr<FunctionObject> reject;
     };
     ResolvingFunctions create_resolving_functions();
 
@@ -58,11 +58,11 @@ private:
     void trigger_reactions() const;
 
     // 27.2.6 Properties of Promise Instances, https://tc39.es/ecma262/#sec-properties-of-promise-instances
-    State m_state { State::Pending };             // [[PromiseState]]
-    Value m_result;                               // [[PromiseResult]]
-    Vector<PromiseReaction*> m_fulfill_reactions; // [[PromiseFulfillReactions]]
-    Vector<PromiseReaction*> m_reject_reactions;  // [[PromiseRejectReactions]]
-    bool m_is_handled { false };                  // [[PromiseIsHandled]]
+    State m_state { State::Pending };                   // [[PromiseState]]
+    Value m_result;                                     // [[PromiseResult]]
+    Vector<GCPtr<PromiseReaction>> m_fulfill_reactions; // [[PromiseFulfillReactions]]
+    Vector<GCPtr<PromiseReaction>> m_reject_reactions;  // [[PromiseRejectReactions]]
+    bool m_is_handled { false };                        // [[PromiseIsHandled]]
 };
 
 }

+ 2 - 2
Userland/Libraries/LibJS/Runtime/PromiseConstructor.cpp

@@ -298,12 +298,12 @@ ThrowCompletionOr<NonnullGCPtr<Object>> PromiseConstructor::construct(FunctionOb
     auto [resolve_function, reject_function] = promise->create_resolving_functions();
 
     // 9. Let completion be Completion(Call(executor, undefined, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »)).
-    auto completion = JS::call(vm, executor.as_function(), js_undefined(), &resolve_function, &reject_function);
+    auto completion = JS::call(vm, executor.as_function(), js_undefined(), resolve_function, reject_function);
 
     // 10. If completion is an abrupt completion, then
     if (completion.is_error()) {
         // a. Perform ? Call(resolvingFunctions.[[Reject]], undefined, « completion.[[Value]] »).
-        TRY(JS::call(vm, reject_function, js_undefined(), *completion.release_error().value()));
+        TRY(JS::call(vm, *reject_function, js_undefined(), *completion.release_error().value()));
     }
 
     // 11. Return promise.

+ 3 - 3
Userland/Libraries/LibJS/Runtime/PromiseJobs.cpp

@@ -129,15 +129,15 @@ static ThrowCompletionOr<Value> run_resolve_thenable_job(VM& vm, Promise& promis
     // b. Let thenCallResult be Completion(HostCallJobCallback(then, thenable, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »)).
     dbgln_if(PROMISE_DEBUG, "run_resolve_thenable_job: Calling then job callback for thenable {}", &thenable);
     MarkedVector<Value> arguments(vm.heap());
-    arguments.append(Value(&resolve_function));
-    arguments.append(Value(&reject_function));
+    arguments.append(Value(resolve_function));
+    arguments.append(Value(reject_function));
     auto then_call_result = vm.host_call_job_callback(then, thenable, move(arguments));
 
     // c. If thenCallResult is an abrupt completion, then
     if (then_call_result.is_error()) {
         // i. Return ? Call(resolvingFunctions.[[Reject]], undefined, « thenCallResult.[[Value]] »).
         dbgln_if(PROMISE_DEBUG, "run_resolve_thenable_job: then_call_result is an abrupt completion, calling reject function with value {}", *then_call_result.throw_completion().value());
-        return call(vm, &reject_function, js_undefined(), *then_call_result.throw_completion().value());
+        return call(vm, *reject_function, js_undefined(), *then_call_result.throw_completion().value());
     }
 
     // d. Return ? thenCallResult.

+ 1 - 1
Userland/Libraries/LibJS/Runtime/PromiseJobs.h

@@ -16,7 +16,7 @@ namespace JS {
 
 struct PromiseJob {
     Function<ThrowCompletionOr<Value>()> job;
-    Realm* realm { nullptr };
+    GCPtr<Realm> realm;
 };
 
 // NOTE: These return a PromiseJob to prevent awkward casting at call sites.

+ 14 - 14
Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.cpp

@@ -50,9 +50,9 @@ void PromiseResolvingElementFunction::visit_edges(Cell::Visitor& visitor)
 {
     Base::visit_edges(visitor);
 
-    visitor.visit(&m_values);
+    visitor.visit(m_values);
     visitor.visit(m_capability);
-    visitor.visit(&m_remaining_elements);
+    visitor.visit(m_remaining_elements);
 }
 
 NonnullGCPtr<PromiseAllResolveElementFunction> PromiseAllResolveElementFunction::create(Realm& realm, size_t index, PromiseValueList& values, NonnullGCPtr<PromiseCapability const> capability, RemainingElements& remaining_elements)
@@ -71,13 +71,13 @@ ThrowCompletionOr<Value> PromiseAllResolveElementFunction::resolve_element()
     auto& realm = *vm.current_realm();
 
     // 8. Set values[index] to x.
-    m_values.values()[m_index] = vm.argument(0);
+    m_values->values()[m_index] = vm.argument(0);
 
     // 9. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
     // 10. If remainingElementsCount.[[Value]] is 0, then
-    if (--m_remaining_elements.value == 0) {
+    if (--m_remaining_elements->value == 0) {
         // a. Let valuesArray be CreateArrayFromList(values).
-        auto values_array = Array::create_from(realm, m_values.values());
+        auto values_array = Array::create_from(realm, m_values->values());
 
         // b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
         return JS::call(vm, *m_capability->resolve(), js_undefined(), values_array);
@@ -112,13 +112,13 @@ ThrowCompletionOr<Value> PromiseAllSettledResolveElementFunction::resolve_elemen
     MUST(object->create_data_property_or_throw(vm.names.value, vm.argument(0)));
 
     // 12. Set values[index] to obj.
-    m_values.values()[m_index] = object;
+    m_values->values()[m_index] = object;
 
     // 13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
     // 14. If remainingElementsCount.[[Value]] is 0, then
-    if (--m_remaining_elements.value == 0) {
+    if (--m_remaining_elements->value == 0) {
         // a. Let valuesArray be CreateArrayFromList(values).
-        auto values_array = Array::create_from(realm, m_values.values());
+        auto values_array = Array::create_from(realm, m_values->values());
 
         // b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
         return JS::call(vm, *m_capability->resolve(), js_undefined(), values_array);
@@ -153,13 +153,13 @@ ThrowCompletionOr<Value> PromiseAllSettledRejectElementFunction::resolve_element
     MUST(object->create_data_property_or_throw(vm.names.reason, vm.argument(0)));
 
     // 12. Set values[index] to obj.
-    m_values.values()[m_index] = object;
+    m_values->values()[m_index] = object;
 
     // 13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
     // 14. If remainingElementsCount.[[Value]] is 0, then
-    if (--m_remaining_elements.value == 0) {
+    if (--m_remaining_elements->value == 0) {
         // a. Let valuesArray be CreateArrayFromList(values).
-        auto values_array = Array::create_from(realm, m_values.values());
+        auto values_array = Array::create_from(realm, m_values->values());
 
         // b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
         return JS::call(vm, *m_capability->resolve(), js_undefined(), values_array);
@@ -185,16 +185,16 @@ ThrowCompletionOr<Value> PromiseAnyRejectElementFunction::resolve_element()
     auto& realm = *vm.current_realm();
 
     // 8. Set errors[index] to x.
-    m_values.values()[m_index] = vm.argument(0);
+    m_values->values()[m_index] = vm.argument(0);
 
     // 9. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
     // 10. If remainingElementsCount.[[Value]] is 0, then
-    if (--m_remaining_elements.value == 0) {
+    if (--m_remaining_elements->value == 0) {
         // a. Let error be a newly created AggregateError object.
         auto error = AggregateError::create(realm);
 
         // b. Perform ! DefinePropertyOrThrow(error, "errors", PropertyDescriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: CreateArrayFromList(errors) }).
-        auto errors_array = Array::create_from(realm, m_values.values());
+        auto errors_array = Array::create_from(realm, m_values->values());
         MUST(error->define_property_or_throw(vm.names.errors, { .value = errors_array, .writable = true, .enumerable = false, .configurable = true }));
 
         // c. Return ? Call(promiseCapability.[[Reject]], undefined, « error »).

+ 2 - 2
Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.h

@@ -56,9 +56,9 @@ protected:
     virtual ThrowCompletionOr<Value> resolve_element() = 0;
 
     size_t m_index { 0 };
-    PromiseValueList& m_values;
+    NonnullGCPtr<PromiseValueList> m_values;
     NonnullGCPtr<PromiseCapability const> m_capability;
-    RemainingElements& m_remaining_elements;
+    NonnullGCPtr<RemainingElements> m_remaining_elements;
 
 private:
     virtual void visit_edges(Visitor&) override;

+ 2 - 2
Userland/Libraries/LibJS/Runtime/PromiseResolvingFunction.cpp

@@ -40,8 +40,8 @@ ThrowCompletionOr<Value> PromiseResolvingFunction::call()
 void PromiseResolvingFunction::visit_edges(Cell::Visitor& visitor)
 {
     Base::visit_edges(visitor);
-    visitor.visit(&m_promise);
-    visitor.visit(&m_already_resolved);
+    visitor.visit(m_promise);
+    visitor.visit(m_already_resolved);
 }
 
 }

+ 2 - 2
Userland/Libraries/LibJS/Runtime/PromiseResolvingFunction.h

@@ -40,8 +40,8 @@ private:
 
     virtual void visit_edges(Visitor&) override;
 
-    Promise& m_promise;
-    AlreadyResolved& m_already_resolved;
+    NonnullGCPtr<Promise> m_promise;
+    NonnullGCPtr<AlreadyResolved> m_already_resolved;
     FunctionType m_native_function;
 };
 

+ 4 - 4
Userland/Libraries/LibJS/Runtime/PropertyDescriptor.h

@@ -35,8 +35,8 @@ public:
     }
 
     Optional<Value> value {};
-    Optional<FunctionObject*> get {};
-    Optional<FunctionObject*> set {};
+    Optional<GCPtr<FunctionObject>> get {};
+    Optional<GCPtr<FunctionObject>> set {};
     Optional<bool> writable {};
     Optional<bool> enumerable {};
     Optional<bool> configurable {};
@@ -54,9 +54,9 @@ struct Formatter<JS::PropertyDescriptor> : Formatter<StringView> {
         if (property_descriptor.value.has_value())
             TRY(parts.try_append(TRY(String::formatted("[[Value]]: {}", TRY(property_descriptor.value->to_string_without_side_effects())))));
         if (property_descriptor.get.has_value())
-            TRY(parts.try_append(TRY(String::formatted("[[Get]]: JS::Function* @ {:p}", *property_descriptor.get))));
+            TRY(parts.try_append(TRY(String::formatted("[[Get]]: JS::Function* @ {:p}", property_descriptor.get->ptr()))));
         if (property_descriptor.set.has_value())
-            TRY(parts.try_append(TRY(String::formatted("[[Set]]: JS::Function* @ {:p}", *property_descriptor.set))));
+            TRY(parts.try_append(TRY(String::formatted("[[Set]]: JS::Function* @ {:p}", property_descriptor.set->ptr()))));
         if (property_descriptor.writable.has_value())
             TRY(parts.try_append(TRY(String::formatted("[[Writable]]: {}", *property_descriptor.writable))));
         if (property_descriptor.enumerable.has_value())

+ 63 - 63
Userland/Libraries/LibJS/Runtime/ProxyObject.cpp

@@ -55,30 +55,30 @@ ThrowCompletionOr<Object*> ProxyObject::internal_get_prototype_of() const
     // 4. Let target be O.[[ProxyTarget]].
 
     // 5. Let trap be ? GetMethod(handler, "getPrototypeOf").
-    auto trap = TRY(Value(&m_handler).get_method(vm, vm.names.getPrototypeOf));
+    auto trap = TRY(Value(m_handler).get_method(vm, vm.names.getPrototypeOf));
 
     // 6. If trap is undefined, then
     if (!trap) {
         // a. Return ? target.[[GetPrototypeOf]]().
-        return TRY(m_target.internal_get_prototype_of());
+        return TRY(m_target->internal_get_prototype_of());
     }
 
     // 7. Let handlerProto be ? Call(trap, handler, « target »).
-    auto handler_proto = TRY(call(vm, *trap, &m_handler, &m_target));
+    auto handler_proto = TRY(call(vm, *trap, m_handler, m_target));
 
     // 8. If Type(handlerProto) is neither Object nor Null, throw a TypeError exception.
     if (!handler_proto.is_object() && !handler_proto.is_null())
         return vm.throw_completion<TypeError>(ErrorType::ProxyGetPrototypeOfReturn);
 
     // 9. Let extensibleTarget be ? IsExtensible(target).
-    auto extensible_target = TRY(m_target.is_extensible());
+    auto extensible_target = TRY(m_target->is_extensible());
 
     // 10. If extensibleTarget is true, return handlerProto.
     if (extensible_target)
         return handler_proto.is_null() ? nullptr : &handler_proto.as_object();
 
     // 11. Let targetProto be ? target.[[GetPrototypeOf]]().
-    auto* target_proto = TRY(m_target.internal_get_prototype_of());
+    auto* target_proto = TRY(m_target->internal_get_prototype_of());
 
     // 12. If SameValue(handlerProto, targetProto) is false, throw a TypeError exception.
     if (!same_value(handler_proto, target_proto))
@@ -103,30 +103,30 @@ ThrowCompletionOr<bool> ProxyObject::internal_set_prototype_of(Object* prototype
     // 4. Let target be O.[[ProxyTarget]].
 
     // 5. Let trap be ? GetMethod(handler, "setPrototypeOf").
-    auto trap = TRY(Value(&m_handler).get_method(vm, vm.names.setPrototypeOf));
+    auto trap = TRY(Value(m_handler).get_method(vm, vm.names.setPrototypeOf));
 
     // 6. If trap is undefined, then
     if (!trap) {
         // a. Return ? target.[[SetPrototypeOf]](V).
-        return m_target.internal_set_prototype_of(prototype);
+        return m_target->internal_set_prototype_of(prototype);
     }
 
     // 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, V »)).
-    auto trap_result = TRY(call(vm, *trap, &m_handler, &m_target, prototype)).to_boolean();
+    auto trap_result = TRY(call(vm, *trap, m_handler, m_target, prototype)).to_boolean();
 
     // 8. If booleanTrapResult is false, return false.
     if (!trap_result)
         return false;
 
     // 9. Let extensibleTarget be ? IsExtensible(target).
-    auto extensible_target = TRY(m_target.is_extensible());
+    auto extensible_target = TRY(m_target->is_extensible());
 
     // 10. If extensibleTarget is true, return true.
     if (extensible_target)
         return true;
 
     // 11. Let targetProto be ? target.[[GetPrototypeOf]]().
-    auto* target_proto = TRY(m_target.internal_get_prototype_of());
+    auto* target_proto = TRY(m_target->internal_get_prototype_of());
 
     // 12. If SameValue(V, targetProto) is false, throw a TypeError exception.
     if (!same_value(prototype, target_proto))
@@ -151,19 +151,19 @@ ThrowCompletionOr<bool> ProxyObject::internal_is_extensible() const
     // 4. Let target be O.[[ProxyTarget]].
 
     // 5. Let trap be ? GetMethod(handler, "isExtensible").
-    auto trap = TRY(Value(&m_handler).get_method(vm, vm.names.isExtensible));
+    auto trap = TRY(Value(m_handler).get_method(vm, vm.names.isExtensible));
 
     // 6. If trap is undefined, then
     if (!trap) {
         // a. Return ? IsExtensible(target).
-        return m_target.is_extensible();
+        return m_target->is_extensible();
     }
 
     // 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target »)).
-    auto trap_result = TRY(call(vm, *trap, &m_handler, &m_target)).to_boolean();
+    auto trap_result = TRY(call(vm, *trap, m_handler, m_target)).to_boolean();
 
     // 8. Let targetResult be ? IsExtensible(target).
-    auto target_result = TRY(m_target.is_extensible());
+    auto target_result = TRY(m_target->is_extensible());
 
     // 9. If SameValue(booleanTrapResult, targetResult) is false, throw a TypeError exception.
     if (trap_result != target_result)
@@ -188,21 +188,21 @@ ThrowCompletionOr<bool> ProxyObject::internal_prevent_extensions()
     // 4. Let target be O.[[ProxyTarget]].
 
     // 5. Let trap be ? GetMethod(handler, "preventExtensions").
-    auto trap = TRY(Value(&m_handler).get_method(vm, vm.names.preventExtensions));
+    auto trap = TRY(Value(m_handler).get_method(vm, vm.names.preventExtensions));
 
     // 6. If trap is undefined, then
     if (!trap) {
         // a. Return ? target.[[PreventExtensions]]().
-        return m_target.internal_prevent_extensions();
+        return m_target->internal_prevent_extensions();
     }
 
     // 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target »)).
-    auto trap_result = TRY(call(vm, *trap, &m_handler, &m_target)).to_boolean();
+    auto trap_result = TRY(call(vm, *trap, m_handler, m_target)).to_boolean();
 
     // 8. If booleanTrapResult is true, then
     if (trap_result) {
         // a. Let extensibleTarget be ? IsExtensible(target).
-        auto extensible_target = TRY(m_target.is_extensible());
+        auto extensible_target = TRY(m_target->is_extensible());
 
         // b. If extensibleTarget is true, throw a TypeError exception.
         if (extensible_target)
@@ -230,23 +230,23 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> ProxyObject::internal_get_own_pr
     // 4. Let target be O.[[ProxyTarget]].
 
     // 5. Let trap be ? GetMethod(handler, "getOwnPropertyDescriptor").
-    auto trap = TRY(Value(&m_handler).get_method(vm, vm.names.getOwnPropertyDescriptor));
+    auto trap = TRY(Value(m_handler).get_method(vm, vm.names.getOwnPropertyDescriptor));
 
     // 6. If trap is undefined, then
     if (!trap) {
         // a. Return ? target.[[GetOwnProperty]](P).
-        return m_target.internal_get_own_property(property_key);
+        return m_target->internal_get_own_property(property_key);
     }
 
     // 7. Let trapResultObj be ? Call(trap, handler, « target, P »).
-    auto trap_result = TRY(call(vm, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key)));
+    auto trap_result = TRY(call(vm, *trap, m_handler, m_target, property_key_to_value(vm, property_key)));
 
     // 8. If Type(trapResultObj) is neither Object nor Undefined, throw a TypeError exception.
     if (!trap_result.is_object() && !trap_result.is_undefined())
         return vm.throw_completion<TypeError>(ErrorType::ProxyGetOwnDescriptorReturn);
 
     // 9. Let targetDesc be ? target.[[GetOwnProperty]](P).
-    auto target_descriptor = TRY(m_target.internal_get_own_property(property_key));
+    auto target_descriptor = TRY(m_target->internal_get_own_property(property_key));
 
     // 10. If trapResultObj is undefined, then
     if (trap_result.is_undefined()) {
@@ -259,7 +259,7 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> ProxyObject::internal_get_own_pr
             return vm.throw_completion<TypeError>(ErrorType::ProxyGetOwnDescriptorNonConfigurable);
 
         // c. Let extensibleTarget be ? IsExtensible(target).
-        auto extensible_target = TRY(m_target.is_extensible());
+        auto extensible_target = TRY(m_target->is_extensible());
 
         // d. If extensibleTarget is false, throw a TypeError exception.
         if (!extensible_target)
@@ -270,7 +270,7 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> ProxyObject::internal_get_own_pr
     }
 
     // 11. Let extensibleTarget be ? IsExtensible(target).
-    auto extensible_target = TRY(m_target.is_extensible());
+    auto extensible_target = TRY(m_target->is_extensible());
 
     // 12. Let resultDesc be ? ToPropertyDescriptor(trapResultObj).
     auto result_desc = TRY(to_property_descriptor(vm, trap_result));
@@ -321,29 +321,29 @@ ThrowCompletionOr<bool> ProxyObject::internal_define_own_property(PropertyKey co
     // 4. Let target be O.[[ProxyTarget]].
 
     // 5. Let trap be ? GetMethod(handler, "defineProperty").
-    auto trap = TRY(Value(&m_handler).get_method(vm, vm.names.defineProperty));
+    auto trap = TRY(Value(m_handler).get_method(vm, vm.names.defineProperty));
 
     // 6. If trap is undefined, then
     if (!trap) {
         // a. Return ? target.[[DefineOwnProperty]](P, Desc).
-        return m_target.internal_define_own_property(property_key, property_descriptor);
+        return m_target->internal_define_own_property(property_key, property_descriptor);
     }
 
     // 7. Let descObj be FromPropertyDescriptor(Desc).
     auto descriptor_object = from_property_descriptor(vm, property_descriptor);
 
     // 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, P, descObj »)).
-    auto trap_result = TRY(call(vm, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key), descriptor_object)).to_boolean();
+    auto trap_result = TRY(call(vm, *trap, m_handler, m_target, property_key_to_value(vm, property_key), descriptor_object)).to_boolean();
 
     // 9. If booleanTrapResult is false, return false.
     if (!trap_result)
         return false;
 
     // 10. Let targetDesc be ? target.[[GetOwnProperty]](P).
-    auto target_descriptor = TRY(m_target.internal_get_own_property(property_key));
+    auto target_descriptor = TRY(m_target->internal_get_own_property(property_key));
 
     // 11. Let extensibleTarget be ? IsExtensible(target).
-    auto extensible_target = TRY(m_target.is_extensible());
+    auto extensible_target = TRY(m_target->is_extensible());
 
     // 12. Else, let settingConfigFalse be false.
     bool setting_config_false = false;
@@ -403,21 +403,21 @@ ThrowCompletionOr<bool> ProxyObject::internal_has_property(PropertyKey const& pr
     // 4. Let target be O.[[ProxyTarget]].
 
     // 5. Let trap be ? GetMethod(handler, "has").
-    auto trap = TRY(Value(&m_handler).get_method(vm, vm.names.has));
+    auto trap = TRY(Value(m_handler).get_method(vm, vm.names.has));
 
     // 6. If trap is undefined, then
     if (!trap) {
         // a. Return ? target.[[HasProperty]](P).
-        return m_target.internal_has_property(property_key);
+        return m_target->internal_has_property(property_key);
     }
 
     // 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, P »)).
-    auto trap_result = TRY(call(vm, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key))).to_boolean();
+    auto trap_result = TRY(call(vm, *trap, m_handler, m_target, property_key_to_value(vm, property_key))).to_boolean();
 
     // 8. If booleanTrapResult is false, then
     if (!trap_result) {
         // a. Let targetDesc be ? target.[[GetOwnProperty]](P).
-        auto target_descriptor = TRY(m_target.internal_get_own_property(property_key));
+        auto target_descriptor = TRY(m_target->internal_get_own_property(property_key));
 
         // b. If targetDesc is not undefined, then
         if (target_descriptor.has_value()) {
@@ -426,7 +426,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_has_property(PropertyKey const& pr
                 return vm.throw_completion<TypeError>(ErrorType::ProxyHasExistingNonConfigurable);
 
             // ii. Let extensibleTarget be ? IsExtensible(target).
-            auto extensible_target = TRY(m_target.is_extensible());
+            auto extensible_target = TRY(m_target->is_extensible());
 
             // iii. If extensibleTarget is false, throw a TypeError exception.
             if (!extensible_target)
@@ -474,19 +474,19 @@ ThrowCompletionOr<Value> ProxyObject::internal_get(PropertyKey const& property_k
         return vm.throw_completion<InternalError>(ErrorType::CallStackSizeExceeded);
 
     // 5. Let trap be ? GetMethod(handler, "get").
-    auto trap = TRY(Value(&m_handler).get_method(vm, vm.names.get));
+    auto trap = TRY(Value(m_handler).get_method(vm, vm.names.get));
 
     // 6. If trap is undefined, then
     if (!trap) {
         // a. Return ? target.[[Get]](P, Receiver).
-        return m_target.internal_get(property_key, receiver);
+        return m_target->internal_get(property_key, receiver);
     }
 
     // 7. Let trapResult be ? Call(trap, handler, « target, P, Receiver »).
-    auto trap_result = TRY(call(vm, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key), receiver));
+    auto trap_result = TRY(call(vm, *trap, m_handler, m_target, property_key_to_value(vm, property_key), receiver));
 
     // 8. Let targetDesc be ? target.[[GetOwnProperty]](P).
-    auto target_descriptor = TRY(m_target.internal_get_own_property(property_key));
+    auto target_descriptor = TRY(m_target->internal_get_own_property(property_key));
 
     // 9. If targetDesc is not undefined and targetDesc.[[Configurable]] is false, then
     if (target_descriptor.has_value() && !*target_descriptor->configurable) {
@@ -527,23 +527,23 @@ ThrowCompletionOr<bool> ProxyObject::internal_set(PropertyKey const& property_ke
     // 4. Let target be O.[[ProxyTarget]].
 
     // 5. Let trap be ? GetMethod(handler, "set").
-    auto trap = TRY(Value(&m_handler).get_method(vm, vm.names.set));
+    auto trap = TRY(Value(m_handler).get_method(vm, vm.names.set));
 
     // 6. If trap is undefined, then
     if (!trap) {
         // a. Return ? target.[[Set]](P, V, Receiver).
-        return m_target.internal_set(property_key, value, receiver);
+        return m_target->internal_set(property_key, value, receiver);
     }
 
     // 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, P, V, Receiver »)).
-    auto trap_result = TRY(call(vm, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key), value, receiver)).to_boolean();
+    auto trap_result = TRY(call(vm, *trap, m_handler, m_target, property_key_to_value(vm, property_key), value, receiver)).to_boolean();
 
     // 8. If booleanTrapResult is false, return false.
     if (!trap_result)
         return false;
 
     // 9. Let targetDesc be ? target.[[GetOwnProperty]](P).
-    auto target_descriptor = TRY(m_target.internal_get_own_property(property_key));
+    auto target_descriptor = TRY(m_target->internal_get_own_property(property_key));
 
     // 10. If targetDesc is not undefined and targetDesc.[[Configurable]] is false, then
     if (target_descriptor.has_value() && !*target_descriptor->configurable) {
@@ -582,23 +582,23 @@ ThrowCompletionOr<bool> ProxyObject::internal_delete(PropertyKey const& property
     // 4. Let target be O.[[ProxyTarget]].
 
     // 5. Let trap be ? GetMethod(handler, "deleteProperty").
-    auto trap = TRY(Value(&m_handler).get_method(vm, vm.names.deleteProperty));
+    auto trap = TRY(Value(m_handler).get_method(vm, vm.names.deleteProperty));
 
     // 6. If trap is undefined, then
     if (!trap) {
         // a. Return ? target.[[Delete]](P).
-        return m_target.internal_delete(property_key);
+        return m_target->internal_delete(property_key);
     }
 
     // 7. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, P »)).
-    auto trap_result = TRY(call(vm, *trap, &m_handler, &m_target, property_key_to_value(vm, property_key))).to_boolean();
+    auto trap_result = TRY(call(vm, *trap, m_handler, m_target, property_key_to_value(vm, property_key))).to_boolean();
 
     // 8. If booleanTrapResult is false, return false.
     if (!trap_result)
         return false;
 
     // 9. Let targetDesc be ? target.[[GetOwnProperty]](P).
-    auto target_descriptor = TRY(m_target.internal_get_own_property(property_key));
+    auto target_descriptor = TRY(m_target->internal_get_own_property(property_key));
 
     // 10. If targetDesc is undefined, return true.
     if (!target_descriptor.has_value())
@@ -609,7 +609,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_delete(PropertyKey const& property
         return vm.throw_completion<TypeError>(ErrorType::ProxyDeleteNonConfigurable);
 
     // 12. Let extensibleTarget be ? IsExtensible(target).
-    auto extensible_target = TRY(m_target.is_extensible());
+    auto extensible_target = TRY(m_target->is_extensible());
 
     // 13. If extensibleTarget is false, throw a TypeError exception.
     if (!extensible_target)
@@ -634,16 +634,16 @@ ThrowCompletionOr<MarkedVector<Value>> ProxyObject::internal_own_property_keys()
     // 4. Let target be O.[[ProxyTarget]].
 
     // 5. Let trap be ? GetMethod(handler, "ownKeys").
-    auto trap = TRY(Value(&m_handler).get_method(vm, vm.names.ownKeys));
+    auto trap = TRY(Value(m_handler).get_method(vm, vm.names.ownKeys));
 
     // 6. If trap is undefined, then
     if (!trap) {
         // a. Return ? target.[[OwnPropertyKeys]]().
-        return m_target.internal_own_property_keys();
+        return m_target->internal_own_property_keys();
     }
 
     // 7. Let trapResultArray be ? Call(trap, handler, « target »).
-    auto trap_result_array = TRY(call(vm, *trap, &m_handler, &m_target));
+    auto trap_result_array = TRY(call(vm, *trap, m_handler, m_target));
 
     // 8. Let trapResult be ? CreateListFromArrayLike(trapResultArray, « String, Symbol »).
     HashTable<PropertyKey> unique_keys;
@@ -660,10 +660,10 @@ ThrowCompletionOr<MarkedVector<Value>> ProxyObject::internal_own_property_keys()
         return vm.throw_completion<TypeError>(ErrorType::ProxyOwnPropertyKeysDuplicates);
 
     // 10. Let extensibleTarget be ? IsExtensible(target).
-    auto extensible_target = TRY(m_target.is_extensible());
+    auto extensible_target = TRY(m_target->is_extensible());
 
     // 11. Let targetKeys be ? target.[[OwnPropertyKeys]]().
-    auto target_keys = TRY(m_target.internal_own_property_keys());
+    auto target_keys = TRY(m_target->internal_own_property_keys());
 
     // 12. Assert: targetKeys is a List of property keys.
     // 13. Assert: targetKeys contains no duplicate entries.
@@ -679,7 +679,7 @@ ThrowCompletionOr<MarkedVector<Value>> ProxyObject::internal_own_property_keys()
         auto property_key = MUST(PropertyKey::from_value(vm, key));
 
         // a. Let desc be ? target.[[GetOwnProperty]](key).
-        auto descriptor = TRY(m_target.internal_get_own_property(property_key));
+        auto descriptor = TRY(m_target->internal_get_own_property(property_key));
 
         // b. If desc is not undefined and desc.[[Configurable]] is false, then
         if (descriptor.has_value() && !*descriptor->configurable) {
@@ -758,19 +758,19 @@ ThrowCompletionOr<Value> ProxyObject::internal_call(Value this_argument, MarkedV
     // 4. Let target be O.[[ProxyTarget]].
 
     // 5. Let trap be ? GetMethod(handler, "apply").
-    auto trap = TRY(Value(&m_handler).get_method(vm, vm.names.apply));
+    auto trap = TRY(Value(m_handler).get_method(vm, vm.names.apply));
 
     // 6. If trap is undefined, then
     if (!trap) {
         // a. Return ? Call(target, thisArgument, argumentsList).
-        return call(vm, &m_target, this_argument, move(arguments_list));
+        return call(vm, m_target, this_argument, move(arguments_list));
     }
 
     // 7. Let argArray be CreateArrayFromList(argumentsList).
     auto arguments_array = Array::create_from(realm, arguments_list);
 
     // 8. Return ? Call(trap, handler, « target, thisArgument, argArray »).
-    return call(vm, trap, &m_handler, &m_target, this_argument, arguments_array);
+    return call(vm, trap, m_handler, m_target, this_argument, arguments_array);
 }
 
 bool ProxyObject::has_constructor() const
@@ -780,7 +780,7 @@ bool ProxyObject::has_constructor() const
     if (!is_function())
         return false;
 
-    return static_cast<FunctionObject&>(m_target).has_constructor();
+    return static_cast<FunctionObject&>(*m_target).has_constructor();
 }
 
 // 10.5.13 [[Construct]] ( argumentsList, newTarget ), https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget
@@ -803,19 +803,19 @@ ThrowCompletionOr<NonnullGCPtr<Object>> ProxyObject::internal_construct(MarkedVe
     // 5. Assert: IsConstructor(target) is true.
 
     // 6. Let trap be ? GetMethod(handler, "construct").
-    auto trap = TRY(Value(&m_handler).get_method(vm, vm.names.construct));
+    auto trap = TRY(Value(m_handler).get_method(vm, vm.names.construct));
 
     // 7. If trap is undefined, then
     if (!trap) {
         // a. Return ? Construct(target, argumentsList, newTarget).
-        return construct(vm, static_cast<FunctionObject&>(m_target), move(arguments_list), &new_target);
+        return construct(vm, static_cast<FunctionObject&>(*m_target), move(arguments_list), &new_target);
     }
 
     // 8. Let argArray be CreateArrayFromList(argumentsList).
     auto arguments_array = Array::create_from(realm, arguments_list);
 
     // 9. Let newObj be ? Call(trap, handler, « target, argArray, newTarget »).
-    auto new_object = TRY(call(vm, trap, &m_handler, &m_target, arguments_array, &new_target));
+    auto new_object = TRY(call(vm, trap, m_handler, m_target, arguments_array, &new_target));
 
     // 10. If Type(newObj) is not Object, throw a TypeError exception.
     if (!new_object.is_object())
@@ -828,14 +828,14 @@ ThrowCompletionOr<NonnullGCPtr<Object>> ProxyObject::internal_construct(MarkedVe
 void ProxyObject::visit_edges(Cell::Visitor& visitor)
 {
     Base::visit_edges(visitor);
-    visitor.visit(&m_target);
-    visitor.visit(&m_handler);
+    visitor.visit(m_target);
+    visitor.visit(m_handler);
 }
 
 DeprecatedFlyString const& ProxyObject::name() const
 {
     VERIFY(is_function());
-    return static_cast<FunctionObject&>(m_target).name();
+    return static_cast<FunctionObject&>(*m_target).name();
 }
 
 }

+ 3 - 3
Userland/Libraries/LibJS/Runtime/ProxyObject.h

@@ -50,11 +50,11 @@ private:
 
     virtual void visit_edges(Visitor&) override;
 
-    virtual bool is_function() const override { return m_target.is_function(); }
+    virtual bool is_function() const override { return m_target->is_function(); }
     virtual bool is_proxy_object() const final { return true; }
 
-    Object& m_target;
-    Object& m_handler;
+    NonnullGCPtr<Object> m_target;
+    NonnullGCPtr<Object> m_handler;
     bool m_is_revoked { false };
 };
 

+ 4 - 4
Userland/Libraries/LibJS/Runtime/Realm.h

@@ -53,10 +53,10 @@ private:
 
     virtual void visit_edges(Visitor&) override;
 
-    Intrinsics* m_intrinsics { nullptr };                // [[Intrinsics]]
-    Object* m_global_object { nullptr };                 // [[GlobalObject]]
-    GlobalEnvironment* m_global_environment { nullptr }; // [[GlobalEnv]]
-    OwnPtr<HostDefined> m_host_defined;                  // [[HostDefined]]
+    GCPtr<Intrinsics> m_intrinsics;                // [[Intrinsics]]
+    GCPtr<Object> m_global_object;                 // [[GlobalObject]]
+    GCPtr<GlobalEnvironment> m_global_environment; // [[GlobalEnv]]
+    OwnPtr<HostDefined> m_host_defined;            // [[HostDefined]]
 };
 
 }

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Reference.cpp

@@ -207,7 +207,7 @@ ThrowCompletionOr<void> Reference::initialize_referenced_binding(VM& vm, Value v
 Reference make_private_reference(VM& vm, Value base_value, DeprecatedFlyString const& private_identifier)
 {
     // 1. Let privEnv be the running execution context's PrivateEnvironment.
-    auto* private_environment = vm.running_execution_context().private_environment;
+    auto private_environment = vm.running_execution_context().private_environment;
 
     // 2. Assert: privEnv is not null.
     VERIFY(private_environment);

+ 1 - 1
Userland/Libraries/LibJS/Runtime/RegExpStringIterator.cpp

@@ -27,7 +27,7 @@ RegExpStringIterator::RegExpStringIterator(Object& prototype, Object& regexp_obj
 void RegExpStringIterator::visit_edges(Cell::Visitor& visitor)
 {
     Base::visit_edges(visitor);
-    visitor.visit(&m_regexp_object);
+    visitor.visit(m_regexp_object);
 }
 
 }

+ 1 - 1
Userland/Libraries/LibJS/Runtime/RegExpStringIterator.h

@@ -33,7 +33,7 @@ private:
 
     virtual void visit_edges(Cell::Visitor&) override;
 
-    Object& m_regexp_object;
+    NonnullGCPtr<Object> m_regexp_object;
     Utf16String m_string;
     bool m_global { false };
     bool m_unicode { false };

+ 1 - 1
Userland/Libraries/LibJS/Runtime/SetIterator.cpp

@@ -25,7 +25,7 @@ SetIterator::SetIterator(Set& set, Object::PropertyKind iteration_kind, Object&
 void SetIterator::visit_edges(Cell::Visitor& visitor)
 {
     Base::visit_edges(visitor);
-    visitor.visit(&m_set);
+    visitor.visit(m_set);
 }
 
 }

+ 1 - 1
Userland/Libraries/LibJS/Runtime/SetIterator.h

@@ -31,7 +31,7 @@ private:
 
     virtual void visit_edges(Cell::Visitor&) override;
 
-    Set& m_set;
+    NonnullGCPtr<Set> m_set;
     bool m_done { false };
     Object::PropertyKind m_iteration_kind;
     Map::ConstIterator m_iterator;

+ 2 - 2
Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp

@@ -30,7 +30,7 @@ void ShadowRealm::visit_edges(Visitor& visitor)
 {
     Base::visit_edges(visitor);
 
-    visitor.visit(&m_shadow_realm);
+    visitor.visit(m_shadow_realm);
 }
 
 // 3.1.2 CopyNameAndLength ( F: a function object, Target: a function object, optional prefix: a String, optional argCount: a Number, ), https://tc39.es/proposal-shadowrealm/#sec-copynameandlength
@@ -239,7 +239,7 @@ ThrowCompletionOr<Value> shadow_realm_import_value(VM& vm, DeprecatedString spec
         VERIFY(is<ModuleNamespaceObject>(exports));
 
         // 2. Let f be the active function object.
-        auto* function = vm.running_execution_context().function;
+        auto function = vm.running_execution_context().function;
 
         // 3. Let string be f.[[ExportNameString]].
         // 4. Assert: Type(string) is String.

+ 1 - 1
Userland/Libraries/LibJS/Runtime/ShadowRealm.h

@@ -30,7 +30,7 @@ private:
     virtual void visit_edges(Visitor&) override;
 
     // 3.5 Properties of ShadowRealm Instances, https://tc39.es/proposal-shadowrealm/#sec-properties-of-shadowrealm-instances
-    Realm& m_shadow_realm;                // [[ShadowRealm]]
+    NonnullGCPtr<Realm> m_shadow_realm;   // [[ShadowRealm]]
     ExecutionContext m_execution_context; // [[ExecutionContext]]
 };
 

+ 3 - 3
Userland/Libraries/LibJS/Runtime/Shape.cpp

@@ -82,7 +82,7 @@ Shape* Shape::create_prototype_transition(Object* new_prototype)
         return existing_shape;
     auto new_shape = heap().allocate_without_realm<Shape>(*this, new_prototype);
     if (!m_prototype_transitions)
-        m_prototype_transitions = make<HashMap<Object*, WeakPtr<Shape>>>();
+        m_prototype_transitions = make<HashMap<GCPtr<Object>, WeakPtr<Shape>>>();
     m_prototype_transitions->set(new_prototype, new_shape.ptr());
     return new_shape;
 }
@@ -115,7 +115,7 @@ Shape::Shape(Shape& previous_shape, Object* new_prototype)
 void Shape::visit_edges(Cell::Visitor& visitor)
 {
     Cell::visit_edges(visitor);
-    visitor.visit(&m_realm);
+    visitor.visit(m_realm);
     visitor.visit(m_prototype);
     visitor.visit(m_previous);
     m_property_key.visit_edges(visitor);
@@ -162,7 +162,7 @@ void Shape::ensure_property_table() const
     u32 next_offset = 0;
 
     Vector<Shape const&, 64> transition_chain;
-    for (auto* shape = m_previous; shape; shape = shape->m_previous) {
+    for (auto shape = m_previous; shape; shape = shape->m_previous) {
         if (shape->m_property_table) {
             *m_property_table = *shape->m_property_table;
             next_offset = shape->m_property_count;

+ 4 - 4
Userland/Libraries/LibJS/Runtime/Shape.h

@@ -93,15 +93,15 @@ private:
 
     void ensure_property_table() const;
 
-    Realm& m_realm;
+    NonnullGCPtr<Realm> m_realm;
 
     mutable OwnPtr<HashMap<StringOrSymbol, PropertyMetadata>> m_property_table;
 
     OwnPtr<HashMap<TransitionKey, WeakPtr<Shape>>> m_forward_transitions;
-    OwnPtr<HashMap<Object*, WeakPtr<Shape>>> m_prototype_transitions;
-    Shape* m_previous { nullptr };
+    OwnPtr<HashMap<GCPtr<Object>, WeakPtr<Shape>>> m_prototype_transitions;
+    GCPtr<Shape> m_previous;
     StringOrSymbol m_property_key;
-    Object* m_prototype { nullptr };
+    GCPtr<Object> m_prototype;
     u32 m_property_count { 0 };
 
     PropertyAttributes m_attributes { 0 };

+ 3 - 3
Userland/Libraries/LibJS/Runtime/StringObject.cpp

@@ -31,7 +31,7 @@ ThrowCompletionOr<void> StringObject::initialize(Realm& realm)
     auto& vm = this->vm();
     MUST_OR_THROW_OOM(Base::initialize(realm));
 
-    define_direct_property(vm.names.length, Value(MUST_OR_THROW_OOM(m_string.utf16_string_view()).length_in_code_units()), 0);
+    define_direct_property(vm.names.length, Value(MUST_OR_THROW_OOM(m_string->utf16_string_view()).length_in_code_units()), 0);
 
     return {};
 }
@@ -39,7 +39,7 @@ ThrowCompletionOr<void> StringObject::initialize(Realm& realm)
 void StringObject::visit_edges(Cell::Visitor& visitor)
 {
     Base::visit_edges(visitor);
-    visitor.visit(&m_string);
+    visitor.visit(m_string);
 }
 
 // 10.4.3.5 StringGetOwnProperty ( S, P ), https://tc39.es/ecma262/#sec-stringgetownproperty
@@ -133,7 +133,7 @@ ThrowCompletionOr<MarkedVector<Value>> StringObject::internal_own_property_keys(
     auto keys = MarkedVector<Value> { heap() };
 
     // 2. Let str be O.[[StringData]].
-    auto str = TRY(m_string.utf16_string_view());
+    auto str = TRY(m_string->utf16_string_view());
 
     // 3. Assert: Type(str) is String.
 

+ 1 - 1
Userland/Libraries/LibJS/Runtime/StringObject.h

@@ -33,7 +33,7 @@ private:
     virtual bool is_string_object() const final { return true; }
     virtual void visit_edges(Visitor&) override;
 
-    PrimitiveString& m_string;
+    NonnullGCPtr<PrimitiveString> m_string;
 };
 
 template<>

+ 1 - 1
Userland/Libraries/LibJS/Runtime/SymbolObject.cpp

@@ -24,7 +24,7 @@ SymbolObject::SymbolObject(Symbol& symbol, Object& prototype)
 void SymbolObject::visit_edges(Cell::Visitor& visitor)
 {
     Base::visit_edges(visitor);
-    visitor.visit(&m_symbol);
+    visitor.visit(m_symbol);
 }
 
 }

+ 1 - 1
Userland/Libraries/LibJS/Runtime/SymbolObject.h

@@ -27,7 +27,7 @@ private:
 
     virtual void visit_edges(Visitor&) override;
 
-    Symbol& m_symbol;
+    NonnullGCPtr<Symbol> m_symbol;
 };
 
 }

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.h

@@ -122,7 +122,7 @@ struct DifferenceSettings {
     String largest_unit;
     String rounding_mode;
     u64 rounding_increment;
-    Object& options;
+    NonnullGCPtr<Object> options;
 };
 
 struct TemporalUnitRequired { };

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Temporal/Instant.cpp

@@ -33,7 +33,7 @@ void Instant::visit_edges(Cell::Visitor& visitor)
 {
     Base::visit_edges(visitor);
 
-    visitor.visit(&m_nanoseconds);
+    visitor.visit(m_nanoseconds);
 }
 
 // 8.5.1 IsValidEpochNanoseconds ( epochNanoseconds ), https://tc39.es/proposal-temporal/#sec-temporal-isvalidepochnanoseconds

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Temporal/Instant.h

@@ -30,7 +30,7 @@ private:
     virtual void visit_edges(Visitor&) override;
 
     // 8.4 Properties of Temporal.Instant Instances, https://tc39.es/proposal-temporal/#sec-properties-of-temporal-instant-instances
-    BigInt const& m_nanoseconds; // [[Nanoseconds]]
+    NonnullGCPtr<BigInt const> m_nanoseconds; // [[Nanoseconds]]
 };
 
 // https://tc39.es/proposal-temporal/#eqn-nsMaxInstant

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp

@@ -35,7 +35,7 @@ PlainDate::PlainDate(i32 year, u8 month, u8 day, Object& calendar, Object& proto
 void PlainDate::visit_edges(Visitor& visitor)
 {
     Base::visit_edges(visitor);
-    visitor.visit(&m_calendar);
+    visitor.visit(m_calendar);
 }
 
 // 3.5.2 CreateISODateRecord ( year, month, day ), https://tc39.es/proposal-temporal/#sec-temporal-create-iso-date-record

+ 4 - 4
Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.h

@@ -32,10 +32,10 @@ private:
     virtual void visit_edges(Visitor&) override;
 
     // 3.4 Properties of Temporal.PlainDate Instances, https://tc39.es/proposal-temporal/#sec-properties-of-temporal-plaindate-instances
-    i32 m_iso_year { 0 }; // [[ISOYear]]
-    u8 m_iso_month { 1 }; // [[ISOMonth]]
-    u8 m_iso_day { 1 };   // [[ISODay]]
-    Object& m_calendar;   // [[Calendar]]
+    i32 m_iso_year { 0 };            // [[ISOYear]]
+    u8 m_iso_month { 1 };            // [[ISOMonth]]
+    u8 m_iso_day { 1 };              // [[ISODay]]
+    NonnullGCPtr<Object> m_calendar; // [[Calendar]]
 };
 
 // 3.5.1 ISO Date Records, https://tc39.es/proposal-temporal/#sec-temporal-iso-date-records

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp

@@ -42,7 +42,7 @@ PlainDateTime::PlainDateTime(i32 iso_year, u8 iso_month, u8 iso_day, u8 iso_hour
 void PlainDateTime::visit_edges(Visitor& visitor)
 {
     Base::visit_edges(visitor);
-    visitor.visit(&m_calendar);
+    visitor.visit(m_calendar);
 }
 
 // nsMinInstant - nsPerDay

+ 10 - 10
Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.h

@@ -39,16 +39,16 @@ private:
     virtual void visit_edges(Visitor&) override;
 
     // 5.4 Properties of Temporal.PlainDateTime Instances, https://tc39.es/proposal-temporal/#sec-properties-of-temporal-plaindatetime-instances
-    i32 m_iso_year { 0 };        // [[ISOYear]]
-    u8 m_iso_month { 0 };        // [[ISOMonth]]
-    u8 m_iso_day { 0 };          // [[ISODay]]
-    u8 m_iso_hour { 0 };         // [[ISOHour]]
-    u8 m_iso_minute { 0 };       // [[ISOMinute]]
-    u8 m_iso_second { 0 };       // [[ISOSecond]]
-    u16 m_iso_millisecond { 0 }; // [[ISOMillisecond]]
-    u16 m_iso_microsecond { 0 }; // [[ISOMicrosecond]]
-    u16 m_iso_nanosecond { 0 };  // [[ISONanosecond]]
-    Object& m_calendar;          // [[Calendar]]
+    i32 m_iso_year { 0 };            // [[ISOYear]]
+    u8 m_iso_month { 0 };            // [[ISOMonth]]
+    u8 m_iso_day { 0 };              // [[ISODay]]
+    u8 m_iso_hour { 0 };             // [[ISOHour]]
+    u8 m_iso_minute { 0 };           // [[ISOMinute]]
+    u8 m_iso_second { 0 };           // [[ISOSecond]]
+    u16 m_iso_millisecond { 0 };     // [[ISOMillisecond]]
+    u16 m_iso_microsecond { 0 };     // [[ISOMicrosecond]]
+    u16 m_iso_nanosecond { 0 };      // [[ISONanosecond]]
+    NonnullGCPtr<Object> m_calendar; // [[Calendar]]
 };
 
 // Used by AddDateTime to temporarily hold values

Vissa filer visades inte eftersom för många filer har ändrats