// 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-utils-gen.h" #include "src/code-stub-assembler.h" #include "src/objects-inl.h" #include "src/wasm/wasm-objects.h" #include "src/wasm/wasm-opcodes.h" namespace v8 { namespace internal { class WasmBuiltinsAssembler : public CodeStubAssembler { public: explicit WasmBuiltinsAssembler(compiler::CodeAssemblerState* state) : CodeStubAssembler(state) {} protected: TNode UncheckedParameter(int index) { return UncheckedCast(Parameter(index)); } TNode LoadBuiltinFromFrame(Builtins::Name id) { TNode instance = LoadInstanceFromFrame(); TNode roots = UncheckedCast( Load(MachineType::Pointer(), instance, IntPtrConstant(WasmInstanceObject::kRootsArrayAddressOffset - kHeapObjectTag))); TNode target = UncheckedCast(Load( MachineType::TaggedPointer(), roots, IntPtrConstant(Heap::roots_to_builtins_offset() + id * kPointerSize))); return target; } TNode LoadInstanceFromFrame() { return UncheckedCast( LoadFromParentFrame(WasmCompiledFrameConstants::kWasmInstanceOffset)); } TNode LoadCEntryFromInstance(TNode instance) { return UncheckedCast( Load(MachineType::AnyTagged(), instance, IntPtrConstant(WasmInstanceObject::kCEntryStubOffset - kHeapObjectTag))); } TNode LoadCEntryFromFrame() { return LoadCEntryFromInstance(LoadInstanceFromFrame()); } }; TF_BUILTIN(WasmAllocateHeapNumber, WasmBuiltinsAssembler) { TNode target = LoadBuiltinFromFrame(Builtins::kAllocateHeapNumber); TailCallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant()); } TF_BUILTIN(WasmArgumentsAdaptor, WasmBuiltinsAssembler) { TNode context = UncheckedParameter(Descriptor::kContext); TNode function = UncheckedParameter(Descriptor::kTarget); TNode new_target = UncheckedParameter(Descriptor::kNewTarget); TNode argc1 = UncheckedParameter(Descriptor::kActualArgumentsCount); TNode argc2 = UncheckedParameter(Descriptor::kExpectedArgumentsCount); TNode target = LoadBuiltinFromFrame(Builtins::kArgumentsAdaptorTrampoline); TailCallStub(ArgumentAdaptorDescriptor{}, target, context, function, new_target, argc1, argc2); } TF_BUILTIN(WasmCallJavaScript, WasmBuiltinsAssembler) { TNode context = UncheckedParameter(Descriptor::kContext); TNode function = UncheckedParameter(Descriptor::kFunction); TNode argc = UncheckedParameter(Descriptor::kActualArgumentsCount); TNode target = LoadBuiltinFromFrame(Builtins::kCall_ReceiverIsAny); TailCallStub(CallTrampolineDescriptor{}, target, context, function, argc); } TF_BUILTIN(WasmToNumber, WasmBuiltinsAssembler) { TNode context = UncheckedParameter(Descriptor::kContext); TNode argument = UncheckedParameter(Descriptor::kArgument); TNode target = LoadBuiltinFromFrame(Builtins::kToNumber); TailCallStub(TypeConversionDescriptor(), target, context, argument); } TF_BUILTIN(WasmStackGuard, WasmBuiltinsAssembler) { TNode centry = LoadCEntryFromFrame(); TailCallRuntimeWithCEntry(Runtime::kWasmStackGuard, centry, NoContextConstant()); } TF_BUILTIN(WasmGrowMemory, WasmBuiltinsAssembler) { TNode num_pages = UncheckedCast(Parameter(Descriptor::kNumPages)); Label num_pages_out_of_range(this, Label::kDeferred); TNode num_pages_fits_in_smi = IsValidPositiveSmi(ChangeInt32ToIntPtr(num_pages)); GotoIfNot(num_pages_fits_in_smi, &num_pages_out_of_range); TNode num_pages_smi = SmiFromInt32(num_pages); TNode instance = LoadInstanceFromFrame(); TNode centry = LoadCEntryFromInstance(instance); TNode ret_smi = UncheckedCast( CallRuntimeWithCEntry(Runtime::kWasmGrowMemory, centry, NoContextConstant(), instance, num_pages_smi)); TNode ret = SmiToInt32(ret_smi); ReturnRaw(ret); BIND(&num_pages_out_of_range); ReturnRaw(Int32Constant(-1)); } #define DECLARE_ENUM(name) \ TF_BUILTIN(ThrowWasm##name, WasmBuiltinsAssembler) { \ TNode centry = LoadCEntryFromFrame(); \ int message_id = wasm::WasmOpcodes::TrapReasonToMessageId(wasm::k##name); \ TailCallRuntimeWithCEntry(Runtime::kThrowWasmError, centry, \ NoContextConstant(), SmiConstant(message_id)); \ } FOREACH_WASM_TRAPREASON(DECLARE_ENUM) #undef DECLARE_ENUM } // namespace internal } // namespace v8