builtins-wasm-gen.cc 5.57 KB
Newer Older
1 2 3 4
// 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.

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 12 13

namespace v8 {
namespace internal {

14 15 16 17
class WasmBuiltinsAssembler : public CodeStubAssembler {
 public:
  explicit WasmBuiltinsAssembler(compiler::CodeAssemblerState* state)
      : CodeStubAssembler(state) {}
18

19 20 21 22 23 24
 protected:
  TNode<Object> UncheckedParameter(int index) {
    return UncheckedCast<Object>(Parameter(index));
  }

  TNode<Code> LoadBuiltinFromFrame(Builtins::Name id) {
25
    TNode<Object> instance = LoadInstanceFromFrame();
26
    TNode<IntPtrT> isolate_root = UncheckedCast<IntPtrT>(
27
        Load(MachineType::Pointer(), instance,
28
             IntPtrConstant(WasmInstanceObject::kIsolateRootOffset -
29
                            kHeapObjectTag)));
30 31 32
    TNode<Code> target = UncheckedCast<Code>(
        Load(MachineType::TaggedPointer(), isolate_root,
             IntPtrConstant(IsolateData::builtin_slot_offset(id))));
33 34
    return target;
  }
35 36 37 38 39 40

  TNode<Object> LoadInstanceFromFrame() {
    return UncheckedCast<Object>(
        LoadFromParentFrame(WasmCompiledFrameConstants::kWasmInstanceOffset));
  }

41 42 43 44 45 46 47
  TNode<Object> LoadContextFromInstance(TNode<Object> instance) {
    return UncheckedCast<Object>(
        Load(MachineType::AnyTagged(), instance,
             IntPtrConstant(WasmInstanceObject::kNativeContextOffset -
                            kHeapObjectTag)));
  }

48 49 50 51 52 53
  TNode<Code> LoadCEntryFromInstance(TNode<Object> instance) {
    return UncheckedCast<Code>(
        Load(MachineType::AnyTagged(), instance,
             IntPtrConstant(WasmInstanceObject::kCEntryStubOffset -
                            kHeapObjectTag)));
  }
54 55 56 57
};

TF_BUILTIN(WasmAllocateHeapNumber, WasmBuiltinsAssembler) {
  TNode<Code> target = LoadBuiltinFromFrame(Builtins::kAllocateHeapNumber);
58
  TailCallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant());
59 60 61 62 63 64 65
}

TF_BUILTIN(WasmCallJavaScript, WasmBuiltinsAssembler) {
  TNode<Object> context = UncheckedParameter(Descriptor::kContext);
  TNode<Object> function = UncheckedParameter(Descriptor::kFunction);
  TNode<Object> argc = UncheckedParameter(Descriptor::kActualArgumentsCount);
  TNode<Code> target = LoadBuiltinFromFrame(Builtins::kCall_ReceiverIsAny);
66
  TailCallStub(CallTrampolineDescriptor{}, target, context, function, argc);
67 68
}

69 70 71 72 73 74 75 76 77 78
TF_BUILTIN(WasmRecordWrite, WasmBuiltinsAssembler) {
  TNode<Object> object = UncheckedParameter(Descriptor::kObject);
  TNode<Object> slot = UncheckedParameter(Descriptor::kSlot);
  TNode<Object> remembered = UncheckedParameter(Descriptor::kRememberedSet);
  TNode<Object> fp_mode = UncheckedParameter(Descriptor::kFPMode);
  TNode<Code> target = LoadBuiltinFromFrame(Builtins::kRecordWrite);
  TailCallStub(RecordWriteDescriptor{}, target, NoContextConstant(), object,
               slot, remembered, fp_mode);
}

79 80 81 82 83 84 85
TF_BUILTIN(WasmToNumber, WasmBuiltinsAssembler) {
  TNode<Object> context = UncheckedParameter(Descriptor::kContext);
  TNode<Object> argument = UncheckedParameter(Descriptor::kArgument);
  TNode<Code> target = LoadBuiltinFromFrame(Builtins::kToNumber);
  TailCallStub(TypeConversionDescriptor(), target, context, argument);
}

86
TF_BUILTIN(WasmStackGuard, WasmBuiltinsAssembler) {
87 88 89 90
  TNode<Object> instance = LoadInstanceFromFrame();
  TNode<Code> centry = LoadCEntryFromInstance(instance);
  TNode<Object> context = LoadContextFromInstance(instance);
  TailCallRuntimeWithCEntry(Runtime::kWasmStackGuard, centry, context);
91 92
}

93 94 95 96 97 98 99 100
TF_BUILTIN(WasmThrow, WasmBuiltinsAssembler) {
  TNode<Object> exception = UncheckedParameter(Descriptor::kException);
  TNode<Object> instance = LoadInstanceFromFrame();
  TNode<Code> centry = LoadCEntryFromInstance(instance);
  TNode<Object> context = LoadContextFromInstance(instance);
  TailCallRuntimeWithCEntry(Runtime::kThrow, centry, context, exception);
}

101
TF_BUILTIN(WasmMemoryGrow, WasmBuiltinsAssembler) {
102 103 104 105 106 107 108 109 110 111 112
  TNode<Int32T> num_pages =
      UncheckedCast<Int32T>(Parameter(Descriptor::kNumPages));
  Label num_pages_out_of_range(this, Label::kDeferred);

  TNode<BoolT> num_pages_fits_in_smi =
      IsValidPositiveSmi(ChangeInt32ToIntPtr(num_pages));
  GotoIfNot(num_pages_fits_in_smi, &num_pages_out_of_range);

  TNode<Smi> num_pages_smi = SmiFromInt32(num_pages);
  TNode<Object> instance = LoadInstanceFromFrame();
  TNode<Code> centry = LoadCEntryFromInstance(instance);
113 114
  TNode<Object> context = LoadContextFromInstance(instance);
  TNode<Smi> ret_smi = UncheckedCast<Smi>(CallRuntimeWithCEntry(
115
      Runtime::kWasmMemoryGrow, centry, context, instance, num_pages_smi));
116 117 118 119 120 121 122
  TNode<Int32T> ret = SmiToInt32(ret_smi);
  ReturnRaw(ret);

  BIND(&num_pages_out_of_range);
  ReturnRaw(Int32Constant(-1));
}

123 124 125 126 127 128 129 130 131
#define DECLARE_ENUM(name)                                                \
  TF_BUILTIN(ThrowWasm##name, WasmBuiltinsAssembler) {                    \
    TNode<Object> instance = LoadInstanceFromFrame();                     \
    TNode<Code> centry = LoadCEntryFromInstance(instance);                \
    TNode<Object> context = LoadContextFromInstance(instance);            \
    MessageTemplate message_id =                                          \
        wasm::WasmOpcodes::TrapReasonToMessageId(wasm::k##name);          \
    TailCallRuntimeWithCEntry(Runtime::kThrowWasmError, centry, context,  \
                              SmiConstant(static_cast<int>(message_id))); \
132 133 134 135
  }
FOREACH_WASM_TRAPREASON(DECLARE_ENUM)
#undef DECLARE_ENUM

136 137
}  // namespace internal
}  // namespace v8