• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-utils-gen.h"
6 #include "src/code-stub-assembler.h"
7 #include "src/objects-inl.h"
8 #include "src/wasm/wasm-objects.h"
9 #include "src/wasm/wasm-opcodes.h"
10 
11 namespace v8 {
12 namespace internal {
13 
14 class WasmBuiltinsAssembler : public CodeStubAssembler {
15  public:
WasmBuiltinsAssembler(compiler::CodeAssemblerState * state)16   explicit WasmBuiltinsAssembler(compiler::CodeAssemblerState* state)
17       : CodeStubAssembler(state) {}
18 
19  protected:
UncheckedParameter(int index)20   TNode<Object> UncheckedParameter(int index) {
21     return UncheckedCast<Object>(Parameter(index));
22   }
23 
LoadBuiltinFromFrame(Builtins::Name id)24   TNode<Code> LoadBuiltinFromFrame(Builtins::Name id) {
25     TNode<Object> instance = LoadInstanceFromFrame();
26     TNode<IntPtrT> roots = UncheckedCast<IntPtrT>(
27         Load(MachineType::Pointer(), instance,
28              IntPtrConstant(WasmInstanceObject::kRootsArrayAddressOffset -
29                             kHeapObjectTag)));
30     TNode<Code> target = UncheckedCast<Code>(Load(
31         MachineType::TaggedPointer(), roots,
32         IntPtrConstant(Heap::roots_to_builtins_offset() + id * kPointerSize)));
33     return target;
34   }
35 
LoadInstanceFromFrame()36   TNode<Object> LoadInstanceFromFrame() {
37     return UncheckedCast<Object>(
38         LoadFromParentFrame(WasmCompiledFrameConstants::kWasmInstanceOffset));
39   }
40 
LoadCEntryFromInstance(TNode<Object> instance)41   TNode<Code> LoadCEntryFromInstance(TNode<Object> instance) {
42     return UncheckedCast<Code>(
43         Load(MachineType::AnyTagged(), instance,
44              IntPtrConstant(WasmInstanceObject::kCEntryStubOffset -
45                             kHeapObjectTag)));
46   }
47 
LoadCEntryFromFrame()48   TNode<Code> LoadCEntryFromFrame() {
49     return LoadCEntryFromInstance(LoadInstanceFromFrame());
50   }
51 };
52 
TF_BUILTIN(WasmAllocateHeapNumber,WasmBuiltinsAssembler)53 TF_BUILTIN(WasmAllocateHeapNumber, WasmBuiltinsAssembler) {
54   TNode<Code> target = LoadBuiltinFromFrame(Builtins::kAllocateHeapNumber);
55   TailCallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant());
56 }
57 
TF_BUILTIN(WasmArgumentsAdaptor,WasmBuiltinsAssembler)58 TF_BUILTIN(WasmArgumentsAdaptor, WasmBuiltinsAssembler) {
59   TNode<Object> context = UncheckedParameter(Descriptor::kContext);
60   TNode<Object> function = UncheckedParameter(Descriptor::kTarget);
61   TNode<Object> new_target = UncheckedParameter(Descriptor::kNewTarget);
62   TNode<Object> argc1 = UncheckedParameter(Descriptor::kActualArgumentsCount);
63   TNode<Object> argc2 = UncheckedParameter(Descriptor::kExpectedArgumentsCount);
64   TNode<Code> target =
65       LoadBuiltinFromFrame(Builtins::kArgumentsAdaptorTrampoline);
66   TailCallStub(ArgumentAdaptorDescriptor{}, target, context, function,
67                new_target, argc1, argc2);
68 }
69 
TF_BUILTIN(WasmCallJavaScript,WasmBuiltinsAssembler)70 TF_BUILTIN(WasmCallJavaScript, WasmBuiltinsAssembler) {
71   TNode<Object> context = UncheckedParameter(Descriptor::kContext);
72   TNode<Object> function = UncheckedParameter(Descriptor::kFunction);
73   TNode<Object> argc = UncheckedParameter(Descriptor::kActualArgumentsCount);
74   TNode<Code> target = LoadBuiltinFromFrame(Builtins::kCall_ReceiverIsAny);
75   TailCallStub(CallTrampolineDescriptor{}, target, context, function, argc);
76 }
77 
TF_BUILTIN(WasmToNumber,WasmBuiltinsAssembler)78 TF_BUILTIN(WasmToNumber, WasmBuiltinsAssembler) {
79   TNode<Object> context = UncheckedParameter(Descriptor::kContext);
80   TNode<Object> argument = UncheckedParameter(Descriptor::kArgument);
81   TNode<Code> target = LoadBuiltinFromFrame(Builtins::kToNumber);
82   TailCallStub(TypeConversionDescriptor(), target, context, argument);
83 }
84 
TF_BUILTIN(WasmStackGuard,WasmBuiltinsAssembler)85 TF_BUILTIN(WasmStackGuard, WasmBuiltinsAssembler) {
86   TNode<Code> centry = LoadCEntryFromFrame();
87   TailCallRuntimeWithCEntry(Runtime::kWasmStackGuard, centry,
88                             NoContextConstant());
89 }
90 
TF_BUILTIN(WasmGrowMemory,WasmBuiltinsAssembler)91 TF_BUILTIN(WasmGrowMemory, WasmBuiltinsAssembler) {
92   TNode<Int32T> num_pages =
93       UncheckedCast<Int32T>(Parameter(Descriptor::kNumPages));
94   Label num_pages_out_of_range(this, Label::kDeferred);
95 
96   TNode<BoolT> num_pages_fits_in_smi =
97       IsValidPositiveSmi(ChangeInt32ToIntPtr(num_pages));
98   GotoIfNot(num_pages_fits_in_smi, &num_pages_out_of_range);
99 
100   TNode<Smi> num_pages_smi = SmiFromInt32(num_pages);
101   TNode<Object> instance = LoadInstanceFromFrame();
102   TNode<Code> centry = LoadCEntryFromInstance(instance);
103   TNode<Smi> ret_smi = UncheckedCast<Smi>(
104       CallRuntimeWithCEntry(Runtime::kWasmGrowMemory, centry,
105                             NoContextConstant(), instance, num_pages_smi));
106   TNode<Int32T> ret = SmiToInt32(ret_smi);
107   ReturnRaw(ret);
108 
109   BIND(&num_pages_out_of_range);
110   ReturnRaw(Int32Constant(-1));
111 }
112 
113 #define DECLARE_ENUM(name)                                                    \
114   TF_BUILTIN(ThrowWasm##name, WasmBuiltinsAssembler) {                        \
115     TNode<Code> centry = LoadCEntryFromFrame();                               \
116     int message_id = wasm::WasmOpcodes::TrapReasonToMessageId(wasm::k##name); \
117     TailCallRuntimeWithCEntry(Runtime::kThrowWasmError, centry,               \
118                               NoContextConstant(), SmiConstant(message_id));  \
119   }
120 FOREACH_WASM_TRAPREASON(DECLARE_ENUM)
121 #undef DECLARE_ENUM
122 
123 }  // namespace internal
124 }  // namespace v8
125