Home | History | Annotate | Download | only in builtins
      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