mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 22:37:35 +00:00
LibJS: Capture UnrealizedSourceRanges in ExecutionContext, not ASTNodes
This loosens the connection to the AST interpreter and will allow us to generate SourceRanges for the Bytecode interpreter in the future as well Moves UnrealizedSourceRanges from TracebackFrame to the JS namespace for this
This commit is contained in:
parent
cd9bb985d4
commit
50bf303edd
11 changed files with 33 additions and 32 deletions
|
@ -154,8 +154,8 @@ ThrowCompletionOr<Value> ECMAScriptFunctionObject::internal_call(Value this_argu
|
|||
|
||||
// Non-standard
|
||||
callee_context.arguments.extend(move(arguments_list));
|
||||
if (auto* interpreter = vm.interpreter_if_exists())
|
||||
callee_context.current_node = interpreter->current_node();
|
||||
if (auto* interpreter = vm.interpreter_if_exists(); interpreter && interpreter->current_node())
|
||||
callee_context.source_range = interpreter->current_node()->unrealized_source_range();
|
||||
|
||||
// 2. Let calleeContext be PrepareForOrdinaryCall(F, undefined).
|
||||
// NOTE: We throw if the end of the native stack is reached, so unlike in the spec this _does_ need an exception check.
|
||||
|
@ -225,8 +225,8 @@ ThrowCompletionOr<NonnullGCPtr<Object>> ECMAScriptFunctionObject::internal_const
|
|||
|
||||
// Non-standard
|
||||
callee_context.arguments.extend(move(arguments_list));
|
||||
if (auto* interpreter = vm.interpreter_if_exists())
|
||||
callee_context.current_node = interpreter->current_node();
|
||||
if (auto* interpreter = vm.interpreter_if_exists(); interpreter && interpreter->current_node())
|
||||
callee_context.source_range = interpreter->current_node()->unrealized_source_range();
|
||||
|
||||
// 4. Let calleeContext be PrepareForOrdinaryCall(F, newTarget).
|
||||
// NOTE: We throw if the end of the native stack is reached, so unlike in the spec this _does_ need an exception check.
|
||||
|
|
|
@ -23,7 +23,7 @@ SourceRange const& TracebackFrame::source_range() const
|
|||
static auto dummy_source_code = SourceCode::create(String {}, String {});
|
||||
return SourceRange { dummy_source_code, {}, {} };
|
||||
}
|
||||
return unrealized->source_code->range_from_offsets(unrealized->start_offset, unrealized->end_offset);
|
||||
return unrealized->realize();
|
||||
}();
|
||||
source_range_storage = move(source_range);
|
||||
}
|
||||
|
@ -85,20 +85,9 @@ void Error::populate_stack()
|
|||
|
||||
TracebackFrame frame {
|
||||
.function_name = move(function_name),
|
||||
.source_range_storage = TracebackFrame::UnrealizedSourceRange {},
|
||||
.source_range_storage = context->source_range,
|
||||
};
|
||||
|
||||
// We might not have an AST node associated with the execution context, e.g. in promise
|
||||
// reaction jobs (which aren't called anywhere from the source code).
|
||||
// They're not going to generate any _unhandled_ exceptions though, so a meaningless
|
||||
// source range is fine.
|
||||
if (context->current_node) {
|
||||
auto* unrealized = frame.source_range_storage.get_pointer<TracebackFrame::UnrealizedSourceRange>();
|
||||
unrealized->source_code = context->current_node->source_code();
|
||||
unrealized->start_offset = context->current_node->start_offset();
|
||||
unrealized->end_offset = context->current_node->end_offset();
|
||||
}
|
||||
|
||||
m_traceback.append(move(frame));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,11 +19,6 @@ struct TracebackFrame {
|
|||
DeprecatedFlyString function_name;
|
||||
[[nodiscard]] SourceRange const& source_range() const;
|
||||
|
||||
struct UnrealizedSourceRange {
|
||||
u32 start_offset { 0 };
|
||||
u32 end_offset { 0 };
|
||||
RefPtr<JS::SourceCode const> source_code;
|
||||
};
|
||||
mutable Variant<SourceRange, UnrealizedSourceRange> source_range_storage;
|
||||
};
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ ExecutionContext ExecutionContext::copy() const
|
|||
copy.lexical_environment = lexical_environment;
|
||||
copy.variable_environment = variable_environment;
|
||||
copy.private_environment = private_environment;
|
||||
copy.current_node = current_node;
|
||||
copy.source_range = source_range;
|
||||
copy.function_name = function_name;
|
||||
copy.this_value = this_value;
|
||||
copy.is_strict_mode = is_strict_mode;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <LibJS/Module.h>
|
||||
#include <LibJS/Runtime/PrivateEnvironment.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
#include <LibJS/SourceRange.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
|
@ -42,7 +43,7 @@ public:
|
|||
// Non-standard: This points at something that owns this ExecutionContext, in case it needs to be protected from GC.
|
||||
GCPtr<Cell> context_owner;
|
||||
|
||||
ASTNode const* current_node { nullptr };
|
||||
UnrealizedSourceRange source_range;
|
||||
DeprecatedFlyString function_name;
|
||||
Value this_value;
|
||||
MarkedVector<Value> arguments;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/AST.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Runtime/FunctionEnvironment.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
|
@ -141,8 +142,8 @@ ThrowCompletionOr<Value> NativeFunction::internal_call(Value this_argument, Mark
|
|||
// NOTE: This is a LibJS specific hack for NativeFunction to inherit the strictness of its caller.
|
||||
callee_context.is_strict_mode = vm.in_strict_mode();
|
||||
|
||||
if (auto* interpreter = vm.interpreter_if_exists())
|
||||
callee_context.current_node = interpreter->current_node();
|
||||
if (auto* interpreter = vm.interpreter_if_exists(); interpreter && interpreter->current_node())
|
||||
callee_context.source_range = interpreter->current_node()->unrealized_source_range();
|
||||
|
||||
// </8.> --------------------------------------------------------------------------
|
||||
|
||||
|
@ -204,8 +205,8 @@ ThrowCompletionOr<NonnullGCPtr<Object>> NativeFunction::internal_construct(Marke
|
|||
// NOTE: This is a LibJS specific hack for NativeFunction to inherit the strictness of its caller.
|
||||
callee_context.is_strict_mode = vm.in_strict_mode();
|
||||
|
||||
if (auto* interpreter = vm.interpreter_if_exists())
|
||||
callee_context.current_node = interpreter->current_node();
|
||||
if (auto* interpreter = vm.interpreter_if_exists(); interpreter && interpreter->current_node())
|
||||
callee_context.source_range = interpreter->current_node()->unrealized_source_range();
|
||||
|
||||
// </8.> --------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -805,8 +805,8 @@ void VM::dump_backtrace() const
|
|||
{
|
||||
for (ssize_t i = m_execution_context_stack.size() - 1; i >= 0; --i) {
|
||||
auto& frame = m_execution_context_stack[i];
|
||||
if (frame->current_node) {
|
||||
auto source_range = frame->current_node->source_range();
|
||||
if (frame->source_range.source_code) {
|
||||
auto source_range = frame->source_range.realize();
|
||||
dbgln("-> {} @ {}:{},{}", frame->function_name, source_range.filename(), source_range.start.line, source_range.start.column);
|
||||
} else {
|
||||
dbgln("-> {}", frame->function_name);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue