mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 13:28:11 +00:00
LibJS: Make ExecutionContext::function_name a GCPtr<PrimitiveString>
This required setting things up so that all function objects can plop a PrimitiveString there instead of an AK string. This is a step towards making ExecutionContext easier to allocate.
This commit is contained in:
parent
eda2a6d9f7
commit
845da3901d
9 changed files with 34 additions and 16 deletions
|
@ -142,9 +142,9 @@ ThrowCompletionOr<Value> Console::trace()
|
||||||
// NOTE: -2 to skip the console.trace() execution context
|
// NOTE: -2 to skip the console.trace() execution context
|
||||||
for (ssize_t i = execution_context_stack.size() - 2; i >= 0; --i) {
|
for (ssize_t i = execution_context_stack.size() - 2; i >= 0; --i) {
|
||||||
auto const& function_name = execution_context_stack[i]->function_name;
|
auto const& function_name = execution_context_stack[i]->function_name;
|
||||||
trace.stack.append(function_name.is_empty()
|
trace.stack.append((!function_name || function_name->is_empty())
|
||||||
? "<anonymous>"_string
|
? "<anonymous>"_string
|
||||||
: TRY_OR_THROW_OOM(vm, String::from_deprecated_string(function_name)));
|
: function_name->utf8_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Optionally, let formattedData be the result of Formatter(data), and incorporate formattedData as a label for trace.
|
// 2. Optionally, let formattedData be the result of Formatter(data), and incorporate formattedData as a label for trace.
|
||||||
|
|
|
@ -333,8 +333,10 @@ void ECMAScriptFunctionObject::initialize(Realm& realm)
|
||||||
// which must give the properties in chronological order which in this case is the order they
|
// which must give the properties in chronological order which in this case is the order they
|
||||||
// are defined in the spec.
|
// are defined in the spec.
|
||||||
|
|
||||||
|
m_name_string = PrimitiveString::create(vm, m_name);
|
||||||
|
|
||||||
MUST(define_property_or_throw(vm.names.length, { .value = Value(m_function_length), .writable = false, .enumerable = false, .configurable = true }));
|
MUST(define_property_or_throw(vm.names.length, { .value = Value(m_function_length), .writable = false, .enumerable = false, .configurable = true }));
|
||||||
MUST(define_property_or_throw(vm.names.name, { .value = PrimitiveString::create(vm, m_name.is_null() ? "" : m_name), .writable = false, .enumerable = false, .configurable = true }));
|
MUST(define_property_or_throw(vm.names.name, { .value = m_name_string, .writable = false, .enumerable = false, .configurable = true }));
|
||||||
|
|
||||||
if (!m_is_arrow_function) {
|
if (!m_is_arrow_function) {
|
||||||
Object* prototype = nullptr;
|
Object* prototype = nullptr;
|
||||||
|
@ -936,7 +938,7 @@ ThrowCompletionOr<void> ECMAScriptFunctionObject::prepare_for_ordinary_call(Exec
|
||||||
|
|
||||||
// 3. Set the Function of calleeContext to F.
|
// 3. Set the Function of calleeContext to F.
|
||||||
callee_context.function = this;
|
callee_context.function = this;
|
||||||
callee_context.function_name = m_name;
|
callee_context.function_name = m_name_string;
|
||||||
|
|
||||||
// 4. Let calleeRealm be F.[[Realm]].
|
// 4. Let calleeRealm be F.[[Realm]].
|
||||||
auto callee_realm = m_realm;
|
auto callee_realm = m_realm;
|
||||||
|
@ -1243,6 +1245,7 @@ void ECMAScriptFunctionObject::set_name(DeprecatedFlyString const& name)
|
||||||
VERIFY(!name.is_null());
|
VERIFY(!name.is_null());
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
m_name = name;
|
m_name = name;
|
||||||
MUST(define_property_or_throw(vm.names.name, { .value = PrimitiveString::create(vm, m_name), .writable = false, .enumerable = false, .configurable = true }));
|
m_name_string = PrimitiveString::create(vm, m_name);
|
||||||
|
MUST(define_property_or_throw(vm.names.name, { .value = m_name_string, .writable = false, .enumerable = false, .configurable = true }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,6 +112,8 @@ private:
|
||||||
ThrowCompletionOr<void> function_declaration_instantiation();
|
ThrowCompletionOr<void> function_declaration_instantiation();
|
||||||
|
|
||||||
DeprecatedFlyString m_name;
|
DeprecatedFlyString m_name;
|
||||||
|
GCPtr<PrimitiveString> m_name_string;
|
||||||
|
|
||||||
GCPtr<Bytecode::Executable> m_bytecode_executable;
|
GCPtr<Bytecode::Executable> m_bytecode_executable;
|
||||||
Vector<NonnullGCPtr<Bytecode::Executable>> m_default_parameter_bytecode_executables;
|
Vector<NonnullGCPtr<Bytecode::Executable>> m_default_parameter_bytecode_executables;
|
||||||
i32 m_function_length { 0 };
|
i32 m_function_length { 0 };
|
||||||
|
|
|
@ -85,7 +85,7 @@ void Error::populate_stack()
|
||||||
if (element.source_range.has_value())
|
if (element.source_range.has_value())
|
||||||
range = element.source_range.value();
|
range = element.source_range.value();
|
||||||
TracebackFrame frame {
|
TracebackFrame frame {
|
||||||
.function_name = context->function_name,
|
.function_name = context->function_name ? context->function_name->deprecated_string() : "",
|
||||||
.source_range_storage = range,
|
.source_range_storage = range,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ void ExecutionContext::visit_edges(Cell::Visitor& visitor)
|
||||||
visitor.visit(this_value);
|
visitor.visit(this_value);
|
||||||
if (instruction_stream_iterator.has_value())
|
if (instruction_stream_iterator.has_value())
|
||||||
visitor.visit(const_cast<Bytecode::Executable*>(instruction_stream_iterator.value().executable()));
|
visitor.visit(const_cast<Bytecode::Executable*>(instruction_stream_iterator.value().executable()));
|
||||||
|
visitor.visit(function_name);
|
||||||
script_or_module.visit(
|
script_or_module.visit(
|
||||||
[](Empty) {},
|
[](Empty) {},
|
||||||
[&](auto& script_or_module) {
|
[&](auto& script_or_module) {
|
||||||
|
|
|
@ -49,7 +49,7 @@ public:
|
||||||
GCPtr<Cell> context_owner;
|
GCPtr<Cell> context_owner;
|
||||||
|
|
||||||
Optional<Bytecode::InstructionStreamIterator> instruction_stream_iterator;
|
Optional<Bytecode::InstructionStreamIterator> instruction_stream_iterator;
|
||||||
DeprecatedFlyString function_name;
|
GCPtr<PrimitiveString> function_name;
|
||||||
Value this_value;
|
Value this_value;
|
||||||
MarkedVector<Value> arguments;
|
MarkedVector<Value> arguments;
|
||||||
MarkedVector<Value> local_variables;
|
MarkedVector<Value> local_variables;
|
||||||
|
|
|
@ -17,6 +17,20 @@ namespace JS {
|
||||||
|
|
||||||
JS_DEFINE_ALLOCATOR(NativeFunction);
|
JS_DEFINE_ALLOCATOR(NativeFunction);
|
||||||
|
|
||||||
|
void NativeFunction::initialize(Realm& realm)
|
||||||
|
{
|
||||||
|
Base::initialize(realm);
|
||||||
|
m_name_string = PrimitiveString::create(vm(), m_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeFunction::visit_edges(Cell::Visitor& visitor)
|
||||||
|
{
|
||||||
|
Base::visit_edges(visitor);
|
||||||
|
visitor.visit(m_native_function);
|
||||||
|
visitor.visit(m_realm);
|
||||||
|
visitor.visit(m_name_string);
|
||||||
|
}
|
||||||
|
|
||||||
// 10.3.3 CreateBuiltinFunction ( behaviour, length, name, additionalInternalSlotsList [ , realm [ , prototype [ , prefix ] ] ] ), https://tc39.es/ecma262/#sec-createbuiltinfunction
|
// 10.3.3 CreateBuiltinFunction ( behaviour, length, name, additionalInternalSlotsList [ , realm [ , prototype [ , prefix ] ] ] ), https://tc39.es/ecma262/#sec-createbuiltinfunction
|
||||||
// NOTE: This doesn't consider additionalInternalSlotsList, which is rarely used, and can either be implemented using only the `function` lambda, or needs a NativeFunction subclass.
|
// NOTE: This doesn't consider additionalInternalSlotsList, which is rarely used, and can either be implemented using only the `function` lambda, or needs a NativeFunction subclass.
|
||||||
NonnullGCPtr<NativeFunction> NativeFunction::create(Realm& allocating_realm, Function<ThrowCompletionOr<Value>(VM&)> behaviour, i32 length, PropertyKey const& name, Optional<Realm*> realm, Optional<Object*> prototype, Optional<StringView> const& prefix)
|
NonnullGCPtr<NativeFunction> NativeFunction::create(Realm& allocating_realm, Function<ThrowCompletionOr<Value>(VM&)> behaviour, i32 length, PropertyKey const& name, Optional<Realm*> realm, Optional<Object*> prototype, Optional<StringView> const& prefix)
|
||||||
|
@ -111,7 +125,7 @@ ThrowCompletionOr<Value> NativeFunction::internal_call(Value this_argument, Read
|
||||||
|
|
||||||
// 4. Set the Function of calleeContext to F.
|
// 4. Set the Function of calleeContext to F.
|
||||||
callee_context.function = this;
|
callee_context.function = this;
|
||||||
callee_context.function_name = m_name;
|
callee_context.function_name = m_name_string;
|
||||||
|
|
||||||
// 5. Let calleeRealm be F.[[Realm]].
|
// 5. Let calleeRealm be F.[[Realm]].
|
||||||
auto callee_realm = m_realm;
|
auto callee_realm = m_realm;
|
||||||
|
@ -175,7 +189,7 @@ ThrowCompletionOr<NonnullGCPtr<Object>> NativeFunction::internal_construct(Reado
|
||||||
|
|
||||||
// 4. Set the Function of calleeContext to F.
|
// 4. Set the Function of calleeContext to F.
|
||||||
callee_context.function = this;
|
callee_context.function = this;
|
||||||
callee_context.function_name = m_name;
|
callee_context.function_name = m_name_string;
|
||||||
|
|
||||||
// 5. Let calleeRealm be F.[[Realm]].
|
// 5. Let calleeRealm be F.[[Realm]].
|
||||||
auto callee_realm = m_realm;
|
auto callee_realm = m_realm;
|
||||||
|
|
|
@ -48,16 +48,14 @@ protected:
|
||||||
NativeFunction(DeprecatedFlyString name, JS::GCPtr<JS::HeapFunction<ThrowCompletionOr<Value>(VM&)>>, Object& prototype);
|
NativeFunction(DeprecatedFlyString name, JS::GCPtr<JS::HeapFunction<ThrowCompletionOr<Value>(VM&)>>, Object& prototype);
|
||||||
explicit NativeFunction(Object& prototype);
|
explicit NativeFunction(Object& prototype);
|
||||||
|
|
||||||
virtual void visit_edges(Cell::Visitor& visitor) override
|
virtual void initialize(Realm&) override;
|
||||||
{
|
virtual void visit_edges(Cell::Visitor& visitor) override;
|
||||||
Base::visit_edges(visitor);
|
|
||||||
visitor.visit(m_native_function);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual bool is_native_function() const final { return true; }
|
virtual bool is_native_function() const final { return true; }
|
||||||
|
|
||||||
DeprecatedFlyString m_name;
|
DeprecatedFlyString m_name;
|
||||||
|
GCPtr<PrimitiveString> m_name_string;
|
||||||
Optional<DeprecatedFlyString> m_initial_name; // [[InitialName]]
|
Optional<DeprecatedFlyString> m_initial_name; // [[InitialName]]
|
||||||
JS::GCPtr<JS::HeapFunction<ThrowCompletionOr<Value>(VM&)>> m_native_function;
|
JS::GCPtr<JS::HeapFunction<ThrowCompletionOr<Value>(VM&)>> m_native_function;
|
||||||
GCPtr<Realm> m_realm;
|
GCPtr<Realm> m_realm;
|
||||||
|
|
|
@ -749,9 +749,9 @@ void VM::dump_backtrace() const
|
||||||
auto& frame = m_execution_context_stack[i];
|
auto& frame = m_execution_context_stack[i];
|
||||||
if (frame->instruction_stream_iterator.has_value() && frame->instruction_stream_iterator->source_code()) {
|
if (frame->instruction_stream_iterator.has_value() && frame->instruction_stream_iterator->source_code()) {
|
||||||
auto source_range = frame->instruction_stream_iterator->source_range().realize();
|
auto source_range = frame->instruction_stream_iterator->source_range().realize();
|
||||||
dbgln("-> {} @ {}:{},{}", frame->function_name, source_range.filename(), source_range.start.line, source_range.start.column);
|
dbgln("-> {} @ {}:{},{}", frame->function_name ? frame->function_name->utf8_string() : ""_string, source_range.filename(), source_range.start.line, source_range.start.column);
|
||||||
} else {
|
} else {
|
||||||
dbgln("-> {}", frame->function_name);
|
dbgln("-> {}", frame->function_name ? frame->function_name->utf8_string() : ""_string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue