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