LCOV - code coverage report
Current view: top level - src/builtins - builtins-wasm-gen.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 101 103 98.1 %
Date: 2019-01-20 Functions: 53 53 100.0 %

          Line data    Source code
       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        1344 :       : CodeStubAssembler(state) {}
      18             : 
      19             :  protected:
      20             :   TNode<Object> UncheckedParameter(int index) {
      21         224 :     return UncheckedCast<Object>(Parameter(index));
      22             :   }
      23             : 
      24         504 :   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        1008 :                             kHeapObjectTag)));
      30             :     TNode<Code> target = UncheckedCast<Code>(
      31             :         Load(MachineType::TaggedPointer(), isolate_root,
      32        1008 :              IntPtrConstant(IsolateData::builtin_slot_offset(id))));
      33         504 :     return target;
      34             :   }
      35             : 
      36             :   TNode<Object> LoadInstanceFromFrame() {
      37             :     return UncheckedCast<Object>(
      38        1512 :         LoadFromParentFrame(WasmCompiledFrameConstants::kWasmInstanceOffset));
      39             :   }
      40             : 
      41         840 :   TNode<Object> LoadContextFromInstance(TNode<Object> instance) {
      42             :     return UncheckedCast<Object>(
      43             :         Load(MachineType::AnyTagged(), instance,
      44             :              IntPtrConstant(WasmInstanceObject::kNativeContextOffset -
      45        1680 :                             kHeapObjectTag)));
      46             :   }
      47             : 
      48        1008 :   TNode<Code> LoadCEntryFromInstance(TNode<Object> instance) {
      49             :     return UncheckedCast<Code>(
      50             :         Load(MachineType::AnyTagged(), instance,
      51             :              IntPtrConstant(WasmInstanceObject::kCEntryStubOffset -
      52        2016 :                             kHeapObjectTag)));
      53             :   }
      54             : };
      55             : 
      56         224 : TF_BUILTIN(WasmAllocateHeapNumber, WasmBuiltinsAssembler) {
      57          56 :   TNode<Code> target = LoadBuiltinFromFrame(Builtins::kAllocateHeapNumber);
      58         168 :   TailCallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant());
      59          56 : }
      60             : 
      61         224 : TF_BUILTIN(WasmCallJavaScript, WasmBuiltinsAssembler) {
      62             :   TNode<Object> context = UncheckedParameter(Descriptor::kContext);
      63             :   TNode<Object> function = UncheckedParameter(Descriptor::kFunction);
      64             :   TNode<Object> argc = UncheckedParameter(Descriptor::kActualArgumentsCount);
      65          56 :   TNode<Code> target = LoadBuiltinFromFrame(Builtins::kCall_ReceiverIsAny);
      66         112 :   TailCallStub(CallTrampolineDescriptor{}, target, context, function, argc);
      67          56 : }
      68             : 
      69         224 : TF_BUILTIN(WasmRecordWrite, WasmBuiltinsAssembler) {
      70             :   TNode<Object> object = UncheckedParameter(Descriptor::kObject);
      71             :   TNode<Object> slot = UncheckedParameter(Descriptor::kSlot);
      72             :   TNode<Object> remembered = UncheckedParameter(Descriptor::kRememberedSet);
      73             :   TNode<Object> fp_mode = UncheckedParameter(Descriptor::kFPMode);
      74          56 :   TNode<Code> target = LoadBuiltinFromFrame(Builtins::kRecordWrite);
      75          56 :   TailCallStub(RecordWriteDescriptor{}, target, NoContextConstant(), object,
      76         168 :                slot, remembered, fp_mode);
      77          56 : }
      78             : 
      79         224 : TF_BUILTIN(WasmToNumber, WasmBuiltinsAssembler) {
      80             :   TNode<Object> context = UncheckedParameter(Descriptor::kContext);
      81             :   TNode<Object> argument = UncheckedParameter(Descriptor::kArgument);
      82          56 :   TNode<Code> target = LoadBuiltinFromFrame(Builtins::kToNumber);
      83         112 :   TailCallStub(TypeConversionDescriptor(), target, context, argument);
      84          56 : }
      85             : 
      86         224 : TF_BUILTIN(WasmStackGuard, WasmBuiltinsAssembler) {
      87          56 :   TNode<Object> instance = LoadInstanceFromFrame();
      88          56 :   TNode<Code> centry = LoadCEntryFromInstance(instance);
      89          56 :   TNode<Object> context = LoadContextFromInstance(instance);
      90          56 :   TailCallRuntimeWithCEntry(Runtime::kWasmStackGuard, centry, context);
      91          56 : }
      92             : 
      93         224 : TF_BUILTIN(WasmThrow, WasmBuiltinsAssembler) {
      94          56 :   TNode<Object> exception = UncheckedParameter(Descriptor::kException);
      95          56 :   TNode<Object> instance = LoadInstanceFromFrame();
      96          56 :   TNode<Code> centry = LoadCEntryFromInstance(instance);
      97          56 :   TNode<Object> context = LoadContextFromInstance(instance);
      98          56 :   TailCallRuntimeWithCEntry(Runtime::kThrow, centry, context, exception);
      99          56 : }
     100             : 
     101         224 : TF_BUILTIN(WasmAtomicWake, WasmBuiltinsAssembler) {
     102             :   TNode<Uint32T> address =
     103             :       UncheckedCast<Uint32T>(Parameter(Descriptor::kAddress));
     104             :   TNode<Uint32T> count = UncheckedCast<Uint32T>(Parameter(Descriptor::kCount));
     105             : 
     106             :   TNode<Object> instance = LoadInstanceFromFrame();
     107          56 :   TNode<Code> centry = LoadCEntryFromInstance(instance);
     108             : 
     109          56 :   TNode<Code> target = LoadBuiltinFromFrame(Builtins::kAllocateHeapNumber);
     110             : 
     111             :   // TODO(aseemgarg): Use SMIs if possible for address and count
     112             :   TNode<HeapNumber> address_heap = UncheckedCast<HeapNumber>(
     113         168 :       CallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant()));
     114         112 :   StoreHeapNumberValue(address_heap, ChangeUint32ToFloat64(address));
     115             : 
     116             :   TNode<HeapNumber> count_heap = UncheckedCast<HeapNumber>(
     117         168 :       CallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant()));
     118         112 :   StoreHeapNumberValue(count_heap, ChangeUint32ToFloat64(count));
     119             : 
     120             :   TNode<Smi> result_smi = UncheckedCast<Smi>(CallRuntimeWithCEntry(
     121             :       Runtime::kWasmAtomicWake, centry, NoContextConstant(), instance,
     122         112 :       address_heap, count_heap));
     123         112 :   ReturnRaw(SmiToInt32(result_smi));
     124          56 : }
     125             : 
     126         224 : TF_BUILTIN(WasmI32AtomicWait, WasmBuiltinsAssembler) {
     127             :   TNode<Uint32T> address =
     128             :       UncheckedCast<Uint32T>(Parameter(Descriptor::kAddress));
     129             :   TNode<Int32T> expected_value =
     130             :       UncheckedCast<Int32T>(Parameter(Descriptor::kExpectedValue));
     131             :   TNode<Float64T> timeout =
     132             :       UncheckedCast<Float64T>(Parameter(Descriptor::kTimeout));
     133             : 
     134             :   TNode<Object> instance = LoadInstanceFromFrame();
     135          56 :   TNode<Code> centry = LoadCEntryFromInstance(instance);
     136             : 
     137          56 :   TNode<Code> target = LoadBuiltinFromFrame(Builtins::kAllocateHeapNumber);
     138             : 
     139             :   // TODO(aseemgarg): Use SMIs if possible for address and expected_value
     140             :   TNode<HeapNumber> address_heap = UncheckedCast<HeapNumber>(
     141         168 :       CallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant()));
     142         112 :   StoreHeapNumberValue(address_heap, ChangeUint32ToFloat64(address));
     143             : 
     144             :   TNode<HeapNumber> expected_value_heap = UncheckedCast<HeapNumber>(
     145         168 :       CallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant()));
     146             :   StoreHeapNumberValue(expected_value_heap,
     147         112 :                        ChangeInt32ToFloat64(expected_value));
     148             : 
     149             :   TNode<HeapNumber> timeout_heap = UncheckedCast<HeapNumber>(
     150         168 :       CallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant()));
     151          56 :   StoreHeapNumberValue(timeout_heap, timeout);
     152             : 
     153             :   TNode<Smi> result_smi = UncheckedCast<Smi>(CallRuntimeWithCEntry(
     154             :       Runtime::kWasmI32AtomicWait, centry, NoContextConstant(), instance,
     155         112 :       address_heap, expected_value_heap, timeout_heap));
     156         112 :   ReturnRaw(SmiToInt32(result_smi));
     157          56 : }
     158             : 
     159         224 : TF_BUILTIN(WasmI64AtomicWait, WasmBuiltinsAssembler) {
     160             :   TNode<Uint32T> address =
     161             :       UncheckedCast<Uint32T>(Parameter(Descriptor::kAddress));
     162             :   TNode<Uint32T> expected_value_high =
     163             :       UncheckedCast<Uint32T>(Parameter(Descriptor::kExpectedValueHigh));
     164             :   TNode<Uint32T> expected_value_low =
     165             :       UncheckedCast<Uint32T>(Parameter(Descriptor::kExpectedValueLow));
     166             :   TNode<Float64T> timeout =
     167             :       UncheckedCast<Float64T>(Parameter(Descriptor::kTimeout));
     168             : 
     169             :   TNode<Object> instance = LoadInstanceFromFrame();
     170          56 :   TNode<Code> centry = LoadCEntryFromInstance(instance);
     171             : 
     172          56 :   TNode<Code> target = LoadBuiltinFromFrame(Builtins::kAllocateHeapNumber);
     173             : 
     174             :   // TODO(aseemgarg): Use SMIs if possible for address and expected_value
     175             :   TNode<HeapNumber> address_heap = UncheckedCast<HeapNumber>(
     176         168 :       CallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant()));
     177         112 :   StoreHeapNumberValue(address_heap, ChangeUint32ToFloat64(address));
     178             : 
     179             :   TNode<HeapNumber> expected_value_high_heap = UncheckedCast<HeapNumber>(
     180         168 :       CallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant()));
     181             :   StoreHeapNumberValue(expected_value_high_heap,
     182         112 :                        ChangeUint32ToFloat64(expected_value_high));
     183             : 
     184             :   TNode<HeapNumber> expected_value_low_heap = UncheckedCast<HeapNumber>(
     185         168 :       CallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant()));
     186             :   StoreHeapNumberValue(expected_value_low_heap,
     187         112 :                        ChangeUint32ToFloat64(expected_value_low));
     188             : 
     189             :   TNode<HeapNumber> timeout_heap = UncheckedCast<HeapNumber>(
     190         168 :       CallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant()));
     191          56 :   StoreHeapNumberValue(timeout_heap, timeout);
     192             : 
     193             :   TNode<Smi> result_smi = UncheckedCast<Smi>(CallRuntimeWithCEntry(
     194             :       Runtime::kWasmI64AtomicWait, centry, NoContextConstant(), instance,
     195             :       address_heap, expected_value_high_heap, expected_value_low_heap,
     196         112 :       timeout_heap));
     197         112 :   ReturnRaw(SmiToInt32(result_smi));
     198          56 : }
     199             : 
     200         224 : TF_BUILTIN(WasmMemoryGrow, WasmBuiltinsAssembler) {
     201             :   TNode<Int32T> num_pages =
     202             :       UncheckedCast<Int32T>(Parameter(Descriptor::kNumPages));
     203             :   Label num_pages_out_of_range(this, Label::kDeferred);
     204             : 
     205             :   TNode<BoolT> num_pages_fits_in_smi =
     206          56 :       IsValidPositiveSmi(ChangeInt32ToIntPtr(num_pages));
     207          56 :   GotoIfNot(num_pages_fits_in_smi, &num_pages_out_of_range);
     208             : 
     209          56 :   TNode<Smi> num_pages_smi = SmiFromInt32(num_pages);
     210             :   TNode<Object> instance = LoadInstanceFromFrame();
     211          56 :   TNode<Code> centry = LoadCEntryFromInstance(instance);
     212          56 :   TNode<Object> context = LoadContextFromInstance(instance);
     213             :   TNode<Smi> ret_smi = UncheckedCast<Smi>(CallRuntimeWithCEntry(
     214             :       Runtime::kWasmMemoryGrow, centry, context, instance, num_pages_smi));
     215          56 :   TNode<Int32T> ret = SmiToInt32(ret_smi);
     216          56 :   ReturnRaw(ret);
     217             : 
     218          56 :   BIND(&num_pages_out_of_range);
     219         112 :   ReturnRaw(Int32Constant(-1));
     220          56 : }
     221             : 
     222         280 : TF_BUILTIN(BigIntToWasmI64, WasmBuiltinsAssembler) {
     223          56 :   if (!Is64()) {
     224           0 :     Unreachable();
     225          56 :     return;
     226             :   }
     227             : 
     228          56 :   TNode<Code> target = LoadBuiltinFromFrame(Builtins::kI64ToBigInt);
     229             :   TNode<IntPtrT> argument =
     230             :       UncheckedCast<IntPtrT>(Parameter(Descriptor::kArgument));
     231             : 
     232          56 :   TailCallStub(BigIntToWasmI64Descriptor(), target, NoContextConstant(),
     233         112 :                argument);
     234             : }
     235             : 
     236         336 : TF_BUILTIN(WasmBigIntToI64, WasmBuiltinsAssembler) {
     237          56 :   if (!Is64()) {
     238           0 :     Unreachable();
     239          56 :     return;
     240             :   }
     241             : 
     242             :   TNode<Object> context =
     243             :       UncheckedCast<Object>(Parameter(Descriptor::kContext));
     244          56 :   TNode<Code> target = LoadBuiltinFromFrame(Builtins::kBigIntToI64);
     245             :   TNode<IntPtrT> argument =
     246             :       UncheckedCast<IntPtrT>(Parameter(Descriptor::kArgument));
     247             : 
     248          56 :   TailCallStub(BigIntToI64Descriptor(), target, context, argument);
     249             : }
     250             : 
     251             : #define DECLARE_ENUM(name)                                                \
     252             :   TF_BUILTIN(ThrowWasm##name, WasmBuiltinsAssembler) {                    \
     253             :     TNode<Object> instance = LoadInstanceFromFrame();                     \
     254             :     TNode<Code> centry = LoadCEntryFromInstance(instance);                \
     255             :     TNode<Object> context = LoadContextFromInstance(instance);            \
     256             :     MessageTemplate message_id =                                          \
     257             :         wasm::WasmOpcodes::TrapReasonToMessageId(wasm::k##name);          \
     258             :     TailCallRuntimeWithCEntry(Runtime::kThrowWasmError, centry, context,  \
     259             :                               SmiConstant(static_cast<int>(message_id))); \
     260             :   }
     261        3360 : FOREACH_WASM_TRAPREASON(DECLARE_ENUM)
     262             : #undef DECLARE_ENUM
     263             : 
     264             : }  // namespace internal
     265       94089 : }  // namespace v8

Generated by: LCOV version 1.10