blob: 52c45bd18b7e6876ce4d37c5760004590315f586 [file] [log] [blame]
// 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<validate>& 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<validate>& 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<validate>& imm,
const Value& rtt, const Value args[], Value* result) {
if (isolate_ == nullptr) return;
std::vector<WasmValue> 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<Map>::cast(rtt.runtime_value.to_ref())),
ValueType::Ref(HeapType(imm.index), kNonNullable));
}
void InitExprInterface::ArrayInit(FullDecoder* decoder,
const ArrayIndexImmediate<validate>& imm,
const base::Vector<Value>& elements,
const Value& rtt, Value* result) {
if (isolate_ == nullptr) return;
std::vector<WasmValue> 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<Map>::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<Object>::cast(AllocateSubRtt(
isolate_, instance_, type_index,
Handle<Map>::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<byte*>(untagged_globals_->backing_store()) +
global.offset;
}
} // namespace wasm
} // namespace internal
} // namespace v8