11cb0ef41Sopenharmony_ci// Copyright 2021 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/wasm/init-expr-interface.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "src/execution/isolate.h"
81cb0ef41Sopenharmony_ci#include "src/handles/handles-inl.h"
91cb0ef41Sopenharmony_ci#include "src/objects/fixed-array-inl.h"
101cb0ef41Sopenharmony_ci#include "src/objects/oddball.h"
111cb0ef41Sopenharmony_ci#include "src/roots/roots-inl.h"
121cb0ef41Sopenharmony_ci#include "src/wasm/decoder.h"
131cb0ef41Sopenharmony_ci#include "src/wasm/function-body-decoder-impl.h"
141cb0ef41Sopenharmony_ci#include "src/wasm/wasm-objects.h"
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_cinamespace v8 {
171cb0ef41Sopenharmony_cinamespace internal {
181cb0ef41Sopenharmony_cinamespace wasm {
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_civoid InitExprInterface::I32Const(FullDecoder* decoder, Value* result,
211cb0ef41Sopenharmony_ci                                 int32_t value) {
221cb0ef41Sopenharmony_ci  if (generate_result()) result->runtime_value = WasmValue(value);
231cb0ef41Sopenharmony_ci}
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_civoid InitExprInterface::I64Const(FullDecoder* decoder, Value* result,
261cb0ef41Sopenharmony_ci                                 int64_t value) {
271cb0ef41Sopenharmony_ci  if (generate_result()) result->runtime_value = WasmValue(value);
281cb0ef41Sopenharmony_ci}
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_civoid InitExprInterface::F32Const(FullDecoder* decoder, Value* result,
311cb0ef41Sopenharmony_ci                                 float value) {
321cb0ef41Sopenharmony_ci  if (generate_result()) result->runtime_value = WasmValue(value);
331cb0ef41Sopenharmony_ci}
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_civoid InitExprInterface::F64Const(FullDecoder* decoder, Value* result,
361cb0ef41Sopenharmony_ci                                 double value) {
371cb0ef41Sopenharmony_ci  if (generate_result()) result->runtime_value = WasmValue(value);
381cb0ef41Sopenharmony_ci}
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_civoid InitExprInterface::S128Const(FullDecoder* decoder,
411cb0ef41Sopenharmony_ci                                  Simd128Immediate<validate>& imm,
421cb0ef41Sopenharmony_ci                                  Value* result) {
431cb0ef41Sopenharmony_ci  if (!generate_result()) return;
441cb0ef41Sopenharmony_ci  result->runtime_value = WasmValue(imm.value, kWasmS128);
451cb0ef41Sopenharmony_ci}
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_civoid InitExprInterface::BinOp(FullDecoder* decoder, WasmOpcode opcode,
481cb0ef41Sopenharmony_ci                              const Value& lhs, const Value& rhs,
491cb0ef41Sopenharmony_ci                              Value* result) {
501cb0ef41Sopenharmony_ci  if (!generate_result()) return;
511cb0ef41Sopenharmony_ci  switch (opcode) {
521cb0ef41Sopenharmony_ci    case kExprI32Add:
531cb0ef41Sopenharmony_ci      result->runtime_value =
541cb0ef41Sopenharmony_ci          WasmValue(lhs.runtime_value.to_i32() + rhs.runtime_value.to_i32());
551cb0ef41Sopenharmony_ci      break;
561cb0ef41Sopenharmony_ci    case kExprI32Sub:
571cb0ef41Sopenharmony_ci      result->runtime_value =
581cb0ef41Sopenharmony_ci          WasmValue(lhs.runtime_value.to_i32() - rhs.runtime_value.to_i32());
591cb0ef41Sopenharmony_ci      break;
601cb0ef41Sopenharmony_ci    case kExprI32Mul:
611cb0ef41Sopenharmony_ci      result->runtime_value =
621cb0ef41Sopenharmony_ci          WasmValue(lhs.runtime_value.to_i32() * rhs.runtime_value.to_i32());
631cb0ef41Sopenharmony_ci      break;
641cb0ef41Sopenharmony_ci    case kExprI64Add:
651cb0ef41Sopenharmony_ci      result->runtime_value =
661cb0ef41Sopenharmony_ci          WasmValue(lhs.runtime_value.to_i64() + rhs.runtime_value.to_i64());
671cb0ef41Sopenharmony_ci      break;
681cb0ef41Sopenharmony_ci    case kExprI64Sub:
691cb0ef41Sopenharmony_ci      result->runtime_value =
701cb0ef41Sopenharmony_ci          WasmValue(lhs.runtime_value.to_i64() - rhs.runtime_value.to_i64());
711cb0ef41Sopenharmony_ci      break;
721cb0ef41Sopenharmony_ci    case kExprI64Mul:
731cb0ef41Sopenharmony_ci      result->runtime_value =
741cb0ef41Sopenharmony_ci          WasmValue(lhs.runtime_value.to_i64() * rhs.runtime_value.to_i64());
751cb0ef41Sopenharmony_ci      break;
761cb0ef41Sopenharmony_ci    default:
771cb0ef41Sopenharmony_ci      UNREACHABLE();
781cb0ef41Sopenharmony_ci  }
791cb0ef41Sopenharmony_ci}
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_civoid InitExprInterface::RefNull(FullDecoder* decoder, ValueType type,
821cb0ef41Sopenharmony_ci                                Value* result) {
831cb0ef41Sopenharmony_ci  if (!generate_result()) return;
841cb0ef41Sopenharmony_ci  result->runtime_value = WasmValue(isolate_->factory()->null_value(), type);
851cb0ef41Sopenharmony_ci}
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_civoid InitExprInterface::RefFunc(FullDecoder* decoder, uint32_t function_index,
881cb0ef41Sopenharmony_ci                                Value* result) {
891cb0ef41Sopenharmony_ci  if (isolate_ == nullptr) {
901cb0ef41Sopenharmony_ci    outer_module_->functions[function_index].declared = true;
911cb0ef41Sopenharmony_ci    return;
921cb0ef41Sopenharmony_ci  }
931cb0ef41Sopenharmony_ci  if (!generate_result()) return;
941cb0ef41Sopenharmony_ci  ValueType type = ValueType::Ref(module_->functions[function_index].sig_index,
951cb0ef41Sopenharmony_ci                                  kNonNullable);
961cb0ef41Sopenharmony_ci  Handle<WasmInternalFunction> internal =
971cb0ef41Sopenharmony_ci      WasmInstanceObject::GetOrCreateWasmInternalFunction(isolate_, instance_,
981cb0ef41Sopenharmony_ci                                                          function_index);
991cb0ef41Sopenharmony_ci  result->runtime_value = WasmValue(internal, type);
1001cb0ef41Sopenharmony_ci}
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_civoid InitExprInterface::GlobalGet(FullDecoder* decoder, Value* result,
1031cb0ef41Sopenharmony_ci                                  const GlobalIndexImmediate<validate>& imm) {
1041cb0ef41Sopenharmony_ci  if (!generate_result()) return;
1051cb0ef41Sopenharmony_ci  const WasmGlobal& global = module_->globals[imm.index];
1061cb0ef41Sopenharmony_ci  DCHECK(!global.mutability);
1071cb0ef41Sopenharmony_ci  result->runtime_value =
1081cb0ef41Sopenharmony_ci      global.type.is_numeric()
1091cb0ef41Sopenharmony_ci          ? WasmValue(
1101cb0ef41Sopenharmony_ci                reinterpret_cast<byte*>(
1111cb0ef41Sopenharmony_ci                    instance_->untagged_globals_buffer().backing_store()) +
1121cb0ef41Sopenharmony_ci                    global.offset,
1131cb0ef41Sopenharmony_ci                global.type)
1141cb0ef41Sopenharmony_ci          : WasmValue(
1151cb0ef41Sopenharmony_ci                handle(instance_->tagged_globals_buffer().get(global.offset),
1161cb0ef41Sopenharmony_ci                       isolate_),
1171cb0ef41Sopenharmony_ci                global.type);
1181cb0ef41Sopenharmony_ci}
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_civoid InitExprInterface::StructNewWithRtt(
1211cb0ef41Sopenharmony_ci    FullDecoder* decoder, const StructIndexImmediate<validate>& imm,
1221cb0ef41Sopenharmony_ci    const Value& rtt, const Value args[], Value* result) {
1231cb0ef41Sopenharmony_ci  if (!generate_result()) return;
1241cb0ef41Sopenharmony_ci  std::vector<WasmValue> field_values(imm.struct_type->field_count());
1251cb0ef41Sopenharmony_ci  for (size_t i = 0; i < field_values.size(); i++) {
1261cb0ef41Sopenharmony_ci    field_values[i] = args[i].runtime_value;
1271cb0ef41Sopenharmony_ci  }
1281cb0ef41Sopenharmony_ci  result->runtime_value =
1291cb0ef41Sopenharmony_ci      WasmValue(isolate_->factory()->NewWasmStruct(
1301cb0ef41Sopenharmony_ci                    imm.struct_type, field_values.data(),
1311cb0ef41Sopenharmony_ci                    Handle<Map>::cast(rtt.runtime_value.to_ref())),
1321cb0ef41Sopenharmony_ci                ValueType::Ref(HeapType(imm.index), kNonNullable));
1331cb0ef41Sopenharmony_ci}
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_cinamespace {
1361cb0ef41Sopenharmony_ciWasmValue DefaultValueForType(ValueType type, Isolate* isolate) {
1371cb0ef41Sopenharmony_ci  switch (type.kind()) {
1381cb0ef41Sopenharmony_ci    case kI32:
1391cb0ef41Sopenharmony_ci    case kI8:
1401cb0ef41Sopenharmony_ci    case kI16:
1411cb0ef41Sopenharmony_ci      return WasmValue(0);
1421cb0ef41Sopenharmony_ci    case kI64:
1431cb0ef41Sopenharmony_ci      return WasmValue(int64_t{0});
1441cb0ef41Sopenharmony_ci    case kF32:
1451cb0ef41Sopenharmony_ci      return WasmValue(0.0f);
1461cb0ef41Sopenharmony_ci    case kF64:
1471cb0ef41Sopenharmony_ci      return WasmValue(0.0);
1481cb0ef41Sopenharmony_ci    case kS128:
1491cb0ef41Sopenharmony_ci      return WasmValue(Simd128());
1501cb0ef41Sopenharmony_ci    case kOptRef:
1511cb0ef41Sopenharmony_ci      return WasmValue(isolate->factory()->null_value(), type);
1521cb0ef41Sopenharmony_ci    case kVoid:
1531cb0ef41Sopenharmony_ci    case kRtt:
1541cb0ef41Sopenharmony_ci    case kRef:
1551cb0ef41Sopenharmony_ci    case kBottom:
1561cb0ef41Sopenharmony_ci      UNREACHABLE();
1571cb0ef41Sopenharmony_ci  }
1581cb0ef41Sopenharmony_ci}
1591cb0ef41Sopenharmony_ci}  // namespace
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_civoid InitExprInterface::StructNewDefault(
1621cb0ef41Sopenharmony_ci    FullDecoder* decoder, const StructIndexImmediate<validate>& imm,
1631cb0ef41Sopenharmony_ci    const Value& rtt, Value* result) {
1641cb0ef41Sopenharmony_ci  if (!generate_result()) return;
1651cb0ef41Sopenharmony_ci  std::vector<WasmValue> field_values(imm.struct_type->field_count());
1661cb0ef41Sopenharmony_ci  for (uint32_t i = 0; i < field_values.size(); i++) {
1671cb0ef41Sopenharmony_ci    field_values[i] = DefaultValueForType(imm.struct_type->field(i), isolate_);
1681cb0ef41Sopenharmony_ci  }
1691cb0ef41Sopenharmony_ci  result->runtime_value =
1701cb0ef41Sopenharmony_ci      WasmValue(isolate_->factory()->NewWasmStruct(
1711cb0ef41Sopenharmony_ci                    imm.struct_type, field_values.data(),
1721cb0ef41Sopenharmony_ci                    Handle<Map>::cast(rtt.runtime_value.to_ref())),
1731cb0ef41Sopenharmony_ci                ValueType::Ref(HeapType(imm.index), kNonNullable));
1741cb0ef41Sopenharmony_ci}
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_civoid InitExprInterface::ArrayInit(FullDecoder* decoder,
1771cb0ef41Sopenharmony_ci                                  const ArrayIndexImmediate<validate>& imm,
1781cb0ef41Sopenharmony_ci                                  const base::Vector<Value>& elements,
1791cb0ef41Sopenharmony_ci                                  const Value& rtt, Value* result) {
1801cb0ef41Sopenharmony_ci  if (!generate_result()) return;
1811cb0ef41Sopenharmony_ci  std::vector<WasmValue> element_values;
1821cb0ef41Sopenharmony_ci  for (Value elem : elements) element_values.push_back(elem.runtime_value);
1831cb0ef41Sopenharmony_ci  result->runtime_value =
1841cb0ef41Sopenharmony_ci      WasmValue(isolate_->factory()->NewWasmArrayFromElements(
1851cb0ef41Sopenharmony_ci                    imm.array_type, element_values,
1861cb0ef41Sopenharmony_ci                    Handle<Map>::cast(rtt.runtime_value.to_ref())),
1871cb0ef41Sopenharmony_ci                ValueType::Ref(HeapType(imm.index), kNonNullable));
1881cb0ef41Sopenharmony_ci}
1891cb0ef41Sopenharmony_ci
1901cb0ef41Sopenharmony_civoid InitExprInterface::ArrayInitFromData(
1911cb0ef41Sopenharmony_ci    FullDecoder* decoder, const ArrayIndexImmediate<validate>& array_imm,
1921cb0ef41Sopenharmony_ci    const IndexImmediate<validate>& data_segment_imm, const Value& offset_value,
1931cb0ef41Sopenharmony_ci    const Value& length_value, const Value& rtt, Value* result) {
1941cb0ef41Sopenharmony_ci  if (!generate_result()) return;
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_ci  uint32_t length = length_value.runtime_value.to_u32();
1971cb0ef41Sopenharmony_ci  uint32_t offset = offset_value.runtime_value.to_u32();
1981cb0ef41Sopenharmony_ci  const WasmDataSegment& data_segment =
1991cb0ef41Sopenharmony_ci      module_->data_segments[data_segment_imm.index];
2001cb0ef41Sopenharmony_ci  uint32_t length_in_bytes =
2011cb0ef41Sopenharmony_ci      length * array_imm.array_type->element_type().value_kind_size();
2021cb0ef41Sopenharmony_ci
2031cb0ef41Sopenharmony_ci  // Error handling.
2041cb0ef41Sopenharmony_ci  if (length >
2051cb0ef41Sopenharmony_ci      static_cast<uint32_t>(WasmArray::MaxLength(array_imm.array_type))) {
2061cb0ef41Sopenharmony_ci    error_ = "length for array.init_from_data too large";
2071cb0ef41Sopenharmony_ci    return;
2081cb0ef41Sopenharmony_ci  }
2091cb0ef41Sopenharmony_ci  if (!base::IsInBounds<uint32_t>(offset, length_in_bytes,
2101cb0ef41Sopenharmony_ci                                  data_segment.source.length())) {
2111cb0ef41Sopenharmony_ci    error_ = "data segment is out of bounds";
2121cb0ef41Sopenharmony_ci    return;
2131cb0ef41Sopenharmony_ci  }
2141cb0ef41Sopenharmony_ci
2151cb0ef41Sopenharmony_ci  Address source =
2161cb0ef41Sopenharmony_ci      instance_->data_segment_starts()[data_segment_imm.index] + offset;
2171cb0ef41Sopenharmony_ci  Handle<WasmArray> array_value = isolate_->factory()->NewWasmArrayFromMemory(
2181cb0ef41Sopenharmony_ci      length, Handle<Map>::cast(rtt.runtime_value.to_ref()), source);
2191cb0ef41Sopenharmony_ci  result->runtime_value = WasmValue(
2201cb0ef41Sopenharmony_ci      array_value, ValueType::Ref(HeapType(array_imm.index), kNonNullable));
2211cb0ef41Sopenharmony_ci}
2221cb0ef41Sopenharmony_ci
2231cb0ef41Sopenharmony_civoid InitExprInterface::RttCanon(FullDecoder* decoder, uint32_t type_index,
2241cb0ef41Sopenharmony_ci                                 Value* result) {
2251cb0ef41Sopenharmony_ci  if (!generate_result()) return;
2261cb0ef41Sopenharmony_ci  result->runtime_value = WasmValue(
2271cb0ef41Sopenharmony_ci      handle(instance_->managed_object_maps().get(type_index), isolate_),
2281cb0ef41Sopenharmony_ci      ValueType::Rtt(type_index));
2291cb0ef41Sopenharmony_ci}
2301cb0ef41Sopenharmony_ci
2311cb0ef41Sopenharmony_civoid InitExprInterface::DoReturn(FullDecoder* decoder,
2321cb0ef41Sopenharmony_ci                                 uint32_t /*drop_values*/) {
2331cb0ef41Sopenharmony_ci  end_found_ = true;
2341cb0ef41Sopenharmony_ci  // End decoding on "end".
2351cb0ef41Sopenharmony_ci  decoder->set_end(decoder->pc() + 1);
2361cb0ef41Sopenharmony_ci  if (generate_result()) result_ = decoder->stack_value(1)->runtime_value;
2371cb0ef41Sopenharmony_ci}
2381cb0ef41Sopenharmony_ci
2391cb0ef41Sopenharmony_ci}  // namespace wasm
2401cb0ef41Sopenharmony_ci}  // namespace internal
2411cb0ef41Sopenharmony_ci}  // namespace v8
242