// Copyright 2017 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/builtins/builtins-wasm-gen.h" #include "src/builtins/builtins-utils-gen.h" #include "src/codegen/code-stub-assembler.h" #include "src/codegen/interface-descriptors.h" #include "src/objects/objects-inl.h" #include "src/wasm/wasm-objects.h" #include "src/wasm/wasm-opcodes.h" namespace v8 { namespace internal { TNode WasmBuiltinsAssembler::LoadInstanceFromFrame() { return CAST(LoadFromParentFrame(WasmFrameConstants::kWasmInstanceOffset)); } TNode WasmBuiltinsAssembler::LoadContextFromInstance( TNode instance) { return CAST(Load(MachineType::AnyTagged(), instance, IntPtrConstant(WasmInstanceObject::kNativeContextOffset - kHeapObjectTag))); } TNode WasmBuiltinsAssembler::LoadTablesFromInstance( TNode instance) { return LoadObjectField(instance, WasmInstanceObject::kTablesOffset); } TNode WasmBuiltinsAssembler::LoadExternalFunctionsFromInstance( TNode instance) { return LoadObjectField( instance, WasmInstanceObject::kWasmExternalFunctionsOffset); } TNode WasmBuiltinsAssembler::LoadManagedObjectMapsFromInstance( TNode instance) { return LoadObjectField( instance, WasmInstanceObject::kManagedObjectMapsOffset); } TF_BUILTIN(WasmFloat32ToNumber, WasmBuiltinsAssembler) { TNode val = UncheckedCast(Parameter(Descriptor::kValue)); Return(ChangeFloat32ToTagged(val)); } TF_BUILTIN(WasmFloat64ToNumber, WasmBuiltinsAssembler) { TNode val = UncheckedCast(Parameter(Descriptor::kValue)); Return(ChangeFloat64ToTagged(val)); } TF_BUILTIN(WasmI32AtomicWait32, WasmBuiltinsAssembler) { if (!Is32()) { Unreachable(); return; } TNode address = UncheckedCast(Parameter(Descriptor::kAddress)); TNode address_number = ChangeUint32ToTagged(address); TNode expected_value = UncheckedCast(Parameter(Descriptor::kExpectedValue)); TNode expected_value_number = ChangeInt32ToTagged(expected_value); TNode timeout_low = UncheckedCast(Parameter(Descriptor::kTimeoutLow)); TNode timeout_high = UncheckedCast(Parameter(Descriptor::kTimeoutHigh)); TNode timeout = BigIntFromInt32Pair(timeout_low, timeout_high); TNode instance = LoadInstanceFromFrame(); TNode context = LoadContextFromInstance(instance); TNode result_smi = CAST(CallRuntime(Runtime::kWasmI32AtomicWait, context, instance, address_number, expected_value_number, timeout)); Return(Unsigned(SmiToInt32(result_smi))); } TF_BUILTIN(WasmI64AtomicWait32, WasmBuiltinsAssembler) { if (!Is32()) { Unreachable(); return; } TNode address = UncheckedCast(Parameter(Descriptor::kAddress)); TNode address_number = ChangeUint32ToTagged(address); TNode expected_value_low = UncheckedCast(Parameter(Descriptor::kExpectedValueLow)); TNode expected_value_high = UncheckedCast(Parameter(Descriptor::kExpectedValueHigh)); TNode expected_value = BigIntFromInt32Pair(expected_value_low, expected_value_high); TNode timeout_low = UncheckedCast(Parameter(Descriptor::kTimeoutLow)); TNode timeout_high = UncheckedCast(Parameter(Descriptor::kTimeoutHigh)); TNode timeout = BigIntFromInt32Pair(timeout_low, timeout_high); TNode instance = LoadInstanceFromFrame(); TNode context = LoadContextFromInstance(instance); TNode result_smi = CAST(CallRuntime(Runtime::kWasmI64AtomicWait, context, instance, address_number, expected_value, timeout)); Return(Unsigned(SmiToInt32(result_smi))); } TF_BUILTIN(WasmAllocateArray, WasmBuiltinsAssembler) { TNode instance = LoadInstanceFromFrame(); TNode map_index = CAST(Parameter(Descriptor::kMapIndex)); TNode length = CAST(Parameter(Descriptor::kLength)); TNode element_size = CAST(Parameter(Descriptor::kElementSize)); TNode maps_list = LoadObjectField( instance, WasmInstanceObject::kManagedObjectMapsOffset); TNode map = CAST(LoadFixedArrayElement(maps_list, map_index)); TNode untagged_length = SmiUntag(length); // instance_size = WasmArray::kHeaderSize // + RoundUp(element_size * length, kObjectAlignment) TNode raw_size = IntPtrMul(SmiUntag(element_size), untagged_length); TNode rounded_size = WordAnd(IntPtrAdd(raw_size, IntPtrConstant(kObjectAlignmentMask)), IntPtrConstant(~kObjectAlignmentMask)); TNode instance_size = IntPtrAdd(IntPtrConstant(WasmArray::kHeaderSize), rounded_size); TNode result = UncheckedCast(Allocate(instance_size)); StoreMap(result, map); StoreObjectFieldNoWriteBarrier(result, WasmArray::kLengthOffset, TruncateIntPtrToInt32(untagged_length)); Return(result); } } // namespace internal } // namespace v8