Commit dc3f7f81 authored by Manos Koukoutos's avatar Manos Koukoutos Committed by V8 LUCI CQ

[wasm] Implement EvaluateInitExpression

So far, initializer-expression evaluation was tied to setting global
values. We now need it to operate independently of globals, so that we
can implement new constant expressions like struct.new, which need their
arguments to be computed before they can be initialized.

Changes:
- Move type computation of WasmInitExpr into WasmInitExpr::type.
- Fix WasmInitExpr::type kRttSub case for rtts without depth.
- Introduce InstanceBuilder::EvaluateInitExpression().
- Rename InstanceBuilder::GetRawGlobalPointer() ->
  GetRawUntaggedGlobalPointer().
- Simplify InstanceBuilder::InitGlobals using EvaluateInitExpression().
- Introduce ValueType::is_numeric.
- Add Simd128(byte*) constructor.
- Introduce WasmValue::CopyTo() for numeric types.

Change-Id: Ic502b611f3998187abd9fc6ec377c2954c27abdc
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2939982
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74949}
parent f9db82ab
...@@ -4102,6 +4102,7 @@ v8_source_set("v8_base_without_compiler") { ...@@ -4102,6 +4102,7 @@ v8_source_set("v8_base_without_compiler") {
"src/wasm/wasm-external-refs.cc", "src/wasm/wasm-external-refs.cc",
"src/wasm/wasm-features.cc", "src/wasm/wasm-features.cc",
"src/wasm/wasm-import-wrapper-cache.cc", "src/wasm/wasm-import-wrapper-cache.cc",
"src/wasm/wasm-init-expr.cc",
"src/wasm/wasm-js.cc", "src/wasm/wasm-js.cc",
"src/wasm/wasm-module-builder.cc", "src/wasm/wasm-module-builder.cc",
"src/wasm/wasm-module-sourcemap.cc", "src/wasm/wasm-module-sourcemap.cc",
......
...@@ -1421,46 +1421,7 @@ class ModuleDecoderImpl : public Decoder { ...@@ -1421,46 +1421,7 @@ class ModuleDecoderImpl : public Decoder {
ModuleOrigin origin_; ModuleOrigin origin_;
ValueType TypeOf(const WasmInitExpr& expr) { ValueType TypeOf(const WasmInitExpr& expr) {
switch (expr.kind()) { return expr.type(module_.get(), enabled_features_);
case WasmInitExpr::kNone:
return kWasmVoid;
case WasmInitExpr::kGlobalGet:
return expr.immediate().index < module_->globals.size()
? module_->globals[expr.immediate().index].type
: kWasmVoid;
case WasmInitExpr::kI32Const:
return kWasmI32;
case WasmInitExpr::kI64Const:
return kWasmI64;
case WasmInitExpr::kF32Const:
return kWasmF32;
case WasmInitExpr::kF64Const:
return kWasmF64;
case WasmInitExpr::kS128Const:
return kWasmS128;
case WasmInitExpr::kRefFuncConst: {
uint32_t heap_type =
enabled_features_.has_typed_funcref()
? module_->functions[expr.immediate().index].sig_index
: HeapType::kFunc;
return ValueType::Ref(heap_type, kNonNullable);
}
case WasmInitExpr::kRefNullConst:
return ValueType::Ref(expr.immediate().heap_type, kNullable);
case WasmInitExpr::kRttCanon: {
return ValueType::Rtt(expr.immediate().heap_type, 0);
}
case WasmInitExpr::kRttSub:
case WasmInitExpr::kRttFreshSub: {
ValueType operand_type = TypeOf(*expr.operand());
if (operand_type.is_rtt()) {
return ValueType::Rtt(expr.immediate().heap_type,
operand_type.depth() + 1);
} else {
return kWasmVoid;
}
}
}
} }
bool has_seen_unordered_section(SectionCode section_code) { bool has_seen_unordered_section(SectionCode section_code) {
......
This diff is collapsed.
...@@ -186,6 +186,18 @@ enum ValueKind : uint8_t { ...@@ -186,6 +186,18 @@ enum ValueKind : uint8_t {
#undef DEF_ENUM #undef DEF_ENUM
}; };
constexpr bool is_numeric(ValueKind kind) {
switch (kind) {
#define NUMERIC_CASE(kind, ...) \
case k##kind: \
return true;
FOREACH_NUMERIC_VALUE_TYPE(NUMERIC_CASE)
#undef NUMERIC_CASE
default:
return false;
}
}
constexpr bool is_reference(ValueKind kind) { constexpr bool is_reference(ValueKind kind) {
return kind == kRef || kind == kOptRef || kind == kRtt || return kind == kRef || kind == kOptRef || kind == kRtt ||
kind == kRttWithDepth; kind == kRttWithDepth;
...@@ -312,6 +324,8 @@ class ValueType { ...@@ -312,6 +324,8 @@ class ValueType {
} }
/******************************** Type checks *******************************/ /******************************** Type checks *******************************/
constexpr bool is_numeric() const { return wasm::is_numeric(kind()); }
constexpr bool is_reference() const { return wasm::is_reference(kind()); } constexpr bool is_reference() const { return wasm::is_reference(kind()); }
constexpr bool is_object_reference() const { constexpr bool is_object_reference() const {
......
// 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/wasm/wasm-init-expr.h"
#include "src/wasm/wasm-features.h"
#include "src/wasm/wasm-module.h"
namespace v8 {
namespace internal {
namespace wasm {
ValueType WasmInitExpr::type(const WasmModule* module,
const WasmFeatures& enabled_features) const {
switch (kind()) {
case kNone:
return kWasmBottom;
case kGlobalGet:
return immediate().index < module->globals.size()
? module->globals[immediate().index].type
: kWasmBottom;
case kI32Const:
return kWasmI32;
case kI64Const:
return kWasmI64;
case kF32Const:
return kWasmF32;
case kF64Const:
return kWasmF64;
case kS128Const:
return kWasmS128;
case kRefFuncConst: {
uint32_t heap_type = enabled_features.has_typed_funcref()
? module->functions[immediate().index].sig_index
: HeapType::kFunc;
return ValueType::Ref(heap_type, kNonNullable);
}
case kRefNullConst:
return ValueType::Ref(immediate().heap_type, kNullable);
case kRttCanon:
return ValueType::Rtt(immediate().heap_type, 0);
case kRttSub:
case kRttFreshSub: {
ValueType operand_type = operand()->type(module, enabled_features);
if (!operand_type.is_rtt()) return kWasmBottom;
if (operand_type.has_depth()) {
return ValueType::Rtt(immediate().heap_type, operand_type.depth() + 1);
} else {
return ValueType::Rtt(immediate().heap_type);
}
}
}
}
} // namespace wasm
} // namespace internal
} // namespace v8
...@@ -17,6 +17,9 @@ namespace v8 { ...@@ -17,6 +17,9 @@ namespace v8 {
namespace internal { namespace internal {
namespace wasm { namespace wasm {
struct WasmModule;
class WasmFeatures;
// Representation of an initializer expression. // Representation of an initializer expression.
class WasmInitExpr { class WasmInitExpr {
public: public:
...@@ -144,6 +147,9 @@ class WasmInitExpr { ...@@ -144,6 +147,9 @@ class WasmInitExpr {
return !(*this == other); return !(*this == other);
} }
ValueType type(const WasmModule* module,
const WasmFeatures& enabled_features) const;
private: private:
Immediate immediate_; Immediate immediate_;
Operator kind_; Operator kind_;
......
...@@ -48,6 +48,11 @@ class Simd128 { ...@@ -48,6 +48,11 @@ class Simd128 {
FOREACH_SIMD_TYPE(DEFINE_SIMD_TYPE_SPECIFIC_METHODS) FOREACH_SIMD_TYPE(DEFINE_SIMD_TYPE_SPECIFIC_METHODS)
#undef DEFINE_SIMD_TYPE_SPECIFIC_METHODS #undef DEFINE_SIMD_TYPE_SPECIFIC_METHODS
explicit Simd128(byte* bytes) {
base::Memcpy(static_cast<void*>(val_), reinterpret_cast<void*>(bytes),
kSimd128Size);
}
const uint8_t* bytes() { return val_; } const uint8_t* bytes() { return val_; }
template <typename T> template <typename T>
...@@ -128,6 +133,12 @@ class WasmValue { ...@@ -128,6 +133,12 @@ class WasmValue {
!memcmp(bit_pattern_, other.bit_pattern_, 16); !memcmp(bit_pattern_, other.bit_pattern_, 16);
} }
void CopyTo(byte* to) {
DCHECK(type_.is_numeric());
base::Memcpy(static_cast<void*>(to), static_cast<void*>(bit_pattern_),
type_.element_size_bytes());
}
template <typename T> template <typename T>
inline T to() const; inline T to() const;
......
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