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: 16 explicit WasmBuiltinsAssembler(compiler::CodeAssemblerState* state) 17 : CodeStubAssembler(state) {} 18 19 protected: 20 TNode<Object> UncheckedParameter(int index) { 21 return UncheckedCast<Object>(Parameter(index)); 22 } 23 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 36 TNode<Object> LoadInstanceFromFrame() { 37 return UncheckedCast<Object>( 38 LoadFromParentFrame(WasmCompiledFrameConstants::kWasmInstanceOffset)); 39 } 40 41 TNode<Code> LoadCEntryFromInstance(TNode<Object> instance) { 42 return UncheckedCast<Code>( 43 Load(MachineType::AnyTagged(), instance, 44 IntPtrConstant(WasmInstanceObject::kCEntryStubOffset - 45 kHeapObjectTag))); 46 } 47 48 TNode<Code> LoadCEntryFromFrame() { 49 return LoadCEntryFromInstance(LoadInstanceFromFrame()); 50 } 51 }; 52 53 TF_BUILTIN(WasmAllocateHeapNumber, WasmBuiltinsAssembler) { 54 TNode<Code> target = LoadBuiltinFromFrame(Builtins::kAllocateHeapNumber); 55 TailCallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant()); 56 } 57 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 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 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 85 TF_BUILTIN(WasmStackGuard, WasmBuiltinsAssembler) { 86 TNode<Code> centry = LoadCEntryFromFrame(); 87 TailCallRuntimeWithCEntry(Runtime::kWasmStackGuard, centry, 88 NoContextConstant()); 89 } 90 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