LCOV - code coverage report
Current view: top level - src/builtins - builtins-wasm-gen.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 142 146 97.3 %
Date: 2019-04-19 Functions: 58 58 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        1512 : class WasmBuiltinsAssembler : public CodeStubAssembler {
      15             :  public:
      16             :   explicit WasmBuiltinsAssembler(compiler::CodeAssemblerState* state)
      17        1512 :       : 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        1008 :              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        1680 :         LoadFromParentFrame(WasmCompiledFrameConstants::kWasmInstanceOffset));
      39             :   }
      40             : 
      41        1008 :   TNode<Object> LoadContextFromInstance(TNode<Object> instance) {
      42             :     return UncheckedCast<Object>(
      43             :         Load(MachineType::AnyTagged(), instance,
      44        2016 :              IntPtrConstant(WasmInstanceObject::kNativeContextOffset -
      45        3024 :                             kHeapObjectTag)));
      46             :   }
      47             : 
      48        1176 :   TNode<Code> LoadCEntryFromInstance(TNode<Object> instance) {
      49             :     return UncheckedCast<Code>(
      50             :         Load(MachineType::AnyTagged(), instance,
      51        2352 :              IntPtrConstant(WasmInstanceObject::kCEntryStubOffset -
      52        3528 :                             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         168 :   TailCallStub(RecordWriteDescriptor{}, target, NoContextConstant(), object,
      76             :                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(WasmStackOverflow, WasmBuiltinsAssembler) {
      94          56 :   TNode<Object> instance = LoadInstanceFromFrame();
      95          56 :   TNode<Code> centry = LoadCEntryFromInstance(instance);
      96          56 :   TNode<Object> context = LoadContextFromInstance(instance);
      97          56 :   TailCallRuntimeWithCEntry(Runtime::kThrowWasmStackOverflow, centry, context);
      98          56 : }
      99             : 
     100         224 : TF_BUILTIN(WasmThrow, WasmBuiltinsAssembler) {
     101          56 :   TNode<Object> exception = UncheckedParameter(Descriptor::kException);
     102          56 :   TNode<Object> instance = LoadInstanceFromFrame();
     103          56 :   TNode<Code> centry = LoadCEntryFromInstance(instance);
     104          56 :   TNode<Object> context = LoadContextFromInstance(instance);
     105          56 :   TailCallRuntimeWithCEntry(Runtime::kThrow, centry, context, exception);
     106          56 : }
     107             : 
     108         224 : TF_BUILTIN(WasmAtomicNotify, WasmBuiltinsAssembler) {
     109             :   TNode<Uint32T> address =
     110             :       UncheckedCast<Uint32T>(Parameter(Descriptor::kAddress));
     111             :   TNode<Uint32T> count = UncheckedCast<Uint32T>(Parameter(Descriptor::kCount));
     112             : 
     113             :   TNode<Object> instance = LoadInstanceFromFrame();
     114          56 :   TNode<Code> centry = LoadCEntryFromInstance(instance);
     115             : 
     116          56 :   TNode<Code> target = LoadBuiltinFromFrame(Builtins::kAllocateHeapNumber);
     117             : 
     118             :   // TODO(aseemgarg): Use SMIs if possible for address and count
     119             :   TNode<HeapNumber> address_heap = UncheckedCast<HeapNumber>(
     120         168 :       CallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant()));
     121         112 :   StoreHeapNumberValue(address_heap, ChangeUint32ToFloat64(address));
     122             : 
     123             :   TNode<HeapNumber> count_heap = UncheckedCast<HeapNumber>(
     124         168 :       CallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant()));
     125         112 :   StoreHeapNumberValue(count_heap, ChangeUint32ToFloat64(count));
     126             : 
     127             :   TNode<Smi> result_smi = UncheckedCast<Smi>(CallRuntimeWithCEntry(
     128         112 :       Runtime::kWasmAtomicNotify, centry, NoContextConstant(), instance,
     129             :       address_heap, count_heap));
     130         112 :   ReturnRaw(SmiToInt32(result_smi));
     131          56 : }
     132             : 
     133         224 : TF_BUILTIN(WasmI32AtomicWait, WasmBuiltinsAssembler) {
     134             :   TNode<Uint32T> address =
     135             :       UncheckedCast<Uint32T>(Parameter(Descriptor::kAddress));
     136             :   TNode<Int32T> expected_value =
     137             :       UncheckedCast<Int32T>(Parameter(Descriptor::kExpectedValue));
     138             :   TNode<Float64T> timeout =
     139             :       UncheckedCast<Float64T>(Parameter(Descriptor::kTimeout));
     140             : 
     141             :   TNode<Object> instance = LoadInstanceFromFrame();
     142          56 :   TNode<Code> centry = LoadCEntryFromInstance(instance);
     143             : 
     144          56 :   TNode<Code> target = LoadBuiltinFromFrame(Builtins::kAllocateHeapNumber);
     145             : 
     146             :   // TODO(aseemgarg): Use SMIs if possible for address and expected_value
     147             :   TNode<HeapNumber> address_heap = UncheckedCast<HeapNumber>(
     148         168 :       CallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant()));
     149         112 :   StoreHeapNumberValue(address_heap, ChangeUint32ToFloat64(address));
     150             : 
     151             :   TNode<HeapNumber> expected_value_heap = UncheckedCast<HeapNumber>(
     152         168 :       CallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant()));
     153          56 :   StoreHeapNumberValue(expected_value_heap,
     154         168 :                        ChangeInt32ToFloat64(expected_value));
     155             : 
     156             :   TNode<HeapNumber> timeout_heap = UncheckedCast<HeapNumber>(
     157         168 :       CallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant()));
     158          56 :   StoreHeapNumberValue(timeout_heap, timeout);
     159             : 
     160             :   TNode<Smi> result_smi = UncheckedCast<Smi>(CallRuntimeWithCEntry(
     161         112 :       Runtime::kWasmI32AtomicWait, centry, NoContextConstant(), instance,
     162             :       address_heap, expected_value_heap, timeout_heap));
     163         112 :   ReturnRaw(SmiToInt32(result_smi));
     164          56 : }
     165             : 
     166         224 : TF_BUILTIN(WasmI64AtomicWait, WasmBuiltinsAssembler) {
     167             :   TNode<Uint32T> address =
     168             :       UncheckedCast<Uint32T>(Parameter(Descriptor::kAddress));
     169             :   TNode<Uint32T> expected_value_high =
     170             :       UncheckedCast<Uint32T>(Parameter(Descriptor::kExpectedValueHigh));
     171             :   TNode<Uint32T> expected_value_low =
     172             :       UncheckedCast<Uint32T>(Parameter(Descriptor::kExpectedValueLow));
     173             :   TNode<Float64T> timeout =
     174             :       UncheckedCast<Float64T>(Parameter(Descriptor::kTimeout));
     175             : 
     176             :   TNode<Object> instance = LoadInstanceFromFrame();
     177          56 :   TNode<Code> centry = LoadCEntryFromInstance(instance);
     178             : 
     179          56 :   TNode<Code> target = LoadBuiltinFromFrame(Builtins::kAllocateHeapNumber);
     180             : 
     181             :   // TODO(aseemgarg): Use SMIs if possible for address and expected_value
     182             :   TNode<HeapNumber> address_heap = UncheckedCast<HeapNumber>(
     183         168 :       CallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant()));
     184         112 :   StoreHeapNumberValue(address_heap, ChangeUint32ToFloat64(address));
     185             : 
     186             :   TNode<HeapNumber> expected_value_high_heap = UncheckedCast<HeapNumber>(
     187         168 :       CallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant()));
     188          56 :   StoreHeapNumberValue(expected_value_high_heap,
     189         168 :                        ChangeUint32ToFloat64(expected_value_high));
     190             : 
     191             :   TNode<HeapNumber> expected_value_low_heap = UncheckedCast<HeapNumber>(
     192         168 :       CallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant()));
     193          56 :   StoreHeapNumberValue(expected_value_low_heap,
     194         168 :                        ChangeUint32ToFloat64(expected_value_low));
     195             : 
     196             :   TNode<HeapNumber> timeout_heap = UncheckedCast<HeapNumber>(
     197         168 :       CallStub(AllocateHeapNumberDescriptor(), target, NoContextConstant()));
     198          56 :   StoreHeapNumberValue(timeout_heap, timeout);
     199             : 
     200             :   TNode<Smi> result_smi = UncheckedCast<Smi>(CallRuntimeWithCEntry(
     201         112 :       Runtime::kWasmI64AtomicWait, centry, NoContextConstant(), instance,
     202             :       address_heap, expected_value_high_heap, expected_value_low_heap,
     203             :       timeout_heap));
     204         112 :   ReturnRaw(SmiToInt32(result_smi));
     205          56 : }
     206             : 
     207         224 : TF_BUILTIN(WasmMemoryGrow, WasmBuiltinsAssembler) {
     208             :   TNode<Int32T> num_pages =
     209             :       UncheckedCast<Int32T>(Parameter(Descriptor::kNumPages));
     210          56 :   Label num_pages_out_of_range(this, Label::kDeferred);
     211             : 
     212             :   TNode<BoolT> num_pages_fits_in_smi =
     213          56 :       IsValidPositiveSmi(ChangeInt32ToIntPtr(num_pages));
     214          56 :   GotoIfNot(num_pages_fits_in_smi, &num_pages_out_of_range);
     215             : 
     216          56 :   TNode<Smi> num_pages_smi = SmiFromInt32(num_pages);
     217             :   TNode<Object> instance = LoadInstanceFromFrame();
     218          56 :   TNode<Code> centry = LoadCEntryFromInstance(instance);
     219          56 :   TNode<Object> context = LoadContextFromInstance(instance);
     220             :   TNode<Smi> ret_smi = UncheckedCast<Smi>(CallRuntimeWithCEntry(
     221             :       Runtime::kWasmMemoryGrow, centry, context, instance, num_pages_smi));
     222          56 :   TNode<Int32T> ret = SmiToInt32(ret_smi);
     223          56 :   ReturnRaw(ret);
     224             : 
     225          56 :   BIND(&num_pages_out_of_range);
     226         112 :   ReturnRaw(Int32Constant(-1));
     227          56 : }
     228             : 
     229         280 : TF_BUILTIN(WasmTableGet, WasmBuiltinsAssembler) {
     230             :   TNode<Int32T> entry_index =
     231             :       UncheckedCast<Int32T>(Parameter(Descriptor::kEntryIndex));
     232          56 :   TNode<Object> instance = LoadInstanceFromFrame();
     233          56 :   TNode<Code> centry = LoadCEntryFromInstance(instance);
     234          56 :   TNode<Object> context = LoadContextFromInstance(instance);
     235          56 :   Label entry_index_out_of_range(this, Label::kDeferred);
     236             : 
     237             :   TNode<BoolT> entry_index_fits_in_smi =
     238          56 :       IsValidPositiveSmi(ChangeInt32ToIntPtr(entry_index));
     239          56 :   GotoIfNot(entry_index_fits_in_smi, &entry_index_out_of_range);
     240             : 
     241          56 :   TNode<Smi> entry_index_smi = SmiFromInt32(entry_index);
     242             :   TNode<Smi> table_index_smi =
     243          56 :       UncheckedCast<Smi>(Parameter(Descriptor::kTableIndex));
     244             : 
     245             :   TailCallRuntimeWithCEntry(Runtime::kWasmFunctionTableGet, centry, context,
     246          56 :                             instance, table_index_smi, entry_index_smi);
     247             : 
     248          56 :   BIND(&entry_index_out_of_range);
     249             :   MessageTemplate message_id =
     250          56 :       wasm::WasmOpcodes::TrapReasonToMessageId(wasm::kTrapTableOutOfBounds);
     251          56 :   TailCallRuntimeWithCEntry(Runtime::kThrowWasmError, centry, context,
     252          56 :                             SmiConstant(static_cast<int>(message_id)));
     253          56 : }
     254             : 
     255         336 : TF_BUILTIN(WasmTableSet, WasmBuiltinsAssembler) {
     256             :   TNode<Int32T> entry_index =
     257             :       UncheckedCast<Int32T>(Parameter(Descriptor::kEntryIndex));
     258          56 :   TNode<Object> instance = LoadInstanceFromFrame();
     259          56 :   TNode<Code> centry = LoadCEntryFromInstance(instance);
     260          56 :   TNode<Object> context = LoadContextFromInstance(instance);
     261          56 :   Label entry_index_out_of_range(this, Label::kDeferred);
     262             : 
     263             :   TNode<BoolT> entry_index_fits_in_smi =
     264          56 :       IsValidPositiveSmi(ChangeInt32ToIntPtr(entry_index));
     265          56 :   GotoIfNot(entry_index_fits_in_smi, &entry_index_out_of_range);
     266             : 
     267          56 :   TNode<Smi> entry_index_smi = SmiFromInt32(entry_index);
     268             :   TNode<Smi> table_index_smi =
     269          56 :       UncheckedCast<Smi>(Parameter(Descriptor::kTableIndex));
     270          56 :   TNode<Object> value = UncheckedCast<Object>(Parameter(Descriptor::kValue));
     271             :   TailCallRuntimeWithCEntry(Runtime::kWasmFunctionTableSet, centry, context,
     272          56 :                             instance, table_index_smi, entry_index_smi, value);
     273             : 
     274          56 :   BIND(&entry_index_out_of_range);
     275             :   MessageTemplate message_id =
     276          56 :       wasm::WasmOpcodes::TrapReasonToMessageId(wasm::kTrapTableOutOfBounds);
     277          56 :   TailCallRuntimeWithCEntry(Runtime::kThrowWasmError, centry, context,
     278          56 :                             SmiConstant(static_cast<int>(message_id)));
     279          56 : }
     280             : 
     281         280 : TF_BUILTIN(WasmI64ToBigInt, WasmBuiltinsAssembler) {
     282          56 :   if (!Is64()) {
     283           0 :     Unreachable();
     284           0 :     return;
     285             :   }
     286             : 
     287          56 :   TNode<Code> target = LoadBuiltinFromFrame(Builtins::kI64ToBigInt);
     288             :   TNode<IntPtrT> argument =
     289             :       UncheckedCast<IntPtrT>(Parameter(Descriptor::kArgument));
     290             : 
     291         112 :   TailCallStub(I64ToBigIntDescriptor(), target, NoContextConstant(), argument);
     292             : }
     293             : 
     294         336 : TF_BUILTIN(WasmBigIntToI64, WasmBuiltinsAssembler) {
     295          56 :   if (!Is64()) {
     296           0 :     Unreachable();
     297           0 :     return;
     298             :   }
     299             : 
     300             :   TNode<Object> context =
     301             :       UncheckedCast<Object>(Parameter(Descriptor::kContext));
     302          56 :   TNode<Code> target = LoadBuiltinFromFrame(Builtins::kBigIntToI64);
     303             :   TNode<IntPtrT> argument =
     304             :       UncheckedCast<IntPtrT>(Parameter(Descriptor::kArgument));
     305             : 
     306          56 :   TailCallStub(BigIntToI64Descriptor(), target, context, argument);
     307             : }
     308             : 
     309             : #define DECLARE_ENUM(name)                                                \
     310             :   TF_BUILTIN(ThrowWasm##name, WasmBuiltinsAssembler) {                    \
     311             :     TNode<Object> instance = LoadInstanceFromFrame();                     \
     312             :     TNode<Code> centry = LoadCEntryFromInstance(instance);                \
     313             :     TNode<Object> context = LoadContextFromInstance(instance);            \
     314             :     MessageTemplate message_id =                                          \
     315             :         wasm::WasmOpcodes::TrapReasonToMessageId(wasm::k##name);          \
     316             :     TailCallRuntimeWithCEntry(Runtime::kThrowWasmError, centry, context,  \
     317             :                               SmiConstant(static_cast<int>(message_id))); \
     318             :   }
     319        3360 : FOREACH_WASM_TRAPREASON(DECLARE_ENUM)
     320             : #undef DECLARE_ENUM
     321             : 
     322             : }  // namespace internal
     323       59480 : }  // namespace v8

Generated by: LCOV version 1.10