Commit 6f6a5404 authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

[wasm][debug] Compile source only once for Debug-Evaluate.

We accidentally compiled the source for Debug-Evaluate on Wasm frames
twice, and used the first script result as outer function info for the
second, actual compile (which goes via the `eval` machinery).

Also unify DebugEvaluate::Local and DebugEvaluate::WebAssembly, since
they are essentially very similar, except for the context.

Bug: chromium:1127914
Change-Id: I8eb85c128c05ab1d4fcb73061de89b0942d1e5c8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2605198
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Auto-Submit: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71890}
parent cbed76b7
...@@ -78,58 +78,37 @@ MaybeHandle<Object> DebugEvaluate::Local(Isolate* isolate, ...@@ -78,58 +78,37 @@ MaybeHandle<Object> DebugEvaluate::Local(Isolate* isolate,
// Get the frame where the debugging is performed. // Get the frame where the debugging is performed.
StackTraceFrameIterator it(isolate, frame_id); StackTraceFrameIterator it(isolate, frame_id);
if (!it.is_javascript()) return isolate->factory()->undefined_value(); if (it.is_javascript()) {
JavaScriptFrame* frame = it.javascript_frame(); JavaScriptFrame* frame = it.javascript_frame();
// This is not a lot different than DebugEvaluate::Global, except that
// variables accessible by the function we are evaluating from are
// materialized and included on top of the native context. Changes to
// the materialized object are written back afterwards.
// Note that the native context is taken from the original context chain,
// which may not be the current native context of the isolate.
ContextBuilder context_builder(isolate, frame, inlined_jsframe_index);
if (isolate->has_pending_exception()) return {};
// This is not a lot different than DebugEvaluate::Global, except that Handle<Context> context = context_builder.evaluation_context();
// variables accessible by the function we are evaluating from are Handle<JSObject> receiver(context->global_proxy(), isolate);
// materialized and included on top of the native context. Changes to MaybeHandle<Object> maybe_result =
// the materialized object are written back afterwards. Evaluate(isolate, context_builder.outer_info(), context, receiver,
// Note that the native context is taken from the original context chain, source, throw_on_side_effect);
// which may not be the current native context of the isolate. if (!maybe_result.is_null()) context_builder.UpdateValues();
ContextBuilder context_builder(isolate, frame, inlined_jsframe_index); return maybe_result;
if (isolate->has_pending_exception()) return MaybeHandle<Object>(); } else {
CHECK(it.is_wasm());
Handle<Context> context = context_builder.evaluation_context(); WasmFrame* frame = WasmFrame::cast(it.frame());
Handle<JSObject> receiver(context->global_proxy(), isolate); Handle<SharedFunctionInfo> outer_info(
MaybeHandle<Object> maybe_result = isolate->native_context()->empty_function().shared(), isolate);
Evaluate(isolate, context_builder.outer_info(), context, receiver, source, Handle<JSProxy> context_extension = WasmJs::GetJSDebugProxy(frame);
throw_on_side_effect); Handle<ScopeInfo> scope_info =
if (!maybe_result.is_null()) context_builder.UpdateValues(); ScopeInfo::CreateForWithScope(isolate, Handle<ScopeInfo>::null());
return maybe_result; Handle<Context> context = isolate->factory()->NewWithContext(
} isolate->native_context(), scope_info, context_extension);
return Evaluate(isolate, outer_info, context, context_extension, source,
V8_EXPORT MaybeHandle<Object> DebugEvaluate::WebAssembly( throw_on_side_effect);
Handle<WasmInstanceObject> instance, StackFrameId frame_id,
Handle<String> source, bool throw_on_side_effect) {
Isolate* isolate = instance->GetIsolate();
StackTraceFrameIterator it(isolate, frame_id);
if (!it.is_wasm()) return isolate->factory()->undefined_value();
WasmFrame* frame = WasmFrame::cast(it.frame());
Handle<JSProxy> context_extension = WasmJs::GetJSDebugProxy(frame);
DisableBreak disable_break_scope(isolate->debug(), /*disable=*/true);
Handle<SharedFunctionInfo> shared_info;
if (!GetFunctionInfo(isolate, source, REPLMode::kNo).ToHandle(&shared_info)) {
return {};
}
Handle<ScopeInfo> scope_info =
ScopeInfo::CreateForWithScope(isolate, Handle<ScopeInfo>::null());
Handle<Context> context = isolate->factory()->NewWithContext(
isolate->native_context(), scope_info, context_extension);
Handle<Object> result;
if (!DebugEvaluate::Evaluate(isolate, shared_info, context, context_extension,
source, throw_on_side_effect)
.ToHandle(&result)) {
return {};
} }
return result;
} }
MaybeHandle<Object> DebugEvaluate::WithTopmostArguments(Isolate* isolate, MaybeHandle<Object> DebugEvaluate::WithTopmostArguments(Isolate* isolate,
......
...@@ -32,15 +32,14 @@ class DebugEvaluate : public AllStatic { ...@@ -32,15 +32,14 @@ class DebugEvaluate : public AllStatic {
// - Parameters and stack-allocated locals need to be materialized. Altered // - Parameters and stack-allocated locals need to be materialized. Altered
// values need to be written back to the stack afterwards. // values need to be written back to the stack afterwards.
// - The arguments object needs to materialized. // - The arguments object needs to materialized.
// The stack frame can be either a JavaScript stack frame or a Wasm
// stack frame. In the latter case, a special Debug Proxy API is
// provided to peek into the Wasm state.
static MaybeHandle<Object> Local(Isolate* isolate, StackFrameId frame_id, static MaybeHandle<Object> Local(Isolate* isolate, StackFrameId frame_id,
int inlined_jsframe_index, int inlined_jsframe_index,
Handle<String> source, Handle<String> source,
bool throw_on_side_effect); bool throw_on_side_effect);
static V8_EXPORT MaybeHandle<Object> WebAssembly(
Handle<WasmInstanceObject> instance, StackFrameId frame_id,
Handle<String> source, bool throw_on_side_effect);
// This is used for break-at-entry for builtins and API functions. // This is used for break-at-entry for builtins and API functions.
// Evaluate a piece of JavaScript in the native context, but with the // Evaluate a piece of JavaScript in the native context, but with the
// materialized arguments object and receiver of the current call. // materialized arguments object and receiver of the current call.
......
...@@ -178,23 +178,10 @@ v8::MaybeLocal<v8::Value> DebugStackTraceIterator::Evaluate( ...@@ -178,23 +178,10 @@ v8::MaybeLocal<v8::Value> DebugStackTraceIterator::Evaluate(
Handle<Object> value; Handle<Object> value;
i::SafeForInterruptsScope safe_for_interrupt_scope(isolate_); i::SafeForInterruptsScope safe_for_interrupt_scope(isolate_);
bool success = false; if (!DebugEvaluate::Local(isolate_, iterator_.frame()->id(),
if (iterator_.is_wasm()) { inlined_frame_index_, Utils::OpenHandle(*source),
FrameSummary summary = FrameSummary::Get(iterator_.frame(), 0); throw_on_side_effect)
const FrameSummary::WasmFrameSummary& wasmSummary = summary.AsWasm(); .ToHandle(&value)) {
Handle<WasmInstanceObject> instance = wasmSummary.wasm_instance();
success = DebugEvaluate::WebAssembly(instance, iterator_.frame()->id(),
Utils::OpenHandle(*source),
throw_on_side_effect)
.ToHandle(&value);
} else {
success = DebugEvaluate::Local(
isolate_, iterator_.frame()->id(), inlined_frame_index_,
Utils::OpenHandle(*source), throw_on_side_effect)
.ToHandle(&value);
}
if (!success) {
isolate_->OptionalRescheduleException(false); isolate_->OptionalRescheduleException(false);
return v8::MaybeLocal<v8::Value>(); return v8::MaybeLocal<v8::Value>();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment