// 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/init-expr-interface.h" #include "src/execution/isolate.h" #include "src/handles/handles-inl.h" #include "src/objects/fixed-array-inl.h" #include "src/objects/oddball.h" #include "src/roots/roots-inl.h" #include "src/wasm/decoder.h" #include "src/wasm/function-body-decoder-impl.h" #include "src/wasm/wasm-objects.h" namespace v8 { namespace internal { namespace wasm { void InitExprInterface::I32Const(FullDecoder* decoder, Value* result, int32_t value) { if (isolate_ != nullptr) result->runtime_value = WasmValue(value); } void InitExprInterface::I64Const(FullDecoder* decoder, Value* result, int64_t value) { if (isolate_ != nullptr) result->runtime_value = WasmValue(value); } void InitExprInterface::F32Const(FullDecoder* decoder, Value* result, float value) { if (isolate_ != nullptr) result->runtime_value = WasmValue(value); } void InitExprInterface::F64Const(FullDecoder* decoder, Value* result, double value) { if (isolate_ != nullptr) result->runtime_value = WasmValue(value); } void InitExprInterface::S128Const(FullDecoder* decoder, Simd128Immediate& imm, Value* result) { if (isolate_ == nullptr) return; result->runtime_value = WasmValue(imm.value, kWasmS128); } void InitExprInterface::RefNull(FullDecoder* decoder, ValueType type, Value* result) { if (isolate_ == nullptr) return; result->runtime_value = WasmValue(isolate_->factory()->null_value(), type); } void InitExprInterface::RefFunc(FullDecoder* decoder, uint32_t function_index, Value* result) { if (isolate_ != nullptr) { auto function = WasmInstanceObject::GetOrCreateWasmExternalFunction( isolate_, instance_, function_index); result->runtime_value = WasmValue( function, ValueType::Ref(module_->functions[function_index].sig_index, kNonNullable)); } else { outer_module_->functions[function_index].declared = true; } } void InitExprInterface::GlobalGet(FullDecoder* decoder, Value* result, const GlobalIndexImmediate& imm) { if (isolate_ == nullptr) return; const WasmGlobal& global = module_->globals[imm.index]; result->runtime_value = global.type.is_numeric() ? WasmValue(GetRawUntaggedGlobalPtr(global), global.type) : WasmValue(handle(tagged_globals_->get(global.offset), isolate_), global.type); } void InitExprInterface::StructNewWithRtt( FullDecoder* decoder, const StructIndexImmediate& imm, const Value& rtt, const Value args[], Value* result) { if (isolate_ == nullptr) return; std::vector field_values(imm.struct_type->field_count()); for (size_t i = 0; i < field_values.size(); i++) { field_values[i] = args[i].runtime_value; } result->runtime_value = WasmValue(isolate_->factory()->NewWasmStruct( imm.struct_type, field_values.data(), Handle::cast(rtt.runtime_value.to_ref())), ValueType::Ref(HeapType(imm.index), kNonNullable)); } void InitExprInterface::ArrayInit(FullDecoder* decoder, const ArrayIndexImmediate& imm, const base::Vector& elements, const Value& rtt, Value* result) { if (isolate_ == nullptr) return; std::vector element_values; for (Value elem : elements) element_values.push_back(elem.runtime_value); result->runtime_value = WasmValue(isolate_->factory()->NewWasmArray( imm.array_type, element_values, Handle::cast(rtt.runtime_value.to_ref())), ValueType::Ref(HeapType(imm.index), kNonNullable)); } void InitExprInterface::RttCanon(FullDecoder* decoder, uint32_t type_index, Value* result) { if (isolate_ == nullptr) return; result->runtime_value = WasmValue( handle(instance_->managed_object_maps().get(type_index), isolate_), ValueType::Rtt(type_index, 0)); } void InitExprInterface::RttSub(FullDecoder* decoder, uint32_t type_index, const Value& parent, Value* result, WasmRttSubMode mode) { if (isolate_ == nullptr) return; ValueType type = parent.type.has_depth() ? ValueType::Rtt(type_index, parent.type.depth() + 1) : ValueType::Rtt(type_index); result->runtime_value = WasmValue(Handle::cast(AllocateSubRtt( isolate_, instance_, type_index, Handle::cast(parent.runtime_value.to_ref()), mode)), type); } void InitExprInterface::DoReturn(FullDecoder* decoder, uint32_t /*drop_values*/) { end_found_ = true; // End decoding on "end". decoder->set_end(decoder->pc() + 1); if (isolate_ != nullptr) result_ = decoder->stack_value(1)->runtime_value; } byte* InitExprInterface::GetRawUntaggedGlobalPtr(const WasmGlobal& global) { return reinterpret_cast(untagged_globals_->backing_store()) + global.offset; } } // namespace wasm } // namespace internal } // namespace v8