Commit f10edd09 authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

[inspector][wasm] Re-add WasmValue as JSObject subclass.

BREAKING CHANGE: The values of Wasm locals, stack, and globals are now
represented as objects instead of holding the (primitive) values
directly, and SIMD128 values are no longer represented as Uint8Arrays.
The DWARF extension has been prepared for this breaking change.

The new `WasmValue` comes with `type` and `value` properties that hold
its contents. The motivation here is that this is a more extensible
approach. In case of SIMD128, the `value` property holds the canonical
string representation, which has the additional advantage that these
values can be compared with `===` (and `==`).

This partially reverts https://crrev.com/c/2614428, the main difference
here being that WasmValue is now a proper JSObject that can be exposed
on the DebugEvaluate proxy API.

Screenshot: https://imgur.com/rcahNKM.png
Bug: chromium:1170282, chromium:1071432, chromium:1159402
Change-Id: Iea304e3680775123c41deb4c3d172ac949da1b98
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2643384Reviewed-by: 's avatarPhilip Pfaffe <pfaffe@chromium.org>
Reviewed-by: 's avatarZhi An Ng <zhin@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72570}
parent 3af1d7c3
...@@ -1359,6 +1359,7 @@ torque_files = [ ...@@ -1359,6 +1359,7 @@ torque_files = [
"src/builtins/typed-array.tq", "src/builtins/typed-array.tq",
"src/builtins/wasm.tq", "src/builtins/wasm.tq",
"src/builtins/weak-ref.tq", "src/builtins/weak-ref.tq",
"src/debug/debug-wasm-objects.tq",
"src/ic/handler-configuration.tq", "src/ic/handler-configuration.tq",
"src/objects/allocation-site.tq", "src/objects/allocation-site.tq",
"src/objects/api-callbacks.tq", "src/objects/api-callbacks.tq",
...@@ -2652,8 +2653,9 @@ v8_source_set("v8_base_without_compiler") { ...@@ -2652,8 +2653,9 @@ v8_source_set("v8_base_without_compiler") {
"src/debug/debug-stack-trace-iterator.h", "src/debug/debug-stack-trace-iterator.h",
"src/debug/debug-type-profile.cc", "src/debug/debug-type-profile.cc",
"src/debug/debug-type-profile.h", "src/debug/debug-type-profile.h",
"src/debug/debug-wasm-support.cc", "src/debug/debug-wasm-objects-inl.h",
"src/debug/debug-wasm-support.h", "src/debug/debug-wasm-objects.cc",
"src/debug/debug-wasm-objects.h",
"src/debug/debug.cc", "src/debug/debug.cc",
"src/debug/debug.h", "src/debug/debug.h",
"src/debug/interface-types.h", "src/debug/interface-types.h",
......
...@@ -1030,6 +1030,7 @@ domain Runtime ...@@ -1030,6 +1030,7 @@ domain Runtime
arraybuffer arraybuffer
dataview dataview
webassemblymemory webassemblymemory
wasmvalue
# Object class (constructor) name. Specified for `object` type values only. # Object class (constructor) name. Specified for `object` type values only.
optional string className optional string className
# Remote object value in case of primitive values or JSON values (if it was requested). # Remote object value in case of primitive values or JSON values (if it was requested).
......
...@@ -263,6 +263,7 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) { ...@@ -263,6 +263,7 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) {
case WASM_MODULE_OBJECT_TYPE: case WASM_MODULE_OBJECT_TYPE:
case WASM_STRUCT_TYPE: case WASM_STRUCT_TYPE:
case WASM_TABLE_OBJECT_TYPE: case WASM_TABLE_OBJECT_TYPE:
case WASM_VALUE_OBJECT_TYPE:
case WEAK_CELL_TYPE: case WEAK_CELL_TYPE:
DCHECK(!map.is_callable()); DCHECK(!map.is_callable());
DCHECK(!map.is_undetectable()); DCHECK(!map.is_undetectable());
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#include "src/common/globals.h" #include "src/common/globals.h"
#include "src/debug/debug-frames.h" #include "src/debug/debug-frames.h"
#include "src/debug/debug-scopes.h" #include "src/debug/debug-scopes.h"
#include "src/debug/debug-wasm-support.h" #include "src/debug/debug-wasm-objects.h"
#include "src/debug/debug.h" #include "src/debug/debug.h"
#include "src/execution/frames-inl.h" #include "src/execution/frames-inl.h"
#include "src/execution/isolate-inl.h" #include "src/execution/isolate-inl.h"
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "src/debug/debug-evaluate.h" #include "src/debug/debug-evaluate.h"
#include "src/debug/debug-property-iterator.h" #include "src/debug/debug-property-iterator.h"
#include "src/debug/debug-type-profile.h" #include "src/debug/debug-type-profile.h"
#include "src/debug/debug-wasm-objects-inl.h"
#include "src/debug/debug.h" #include "src/debug/debug.h"
#include "src/execution/vm-state-inl.h" #include "src/execution/vm-state-inl.h"
#include "src/objects/js-generator-inl.h" #include "src/objects/js-generator-inl.h"
...@@ -740,6 +741,12 @@ void AccessorPair::CheckCast(Value* that) { ...@@ -740,6 +741,12 @@ void AccessorPair::CheckCast(Value* that) {
"Value is not a v8::debug::AccessorPair"); "Value is not a v8::debug::AccessorPair");
} }
void WasmValueObject::CheckCast(Value* that) {
i::Handle<i::Object> obj = Utils::OpenHandle(that);
Utils::ApiCheck(obj->IsWasmValueObject(), "v8::debug::WasmValueObject::Cast",
"Value is not a v8::debug::WasmValueObject");
}
Local<Function> GetBuiltin(Isolate* v8_isolate, Builtin builtin) { Local<Function> GetBuiltin(Isolate* v8_isolate, Builtin builtin) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
...@@ -1102,6 +1109,27 @@ bool AccessorPair::IsAccessorPair(Local<Value> that) { ...@@ -1102,6 +1109,27 @@ bool AccessorPair::IsAccessorPair(Local<Value> that) {
return obj->IsAccessorPair(); return obj->IsAccessorPair();
} }
bool WasmValueObject::IsWasmValueObject(Local<Value> that) {
i::Handle<i::Object> obj = Utils::OpenHandle(*that);
return obj->IsWasmValueObject();
}
Local<String> WasmValueObject::type() const {
i::Handle<i::WasmValueObject> object =
i::Handle<i::WasmValueObject>::cast(Utils::OpenHandle(this));
i::Isolate* isolate = object->GetIsolate();
i::Handle<i::String> type(object->type(), isolate);
return Utils::ToLocal(type);
}
Local<Value> WasmValueObject::value() const {
i::Handle<i::WasmValueObject> object =
i::Handle<i::WasmValueObject>::cast(Utils::OpenHandle(this));
i::Isolate* isolate = object->GetIsolate();
i::Handle<i::Object> value(object->value(), isolate);
return Utils::ToLocal(value);
}
MaybeLocal<Message> GetMessageFromPromise(Local<Promise> p) { MaybeLocal<Message> GetMessageFromPromise(Local<Promise> p) {
i::Handle<i::JSPromise> promise = Utils::OpenHandle(*p); i::Handle<i::JSPromise> promise = Utils::OpenHandle(*p);
i::Isolate* isolate = promise->GetIsolate(); i::Isolate* isolate = promise->GetIsolate();
......
...@@ -616,6 +616,19 @@ class PropertyIterator { ...@@ -616,6 +616,19 @@ class PropertyIterator {
virtual bool is_array_index() = 0; virtual bool is_array_index() = 0;
}; };
class V8_EXPORT_PRIVATE WasmValueObject : public v8::Object {
public:
WasmValueObject() = delete;
static bool IsWasmValueObject(v8::Local<v8::Value> obj);
V8_INLINE static WasmValueObject* Cast(v8::Value* obj);
v8::Local<v8::String> type() const;
v8::Local<v8::Value> value() const;
private:
static void CheckCast(v8::Value* obj);
};
AccessorPair* AccessorPair::Cast(v8::Value* value) { AccessorPair* AccessorPair::Cast(v8::Value* value) {
#ifdef V8_ENABLE_CHECKS #ifdef V8_ENABLE_CHECKS
CheckCast(value); CheckCast(value);
...@@ -623,6 +636,13 @@ AccessorPair* AccessorPair::Cast(v8::Value* value) { ...@@ -623,6 +636,13 @@ AccessorPair* AccessorPair::Cast(v8::Value* value) {
return static_cast<AccessorPair*>(value); return static_cast<AccessorPair*>(value);
} }
WasmValueObject* WasmValueObject::Cast(v8::Value* value) {
#ifdef V8_ENABLE_CHECKS
CheckCast(value);
#endif
return static_cast<WasmValueObject*>(value);
}
MaybeLocal<Message> GetMessageFromPromise(Local<Promise> promise); MaybeLocal<Message> GetMessageFromPromise(Local<Promise> promise);
} // namespace debug } // namespace debug
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include "src/api/api-inl.h" #include "src/api/api-inl.h"
#include "src/debug/debug-evaluate.h" #include "src/debug/debug-evaluate.h"
#include "src/debug/debug-scope-iterator.h" #include "src/debug/debug-scope-iterator.h"
#include "src/debug/debug-wasm-support.h" #include "src/debug/debug-wasm-objects.h"
#include "src/debug/debug.h" #include "src/debug/debug.h"
#include "src/debug/liveedit.h" #include "src/debug/liveedit.h"
#include "src/execution/frames-inl.h" #include "src/execution/frames-inl.h"
......
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_DEBUG_DEBUG_WASM_OBJECTS_INL_H_
#define V8_DEBUG_DEBUG_WASM_OBJECTS_INL_H_
#include "src/debug/debug-wasm-objects.h"
#include "src/objects/js-objects-inl.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8 {
namespace internal {
#include "torque-generated/src/debug/debug-wasm-objects-tq-inl.inc"
OBJECT_CONSTRUCTORS_IMPL(WasmValueObject, JSObject)
CAST_ACCESSOR(WasmValueObject)
ACCESSORS(WasmValueObject, type, String, kTypeOffset)
ACCESSORS(WasmValueObject, value, Object, kValueOffset)
} // namespace internal
} // namespace v8
#include "src/objects/object-macros-undef.h"
#endif // V8_DEBUG_DEBUG_WASM_OBJECTS_INL_H_
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "src/debug/debug-wasm-support.h" #include "src/debug/debug-wasm-objects.h"
#include "src/api/api-inl.h" #include "src/api/api-inl.h"
#include "src/api/api-natives.h" #include "src/api/api-natives.h"
#include "src/debug/debug-wasm-objects-inl.h"
#include "src/execution/frames-inl.h" #include "src/execution/frames-inl.h"
#include "src/objects/property-descriptor.h" #include "src/objects/property-descriptor.h"
#include "src/wasm/wasm-debug.h" #include "src/wasm/wasm-debug.h"
...@@ -16,49 +17,6 @@ namespace v8 { ...@@ -16,49 +17,6 @@ namespace v8 {
namespace internal { namespace internal {
namespace { namespace {
// Convert a WasmValue to an appropriate JS representation.
Handle<Object> WasmValueToObject(Isolate* isolate, wasm::WasmValue value) {
auto* factory = isolate->factory();
switch (value.type().kind()) {
case wasm::ValueType::kI32:
return factory->NewNumberFromInt(value.to_i32());
case wasm::ValueType::kI64:
return BigInt::FromInt64(isolate, value.to_i64());
case wasm::ValueType::kF32:
return factory->NewNumber(value.to_f32());
case wasm::ValueType::kF64:
return factory->NewNumber(value.to_f64());
case wasm::ValueType::kS128: {
wasm::Simd128 s128 = value.to_s128();
Handle<JSArrayBuffer> buffer;
if (!factory
->NewJSArrayBufferAndBackingStore(
kSimd128Size, InitializedFlag::kUninitialized)
.ToHandle(&buffer)) {
isolate->FatalProcessOutOfHeapMemory(
"failed to allocate backing store");
}
base::Memcpy(buffer->allocation_base(), s128.bytes(),
buffer->byte_length());
auto array = factory->NewJSTypedArray(kExternalUint8Array, buffer, 0,
kSimd128Size);
JSObject::SetPrototype(array, factory->null_value(), false, kDontThrow)
.Check();
return array;
}
case wasm::ValueType::kRef:
return value.to_externref();
default:
break;
}
return factory->undefined_value();
}
} // namespace
namespace {
// Helper for unpacking a maybe name that makes a default with an index if // Helper for unpacking a maybe name that makes a default with an index if
// the name is empty. If the name is not empty, it's prefixed with a $. // the name is empty. If the name is not empty, it's prefixed with a $.
Handle<String> GetNameOrDefault(Isolate* isolate, Handle<String> GetNameOrDefault(Isolate* isolate,
...@@ -124,6 +82,18 @@ enum DebugProxyId { ...@@ -124,6 +82,18 @@ enum DebugProxyId {
kNumInstanceProxies = kLastInstanceProxyId + 1 kNumInstanceProxies = kLastInstanceProxyId + 1
}; };
constexpr int kWasmValueMapIndex = kNumProxies;
constexpr int kNumDebugMaps = kWasmValueMapIndex + 1;
Handle<FixedArray> GetOrCreateDebugMaps(Isolate* isolate) {
Handle<FixedArray> maps = isolate->wasm_debug_maps();
if (maps->length() == 0) {
maps = isolate->factory()->NewFixedArrayWithHoles(kNumDebugMaps);
isolate->native_context()->set_wasm_debug_maps(*maps);
}
return maps;
}
// Creates a Map for the given debug proxy |id| using the |create_template_fn| // Creates a Map for the given debug proxy |id| using the |create_template_fn|
// on-demand and caches this map in the global object. The map is derived from // on-demand and caches this map in the global object. The map is derived from
// the FunctionTemplate returned by |create_template_fn| and has it's prototype // the FunctionTemplate returned by |create_template_fn| and has it's prototype
...@@ -131,12 +101,8 @@ enum DebugProxyId { ...@@ -131,12 +101,8 @@ enum DebugProxyId {
Handle<Map> GetOrCreateDebugProxyMap( Handle<Map> GetOrCreateDebugProxyMap(
Isolate* isolate, DebugProxyId id, Isolate* isolate, DebugProxyId id,
v8::Local<v8::FunctionTemplate> (*create_template_fn)(v8::Isolate*)) { v8::Local<v8::FunctionTemplate> (*create_template_fn)(v8::Isolate*)) {
Handle<FixedArray> maps = isolate->wasm_debug_proxy_maps(); auto maps = GetOrCreateDebugMaps(isolate);
if (maps->length() == 0) { CHECK_LE(kNumProxies, maps->length());
maps = isolate->factory()->NewFixedArrayWithHoles(kNumProxies);
isolate->native_context()->set_wasm_debug_proxy_maps(*maps);
}
CHECK_EQ(kNumProxies, maps->length());
if (!maps->is_the_hole(isolate, id)) { if (!maps->is_the_hole(isolate, id)) {
return handle(Map::cast(maps->get(id)), isolate); return handle(Map::cast(maps->get(id)), isolate);
} }
...@@ -372,9 +338,9 @@ struct GlobalsProxy : NamedDebugProxy<GlobalsProxy, kGlobalsProxy> { ...@@ -372,9 +338,9 @@ struct GlobalsProxy : NamedDebugProxy<GlobalsProxy, kGlobalsProxy> {
static Handle<Object> Get(Isolate* isolate, static Handle<Object> Get(Isolate* isolate,
Handle<WasmInstanceObject> instance, Handle<WasmInstanceObject> instance,
uint32_t index) { uint32_t index) {
return WasmValueToObject(isolate, return WasmValueObject::New(
WasmInstanceObject::GetGlobalValue( isolate, WasmInstanceObject::GetGlobalValue(
instance, instance->module()->globals[index])); instance, instance->module()->globals[index]));
} }
static Handle<String> GetName(Isolate* isolate, static Handle<String> GetName(Isolate* isolate,
...@@ -453,7 +419,7 @@ struct LocalsProxy : NamedDebugProxy<LocalsProxy, kLocalsProxy, FixedArray> { ...@@ -453,7 +419,7 @@ struct LocalsProxy : NamedDebugProxy<LocalsProxy, kLocalsProxy, FixedArray> {
auto function = debug_info->GetFunctionAtAddress(frame->pc()); auto function = debug_info->GetFunctionAtAddress(frame->pc());
auto values = isolate->factory()->NewFixedArray(count + 2); auto values = isolate->factory()->NewFixedArray(count + 2);
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
auto value = WasmValueToObject( auto value = WasmValueObject::New(
isolate, debug_info->GetLocalValue(i, frame->pc(), frame->fp(), isolate, debug_info->GetLocalValue(i, frame->pc(), frame->fp(),
frame->callee_fp())); frame->callee_fp()));
values->set(i, *value); values->set(i, *value);
...@@ -500,7 +466,7 @@ struct StackProxy : IndexedDebugProxy<StackProxy, kStackProxy, FixedArray> { ...@@ -500,7 +466,7 @@ struct StackProxy : IndexedDebugProxy<StackProxy, kStackProxy, FixedArray> {
int count = debug_info->GetStackDepth(frame->pc()); int count = debug_info->GetStackDepth(frame->pc());
auto values = isolate->factory()->NewFixedArray(count); auto values = isolate->factory()->NewFixedArray(count);
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
auto value = WasmValueToObject( auto value = WasmValueObject::New(
isolate, debug_info->GetStackValue(i, frame->pc(), frame->fp(), isolate, debug_info->GetStackValue(i, frame->pc(), frame->fp(),
frame->callee_fp())); frame->callee_fp()));
values->set(i, *value); values->set(i, *value);
...@@ -555,8 +521,10 @@ Handle<JSObject> GetOrCreateInstanceProxy(Isolate* isolate, ...@@ -555,8 +521,10 @@ Handle<JSObject> GetOrCreateInstanceProxy(Isolate* isolate,
// and extensions to inspect the WebAssembly engine state from JavaScript. // and extensions to inspect the WebAssembly engine state from JavaScript.
// The proxy provides the following interface: // The proxy provides the following interface:
// //
// type WasmSimdValue = Uint8Array; // type WasmValue = {
// type WasmValue = number | bigint | object | WasmSimdValue; // type: string;
// value: number | bigint | object | string;
// };
// type WasmFunction = (... args : WasmValue[]) = > WasmValue; // type WasmFunction = (... args : WasmValue[]) = > WasmValue;
// interface WasmInterface { // interface WasmInterface {
// $globalX: WasmValue; // $globalX: WasmValue;
...@@ -773,8 +741,97 @@ class DebugWasmScopeIterator final : public debug::ScopeIterator { ...@@ -773,8 +741,97 @@ class DebugWasmScopeIterator final : public debug::ScopeIterator {
ScopeType type_; ScopeType type_;
}; };
Handle<String> WasmSimd128ToString(Isolate* isolate, wasm::Simd128 s128) {
// We use the canonical format as described in:
// https://github.com/WebAssembly/simd/blob/master/proposals/simd/TextSIMD.md
EmbeddedVector<char, 50> buffer;
auto i32x4 = s128.to_i32x4();
SNPrintF(buffer, "i32x4 0x%08X 0x%08X 0x%08X 0x%08X", i32x4.val[0],
i32x4.val[1], i32x4.val[2], i32x4.val[3]);
return isolate->factory()->NewStringFromAsciiChecked(buffer.data());
}
} // namespace } // namespace
// static
Handle<WasmValueObject> WasmValueObject::New(Isolate* isolate,
Handle<String> type,
Handle<Object> value) {
auto maps = GetOrCreateDebugMaps(isolate);
if (maps->is_the_hole(isolate, kWasmValueMapIndex)) {
Handle<Map> map = isolate->factory()->NewMap(
WASM_VALUE_OBJECT_TYPE, WasmValueObject::kSize,
TERMINAL_FAST_ELEMENTS_KIND, 2);
Map::EnsureDescriptorSlack(isolate, map, 2);
{ // type
Descriptor d = Descriptor::DataField(
isolate,
isolate->factory()->InternalizeString(StaticCharVector("type")),
WasmValueObject::kTypeIndex, FROZEN, Representation::Tagged());
map->AppendDescriptor(isolate, &d);
}
{ // value
Descriptor d = Descriptor::DataField(
isolate,
isolate->factory()->InternalizeString(StaticCharVector("value")),
WasmValueObject::kValueIndex, FROZEN, Representation::Tagged());
map->AppendDescriptor(isolate, &d);
}
map->set_is_extensible(false);
maps->set(kWasmValueMapIndex, *map);
}
Handle<Map> value_map =
handle(Map::cast(maps->get(kWasmValueMapIndex)), isolate);
Handle<WasmValueObject> object = Handle<WasmValueObject>::cast(
isolate->factory()->NewJSObjectFromMap(value_map));
object->set_type(*type);
object->set_value(*value);
return object;
}
// static
Handle<WasmValueObject> WasmValueObject::New(Isolate* isolate,
const wasm::WasmValue& value) {
Handle<String> t;
Handle<Object> v;
switch (value.type().kind()) {
case wasm::ValueType::kI32: {
t = isolate->factory()->InternalizeString(StaticCharVector("i32"));
v = isolate->factory()->NewNumberFromInt(value.to_i32_unchecked());
break;
}
case wasm::ValueType::kI64: {
t = isolate->factory()->InternalizeString(StaticCharVector("i64"));
v = BigInt::FromInt64(isolate, value.to_i64_unchecked());
break;
}
case wasm::ValueType::kF32: {
t = isolate->factory()->InternalizeString(StaticCharVector("f32"));
v = isolate->factory()->NewNumber(value.to_f32_unchecked());
break;
}
case wasm::ValueType::kF64: {
t = isolate->factory()->InternalizeString(StaticCharVector("f64"));
v = isolate->factory()->NewNumber(value.to_f64_unchecked());
break;
}
case wasm::ValueType::kS128: {
t = isolate->factory()->InternalizeString(StaticCharVector("v128"));
v = WasmSimd128ToString(isolate, value.to_s128_unchecked());
break;
}
case wasm::ValueType::kRef: {
t = isolate->factory()->InternalizeString(StaticCharVector("externref"));
v = value.to_externref();
break;
}
default:
UNREACHABLE();
}
return New(isolate, t, v);
}
Handle<JSObject> GetWasmDebugProxy(WasmFrame* frame) { Handle<JSObject> GetWasmDebugProxy(WasmFrame* frame) {
return ContextProxy::Create(frame); return ContextProxy::Create(frame);
} }
......
...@@ -2,26 +2,63 @@ ...@@ -2,26 +2,63 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef V8_DEBUG_DEBUG_WASM_SUPPORT_H_ #ifndef V8_DEBUG_DEBUG_WASM_OBJECTS_H_
#define V8_DEBUG_DEBUG_WASM_SUPPORT_H_ #define V8_DEBUG_DEBUG_WASM_OBJECTS_H_
#include <memory> #include <memory>
#include "src/objects/js-objects.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8 { namespace v8 {
namespace debug { namespace debug {
class ScopeIterator; class ScopeIterator;
} // namespace debug } // namespace debug
namespace internal { namespace internal {
namespace wasm {
class WasmValue;
} // namespace wasm
#include "torque-generated/src/debug/debug-wasm-objects-tq.inc"
template <typename T>
class Handle;
class JSArray;
class JSObject;
class WasmFrame; class WasmFrame;
class WasmInstanceObject; class WasmInstanceObject;
class WasmModuleObject; class WasmModuleObject;
class WasmValueObject : public JSObject {
public:
DECL_CAST(WasmValueObject)
DECL_ACCESSORS(type, String)
DECL_ACCESSORS(value, Object)
// Dispatched behavior.
DECL_PRINTER(WasmValueObject)
DECL_VERIFIER(WasmValueObject)
// Layout description.
#define WASM_VALUE_FIELDS(V) \
V(kTypeOffset, kTaggedSize) \
V(kValueOffset, kTaggedSize) \
V(kSize, 0)
DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, WASM_VALUE_FIELDS)
#undef WASM_VALUE_FIELDS
// Indices of in-object properties.
static constexpr int kTypeIndex = 0;
static constexpr int kValueIndex = 1;
static Handle<WasmValueObject> New(Isolate* isolate, Handle<String> type,
Handle<Object> value);
static Handle<WasmValueObject> New(Isolate* isolate,
const wasm::WasmValue& value);
OBJECT_CONSTRUCTORS(WasmValueObject, JSObject);
};
Handle<JSObject> GetWasmDebugProxy(WasmFrame* frame); Handle<JSObject> GetWasmDebugProxy(WasmFrame* frame);
std::unique_ptr<debug::ScopeIterator> GetWasmScopeIterator(WasmFrame* frame); std::unique_ptr<debug::ScopeIterator> GetWasmScopeIterator(WasmFrame* frame);
...@@ -34,4 +71,6 @@ Handle<JSArray> GetWasmModuleObjectInternalProperties( ...@@ -34,4 +71,6 @@ Handle<JSArray> GetWasmModuleObjectInternalProperties(
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
#endif // V8_DEBUG_DEBUG_WASM_SUPPORT_H_ #include "src/objects/object-macros-undef.h"
#endif // V8_DEBUG_DEBUG_WASM_OBJECTS_H_
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include 'src/debug/debug-wasm-objects.h'
extern class WasmValueObject extends JSObject;
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "src/codegen/assembler-inl.h" #include "src/codegen/assembler-inl.h"
#include "src/common/globals.h" #include "src/common/globals.h"
#include "src/date/date.h" #include "src/date/date.h"
#include "src/debug/debug-wasm-objects-inl.h"
#include "src/diagnostics/disasm.h" #include "src/diagnostics/disasm.h"
#include "src/diagnostics/disassembler.h" #include "src/diagnostics/disassembler.h"
#include "src/heap/combined-heap.h" #include "src/heap/combined-heap.h"
...@@ -228,6 +229,9 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) { ...@@ -228,6 +229,9 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) {
case WASM_INSTANCE_OBJECT_TYPE: case WASM_INSTANCE_OBJECT_TYPE:
WasmInstanceObject::cast(*this).WasmInstanceObjectVerify(isolate); WasmInstanceObject::cast(*this).WasmInstanceObjectVerify(isolate);
break; break;
case WASM_VALUE_OBJECT_TYPE:
WasmValueObject::cast(*this).WasmValueObjectVerify(isolate);
break;
case JS_SET_KEY_VALUE_ITERATOR_TYPE: case JS_SET_KEY_VALUE_ITERATOR_TYPE:
case JS_SET_VALUE_ITERATOR_TYPE: case JS_SET_VALUE_ITERATOR_TYPE:
JSSetIterator::cast(*this).JSSetIteratorVerify(isolate); JSSetIterator::cast(*this).JSSetIteratorVerify(isolate);
...@@ -1539,6 +1543,12 @@ void WasmInstanceObject::WasmInstanceObjectVerify(Isolate* isolate) { ...@@ -1539,6 +1543,12 @@ void WasmInstanceObject::WasmInstanceObjectVerify(Isolate* isolate) {
} }
} }
void WasmValueObject::WasmValueObjectVerify(Isolate* isolate) {
JSObjectVerify(isolate);
CHECK(IsWasmValueObject());
CHECK(type().IsString());
}
void WasmExportedFunctionData::WasmExportedFunctionDataVerify( void WasmExportedFunctionData::WasmExportedFunctionDataVerify(
Isolate* isolate) { Isolate* isolate) {
TorqueGeneratedClassVerifiers::WasmExportedFunctionDataVerify(*this, isolate); TorqueGeneratedClassVerifiers::WasmExportedFunctionDataVerify(*this, isolate);
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "src/common/globals.h" #include "src/common/globals.h"
#include "src/compiler/node.h" #include "src/compiler/node.h"
#include "src/debug/debug-wasm-objects-inl.h"
#include "src/diagnostics/disasm.h" #include "src/diagnostics/disasm.h"
#include "src/diagnostics/disassembler.h" #include "src/diagnostics/disassembler.h"
#include "src/heap/heap-inl.h" // For InOldSpace. #include "src/heap/heap-inl.h" // For InOldSpace.
...@@ -175,6 +176,9 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT ...@@ -175,6 +176,9 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT
case WASM_INSTANCE_OBJECT_TYPE: case WASM_INSTANCE_OBJECT_TYPE:
WasmInstanceObject::cast(*this).WasmInstanceObjectPrint(os); WasmInstanceObject::cast(*this).WasmInstanceObjectPrint(os);
break; break;
case WASM_VALUE_OBJECT_TYPE:
WasmValueObject::cast(*this).WasmValueObjectPrint(os);
break;
case CODE_TYPE: case CODE_TYPE:
Code::cast(*this).CodePrint(os); Code::cast(*this).CodePrint(os);
break; break;
...@@ -1895,6 +1899,13 @@ void WasmTableObject::WasmTableObjectPrint(std::ostream& os) { // NOLINT ...@@ -1895,6 +1899,13 @@ void WasmTableObject::WasmTableObjectPrint(std::ostream& os) { // NOLINT
os << "\n"; os << "\n";
} }
void WasmValueObject::WasmValueObjectPrint(std::ostream& os) { // NOLINT
PrintHeader(os, "WasmValueObject");
os << "\n - type: " << Brief(type());
os << "\n - value: " << Brief(value());
os << "\n";
}
void WasmGlobalObject::WasmGlobalObjectPrint(std::ostream& os) { // NOLINT void WasmGlobalObject::WasmGlobalObjectPrint(std::ostream& os) { // NOLINT
PrintHeader(os, "WasmGlobalObject"); PrintHeader(os, "WasmGlobalObject");
if (type().is_reference_type()) { if (type().is_reference_type()) {
......
...@@ -4594,8 +4594,8 @@ bool Genesis::InstallABunchOfRandomThings() { ...@@ -4594,8 +4594,8 @@ bool Genesis::InstallABunchOfRandomThings() {
native_context()->set_slow_template_instantiations_cache( native_context()->set_slow_template_instantiations_cache(
*slow_template_instantiations_cache); *slow_template_instantiations_cache);
auto wasm_debug_proxy_maps = isolate()->factory()->empty_fixed_array(); auto wasm_debug_maps = isolate()->factory()->empty_fixed_array();
native_context()->set_wasm_debug_proxy_maps(*wasm_debug_proxy_maps); native_context()->set_wasm_debug_maps(*wasm_debug_maps);
// Store the map for the %ObjectPrototype% after the natives has been compiled // Store the map for the %ObjectPrototype% after the natives has been compiled
// and the Object function has been set up. // and the Object function has been set up.
......
...@@ -43,26 +43,6 @@ V8InternalValueType v8InternalValueTypeFrom(v8::Local<v8::Context> context, ...@@ -43,26 +43,6 @@ V8InternalValueType v8InternalValueTypeFrom(v8::Local<v8::Context> context,
return inspectedContext->getInternalType(value.As<v8::Object>()); return inspectedContext->getInternalType(value.As<v8::Object>());
} }
template <typename ResultType>
ResultType unpackWasmValue(v8::Local<v8::Context> context,
v8::Local<v8::Array> array) {
ResultType result;
constexpr int kSize = sizeof(result);
uint8_t buffer[kSize];
for (int i = 0; i < kSize; i++) {
v8::Local<v8::Int32> i32 =
array->Get(context, i).ToLocalChecked().As<v8::Int32>();
buffer[i] = static_cast<uint8_t>(i32->Value());
}
memcpy(&result, buffer, kSize);
return result;
}
// Partial list of Wasm's ValueType, copied here to avoid including internal
// header. Using an unscoped enumeration here to allow implicit conversions from
// int. Keep in sync with ValueType::Kind in wasm/value-type.h.
enum WasmValueType { kStmt, kI32, kI64, kF32, kF64, kS128, kExternRef };
Response toProtocolValue(v8::Local<v8::Context> context, Response toProtocolValue(v8::Local<v8::Context> context,
v8::Local<v8::Value> value, int maxDepth, v8::Local<v8::Value> value, int maxDepth,
std::unique_ptr<protocol::Value>* result) { std::unique_ptr<protocol::Value>* result) {
...@@ -325,6 +305,22 @@ String16 descriptionForCollection(v8::Isolate* isolate, ...@@ -325,6 +305,22 @@ String16 descriptionForCollection(v8::Isolate* isolate,
return String16::concat(className, '(', String16::fromInteger(length), ')'); return String16::concat(className, '(', String16::fromInteger(length), ')');
} }
String16 descriptionForWasmValueObject(
v8::Local<v8::Context> context,
v8::Local<v8::debug::WasmValueObject> object) {
v8::Isolate* isolate = context->GetIsolate();
auto type = toProtocolString(isolate, object->type());
auto value = object->value();
if (type == "i32" || type == "f32" || type == "f64") {
return String16::fromDouble(v8::Local<v8::Number>::Cast(value)->Value());
} else if (type == "i64") {
return descriptionForBigInt(context, v8::Local<v8::BigInt>::Cast(value));
} else if (type == "v128") {
return toProtocolString(isolate, v8::Local<v8::String>::Cast(value));
}
return type;
}
String16 descriptionForEntry(v8::Local<v8::Context> context, String16 descriptionForEntry(v8::Local<v8::Context> context,
v8::Local<v8::Object> object) { v8::Local<v8::Object> object) {
v8::Isolate* isolate = context->GetIsolate(); v8::Isolate* isolate = context->GetIsolate();
...@@ -1711,6 +1707,13 @@ std::unique_ptr<ValueMirror> ValueMirror::create(v8::Local<v8::Context> context, ...@@ -1711,6 +1707,13 @@ std::unique_ptr<ValueMirror> ValueMirror::create(v8::Local<v8::Context> context,
descriptionForCollection( descriptionForCollection(
isolate, memory, memory->Buffer()->ByteLength() / kWasmPageSize)); isolate, memory, memory->Buffer()->ByteLength() / kWasmPageSize));
} }
if (v8::debug::WasmValueObject::IsWasmValueObject(value)) {
v8::Local<v8::debug::WasmValueObject> v =
value.As<v8::debug::WasmValueObject>();
return std::make_unique<ObjectMirror>(
value, RemoteObject::SubtypeEnum::Wasmvalue,
descriptionForWasmValueObject(context, v));
}
V8InternalValueType internalType = V8InternalValueType internalType =
v8InternalValueTypeFrom(context, value.As<v8::Object>()); v8InternalValueTypeFrom(context, value.As<v8::Object>());
if (value->IsArray() && internalType == V8InternalValueType::kScopeList) { if (value->IsArray() && internalType == V8InternalValueType::kScopeList) {
......
...@@ -237,7 +237,7 @@ enum ContextLookupFlags { ...@@ -237,7 +237,7 @@ enum ContextLookupFlags {
V(SLOW_TEMPLATE_INSTANTIATIONS_CACHE_INDEX, SimpleNumberDictionary, \ V(SLOW_TEMPLATE_INSTANTIATIONS_CACHE_INDEX, SimpleNumberDictionary, \
slow_template_instantiations_cache) \ slow_template_instantiations_cache) \
V(ATOMICS_WAITASYNC_PROMISES, OrderedHashSet, atomics_waitasync_promises) \ V(ATOMICS_WAITASYNC_PROMISES, OrderedHashSet, atomics_waitasync_promises) \
V(WASM_DEBUG_PROXY_MAPS, FixedArray, wasm_debug_proxy_maps) \ V(WASM_DEBUG_MAPS, FixedArray, wasm_debug_maps) \
/* Fast Path Protectors */ \ /* Fast Path Protectors */ \
V(REGEXP_SPECIES_PROTECTOR_INDEX, PropertyCell, regexp_species_protector) \ V(REGEXP_SPECIES_PROTECTOR_INDEX, PropertyCell, regexp_species_protector) \
/* All *_FUNCTION_MAP_INDEX definitions used by Context::FunctionMapIndex */ \ /* All *_FUNCTION_MAP_INDEX definitions used by Context::FunctionMapIndex */ \
......
...@@ -596,6 +596,7 @@ bool CanSubclassHaveInobjectProperties(InstanceType instance_type) { ...@@ -596,6 +596,7 @@ bool CanSubclassHaveInobjectProperties(InstanceType instance_type) {
case WASM_MEMORY_OBJECT_TYPE: case WASM_MEMORY_OBJECT_TYPE:
case WASM_MODULE_OBJECT_TYPE: case WASM_MODULE_OBJECT_TYPE:
case WASM_TABLE_OBJECT_TYPE: case WASM_TABLE_OBJECT_TYPE:
case WASM_VALUE_OBJECT_TYPE:
return true; return true;
case BIGINT_TYPE: case BIGINT_TYPE:
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "src/api/api-arguments-inl.h" #include "src/api/api-arguments-inl.h"
#include "src/common/globals.h" #include "src/common/globals.h"
#include "src/date/date.h" #include "src/date/date.h"
#include "src/debug/debug-wasm-objects.h"
#include "src/execution/arguments.h" #include "src/execution/arguments.h"
#include "src/execution/frames.h" #include "src/execution/frames.h"
#include "src/execution/isolate.h" #include "src/execution/isolate.h"
...@@ -2301,6 +2302,8 @@ int JSObject::GetHeaderSize(InstanceType type, ...@@ -2301,6 +2302,8 @@ int JSObject::GetHeaderSize(InstanceType type,
return WasmModuleObject::kHeaderSize; return WasmModuleObject::kHeaderSize;
case WASM_TABLE_OBJECT_TYPE: case WASM_TABLE_OBJECT_TYPE:
return WasmTableObject::kHeaderSize; return WasmTableObject::kHeaderSize;
case WASM_VALUE_OBJECT_TYPE:
return WasmValueObject::kHeaderSize;
case WASM_EXCEPTION_OBJECT_TYPE: case WASM_EXCEPTION_OBJECT_TYPE:
return WasmExceptionObject::kHeaderSize; return WasmExceptionObject::kHeaderSize;
default: default:
......
...@@ -309,6 +309,7 @@ VisitorId Map::GetVisitorId(Map map) { ...@@ -309,6 +309,7 @@ VisitorId Map::GetVisitorId(Map map) {
case WASM_MEMORY_OBJECT_TYPE: case WASM_MEMORY_OBJECT_TYPE:
case WASM_MODULE_OBJECT_TYPE: case WASM_MODULE_OBJECT_TYPE:
case WASM_TABLE_OBJECT_TYPE: case WASM_TABLE_OBJECT_TYPE:
case WASM_VALUE_OBJECT_TYPE:
case JS_BOUND_FUNCTION_TYPE: { case JS_BOUND_FUNCTION_TYPE: {
const bool has_raw_data_fields = const bool has_raw_data_fields =
(FLAG_unbox_double_fields && !map.HasFastPointerLayout()) || (FLAG_unbox_double_fields && !map.HasFastPointerLayout()) ||
......
...@@ -226,6 +226,7 @@ class ZoneForwardList; ...@@ -226,6 +226,7 @@ class ZoneForwardList;
V(WasmStruct) \ V(WasmStruct) \
V(WasmTypeInfo) \ V(WasmTypeInfo) \
V(WasmTableObject) \ V(WasmTableObject) \
V(WasmValueObject) \
V(WeakFixedArray) \ V(WeakFixedArray) \
V(WeakArrayList) \ V(WeakArrayList) \
V(WeakCell) \ V(WeakCell) \
......
...@@ -994,6 +994,7 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) { ...@@ -994,6 +994,7 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
case WASM_MEMORY_OBJECT_TYPE: case WASM_MEMORY_OBJECT_TYPE:
case WASM_MODULE_OBJECT_TYPE: case WASM_MODULE_OBJECT_TYPE:
case WASM_TABLE_OBJECT_TYPE: case WASM_TABLE_OBJECT_TYPE:
case WASM_VALUE_OBJECT_TYPE:
return Op::template apply<JSObject::BodyDescriptor>(p1, p2, p3, p4); return Op::template apply<JSObject::BodyDescriptor>(p1, p2, p3, p4);
case WASM_INSTANCE_OBJECT_TYPE: case WASM_INSTANCE_OBJECT_TYPE:
return Op::template apply<WasmInstanceObject::BodyDescriptor>(p1, p2, p3, return Op::template apply<WasmInstanceObject::BodyDescriptor>(p1, p2, p3,
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#include "src/debug/debug-evaluate.h" #include "src/debug/debug-evaluate.h"
#include "src/debug/debug-frames.h" #include "src/debug/debug-frames.h"
#include "src/debug/debug-scopes.h" #include "src/debug/debug-scopes.h"
#include "src/debug/debug-wasm-support.h" #include "src/debug/debug-wasm-objects.h"
#include "src/debug/debug.h" #include "src/debug/debug.h"
#include "src/debug/liveedit.h" #include "src/debug/liveedit.h"
#include "src/execution/arguments-inl.h" #include "src/execution/arguments-inl.h"
......
...@@ -8,7 +8,6 @@ type PodArrayOfWasmValueType extends ByteArray ...@@ -8,7 +8,6 @@ type PodArrayOfWasmValueType extends ByteArray
@useParentTypeChecker @useParentTypeChecker
type ManagedWasmNativeModule extends Foreign type ManagedWasmNativeModule extends Foreign
constexpr 'Managed<wasm::NativeModule>'; constexpr 'Managed<wasm::NativeModule>';
type WasmValueType extends uint8 constexpr 'wasm::ValueType::Kind';
extern class WasmInstanceObject extends JSObject; extern class WasmInstanceObject extends JSObject;
......
...@@ -28,7 +28,7 @@ Setting breakpoint at offset 41, condition "true" ...@@ -28,7 +28,7 @@ Setting breakpoint at offset 41, condition "true"
breakpointId : <breakpointId> breakpointId : <breakpointId>
} }
} }
Setting breakpoint at offset 46, condition "$var0==3" Setting breakpoint at offset 46, condition "$var0.value==3"
{ {
id : <messageId> id : <messageId>
result : { result : {
...@@ -42,25 +42,25 @@ Setting breakpoint at offset 46, condition "$var0==3" ...@@ -42,25 +42,25 @@ Setting breakpoint at offset 46, condition "$var0==3"
} }
Calling fib(5) Calling fib(5)
Script wasm://wasm/f00dbc56 byte offset 41: Wasm opcode 0x0d (kExprBrIf) Script wasm://wasm/f00dbc56 byte offset 41: Wasm opcode 0x0d (kExprBrIf)
$var0: 5 $var0: 5 (i32)
Script wasm://wasm/f00dbc56 byte offset 41: Wasm opcode 0x0d (kExprBrIf) Script wasm://wasm/f00dbc56 byte offset 41: Wasm opcode 0x0d (kExprBrIf)
$var0: 4 $var0: 4 (i32)
Script wasm://wasm/f00dbc56 byte offset 41: Wasm opcode 0x0d (kExprBrIf) Script wasm://wasm/f00dbc56 byte offset 41: Wasm opcode 0x0d (kExprBrIf)
$var0: 3 $var0: 3 (i32)
Script wasm://wasm/f00dbc56 byte offset 46: Wasm opcode 0x10 (kExprCallFunction) Script wasm://wasm/f00dbc56 byte offset 46: Wasm opcode 0x10 (kExprCallFunction)
$var0: 3 $var0: 3 (i32)
Script wasm://wasm/f00dbc56 byte offset 41: Wasm opcode 0x0d (kExprBrIf) Script wasm://wasm/f00dbc56 byte offset 41: Wasm opcode 0x0d (kExprBrIf)
$var0: 2 $var0: 2 (i32)
Script wasm://wasm/f00dbc56 byte offset 41: Wasm opcode 0x0d (kExprBrIf) Script wasm://wasm/f00dbc56 byte offset 41: Wasm opcode 0x0d (kExprBrIf)
$var0: 1 $var0: 1 (i32)
Script wasm://wasm/f00dbc56 byte offset 41: Wasm opcode 0x0d (kExprBrIf) Script wasm://wasm/f00dbc56 byte offset 41: Wasm opcode 0x0d (kExprBrIf)
$var0: 2 $var0: 2 (i32)
Script wasm://wasm/f00dbc56 byte offset 41: Wasm opcode 0x0d (kExprBrIf) Script wasm://wasm/f00dbc56 byte offset 41: Wasm opcode 0x0d (kExprBrIf)
$var0: 3 $var0: 3 (i32)
Script wasm://wasm/f00dbc56 byte offset 46: Wasm opcode 0x10 (kExprCallFunction) Script wasm://wasm/f00dbc56 byte offset 46: Wasm opcode 0x10 (kExprCallFunction)
$var0: 3 $var0: 3 (i32)
Script wasm://wasm/f00dbc56 byte offset 41: Wasm opcode 0x0d (kExprBrIf) Script wasm://wasm/f00dbc56 byte offset 41: Wasm opcode 0x0d (kExprBrIf)
$var0: 2 $var0: 2 (i32)
Script wasm://wasm/f00dbc56 byte offset 41: Wasm opcode 0x0d (kExprBrIf) Script wasm://wasm/f00dbc56 byte offset 41: Wasm opcode 0x0d (kExprBrIf)
$var0: 1 $var0: 1 (i32)
fib returned! fib returned!
...@@ -29,7 +29,7 @@ const find_offset = opcode => fib.body_offset + fib_body.indexOf(opcode); ...@@ -29,7 +29,7 @@ const find_offset = opcode => fib.body_offset + fib_body.indexOf(opcode);
const breakpoints = [ const breakpoints = [
{loc: find_offset(kExprLocalGet), cond: 'false'}, {loc: find_offset(kExprLocalGet), cond: 'false'},
{loc: find_offset(kExprBrIf), cond: 'true'}, {loc: find_offset(kExprBrIf), cond: 'true'},
{loc: find_offset(kExprCallFunction), cond: '$var0==3'} {loc: find_offset(kExprCallFunction), cond: '$var0.value==3'}
]; ];
Protocol.Debugger.onPaused(async msg => { Protocol.Debugger.onPaused(async msg => {
...@@ -40,8 +40,10 @@ Protocol.Debugger.onPaused(async msg => { ...@@ -40,8 +40,10 @@ Protocol.Debugger.onPaused(async msg => {
if (scope.type != 'local') continue; if (scope.type != 'local') continue;
var properties = await Protocol.Runtime.getProperties( var properties = await Protocol.Runtime.getProperties(
{'objectId': scope.object.objectId}); {'objectId': scope.object.objectId});
InspectorTest.log(properties.result.result.map( for (var {name, value} of properties.result.result) {
value => `${value.name}: ${value.value.value}`)); value = await WasmInspectorTest.getWasmValue(value);
InspectorTest.log(`${name}: ${value}`);
}
} }
Protocol.Debugger.resume(); Protocol.Debugger.resume();
}); });
......
...@@ -24,8 +24,9 @@ Protocol.Debugger.onPaused(async msg => { ...@@ -24,8 +24,9 @@ Protocol.Debugger.onPaused(async msg => {
if (scope.type == 'module') continue; if (scope.type == 'module') continue;
var scope_properties = var scope_properties =
await Protocol.Runtime.getProperties({objectId: scope.object.objectId}); await Protocol.Runtime.getProperties({objectId: scope.object.objectId});
let str = scope_properties.result.result.map( let str = (await Promise.all(scope_properties.result.result.map(
elem => WasmInspectorTest.getWasmValue(elem.value)).join(', '); elem => WasmInspectorTest.getWasmValue(elem.value))))
.join(', ');
line.push(`${scope.type}: [${str}]`); line.push(`${scope.type}: [${str}]`);
} }
InspectorTest.log(line.join('; ')); InspectorTest.log(line.join('; '));
......
...@@ -6,8 +6,8 @@ Wait for script ...@@ -6,8 +6,8 @@ Wait for script
Got wasm script: wasm://wasm/c84b7cde Got wasm script: wasm://wasm/c84b7cde
Run Run
Expecting to pause at 61 Expecting to pause at 61
Paused at offset 61; wasm-expression-stack: []; local: [12] Paused at offset 61; wasm-expression-stack: []; local: [12 (i32)]
Paused at offset 62; wasm-expression-stack: []; local: [12] Paused at offset 62; wasm-expression-stack: []; local: [12 (i32)]
Paused at offset 64; wasm-expression-stack: [12]; local: [12] Paused at offset 64; wasm-expression-stack: [12 (i32)]; local: [12 (i32)]
Paused at offset 66; wasm-expression-stack: [12, 1]; local: [12] Paused at offset 66; wasm-expression-stack: [12 (i32), 1 (i32)]; local: [12 (i32)]
Paused at offset 67; wasm-expression-stack: [13]; local: [12] Paused at offset 67; wasm-expression-stack: [13 (i32)]; local: [12 (i32)]
...@@ -70,8 +70,9 @@ async function inspect(frame) { ...@@ -70,8 +70,9 @@ async function inspect(frame) {
if (scope.type == 'module') continue; if (scope.type == 'module') continue;
var scope_properties = var scope_properties =
await Protocol.Runtime.getProperties({objectId: scope.object.objectId}); await Protocol.Runtime.getProperties({objectId: scope.object.objectId});
let str = scope_properties.result.result.map( let str = (await Promise.all(scope_properties.result.result.map(
elem => WasmInspectorTest.getWasmValue(elem.value)).join(', '); elem => WasmInspectorTest.getWasmValue(elem.value))))
.join(', ');
line.push(`${scope.type}: [${str}]`); line.push(`${scope.type}: [${str}]`);
} }
InspectorTest.log(line.join('; ')); InspectorTest.log(line.join('; '));
......
...@@ -7,11 +7,11 @@ Paused at: ...@@ -7,11 +7,11 @@ Paused at:
--- 0 --- --- 0 ---
Script wasm://wasm/a9a86c5e byte offset 46: Wasm opcode 0x6d (kExprI32DivS) Script wasm://wasm/a9a86c5e byte offset 46: Wasm opcode 0x6d (kExprI32DivS)
scope at div (0:46): scope at div (0:46):
$a: 1 $a: 1 (i32)
$b: 0 $b: 0 (i32)
$unused: 4711 $unused: 4711 (i32)
$local_zero: 0 $local_zero: 0 (i32)
$local_const_11: 11 $local_const_11: 11 (i32)
--- 1 --- --- 1 ---
try { try {
instance.exports.#div(1, 0, 4711); // traps (div by zero) instance.exports.#div(1, 0, 4711); // traps (div by zero)
...@@ -37,11 +37,11 @@ Paused at: ...@@ -37,11 +37,11 @@ Paused at:
--- 0 --- --- 0 ---
Script wasm://wasm/a9a86c5e byte offset 46: Wasm opcode 0x6d (kExprI32DivS) Script wasm://wasm/a9a86c5e byte offset 46: Wasm opcode 0x6d (kExprI32DivS)
scope at div (0:46): scope at div (0:46):
$a: -2147483648 $a: -2147483648 (i32)
$b: -1 $b: -1 (i32)
$unused: 4711 $unused: 4711 (i32)
$local_zero: 0 $local_zero: 0 (i32)
$local_const_11: 11 $local_const_11: 11 (i32)
--- 1 --- --- 1 ---
try { try {
instance.exports.#div(0x80000000, -1, 4711); // traps (unrepresentable) instance.exports.#div(0x80000000, -1, 4711); // traps (unrepresentable)
......
...@@ -80,8 +80,9 @@ async function printLocalScope(frame) { ...@@ -80,8 +80,9 @@ async function printLocalScope(frame) {
if (scope.type != 'local') continue; if (scope.type != 'local') continue;
let properties = await Protocol.Runtime.getProperties( let properties = await Protocol.Runtime.getProperties(
{'objectId': scope.object.objectId}); {'objectId': scope.object.objectId});
for (let value of properties.result.result) { for (let {name, value} of properties.result.result) {
InspectorTest.log(` ${value.name}: ${value.value.value}`); value = await WasmInspectorTest.getWasmValue(value);
InspectorTest.log(` ${name}: ${value}`);
} }
} }
} }
...@@ -2,14 +2,14 @@ Tests that Liftoff does not merge opcodes while stepping ...@@ -2,14 +2,14 @@ Tests that Liftoff does not merge opcodes while stepping
Running test: test Running test: test
Setting breakpoint at offset 33. Setting breakpoint at offset 33.
Paused at offset 33: [0] Paused at offset 33: [0 (i32)]
Paused at offset 35: [0, 0] Paused at offset 35: [0 (i32), 0 (i32)]
Paused at offset 36: [0, 1] Paused at offset 36: [0 (i32), 1 (i32)]
Paused at offset 33: [-1] Paused at offset 33: [-1 (i32)]
Paused at offset 35: [-1, -1] Paused at offset 35: [-1 (i32), -1 (i32)]
Paused at offset 36: [-1, 0] Paused at offset 36: [-1 (i32), 0 (i32)]
Paused at offset 38: [-1] Paused at offset 38: [-1 (i32)]
Paused at offset 33: [13] Paused at offset 33: [13 (i32)]
Paused at offset 35: [13, 13] Paused at offset 35: [13 (i32), 13 (i32)]
Paused at offset 36: [13, 0] Paused at offset 36: [13 (i32), 0 (i32)]
Paused at offset 38: [13] Paused at offset 38: [13 (i32)]
...@@ -56,8 +56,8 @@ async function printPauseLocationAndStep(msg) { ...@@ -56,8 +56,8 @@ async function printPauseLocationAndStep(msg) {
if (scope.type == 'module') continue; if (scope.type == 'module') continue;
let scope_properties = let scope_properties =
await Protocol.Runtime.getProperties({objectId: scope.object.objectId}); await Protocol.Runtime.getProperties({objectId: scope.object.objectId});
scopes[scope.type] = scope_properties.result.result.map( scopes[scope.type] = await Promise.all(scope_properties.result.result.map(
elem => WasmInspectorTest.getWasmValue(elem.value)); elem => WasmInspectorTest.getWasmValue(elem.value)));
} }
let values = scopes['local'].concat(scopes['wasm-expression-stack']).join(', '); let values = scopes['local'].concat(scopes['wasm-expression-stack']).join(', ');
InspectorTest.log(`Paused at offset ${loc.columnNumber}: [${values}]`); InspectorTest.log(`Paused at offset ${loc.columnNumber}: [${values}]`);
......
...@@ -14,9 +14,9 @@ Setting breakpoint on offset 54 (on the setlocal before the call), url wasm://wa ...@@ -14,9 +14,9 @@ Setting breakpoint on offset 54 (on the setlocal before the call), url wasm://wa
Script wasm://wasm/9b4bf87e byte offset 54: Wasm opcode 0x21 (kExprLocalSet) Script wasm://wasm/9b4bf87e byte offset 54: Wasm opcode 0x21 (kExprLocalSet)
at wasm_B (0:54): at wasm_B (0:54):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{"0":3} 0: 3 (i32)
- scope (local): - scope (local):
{"$var0":4} $var0: 4 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -26,9 +26,8 @@ Debugger.stepInto called ...@@ -26,9 +26,8 @@ Debugger.stepInto called
Script wasm://wasm/9b4bf87e byte offset 56: Wasm opcode 0x10 (kExprCallFunction) Script wasm://wasm/9b4bf87e byte offset 56: Wasm opcode 0x10 (kExprCallFunction)
at wasm_B (0:56): at wasm_B (0:56):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{"$var0":3} $var0: 3 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -38,16 +37,13 @@ Debugger.stepInto called ...@@ -38,16 +37,13 @@ Debugger.stepInto called
Script wasm://wasm/9b4bf87e byte offset 38: Wasm opcode 0x01 (kExprNop) Script wasm://wasm/9b4bf87e byte offset 38: Wasm opcode 0x01 (kExprNop)
at wasm_A (0:38): at wasm_A (0:38):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{}
- scope (module): - scope (module):
-- skipped -- skipped
at wasm_B (0:56): at wasm_B (0:56):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{"$var0":3} $var0: 3 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -57,16 +53,13 @@ Debugger.stepOver called ...@@ -57,16 +53,13 @@ Debugger.stepOver called
Script wasm://wasm/9b4bf87e byte offset 39: Wasm opcode 0x01 (kExprNop) Script wasm://wasm/9b4bf87e byte offset 39: Wasm opcode 0x01 (kExprNop)
at wasm_A (0:39): at wasm_A (0:39):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{}
- scope (module): - scope (module):
-- skipped -- skipped
at wasm_B (0:56): at wasm_B (0:56):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{"$var0":3} $var0: 3 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -76,9 +69,8 @@ Debugger.stepOut called ...@@ -76,9 +69,8 @@ Debugger.stepOut called
Script wasm://wasm/9b4bf87e byte offset 58: Wasm opcode 0x0c (kExprBr) Script wasm://wasm/9b4bf87e byte offset 58: Wasm opcode 0x0c (kExprBr)
at wasm_B (0:58): at wasm_B (0:58):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{"$var0":3} $var0: 3 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -88,9 +80,9 @@ Debugger.stepOut called ...@@ -88,9 +80,9 @@ Debugger.stepOut called
Script wasm://wasm/9b4bf87e byte offset 54: Wasm opcode 0x21 (kExprLocalSet) Script wasm://wasm/9b4bf87e byte offset 54: Wasm opcode 0x21 (kExprLocalSet)
at wasm_B (0:54): at wasm_B (0:54):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{"0":2} 0: 2 (i32)
- scope (local): - scope (local):
{"$var0":3} $var0: 3 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -100,9 +92,8 @@ Debugger.stepOver called ...@@ -100,9 +92,8 @@ Debugger.stepOver called
Script wasm://wasm/9b4bf87e byte offset 56: Wasm opcode 0x10 (kExprCallFunction) Script wasm://wasm/9b4bf87e byte offset 56: Wasm opcode 0x10 (kExprCallFunction)
at wasm_B (0:56): at wasm_B (0:56):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{"$var0":2} $var0: 2 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -112,9 +103,8 @@ Debugger.stepOver called ...@@ -112,9 +103,8 @@ Debugger.stepOver called
Script wasm://wasm/9b4bf87e byte offset 58: Wasm opcode 0x0c (kExprBr) Script wasm://wasm/9b4bf87e byte offset 58: Wasm opcode 0x0c (kExprBr)
at wasm_B (0:58): at wasm_B (0:58):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{"$var0":2} $var0: 2 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -124,9 +114,9 @@ Debugger.resume called ...@@ -124,9 +114,9 @@ Debugger.resume called
Script wasm://wasm/9b4bf87e byte offset 54: Wasm opcode 0x21 (kExprLocalSet) Script wasm://wasm/9b4bf87e byte offset 54: Wasm opcode 0x21 (kExprLocalSet)
at wasm_B (0:54): at wasm_B (0:54):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{"0":1} 0: 1 (i32)
- scope (local): - scope (local):
{"$var0":2} $var0: 2 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -136,9 +126,8 @@ Debugger.stepInto called ...@@ -136,9 +126,8 @@ Debugger.stepInto called
Script wasm://wasm/9b4bf87e byte offset 56: Wasm opcode 0x10 (kExprCallFunction) Script wasm://wasm/9b4bf87e byte offset 56: Wasm opcode 0x10 (kExprCallFunction)
at wasm_B (0:56): at wasm_B (0:56):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{"$var0":1} $var0: 1 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -148,16 +137,13 @@ Debugger.stepInto called ...@@ -148,16 +137,13 @@ Debugger.stepInto called
Script wasm://wasm/9b4bf87e byte offset 38: Wasm opcode 0x01 (kExprNop) Script wasm://wasm/9b4bf87e byte offset 38: Wasm opcode 0x01 (kExprNop)
at wasm_A (0:38): at wasm_A (0:38):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{}
- scope (module): - scope (module):
-- skipped -- skipped
at wasm_B (0:56): at wasm_B (0:56):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{"$var0":1} $var0: 1 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -167,9 +153,8 @@ Debugger.stepOut called ...@@ -167,9 +153,8 @@ Debugger.stepOut called
Script wasm://wasm/9b4bf87e byte offset 58: Wasm opcode 0x0c (kExprBr) Script wasm://wasm/9b4bf87e byte offset 58: Wasm opcode 0x0c (kExprBr)
at wasm_B (0:58): at wasm_B (0:58):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{"$var0":1} $var0: 1 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -179,9 +164,8 @@ Debugger.stepInto called ...@@ -179,9 +164,8 @@ Debugger.stepInto called
Script wasm://wasm/9b4bf87e byte offset 45: Wasm opcode 0x20 (kExprLocalGet) Script wasm://wasm/9b4bf87e byte offset 45: Wasm opcode 0x20 (kExprLocalGet)
at wasm_B (0:45): at wasm_B (0:45):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{"$var0":1} $var0: 1 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -191,9 +175,9 @@ Debugger.stepInto called ...@@ -191,9 +175,9 @@ Debugger.stepInto called
Script wasm://wasm/9b4bf87e byte offset 47: Wasm opcode 0x04 (kExprIf) Script wasm://wasm/9b4bf87e byte offset 47: Wasm opcode 0x04 (kExprIf)
at wasm_B (0:47): at wasm_B (0:47):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{"0":1} 0: 1 (i32)
- scope (local): - scope (local):
{"$var0":1} $var0: 1 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -203,9 +187,8 @@ Debugger.stepInto called ...@@ -203,9 +187,8 @@ Debugger.stepInto called
Script wasm://wasm/9b4bf87e byte offset 49: Wasm opcode 0x20 (kExprLocalGet) Script wasm://wasm/9b4bf87e byte offset 49: Wasm opcode 0x20 (kExprLocalGet)
at wasm_B (0:49): at wasm_B (0:49):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{"$var0":1} $var0: 1 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -215,9 +198,9 @@ Debugger.stepInto called ...@@ -215,9 +198,9 @@ Debugger.stepInto called
Script wasm://wasm/9b4bf87e byte offset 51: Wasm opcode 0x41 (kExprI32Const) Script wasm://wasm/9b4bf87e byte offset 51: Wasm opcode 0x41 (kExprI32Const)
at wasm_B (0:51): at wasm_B (0:51):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{"0":1} 0: 1 (i32)
- scope (local): - scope (local):
{"$var0":1} $var0: 1 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -227,9 +210,10 @@ Debugger.stepInto called ...@@ -227,9 +210,10 @@ Debugger.stepInto called
Script wasm://wasm/9b4bf87e byte offset 53: Wasm opcode 0x6b (kExprI32Sub) Script wasm://wasm/9b4bf87e byte offset 53: Wasm opcode 0x6b (kExprI32Sub)
at wasm_B (0:53): at wasm_B (0:53):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{"0":1,"1":1} 0: 1 (i32)
1: 1 (i32)
- scope (local): - scope (local):
{"$var0":1} $var0: 1 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -239,9 +223,9 @@ Debugger.stepInto called ...@@ -239,9 +223,9 @@ Debugger.stepInto called
Script wasm://wasm/9b4bf87e byte offset 54: Wasm opcode 0x21 (kExprLocalSet) Script wasm://wasm/9b4bf87e byte offset 54: Wasm opcode 0x21 (kExprLocalSet)
at wasm_B (0:54): at wasm_B (0:54):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{"0":0} 0: 0 (i32)
- scope (local): - scope (local):
{"$var0":1} $var0: 1 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -251,9 +235,8 @@ Debugger.stepInto called ...@@ -251,9 +235,8 @@ Debugger.stepInto called
Script wasm://wasm/9b4bf87e byte offset 56: Wasm opcode 0x10 (kExprCallFunction) Script wasm://wasm/9b4bf87e byte offset 56: Wasm opcode 0x10 (kExprCallFunction)
at wasm_B (0:56): at wasm_B (0:56):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{"$var0":0} $var0: 0 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -263,16 +246,13 @@ Debugger.stepInto called ...@@ -263,16 +246,13 @@ Debugger.stepInto called
Script wasm://wasm/9b4bf87e byte offset 38: Wasm opcode 0x01 (kExprNop) Script wasm://wasm/9b4bf87e byte offset 38: Wasm opcode 0x01 (kExprNop)
at wasm_A (0:38): at wasm_A (0:38):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{}
- scope (module): - scope (module):
-- skipped -- skipped
at wasm_B (0:56): at wasm_B (0:56):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{"$var0":0} $var0: 0 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -282,16 +262,13 @@ Debugger.stepInto called ...@@ -282,16 +262,13 @@ Debugger.stepInto called
Script wasm://wasm/9b4bf87e byte offset 39: Wasm opcode 0x01 (kExprNop) Script wasm://wasm/9b4bf87e byte offset 39: Wasm opcode 0x01 (kExprNop)
at wasm_A (0:39): at wasm_A (0:39):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{}
- scope (module): - scope (module):
-- skipped -- skipped
at wasm_B (0:56): at wasm_B (0:56):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{"$var0":0} $var0: 0 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -301,16 +278,13 @@ Debugger.stepInto called ...@@ -301,16 +278,13 @@ Debugger.stepInto called
Script wasm://wasm/9b4bf87e byte offset 40: Wasm opcode 0x0b (kExprEnd) Script wasm://wasm/9b4bf87e byte offset 40: Wasm opcode 0x0b (kExprEnd)
at wasm_A (0:40): at wasm_A (0:40):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{}
- scope (module): - scope (module):
-- skipped -- skipped
at wasm_B (0:56): at wasm_B (0:56):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{"$var0":0} $var0: 0 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
...@@ -320,9 +294,8 @@ Debugger.stepInto called ...@@ -320,9 +294,8 @@ Debugger.stepInto called
Script wasm://wasm/9b4bf87e byte offset 58: Wasm opcode 0x0c (kExprBr) Script wasm://wasm/9b4bf87e byte offset 58: Wasm opcode 0x0c (kExprBr)
at wasm_B (0:58): at wasm_B (0:58):
- scope (wasm-expression-stack): - scope (wasm-expression-stack):
{}
- scope (local): - scope (local):
{"$var0":0} $var0: 0 (i32)
- scope (module): - scope (module):
-- skipped -- skipped
at (anonymous) (0:17): at (anonymous) (0:17):
......
...@@ -91,15 +91,12 @@ async function waitForPauseAndStep(stepAction) { ...@@ -91,15 +91,12 @@ async function waitForPauseAndStep(stepAction) {
if (scope.type === 'global' || scope.type === 'module') { if (scope.type === 'global' || scope.type === 'module') {
InspectorTest.logObject(' -- skipped'); InspectorTest.logObject(' -- skipped');
} else { } else {
const object = {}; let properties = await Protocol.Runtime.getProperties(
const {result: {result: properties}} = {objectId: scope.object.objectId});
await Protocol.Runtime.getProperties({ for (let {name, value} of properties.result.result) {
objectId: scope.object.objectId value = await WasmInspectorTest.getWasmValue(value);
}); InspectorTest.log(` ${name}: ${value}`);
for (const {name, value: {value}} of properties) {
object[name] = value;
} }
InspectorTest.log(` ${JSON.stringify(object)}`);
} }
} }
} }
......
...@@ -7,10 +7,11 @@ utils.load('test/mjsunit/wasm/wasm-module-builder.js'); ...@@ -7,10 +7,11 @@ utils.load('test/mjsunit/wasm/wasm-module-builder.js');
WasmInspectorTest = {} WasmInspectorTest = {}
InspectorTest.getWasmOpcodeName = getOpcodeName; InspectorTest.getWasmOpcodeName = getOpcodeName;
WasmInspectorTest.evalWithUrl = (code, url) => WasmInspectorTest.evalWithUrl = async function(code, url) {
Protocol.Runtime return await Protocol.Runtime
.evaluate({'expression': code + '\n//# sourceURL=v8://test/' + url}) .evaluate({'expression': code + '\n//# sourceURL=v8://test/' + url})
.then(printIfFailure); .then(printIfFailure);
};
WasmInspectorTest.instantiateFromBuffer = function(bytes, imports) { WasmInspectorTest.instantiateFromBuffer = function(bytes, imports) {
var buffer = new ArrayBuffer(bytes.length); var buffer = new ArrayBuffer(bytes.length);
...@@ -20,12 +21,14 @@ WasmInspectorTest.instantiateFromBuffer = function(bytes, imports) { ...@@ -20,12 +21,14 @@ WasmInspectorTest.instantiateFromBuffer = function(bytes, imports) {
} }
const module = new WebAssembly.Module(buffer); const module = new WebAssembly.Module(buffer);
return new WebAssembly.Instance(module, imports); return new WebAssembly.Instance(module, imports);
} };
WasmInspectorTest.instantiate = async function(bytes, instance_name = 'instance') { WasmInspectorTest.instantiate =
const instantiate_code = `var ${instance_name} = (${WasmInspectorTest.instantiateFromBuffer})(${JSON.stringify(bytes)});`; async function(bytes, instance_name = 'instance') {
const instantiate_code = `var ${instance_name} = (${
WasmInspectorTest.instantiateFromBuffer})(${JSON.stringify(bytes)});`;
await WasmInspectorTest.evalWithUrl(instantiate_code, 'instantiate'); await WasmInspectorTest.evalWithUrl(instantiate_code, 'instantiate');
} };
WasmInspectorTest.dumpScopeProperties = async function(message) { WasmInspectorTest.dumpScopeProperties = async function(message) {
printIfFailure(message); printIfFailure(message);
...@@ -33,11 +36,17 @@ WasmInspectorTest.dumpScopeProperties = async function(message) { ...@@ -33,11 +36,17 @@ WasmInspectorTest.dumpScopeProperties = async function(message) {
var value_str = await getScopeValues(value.name, value.value); var value_str = await getScopeValues(value.name, value.value);
InspectorTest.log(' ' + value.name + ': ' + value_str); InspectorTest.log(' ' + value.name + ': ' + value_str);
} }
} };
WasmInspectorTest.getWasmValue = value => { WasmInspectorTest.getWasmValue = async function(value) {
return value.unserializableValue ?? value.value; let msg = await Protocol.Runtime.getProperties({objectId: value.objectId});
} printIfFailure(msg);
const value_type = msg.result.result.find(({name}) => name === 'type');
const value_value = msg.result.result.find(({name}) => name === 'value');
return `${
value_value.value.unserializableValue ??
value_value.value.value} (${value_type.value.value})`;
};
function printIfFailure(message) { function printIfFailure(message) {
if (!message.result) { if (!message.result) {
...@@ -47,22 +56,29 @@ function printIfFailure(message) { ...@@ -47,22 +56,29 @@ function printIfFailure(message) {
} }
async function getScopeValues(name, value) { async function getScopeValues(name, value) {
if (value.type === 'object') { async function printValue(value) {
if (value.subtype === 'typedarray' || value.subtype == 'webassemblymemory') return value.description; if (value.type === 'object' && value.subtype === 'wasmvalue') {
return await WasmInspectorTest.getWasmValue(value);
} else if ('className' in value) {
return `(${value.className})`;
}
return `${value.unserializableValue ?? value.value} (${
value.subtype ?? value.type})`;
}
if (value.type === 'object' && value.subtype !== 'wasmvalue') {
if (value.subtype === 'typedarray' || value.subtype == 'webassemblymemory')
return value.description;
if (name === 'instance') return dumpInstanceProperties(value); if (name === 'instance') return dumpInstanceProperties(value);
if (name === 'module') return value.description; if (name === 'module') return value.description;
let msg = await Protocol.Runtime.getProperties({objectId: value.objectId}); let msg = await Protocol.Runtime.getProperties({objectId: value.objectId});
printIfFailure(msg); printIfFailure(msg);
const printProperty = function({name, value}) { async function printProperty({name, value}) {
if ('className' in value) { return `"${name}": ${await printValue(value)}`;
return `"${name}" (${value.className})`;
}
return `"${name}": ${WasmInspectorTest.getWasmValue(value)} (${value.subtype ?? value.type})`;
} }
return msg.result.result.map(printProperty).join(', '); return (await Promise.all(msg.result.result.map(printProperty))).join(', ');
} }
return `${WasmInspectorTest.getWasmValue(value)} (${value.subtype ?? value.type})`; return await printValue(value);
} }
function recursiveGetPropertiesWrapper(value, depth) { function recursiveGetPropertiesWrapper(value, depth) {
...@@ -71,10 +87,12 @@ function recursiveGetPropertiesWrapper(value, depth) { ...@@ -71,10 +87,12 @@ function recursiveGetPropertiesWrapper(value, depth) {
async function recursiveGetProperties(value, depth) { async function recursiveGetProperties(value, depth) {
if (depth > 0) { if (depth > 0) {
const properties = await Promise.all(value.result.result.map( const properties = await Promise.all(value.result.result.map(x => {
x => {return Protocol.Runtime.getProperties({objectId: x.value.objectId});})); return Protocol.Runtime.getProperties({objectId: x.value.objectId});
const recursiveProperties = await Promise.all(properties.map( }));
x => {return recursiveGetProperties(x, depth - 1);})); const recursiveProperties = await Promise.all(properties.map(x => {
return recursiveGetProperties(x, depth - 1);
}));
return recursiveProperties.flat(); return recursiveProperties.flat();
} }
return value; return value;
...@@ -86,17 +104,17 @@ async function dumpInstanceProperties(instanceObj) { ...@@ -86,17 +104,17 @@ async function dumpInstanceProperties(instanceObj) {
} }
const exportsName = 'exports'; const exportsName = 'exports';
let exportsObj = await Protocol.Runtime.callFunctionOn( let exportsObj = await Protocol.Runtime.callFunctionOn({
{objectId: instanceObj.objectId, objectId: instanceObj.objectId,
functionDeclaration: invokeGetter.toString(), functionDeclaration: invokeGetter.toString(),
arguments: [{value: JSON.stringify(exportsName)}] arguments: [{value: JSON.stringify(exportsName)}]
}); });
printIfFailure(exportsObj); printIfFailure(exportsObj);
let exports = await Protocol.Runtime.getProperties( let exports = await Protocol.Runtime.getProperties(
{objectId: exportsObj.result.result.objectId}); {objectId: exportsObj.result.result.objectId});
printIfFailure(exports); printIfFailure(exports);
const printExports = function(value) { function printExports(value) {
return `"${value.name}" (${value.value.className})`; return `"${value.name}" (${value.value.className})`;
} }
const formattedExports = exports.result.result.map(printExports).join(', '); const formattedExports = exports.result.result.map(printExports).join(', ');
......
...@@ -227,6 +227,7 @@ INSTANCE_TYPES = { ...@@ -227,6 +227,7 @@ INSTANCE_TYPES = {
1114: "WASM_MEMORY_OBJECT_TYPE", 1114: "WASM_MEMORY_OBJECT_TYPE",
1115: "WASM_MODULE_OBJECT_TYPE", 1115: "WASM_MODULE_OBJECT_TYPE",
1116: "WASM_TABLE_OBJECT_TYPE", 1116: "WASM_TABLE_OBJECT_TYPE",
1117: "WASM_VALUE_OBJECT_TYPE",
} }
# List of known V8 maps. # List of known V8 maps.
......
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