tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

WasmBuiltins.h (12579B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 *
      4 * Copyright 2017 Mozilla Foundation
      5 *
      6 * Licensed under the Apache License, Version 2.0 (the "License");
      7 * you may not use this file except in compliance with the License.
      8 * You may obtain a copy of the License at
      9 *
     10 *     http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing, software
     13 * distributed under the License is distributed on an "AS IS" BASIS,
     14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15 * See the License for the specific language governing permissions and
     16 * limitations under the License.
     17 */
     18 
     19 #ifndef wasm_builtins_h
     20 #define wasm_builtins_h
     21 
     22 #include "intgemm/IntegerGemmIntrinsic.h"
     23 #include "jit/IonTypes.h"
     24 #include "wasm/WasmBuiltinModuleGenerated.h"
     25 #include "wasm/WasmConstants.h"
     26 
     27 namespace js {
     28 class JitFrameIter;
     29 namespace jit {
     30 class AutoMarkJitCodeWritableForThread;
     31 struct ResumeFromException;
     32 }  // namespace jit
     33 namespace wasm {
     34 
     35 class WasmFrameIter;
     36 class CodeRange;
     37 class FuncType;
     38 
     39 // A wasm::SymbolicAddress represents a pointer to a well-known function/global
     40 // that is embedded in wasm code. Since wasm code is serialized and later
     41 // deserialized into a different address space, symbolic addresses must be used
     42 // for *all* pointers into the address space. The MacroAssembler records a list
     43 // of all SymbolicAddresses and the offsets of their use in the code for later
     44 // patching during static linking.
     45 
     46 enum class SymbolicAddress {
     47  ToInt32,
     48 #if defined(JS_CODEGEN_ARM)
     49  aeabi_idivmod,
     50  aeabi_uidivmod,
     51 #endif
     52  ModD,
     53  SinNativeD,
     54  SinFdlibmD,
     55  CosNativeD,
     56  CosFdlibmD,
     57  TanNativeD,
     58  TanFdlibmD,
     59  ASinD,
     60  ACosD,
     61  ATanD,
     62  CeilD,
     63  CeilF,
     64  FloorD,
     65  FloorF,
     66  TruncD,
     67  TruncF,
     68  NearbyIntD,
     69  NearbyIntF,
     70  ExpD,
     71  LogD,
     72  PowD,
     73  ATan2D,
     74  ArrayMemMove,
     75  ArrayRefsMove,
     76  HandleDebugTrap,
     77  HandleRequestTierUp,
     78  HandleThrow,
     79  HandleTrap,
     80  ReportV128JSCall,
     81  CallImport_General,
     82  CoerceInPlace_ToInt32,
     83  CoerceInPlace_ToNumber,
     84  CoerceInPlace_JitEntry,
     85  CoerceInPlace_ToBigInt,
     86  AllocateBigInt,
     87  BoxValue_Anyref,
     88  DivI64,
     89  UDivI64,
     90  ModI64,
     91  UModI64,
     92  TruncateDoubleToInt64,
     93  TruncateDoubleToUint64,
     94  SaturatingTruncateDoubleToInt64,
     95  SaturatingTruncateDoubleToUint64,
     96  Uint64ToFloat32,
     97  Uint64ToDouble,
     98  Int64ToFloat32,
     99  Int64ToDouble,
    100  MemoryGrowM32,
    101  MemoryGrowM64,
    102  MemorySizeM32,
    103  MemorySizeM64,
    104  WaitI32M32,
    105  WaitI32M64,
    106  WaitI64M32,
    107  WaitI64M64,
    108  WakeM32,
    109  WakeM64,
    110  MemCopyM32,
    111  MemCopySharedM32,
    112  MemCopyM64,
    113  MemCopySharedM64,
    114  MemCopyAny,
    115  DataDrop,
    116  MemFillM32,
    117  MemFillSharedM32,
    118  MemFillM64,
    119  MemFillSharedM64,
    120  MemDiscardM32,
    121  MemDiscardSharedM32,
    122  MemDiscardM64,
    123  MemDiscardSharedM64,
    124  MemInitM32,
    125  MemInitM64,
    126  TableCopy,
    127  ElemDrop,
    128  TableFill,
    129  TableGet,
    130  TableGrow,
    131  TableInit,
    132  TableSet,
    133  TableSize,
    134  RefFunc,
    135  PostBarrierEdge,
    136  PostBarrierEdgePrecise,
    137  PostBarrierWholeCell,
    138  ExceptionNew,
    139  ThrowException,
    140  StructNewIL_true,
    141  StructNewIL_false,
    142  StructNewOOL_true,
    143  StructNewOOL_false,
    144  ArrayNew_true,
    145  ArrayNew_false,
    146  ArrayNewData,
    147  ArrayNewElem,
    148  ArrayInitData,
    149  ArrayInitElem,
    150  ArrayCopy,
    151  SlotsToAllocKindBytesTable,
    152 #define VISIT_BUILTIN_FUNC(op, export, sa_name, ...) sa_name,
    153  FOR_EACH_BUILTIN_MODULE_FUNC(VISIT_BUILTIN_FUNC)
    154 #undef VISIT_BUILTIN_FUNC
    155 #ifdef ENABLE_WASM_JSPI
    156      UpdateSuspenderState,
    157 #endif
    158 #ifdef WASM_CODEGEN_DEBUG
    159  PrintI32,
    160  PrintPtr,
    161  PrintF32,
    162  PrintF64,
    163  PrintText,
    164 #endif
    165  Limit
    166 };
    167 
    168 // The FailureMode indicates whether, immediately after a call to a builtin
    169 // returns, the return value should be checked against an error condition
    170 // (and if so, which one) which signals that the C++ calle has already
    171 // reported an error and thus wasm needs to wasmTrap(Trap::ThrowReported).
    172 
    173 enum class FailureMode : uint8_t {
    174  Infallible,
    175  FailOnNegI32,
    176  FailOnMaxI32,
    177  FailOnNullPtr,
    178  FailOnInvalidRef,
    179 };
    180 
    181 // SymbolicAddressSignature carries type information for a function referred
    182 // to by a SymbolicAddress.  In order that |argTypes| can be written out as a
    183 // static initialiser, it has to have fixed length.  At present
    184 // SymbolicAddressType is used to describe functions with at most 14 arguments,
    185 // so |argTypes| has 15 entries in order to allow the last value to be
    186 // MIRType::None, in the hope of catching any accidental overruns of the
    187 // defined section of the array.
    188 
    189 static constexpr size_t SymbolicAddressSignatureMaxArgs = 14;
    190 
    191 struct SymbolicAddressSignature {
    192  // The SymbolicAddress that is described.
    193  const SymbolicAddress identity;
    194  // The return type, or MIRType::None to denote 'void'.
    195  const jit::MIRType retType;
    196  // The failure mode, which is checked by masm.wasmCallBuiltinInstanceMethod.
    197  const FailureMode failureMode;
    198  // The trap to execute if the builtin fails.
    199  const Trap failureTrap;
    200  // The number of arguments, 0 .. SymbolicAddressSignatureMaxArgs only.
    201  const uint8_t numArgs;
    202  // The argument types; SymbolicAddressSignatureMaxArgs + 1 guard, which
    203  // should be MIRType::None.
    204  const jit::MIRType argTypes[SymbolicAddressSignatureMaxArgs + 1];
    205 };
    206 
    207 // The 32 in this assertion is derived as follows: SymbolicAddress is probably
    208 // size-4 aligned-4, but it's at the start of the struct, so there's no
    209 // alignment hole before it.  All other components (MIRType and uint8_t) are
    210 // size-1 aligned-1, and there are 18 in total, so it is reasonable to assume
    211 // that they also don't create any alignment holes.  Hence it is also
    212 // reasonable to assume that the actual size is 1 * 4 + 18 * 1 == 22.  The
    213 // worst-plausible-case rounding will take that up to 32.  Hence, the
    214 // assertion uses 32.
    215 
    216 static_assert(sizeof(SymbolicAddressSignature) <= 32,
    217              "SymbolicAddressSignature unexpectedly large");
    218 
    219 // These provide argument type information for a subset of the SymbolicAddress
    220 // targets, for which type info is needed to generate correct stackmaps.
    221 
    222 extern const SymbolicAddressSignature SASigSinNativeD;
    223 extern const SymbolicAddressSignature SASigSinFdlibmD;
    224 extern const SymbolicAddressSignature SASigCosNativeD;
    225 extern const SymbolicAddressSignature SASigCosFdlibmD;
    226 extern const SymbolicAddressSignature SASigTanNativeD;
    227 extern const SymbolicAddressSignature SASigTanFdlibmD;
    228 extern const SymbolicAddressSignature SASigASinD;
    229 extern const SymbolicAddressSignature SASigACosD;
    230 extern const SymbolicAddressSignature SASigATanD;
    231 extern const SymbolicAddressSignature SASigCeilD;
    232 extern const SymbolicAddressSignature SASigCeilF;
    233 extern const SymbolicAddressSignature SASigFloorD;
    234 extern const SymbolicAddressSignature SASigFloorF;
    235 extern const SymbolicAddressSignature SASigTruncD;
    236 extern const SymbolicAddressSignature SASigTruncF;
    237 extern const SymbolicAddressSignature SASigNearbyIntD;
    238 extern const SymbolicAddressSignature SASigNearbyIntF;
    239 extern const SymbolicAddressSignature SASigExpD;
    240 extern const SymbolicAddressSignature SASigLogD;
    241 extern const SymbolicAddressSignature SASigPowD;
    242 extern const SymbolicAddressSignature SASigATan2D;
    243 extern const SymbolicAddressSignature SASigArrayMemMove;
    244 extern const SymbolicAddressSignature SASigArrayRefsMove;
    245 extern const SymbolicAddressSignature SASigMemoryGrowM32;
    246 extern const SymbolicAddressSignature SASigMemoryGrowM64;
    247 extern const SymbolicAddressSignature SASigMemorySizeM32;
    248 extern const SymbolicAddressSignature SASigMemorySizeM64;
    249 extern const SymbolicAddressSignature SASigWaitI32M32;
    250 extern const SymbolicAddressSignature SASigWaitI32M64;
    251 extern const SymbolicAddressSignature SASigWaitI64M32;
    252 extern const SymbolicAddressSignature SASigWaitI64M64;
    253 extern const SymbolicAddressSignature SASigWakeM32;
    254 extern const SymbolicAddressSignature SASigWakeM64;
    255 extern const SymbolicAddressSignature SASigMemCopyM32;
    256 extern const SymbolicAddressSignature SASigMemCopySharedM32;
    257 extern const SymbolicAddressSignature SASigMemCopyM64;
    258 extern const SymbolicAddressSignature SASigMemCopySharedM64;
    259 extern const SymbolicAddressSignature SASigMemCopyAny;
    260 extern const SymbolicAddressSignature SASigDataDrop;
    261 extern const SymbolicAddressSignature SASigMemFillM32;
    262 extern const SymbolicAddressSignature SASigMemFillSharedM32;
    263 extern const SymbolicAddressSignature SASigMemFillM64;
    264 extern const SymbolicAddressSignature SASigMemFillSharedM64;
    265 extern const SymbolicAddressSignature SASigMemDiscardM32;
    266 extern const SymbolicAddressSignature SASigMemDiscardSharedM32;
    267 extern const SymbolicAddressSignature SASigMemDiscardM64;
    268 extern const SymbolicAddressSignature SASigMemDiscardSharedM64;
    269 extern const SymbolicAddressSignature SASigMemInitM32;
    270 extern const SymbolicAddressSignature SASigMemInitM64;
    271 extern const SymbolicAddressSignature SASigTableCopy;
    272 extern const SymbolicAddressSignature SASigElemDrop;
    273 extern const SymbolicAddressSignature SASigTableFill;
    274 extern const SymbolicAddressSignature SASigTableGet;
    275 extern const SymbolicAddressSignature SASigTableGrow;
    276 extern const SymbolicAddressSignature SASigTableInit;
    277 extern const SymbolicAddressSignature SASigTableSet;
    278 extern const SymbolicAddressSignature SASigTableSize;
    279 extern const SymbolicAddressSignature SASigRefFunc;
    280 extern const SymbolicAddressSignature SASigPostBarrierEdge;
    281 extern const SymbolicAddressSignature SASigPostBarrierEdgePrecise;
    282 extern const SymbolicAddressSignature SASigPostBarrierWholeCell;
    283 extern const SymbolicAddressSignature SASigExceptionNew;
    284 extern const SymbolicAddressSignature SASigThrowException;
    285 extern const SymbolicAddressSignature SASigStructNewIL_true;
    286 extern const SymbolicAddressSignature SASigStructNewIL_false;
    287 extern const SymbolicAddressSignature SASigStructNewOOL_true;
    288 extern const SymbolicAddressSignature SASigStructNewOOL_false;
    289 extern const SymbolicAddressSignature SASigArrayNew_true;
    290 extern const SymbolicAddressSignature SASigArrayNew_false;
    291 extern const SymbolicAddressSignature SASigArrayNewData;
    292 extern const SymbolicAddressSignature SASigArrayNewElem;
    293 extern const SymbolicAddressSignature SASigArrayInitData;
    294 extern const SymbolicAddressSignature SASigArrayInitElem;
    295 extern const SymbolicAddressSignature SASigArrayCopy;
    296 extern const SymbolicAddressSignature SASigUpdateSuspenderState;
    297 #define VISIT_BUILTIN_FUNC(op, export, sa_name, ...) \
    298  extern const SymbolicAddressSignature SASig##sa_name;
    299 FOR_EACH_BUILTIN_MODULE_FUNC(VISIT_BUILTIN_FUNC)
    300 #undef VISIT_BUILTIN_FUNC
    301 
    302 bool IsRoundingFunction(SymbolicAddress callee, jit::RoundingMode* mode);
    303 
    304 // A SymbolicAddress that NeedsBuiltinThunk() will call through a thunk to the
    305 // C++ function. This will be true for all normal calls from normal wasm
    306 // function code. Only calls to C++ from other exits/thunks do not need a thunk.
    307 // See "The Wasm-builtin ABIs in WasmFrame.h".
    308 
    309 bool NeedsBuiltinThunk(SymbolicAddress sym);
    310 
    311 // Returns the ABI that needs to be used to call a builtin.
    312 inline jit::ABIKind ABIForBuiltin(SymbolicAddress sym) {
    313  // Builtin thunks use the WebAssembly ABI. See GenerateBuiltinThunk for more
    314  // information.
    315  if (NeedsBuiltinThunk(sym)) {
    316    return jit::ABIKind::Wasm;
    317  }
    318 
    319  // Otherwise non-thunked builtins use the System ABI directly.
    320  return jit::ABIKind::System;
    321 }
    322 
    323 // This function queries whether pc is in one of the process's builtin thunks
    324 // and, if so, returns the CodeRange and pointer to the code segment that the
    325 // CodeRange is relative to.
    326 
    327 bool LookupBuiltinThunk(void* pc, const CodeRange** codeRange,
    328                        const uint8_t** codeBase);
    329 
    330 // EnsureBuiltinThunksInitialized() must be called, and must succeed, before
    331 // SymbolicAddressTarget() or MaybeGetBuiltinThunk(). This function creates all
    332 // thunks for the process. ReleaseBuiltinThunks() should be called before
    333 // ReleaseProcessExecutableMemory() so that the latter can assert that all
    334 // executable code has been released.
    335 
    336 bool EnsureBuiltinThunksInitialized();
    337 bool EnsureBuiltinThunksInitialized(
    338    jit::AutoMarkJitCodeWritableForThread& writable);
    339 
    340 void HandleExceptionWasm(JSContext* cx, JitFrameIter& iter,
    341                         jit::ResumeFromException* rfe);
    342 
    343 void* SymbolicAddressTarget(SymbolicAddress sym);
    344 
    345 void* ProvisionalLazyJitEntryStub();
    346 
    347 void* MaybeGetTypedNative(JSFunction* f, const FuncType& funcType);
    348 
    349 void ReleaseBuiltinThunks();
    350 
    351 void* AddressOf(SymbolicAddress imm, jit::ABIFunctionType* abiType);
    352 
    353 #ifdef WASM_CODEGEN_DEBUG
    354 void PrintI32(int32_t val);
    355 void PrintF32(float val);
    356 void PrintF64(double val);
    357 void PrintPtr(uint8_t* val);
    358 void PrintText(const char* out);
    359 #endif
    360 
    361 }  // namespace wasm
    362 }  // namespace js
    363 
    364 #endif  // wasm_builtins_h