[wasm] Move {GetGlobalValue} out of the interpreter
This will allow us to reuse this method in other contexts. This CL also contains smaller refactorings that helped to move the code. E.g. the WASMVALUE_CTYPES macro (defined in value-type.h) replaces the WASM_CTYPES macro (from wasm-interpreter.cc). R=mstarzinger@chromium.org Bug: v8:9676 Change-Id: Id788f843af9a09eb940593afa1639f12b652c514 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1876054 Commit-Queue: Clemens Backes <clemensb@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Cr-Commit-Position: refs/heads/master@{#64534}
This commit is contained in:
parent
5bba668004
commit
334dd91987
@ -16,6 +16,9 @@ class Signature;
|
|||||||
|
|
||||||
namespace wasm {
|
namespace wasm {
|
||||||
|
|
||||||
|
// Type for holding simd values, defined in wasm-value.h.
|
||||||
|
class Simd128;
|
||||||
|
|
||||||
// Type lattice: For any two types connected by a line, the type at the bottom
|
// Type lattice: For any two types connected by a line, the type at the bottom
|
||||||
// is a subtype of the other type.
|
// is a subtype of the other type.
|
||||||
//
|
//
|
||||||
@ -40,6 +43,13 @@ enum ValueType : uint8_t {
|
|||||||
kWasmBottom,
|
kWasmBottom,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define FOREACH_WASMVALUE_CTYPES(V) \
|
||||||
|
V(kWasmI32, int32_t) \
|
||||||
|
V(kWasmI64, int64_t) \
|
||||||
|
V(kWasmF32, float) \
|
||||||
|
V(kWasmF64, double) \
|
||||||
|
V(kWasmS128, Simd128)
|
||||||
|
|
||||||
using FunctionSig = Signature<ValueType>;
|
using FunctionSig = Signature<ValueType>;
|
||||||
|
|
||||||
inline size_t hash_value(ValueType type) { return static_cast<size_t>(type); }
|
inline size_t hash_value(ValueType type) { return static_cast<size_t>(type); }
|
||||||
|
@ -380,11 +380,8 @@ class InterpreterHandle {
|
|||||||
.Assert();
|
.Assert();
|
||||||
}
|
}
|
||||||
|
|
||||||
DCHECK_EQ(1, interpreter()->GetThreadCount());
|
auto& globals = module()->globals;
|
||||||
WasmInterpreter::Thread* thread = interpreter()->GetThread(0);
|
if (!globals.empty()) {
|
||||||
|
|
||||||
uint32_t global_count = thread->GetGlobalCount();
|
|
||||||
if (global_count > 0) {
|
|
||||||
Handle<JSObject> globals_obj =
|
Handle<JSObject> globals_obj =
|
||||||
isolate_->factory()->NewJSObjectWithNullProto();
|
isolate_->factory()->NewJSObjectWithNullProto();
|
||||||
Handle<String> globals_name =
|
Handle<String> globals_name =
|
||||||
@ -393,10 +390,11 @@ class InterpreterHandle {
|
|||||||
globals_name, globals_obj, NONE)
|
globals_name, globals_obj, NONE)
|
||||||
.Assert();
|
.Assert();
|
||||||
|
|
||||||
for (uint32_t i = 0; i < global_count; ++i) {
|
for (uint32_t i = 0; i < globals.size(); ++i) {
|
||||||
const char* label = "global#%d";
|
const char* label = "global#%d";
|
||||||
Handle<String> name = PrintFToOneByteString<true>(isolate_, label, i);
|
Handle<String> name = PrintFToOneByteString<true>(isolate_, label, i);
|
||||||
WasmValue value = thread->GetGlobalValue(i);
|
WasmValue value =
|
||||||
|
WasmInstanceObject::GetGlobalValue(instance, globals[i]);
|
||||||
Handle<Object> value_obj = WasmValueToValueObject(isolate_, value);
|
Handle<Object> value_obj = WasmValueToValueObject(isolate_, value);
|
||||||
JSObject::SetOwnPropertyIgnoreAttributes(globals_obj, name, value_obj,
|
JSObject::SetOwnPropertyIgnoreAttributes(globals_obj, name, value_obj,
|
||||||
NONE)
|
NONE)
|
||||||
|
@ -51,9 +51,6 @@ using base::WriteUnalignedValue;
|
|||||||
|
|
||||||
#define FOREACH_INTERNAL_OPCODE(V) V(Breakpoint, 0xFF)
|
#define FOREACH_INTERNAL_OPCODE(V) V(Breakpoint, 0xFF)
|
||||||
|
|
||||||
#define WASM_CTYPES(V) \
|
|
||||||
V(I32, int32_t) V(I64, int64_t) V(F32, float) V(F64, double) V(S128, Simd128)
|
|
||||||
|
|
||||||
#define FOREACH_SIMPLE_BINOP(V) \
|
#define FOREACH_SIMPLE_BINOP(V) \
|
||||||
V(I32Add, uint32_t, +) \
|
V(I32Add, uint32_t, +) \
|
||||||
V(I32Sub, uint32_t, -) \
|
V(I32Sub, uint32_t, -) \
|
||||||
@ -1295,40 +1292,6 @@ class ThreadImpl {
|
|||||||
return WasmInterpreter::Thread::HANDLED;
|
return WasmInterpreter::Thread::HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t GetGlobalCount() {
|
|
||||||
return static_cast<uint32_t>(module()->globals.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
WasmValue GetGlobalValue(uint32_t index) {
|
|
||||||
auto& global = module()->globals[index];
|
|
||||||
switch (global.type) {
|
|
||||||
#define CASE_TYPE(wasm, ctype) \
|
|
||||||
case kWasm##wasm: { \
|
|
||||||
byte* ptr = \
|
|
||||||
WasmInstanceObject::GetGlobalStorage(instance_object_, global); \
|
|
||||||
return WasmValue( \
|
|
||||||
ReadLittleEndianValue<ctype>(reinterpret_cast<Address>(ptr))); \
|
|
||||||
break; \
|
|
||||||
}
|
|
||||||
WASM_CTYPES(CASE_TYPE)
|
|
||||||
#undef CASE_TYPE
|
|
||||||
case kWasmAnyRef:
|
|
||||||
case kWasmFuncRef:
|
|
||||||
case kWasmExnRef: {
|
|
||||||
HandleScope handle_scope(isolate_); // Avoid leaking handles.
|
|
||||||
Handle<FixedArray> global_buffer; // The buffer of the global.
|
|
||||||
uint32_t global_index; // The index into the buffer.
|
|
||||||
std::tie(global_buffer, global_index) =
|
|
||||||
WasmInstanceObject::GetGlobalBufferAndIndex(instance_object_,
|
|
||||||
global);
|
|
||||||
Handle<Object> value(global_buffer->get(global_index), isolate_);
|
|
||||||
return WasmValue(handle_scope.CloseAndEscape(value));
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Handle a thrown exception. Returns whether the exception was handled inside
|
// Handle a thrown exception. Returns whether the exception was handled inside
|
||||||
// the current activation. Unwinds the interpreted stack accordingly.
|
// the current activation. Unwinds the interpreted stack accordingly.
|
||||||
@ -1490,11 +1453,11 @@ class ThreadImpl {
|
|||||||
for (auto p : code->locals.type_list) {
|
for (auto p : code->locals.type_list) {
|
||||||
WasmValue val;
|
WasmValue val;
|
||||||
switch (p) {
|
switch (p) {
|
||||||
#define CASE_TYPE(wasm, ctype) \
|
#define CASE_TYPE(valuetype, ctype) \
|
||||||
case kWasm##wasm: \
|
case valuetype: \
|
||||||
val = WasmValue(ctype{}); \
|
val = WasmValue(ctype{}); \
|
||||||
break;
|
break;
|
||||||
WASM_CTYPES(CASE_TYPE)
|
FOREACH_WASMVALUE_CTYPES(CASE_TYPE)
|
||||||
#undef CASE_TYPE
|
#undef CASE_TYPE
|
||||||
case kWasmAnyRef:
|
case kWasmAnyRef:
|
||||||
case kWasmFuncRef:
|
case kWasmFuncRef:
|
||||||
@ -3311,7 +3274,8 @@ class ThreadImpl {
|
|||||||
GlobalIndexImmediate<Decoder::kNoValidate> imm(&decoder,
|
GlobalIndexImmediate<Decoder::kNoValidate> imm(&decoder,
|
||||||
code->at(pc));
|
code->at(pc));
|
||||||
HandleScope handle_scope(isolate_);
|
HandleScope handle_scope(isolate_);
|
||||||
Push(GetGlobalValue(imm.index));
|
Push(WasmInstanceObject::GetGlobalValue(
|
||||||
|
instance_object_, module()->globals[imm.index]));
|
||||||
len = 1 + imm.length;
|
len = 1 + imm.length;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3320,15 +3284,15 @@ class ThreadImpl {
|
|||||||
code->at(pc));
|
code->at(pc));
|
||||||
auto& global = module()->globals[imm.index];
|
auto& global = module()->globals[imm.index];
|
||||||
switch (global.type) {
|
switch (global.type) {
|
||||||
#define CASE_TYPE(wasm, ctype) \
|
#define CASE_TYPE(valuetype, ctype) \
|
||||||
case kWasm##wasm: { \
|
case valuetype: { \
|
||||||
byte* ptr = \
|
uint8_t* ptr = \
|
||||||
WasmInstanceObject::GetGlobalStorage(instance_object_, global); \
|
WasmInstanceObject::GetGlobalStorage(instance_object_, global); \
|
||||||
WriteLittleEndianValue<ctype>(reinterpret_cast<Address>(ptr), \
|
WriteLittleEndianValue<ctype>(reinterpret_cast<Address>(ptr), \
|
||||||
Pop().to<ctype>()); \
|
Pop().to<ctype>()); \
|
||||||
break; \
|
break; \
|
||||||
}
|
}
|
||||||
WASM_CTYPES(CASE_TYPE)
|
FOREACH_WASMVALUE_CTYPES(CASE_TYPE)
|
||||||
#undef CASE_TYPE
|
#undef CASE_TYPE
|
||||||
case kWasmAnyRef:
|
case kWasmAnyRef:
|
||||||
case kWasmFuncRef:
|
case kWasmFuncRef:
|
||||||
@ -4069,12 +4033,6 @@ WasmValue WasmInterpreter::Thread::GetReturnValue(int index) {
|
|||||||
TrapReason WasmInterpreter::Thread::GetTrapReason() {
|
TrapReason WasmInterpreter::Thread::GetTrapReason() {
|
||||||
return ToImpl(this)->GetTrapReason();
|
return ToImpl(this)->GetTrapReason();
|
||||||
}
|
}
|
||||||
uint32_t WasmInterpreter::Thread::GetGlobalCount() {
|
|
||||||
return ToImpl(this)->GetGlobalCount();
|
|
||||||
}
|
|
||||||
WasmValue WasmInterpreter::Thread::GetGlobalValue(uint32_t index) {
|
|
||||||
return ToImpl(this)->GetGlobalValue(index);
|
|
||||||
}
|
|
||||||
bool WasmInterpreter::Thread::PossibleNondeterminism() {
|
bool WasmInterpreter::Thread::PossibleNondeterminism() {
|
||||||
return ToImpl(this)->PossibleNondeterminism();
|
return ToImpl(this)->PossibleNondeterminism();
|
||||||
}
|
}
|
||||||
@ -4259,7 +4217,6 @@ void InterpretedFrameDeleter::operator()(InterpretedFrame* ptr) {
|
|||||||
#undef TRACE
|
#undef TRACE
|
||||||
#undef LANE
|
#undef LANE
|
||||||
#undef FOREACH_INTERNAL_OPCODE
|
#undef FOREACH_INTERNAL_OPCODE
|
||||||
#undef WASM_CTYPES
|
|
||||||
#undef FOREACH_SIMPLE_BINOP
|
#undef FOREACH_SIMPLE_BINOP
|
||||||
#undef FOREACH_OTHER_BINOP
|
#undef FOREACH_OTHER_BINOP
|
||||||
#undef FOREACH_I32CONV_FLOATOP
|
#undef FOREACH_I32CONV_FLOATOP
|
||||||
|
@ -139,9 +139,6 @@ class V8_EXPORT_PRIVATE WasmInterpreter {
|
|||||||
WasmValue GetReturnValue(int index = 0);
|
WasmValue GetReturnValue(int index = 0);
|
||||||
TrapReason GetTrapReason();
|
TrapReason GetTrapReason();
|
||||||
|
|
||||||
uint32_t GetGlobalCount();
|
|
||||||
WasmValue GetGlobalValue(uint32_t index);
|
|
||||||
|
|
||||||
// Returns true if the thread executed an instruction which may produce
|
// Returns true if the thread executed an instruction which may produce
|
||||||
// nondeterministic results, e.g. float div, float sqrt, and float mul,
|
// nondeterministic results, e.g. float div, float sqrt, and float mul,
|
||||||
// where the sign bit of a NaN is nondeterministic.
|
// where the sign bit of a NaN is nondeterministic.
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "src/wasm/wasm-limits.h"
|
#include "src/wasm/wasm-limits.h"
|
||||||
#include "src/wasm/wasm-module.h"
|
#include "src/wasm/wasm-module.h"
|
||||||
#include "src/wasm/wasm-objects-inl.h"
|
#include "src/wasm/wasm-objects-inl.h"
|
||||||
|
#include "src/wasm/wasm-value.h"
|
||||||
|
|
||||||
#define TRACE_IFT(...) \
|
#define TRACE_IFT(...) \
|
||||||
do { \
|
do { \
|
||||||
@ -1626,6 +1627,30 @@ WasmInstanceObject::GetGlobalBufferAndIndex(Handle<WasmInstanceObject> instance,
|
|||||||
return {handle(instance->tagged_globals_buffer(), isolate), global.offset};
|
return {handle(instance->tagged_globals_buffer(), isolate), global.offset};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
wasm::WasmValue WasmInstanceObject::GetGlobalValue(
|
||||||
|
Handle<WasmInstanceObject> instance, const wasm::WasmGlobal& global) {
|
||||||
|
Isolate* isolate = instance->GetIsolate();
|
||||||
|
if (wasm::ValueTypes::IsReferenceType(global.type)) {
|
||||||
|
Handle<FixedArray> global_buffer; // The buffer of the global.
|
||||||
|
uint32_t global_index = 0; // The index into the buffer.
|
||||||
|
std::tie(global_buffer, global_index) =
|
||||||
|
GetGlobalBufferAndIndex(instance, global);
|
||||||
|
return wasm::WasmValue(handle(global_buffer->get(global_index), isolate));
|
||||||
|
}
|
||||||
|
Address ptr = reinterpret_cast<Address>(GetGlobalStorage(instance, global));
|
||||||
|
using wasm::Simd128;
|
||||||
|
switch (global.type) {
|
||||||
|
#define CASE_TYPE(valuetype, ctype) \
|
||||||
|
case wasm::valuetype: \
|
||||||
|
return wasm::WasmValue(base::ReadLittleEndianValue<ctype>(ptr));
|
||||||
|
FOREACH_WASMVALUE_CTYPES(CASE_TYPE)
|
||||||
|
#undef CASE_TYPE
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
Handle<WasmExceptionObject> WasmExceptionObject::New(
|
Handle<WasmExceptionObject> WasmExceptionObject::New(
|
||||||
Isolate* isolate, const wasm::FunctionSig* sig,
|
Isolate* isolate, const wasm::FunctionSig* sig,
|
||||||
|
@ -569,6 +569,10 @@ class WasmInstanceObject : public JSObject {
|
|||||||
static std::pair<Handle<FixedArray>, uint32_t> GetGlobalBufferAndIndex(
|
static std::pair<Handle<FixedArray>, uint32_t> GetGlobalBufferAndIndex(
|
||||||
Handle<WasmInstanceObject>, const wasm::WasmGlobal&);
|
Handle<WasmInstanceObject>, const wasm::WasmGlobal&);
|
||||||
|
|
||||||
|
// Get the value of a global in the given instance.
|
||||||
|
static wasm::WasmValue GetGlobalValue(Handle<WasmInstanceObject>,
|
||||||
|
const wasm::WasmGlobal&);
|
||||||
|
|
||||||
OBJECT_CONSTRUCTORS(WasmInstanceObject, JSObject);
|
OBJECT_CONSTRUCTORS(WasmInstanceObject, JSObject);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -32,11 +32,8 @@ FOREACH_SIMD_TYPE(DEFINE_SIMD_TYPE)
|
|||||||
|
|
||||||
class Simd128 {
|
class Simd128 {
|
||||||
public:
|
public:
|
||||||
Simd128() : val_() {
|
Simd128() = default;
|
||||||
for (size_t i = 0; i < 16; i++) {
|
|
||||||
val_[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#define DEFINE_SIMD_TYPE_SPECIFIC_METHODS(cType, sType, name, size) \
|
#define DEFINE_SIMD_TYPE_SPECIFIC_METHODS(cType, sType, name, size) \
|
||||||
explicit Simd128(sType val) { \
|
explicit Simd128(sType val) { \
|
||||||
base::WriteUnalignedValue<sType>(reinterpret_cast<Address>(val_), val); \
|
base::WriteUnalignedValue<sType>(reinterpret_cast<Address>(val_), val); \
|
||||||
@ -48,7 +45,7 @@ class Simd128 {
|
|||||||
#undef DEFINE_SIMD_TYPE_SPECIFIC_METHODS
|
#undef DEFINE_SIMD_TYPE_SPECIFIC_METHODS
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t val_[16];
|
uint8_t val_[16] = {0};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Macro for defining WasmValue methods for different types.
|
// Macro for defining WasmValue methods for different types.
|
||||||
|
Loading…
Reference in New Issue
Block a user