1 // Copyright 2017 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/builtins/builtins-wasm-gen.h"
6
7 #include "src/builtins/builtins-utils-gen.h"
8 #include "src/codegen/code-stub-assembler.h"
9 #include "src/codegen/interface-descriptors.h"
10 #include "src/objects/objects-inl.h"
11 #include "src/wasm/wasm-objects.h"
12 #include "src/wasm/wasm-opcodes.h"
13
14 namespace v8 {
15 namespace internal {
16
LoadInstanceFromFrame()17 TNode<WasmInstanceObject> WasmBuiltinsAssembler::LoadInstanceFromFrame() {
18 return CAST(LoadFromParentFrame(WasmFrameConstants::kWasmInstanceOffset));
19 }
20
LoadContextFromInstance(TNode<WasmInstanceObject> instance)21 TNode<NativeContext> WasmBuiltinsAssembler::LoadContextFromInstance(
22 TNode<WasmInstanceObject> instance) {
23 return CAST(Load(MachineType::AnyTagged(), instance,
24 IntPtrConstant(WasmInstanceObject::kNativeContextOffset -
25 kHeapObjectTag)));
26 }
27
LoadTablesFromInstance(TNode<WasmInstanceObject> instance)28 TNode<FixedArray> WasmBuiltinsAssembler::LoadTablesFromInstance(
29 TNode<WasmInstanceObject> instance) {
30 return LoadObjectField<FixedArray>(instance,
31 WasmInstanceObject::kTablesOffset);
32 }
33
LoadExternalFunctionsFromInstance(TNode<WasmInstanceObject> instance)34 TNode<FixedArray> WasmBuiltinsAssembler::LoadExternalFunctionsFromInstance(
35 TNode<WasmInstanceObject> instance) {
36 return LoadObjectField<FixedArray>(
37 instance, WasmInstanceObject::kWasmExternalFunctionsOffset);
38 }
39
LoadManagedObjectMapsFromInstance(TNode<WasmInstanceObject> instance)40 TNode<FixedArray> WasmBuiltinsAssembler::LoadManagedObjectMapsFromInstance(
41 TNode<WasmInstanceObject> instance) {
42 return LoadObjectField<FixedArray>(
43 instance, WasmInstanceObject::kManagedObjectMapsOffset);
44 }
45
TF_BUILTIN(WasmFloat32ToNumber,WasmBuiltinsAssembler)46 TF_BUILTIN(WasmFloat32ToNumber, WasmBuiltinsAssembler) {
47 auto val = UncheckedParameter<Float32T>(Descriptor::kValue);
48 Return(ChangeFloat32ToTagged(val));
49 }
50
TF_BUILTIN(WasmFloat64ToNumber,WasmBuiltinsAssembler)51 TF_BUILTIN(WasmFloat64ToNumber, WasmBuiltinsAssembler) {
52 auto val = UncheckedParameter<Float64T>(Descriptor::kValue);
53 Return(ChangeFloat64ToTagged(val));
54 }
55
TF_BUILTIN(WasmI32AtomicWait32,WasmBuiltinsAssembler)56 TF_BUILTIN(WasmI32AtomicWait32, WasmBuiltinsAssembler) {
57 if (!Is32()) {
58 Unreachable();
59 return;
60 }
61
62 auto address = UncheckedParameter<Uint32T>(Descriptor::kAddress);
63 TNode<Number> address_number = ChangeUint32ToTagged(address);
64
65 auto expected_value = UncheckedParameter<Int32T>(Descriptor::kExpectedValue);
66 TNode<Number> expected_value_number = ChangeInt32ToTagged(expected_value);
67
68 auto timeout_low = UncheckedParameter<IntPtrT>(Descriptor::kTimeoutLow);
69 auto timeout_high = UncheckedParameter<IntPtrT>(Descriptor::kTimeoutHigh);
70 TNode<BigInt> timeout = BigIntFromInt32Pair(timeout_low, timeout_high);
71
72 TNode<WasmInstanceObject> instance = LoadInstanceFromFrame();
73 TNode<Context> context = LoadContextFromInstance(instance);
74
75 TNode<Smi> result_smi =
76 CAST(CallRuntime(Runtime::kWasmI32AtomicWait, context, instance,
77 address_number, expected_value_number, timeout));
78 Return(Unsigned(SmiToInt32(result_smi)));
79 }
80
TF_BUILTIN(WasmI64AtomicWait32,WasmBuiltinsAssembler)81 TF_BUILTIN(WasmI64AtomicWait32, WasmBuiltinsAssembler) {
82 if (!Is32()) {
83 Unreachable();
84 return;
85 }
86
87 auto address = UncheckedParameter<Uint32T>(Descriptor::kAddress);
88 TNode<Number> address_number = ChangeUint32ToTagged(address);
89
90 auto expected_value_low =
91 UncheckedParameter<IntPtrT>(Descriptor::kExpectedValueLow);
92 auto expected_value_high =
93 UncheckedParameter<IntPtrT>(Descriptor::kExpectedValueHigh);
94 TNode<BigInt> expected_value =
95 BigIntFromInt32Pair(expected_value_low, expected_value_high);
96
97 auto timeout_low = UncheckedParameter<IntPtrT>(Descriptor::kTimeoutLow);
98 auto timeout_high = UncheckedParameter<IntPtrT>(Descriptor::kTimeoutHigh);
99 TNode<BigInt> timeout = BigIntFromInt32Pair(timeout_low, timeout_high);
100
101 TNode<WasmInstanceObject> instance = LoadInstanceFromFrame();
102 TNode<Context> context = LoadContextFromInstance(instance);
103
104 TNode<Smi> result_smi =
105 CAST(CallRuntime(Runtime::kWasmI64AtomicWait, context, instance,
106 address_number, expected_value, timeout));
107 Return(Unsigned(SmiToInt32(result_smi)));
108 }
109
TF_BUILTIN(WasmAllocateArrayWithRtt,WasmBuiltinsAssembler)110 TF_BUILTIN(WasmAllocateArrayWithRtt, WasmBuiltinsAssembler) {
111 auto map = Parameter<Map>(Descriptor::kMap);
112 auto length = Parameter<Smi>(Descriptor::kLength);
113 auto element_size = Parameter<Smi>(Descriptor::kElementSize);
114 TNode<IntPtrT> untagged_length = SmiUntag(length);
115 // instance_size = WasmArray::kHeaderSize
116 // + RoundUp(element_size * length, kObjectAlignment)
117 TNode<IntPtrT> raw_size = IntPtrMul(SmiUntag(element_size), untagged_length);
118 TNode<IntPtrT> rounded_size =
119 WordAnd(IntPtrAdd(raw_size, IntPtrConstant(kObjectAlignmentMask)),
120 IntPtrConstant(~kObjectAlignmentMask));
121 TNode<IntPtrT> instance_size =
122 IntPtrAdd(IntPtrConstant(WasmArray::kHeaderSize), rounded_size);
123 TNode<WasmArray> result = UncheckedCast<WasmArray>(Allocate(instance_size));
124 StoreMap(result, map);
125 StoreObjectFieldNoWriteBarrier(result, WasmArray::kLengthOffset,
126 TruncateIntPtrToInt32(untagged_length));
127 Return(result);
128 }
129
TF_BUILTIN(WasmAllocatePair,WasmBuiltinsAssembler)130 TF_BUILTIN(WasmAllocatePair, WasmBuiltinsAssembler) {
131 TNode<WasmInstanceObject> instance = LoadInstanceFromFrame();
132 TNode<HeapObject> value1 = Parameter<HeapObject>(Descriptor::kValue1);
133 TNode<HeapObject> value2 = Parameter<HeapObject>(Descriptor::kValue2);
134
135 TNode<IntPtrT> roots = LoadObjectField<IntPtrT>(
136 instance, WasmInstanceObject::kIsolateRootOffset);
137 TNode<Map> map = CAST(Load(
138 MachineType::AnyTagged(), roots,
139 IntPtrConstant(IsolateData::root_slot_offset(RootIndex::kTuple2Map))));
140
141 TNode<IntPtrT> instance_size =
142 TimesTaggedSize(LoadMapInstanceSizeInWords(map));
143 TNode<Tuple2> result = UncheckedCast<Tuple2>(Allocate(instance_size));
144
145 StoreMap(result, map);
146 StoreObjectField(result, Tuple2::kValue1Offset, value1);
147 StoreObjectField(result, Tuple2::kValue2Offset, value2);
148
149 Return(result);
150 }
151
152 } // namespace internal
153 } // namespace v8
154