Commit 782fa8d8 authored by Manos Koukoutos's avatar Manos Koukoutos Committed by Commit Bot

[wasm-gc] Add packed types to ValueType

Motivation:
In the wasm-gc proposal, structs and arrays are allowed to store
elements of packed types i8 and i16.

Changes:
- Add i8 and i16 to ValueType.
- Fix all case switches to handle the new cases.
- Add a couple helper methods to ValueType and improve the
  implementation/usage of a couple more.

Bug: v8:7748
Change-Id: I527cfe5acf5d877fc38e4212174ba9f9de5c40ad
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2215046Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67994}
parent dfbbb4a5
...@@ -2126,6 +2126,8 @@ Node* WasmGraphBuilder::Throw(uint32_t exception_index, ...@@ -2126,6 +2126,8 @@ Node* WasmGraphBuilder::Throw(uint32_t exception_index,
STORE_FIXED_ARRAY_SLOT_ANY(values_array, index, value); STORE_FIXED_ARRAY_SLOT_ANY(values_array, index, value);
++index; ++index;
break; break;
case wasm::ValueType::kI8:
case wasm::ValueType::kI16:
case wasm::ValueType::kStmt: case wasm::ValueType::kStmt:
case wasm::ValueType::kBottom: case wasm::ValueType::kBottom:
UNREACHABLE(); UNREACHABLE();
...@@ -2279,6 +2281,8 @@ Node* WasmGraphBuilder::GetExceptionValues(Node* except_obj, ...@@ -2279,6 +2281,8 @@ Node* WasmGraphBuilder::GetExceptionValues(Node* except_obj,
value = LOAD_FIXED_ARRAY_SLOT_ANY(values_array, index); value = LOAD_FIXED_ARRAY_SLOT_ANY(values_array, index);
++index; ++index;
break; break;
case wasm::ValueType::kI8:
case wasm::ValueType::kI16:
case wasm::ValueType::kStmt: case wasm::ValueType::kStmt:
case wasm::ValueType::kBottom: case wasm::ValueType::kBottom:
UNREACHABLE(); UNREACHABLE();
...@@ -5507,6 +5511,9 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -5507,6 +5511,9 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
// TODO(7748): Implement properly. For now, we just expose the raw // TODO(7748): Implement properly. For now, we just expose the raw
// object for testing. // object for testing.
return node; return node;
case wasm::ValueType::kI8:
case wasm::ValueType::kI16:
UNIMPLEMENTED();
case wasm::ValueType::kStmt: case wasm::ValueType::kStmt:
case wasm::ValueType::kBottom: case wasm::ValueType::kBottom:
UNREACHABLE(); UNREACHABLE();
...@@ -5616,7 +5623,14 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -5616,7 +5623,14 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
DCHECK(enabled_features_.has_bigint()); DCHECK(enabled_features_.has_bigint());
return BuildChangeBigIntToInt64(input, js_context); return BuildChangeBigIntToInt64(input, js_context);
default: case wasm::ValueType::kS128:
case wasm::ValueType::kRef:
case wasm::ValueType::kOptRef:
case wasm::ValueType::kEqRef:
case wasm::ValueType::kI8:
case wasm::ValueType::kI16:
case wasm::ValueType::kBottom:
case wasm::ValueType::kStmt:
UNREACHABLE(); UNREACHABLE();
break; break;
} }
......
...@@ -1690,6 +1690,8 @@ void WasmStruct::WasmStructPrint(std::ostream& os) { // NOLINT ...@@ -1690,6 +1690,8 @@ void WasmStruct::WasmStructPrint(std::ostream& os) { // NOLINT
case wasm::ValueType::kF64: case wasm::ValueType::kF64:
os << base::ReadUnalignedValue<double>(field_address); os << base::ReadUnalignedValue<double>(field_address);
break; break;
case wasm::ValueType::kI8:
case wasm::ValueType::kI16:
case wasm::ValueType::kS128: case wasm::ValueType::kS128:
case wasm::ValueType::kAnyRef: case wasm::ValueType::kAnyRef:
case wasm::ValueType::kFuncRef: case wasm::ValueType::kFuncRef:
...@@ -1731,6 +1733,8 @@ void WasmArray::WasmArrayPrint(std::ostream& os) { // NOLINT ...@@ -1731,6 +1733,8 @@ void WasmArray::WasmArrayPrint(std::ostream& os) { // NOLINT
PrintTypedArrayElements(os, reinterpret_cast<double*>(data_ptr), len, PrintTypedArrayElements(os, reinterpret_cast<double*>(data_ptr), len,
true); true);
break; break;
case wasm::ValueType::kI8:
case wasm::ValueType::kI16:
case wasm::ValueType::kS128: case wasm::ValueType::kS128:
case wasm::ValueType::kAnyRef: case wasm::ValueType::kAnyRef:
case wasm::ValueType::kFuncRef: case wasm::ValueType::kFuncRef:
......
...@@ -333,9 +333,11 @@ ValueType read_value_type(Decoder* decoder, const byte* pc, ...@@ -333,9 +333,11 @@ ValueType read_value_type(Decoder* decoder, const byte* pc,
"--experimental-wasm-simd"); "--experimental-wasm-simd");
return kWasmBottom; return kWasmBottom;
case kLocalVoid: case kLocalVoid:
// Although void is included in ValueType, it is technically not a value case kLocalI8:
// type and is only used to indicate a void block return type. The caller case kLocalI16:
// of this function is responsible to check for its presence separately. // Although these types are included in ValueType, they are technically
// not value types and are only used in specific contexts. The caller of
// this function is responsible to check for them separately.
break; break;
} }
// Malformed modules specifying invalid types can get here. // Malformed modules specifying invalid types can get here.
...@@ -2275,7 +2277,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2275,7 +2277,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Value fval = Pop(); Value fval = Pop();
Value tval = Pop(0, fval.type); Value tval = Pop(0, fval.type);
ValueType type = tval.type == kWasmBottom ? fval.type : tval.type; ValueType type = tval.type == kWasmBottom ? fval.type : tval.type;
if (type.IsSubTypeOf(kWasmAnyRef)) { if (type.IsReferenceType()) {
this->error( this->error(
"select without type is only valid for value type inputs"); "select without type is only valid for value type inputs");
break; break;
......
...@@ -795,6 +795,8 @@ class WasmGraphBuildingInterface { ...@@ -795,6 +795,8 @@ class WasmGraphBuildingInterface {
TFNode* DefaultValue(ValueType type) { TFNode* DefaultValue(ValueType type) {
switch (type.kind()) { switch (type.kind()) {
case ValueType::kI8:
case ValueType::kI16:
case ValueType::kI32: case ValueType::kI32:
return builder_->Int32Constant(0); return builder_->Int32Constant(0);
case ValueType::kI64: case ValueType::kI64:
......
...@@ -815,6 +815,8 @@ void InstanceBuilder::WriteGlobalValue(const WasmGlobal& global, ...@@ -815,6 +815,8 @@ void InstanceBuilder::WriteGlobalValue(const WasmGlobal& global,
case ValueType::kStmt: case ValueType::kStmt:
case ValueType::kS128: case ValueType::kS128:
case ValueType::kBottom: case ValueType::kBottom:
case ValueType::kI8:
case ValueType::kI16:
UNREACHABLE(); UNREACHABLE();
} }
TRACE(", type = %s (from WebAssembly.Global)\n", global.type.type_name()); TRACE(", type = %s (from WebAssembly.Global)\n", global.type.type_name());
......
...@@ -49,6 +49,8 @@ class Simd128; ...@@ -49,6 +49,8 @@ class Simd128;
V(F32, 2, F32, Float32, 'f', "f32") \ V(F32, 2, F32, Float32, 'f', "f32") \
V(F64, 3, F64, Float64, 'd', "f64") \ V(F64, 3, F64, Float64, 'd', "f64") \
V(S128, 4, S128, Simd128, 's', "s128") \ V(S128, 4, S128, Simd128, 's', "s128") \
V(I8, 1, I8, Int8, 'b', "i8") \
V(I16, 1, I16, Int16, 'h', "i16") \
V(AnyRef, kSystemPointerSizeLog2, AnyRef, TaggedPointer, 'r', "anyref") \ V(AnyRef, kSystemPointerSizeLog2, AnyRef, TaggedPointer, 'r', "anyref") \
V(FuncRef, kSystemPointerSizeLog2, FuncRef, TaggedPointer, 'a', "funcref") \ V(FuncRef, kSystemPointerSizeLog2, FuncRef, TaggedPointer, 'a', "funcref") \
V(NullRef, kSystemPointerSizeLog2, NullRef, TaggedPointer, 'n', "nullref") \ V(NullRef, kSystemPointerSizeLog2, NullRef, TaggedPointer, 'n', "nullref") \
...@@ -129,9 +131,7 @@ class ValueType { ...@@ -129,9 +131,7 @@ class ValueType {
} }
constexpr bool IsReferenceType() const { constexpr bool IsReferenceType() const {
return kind() == kAnyRef || kind() == kFuncRef || kind() == kNullRef || return kAnyRef <= kind() && kind() <= kEqRef;
kind() == kExnRef || kind() == kRef || kind() == kOptRef ||
kind() == kEqRef;
} }
// TODO(7748): Extend this with struct and function subtyping. // TODO(7748): Extend this with struct and function subtyping.
...@@ -226,6 +226,12 @@ class ValueType { ...@@ -226,6 +226,12 @@ class ValueType {
return kTypeName[kind()]; return kTypeName[kind()];
} }
constexpr bool IsPacked() const { return kind() == kI8 || kind() == kI16; }
constexpr ValueType Unpack() const {
return IsPacked() ? ValueType(kI32) : *this;
}
private: private:
using KindField = base::BitField<Kind, 0, 8>; using KindField = base::BitField<Kind, 0, 8>;
using RefIndexField = base::BitField<uint32_t, 8, 24>; using RefIndexField = base::BitField<uint32_t, 8, 24>;
...@@ -255,6 +261,8 @@ constexpr ValueType kWasmExnRef = ValueType(ValueType::kExnRef); ...@@ -255,6 +261,8 @@ constexpr ValueType kWasmExnRef = ValueType(ValueType::kExnRef);
constexpr ValueType kWasmFuncRef = ValueType(ValueType::kFuncRef); constexpr ValueType kWasmFuncRef = ValueType(ValueType::kFuncRef);
constexpr ValueType kWasmNullRef = ValueType(ValueType::kNullRef); constexpr ValueType kWasmNullRef = ValueType(ValueType::kNullRef);
constexpr ValueType kWasmS128 = ValueType(ValueType::kS128); constexpr ValueType kWasmS128 = ValueType(ValueType::kS128);
constexpr ValueType kWasmI8 = ValueType(ValueType::kI8);
constexpr ValueType kWasmI16 = ValueType(ValueType::kI16);
constexpr ValueType kWasmStmt = ValueType(ValueType::kStmt); constexpr ValueType kWasmStmt = ValueType(ValueType::kStmt);
constexpr ValueType kWasmBottom = ValueType(ValueType::kBottom); constexpr ValueType kWasmBottom = ValueType(ValueType::kBottom);
......
...@@ -35,6 +35,8 @@ enum ValueTypeCode : uint8_t { ...@@ -35,6 +35,8 @@ enum ValueTypeCode : uint8_t {
kLocalI31Ref = 0x6a, // GC proposal kLocalI31Ref = 0x6a, // GC proposal
kLocalRttRef = 0x69, // GC proposal kLocalRttRef = 0x69, // GC proposal
kLocalExnRef = 0x68, kLocalExnRef = 0x68,
kLocalI8 = 0x7a, // GC proposal
kLocalI16 = 0x79 // GC proposal
}; };
// Binary encoding of other types. // Binary encoding of other types.
constexpr uint8_t kWasmFunctionTypeCode = 0x60; constexpr uint8_t kWasmFunctionTypeCode = 0x60;
......
...@@ -1444,6 +1444,8 @@ class ThreadImpl { ...@@ -1444,6 +1444,8 @@ class ThreadImpl {
} }
case ValueType::kStmt: case ValueType::kStmt:
case ValueType::kBottom: case ValueType::kBottom:
case ValueType::kI8:
case ValueType::kI16:
UNREACHABLE(); UNREACHABLE();
break; break;
} }
...@@ -2877,6 +2879,8 @@ class ThreadImpl { ...@@ -2877,6 +2879,8 @@ class ThreadImpl {
case ValueType::kEqRef: case ValueType::kEqRef:
// TODO(7748): Implement these. // TODO(7748): Implement these.
UNIMPLEMENTED(); UNIMPLEMENTED();
case ValueType::kI8:
case ValueType::kI16:
case ValueType::kStmt: case ValueType::kStmt:
case ValueType::kBottom: case ValueType::kBottom:
UNREACHABLE(); UNREACHABLE();
...@@ -2987,6 +2991,8 @@ class ThreadImpl { ...@@ -2987,6 +2991,8 @@ class ThreadImpl {
case ValueType::kEqRef: case ValueType::kEqRef:
// TODO(7748): Implement these. // TODO(7748): Implement these.
UNIMPLEMENTED(); UNIMPLEMENTED();
case ValueType::kI8:
case ValueType::kI16:
case ValueType::kStmt: case ValueType::kStmt:
case ValueType::kBottom: case ValueType::kBottom:
UNREACHABLE(); UNREACHABLE();
...@@ -3430,6 +3436,8 @@ class ThreadImpl { ...@@ -3430,6 +3436,8 @@ class ThreadImpl {
global_buffer->set(global_index, *ref); global_buffer->set(global_index, *ref);
break; break;
} }
case ValueType::kI8:
case ValueType::kI16:
case ValueType::kStmt: case ValueType::kStmt:
case ValueType::kBottom: case ValueType::kBottom:
UNREACHABLE(); UNREACHABLE();
...@@ -3835,6 +3843,8 @@ class ThreadImpl { ...@@ -3835,6 +3843,8 @@ class ThreadImpl {
case ValueType::kEqRef: case ValueType::kEqRef:
PrintF("(func|null|exn|opt|eq|)ref:unimplemented"); PrintF("(func|null|exn|opt|eq|)ref:unimplemented");
break; break;
case ValueType::kI8:
case ValueType::kI16:
case ValueType::kBottom: case ValueType::kBottom:
UNREACHABLE(); UNREACHABLE();
break; break;
......
...@@ -1369,6 +1369,8 @@ void WebAssemblyGlobal(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -1369,6 +1369,8 @@ void WebAssemblyGlobal(const v8::FunctionCallbackInfo<v8::Value>& args) {
case i::wasm::ValueType::kEqRef: case i::wasm::ValueType::kEqRef:
// TODO(7748): Implement these. // TODO(7748): Implement these.
UNIMPLEMENTED(); UNIMPLEMENTED();
case i::wasm::ValueType::kI8:
case i::wasm::ValueType::kI16:
case i::wasm::ValueType::kStmt: case i::wasm::ValueType::kStmt:
case i::wasm::ValueType::kS128: case i::wasm::ValueType::kS128:
case i::wasm::ValueType::kBottom: case i::wasm::ValueType::kBottom:
...@@ -1834,6 +1836,8 @@ void WebAssemblyGlobalGetValueCommon( ...@@ -1834,6 +1836,8 @@ void WebAssemblyGlobalGetValueCommon(
case i::wasm::ValueType::kEqRef: case i::wasm::ValueType::kEqRef:
// TODO(7748): Implement these. // TODO(7748): Implement these.
UNIMPLEMENTED(); UNIMPLEMENTED();
case i::wasm::ValueType::kI8:
case i::wasm::ValueType::kI16:
case i::wasm::ValueType::kBottom: case i::wasm::ValueType::kBottom:
case i::wasm::ValueType::kStmt: case i::wasm::ValueType::kStmt:
case i::wasm::ValueType::kS128: case i::wasm::ValueType::kS128:
...@@ -1924,6 +1928,8 @@ void WebAssemblyGlobalSetValue( ...@@ -1924,6 +1928,8 @@ void WebAssemblyGlobalSetValue(
case i::wasm::ValueType::kEqRef: case i::wasm::ValueType::kEqRef:
// TODO(7748): Implement these. // TODO(7748): Implement these.
UNIMPLEMENTED(); UNIMPLEMENTED();
case i::wasm::ValueType::kI8:
case i::wasm::ValueType::kI16:
case i::wasm::ValueType::kBottom: case i::wasm::ValueType::kBottom:
case i::wasm::ValueType::kStmt: case i::wasm::ValueType::kStmt:
case i::wasm::ValueType::kS128: case i::wasm::ValueType::kS128:
......
...@@ -595,6 +595,8 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer* buffer) const { ...@@ -595,6 +595,8 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer* buffer) const {
case ValueType::kEqRef: case ValueType::kEqRef:
buffer->write_u8(kExprRefNull); buffer->write_u8(kExprRefNull);
break; break;
case ValueType::kI8:
case ValueType::kI16:
case ValueType::kStmt: case ValueType::kStmt:
case ValueType::kS128: case ValueType::kS128:
case ValueType::kBottom: case ValueType::kBottom:
......
...@@ -1738,6 +1738,8 @@ uint32_t WasmExceptionPackage::GetEncodedSize( ...@@ -1738,6 +1738,8 @@ uint32_t WasmExceptionPackage::GetEncodedSize(
break; break;
case wasm::ValueType::kStmt: case wasm::ValueType::kStmt:
case wasm::ValueType::kBottom: case wasm::ValueType::kBottom:
case wasm::ValueType::kI8:
case wasm::ValueType::kI16:
UNREACHABLE(); UNREACHABLE();
} }
} }
......
...@@ -112,6 +112,8 @@ bool InterpretWasmModuleForTesting(Isolate* isolate, ...@@ -112,6 +112,8 @@ bool InterpretWasmModuleForTesting(Isolate* isolate,
arguments[i] = arguments[i] =
WasmValue(Handle<Object>::cast(isolate->factory()->null_value())); WasmValue(Handle<Object>::cast(isolate->factory()->null_value()));
break; break;
case ValueType::kI8:
case ValueType::kI16:
case ValueType::kStmt: case ValueType::kStmt:
case ValueType::kBottom: case ValueType::kBottom:
case ValueType::kS128: case ValueType::kS128:
......
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