summaryrefslogtreecommitdiffstats
path: root/js/src/wasm/WasmBuiltins.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/wasm/WasmBuiltins.h')
-rw-r--r--js/src/wasm/WasmBuiltins.h324
1 files changed, 324 insertions, 0 deletions
diff --git a/js/src/wasm/WasmBuiltins.h b/js/src/wasm/WasmBuiltins.h
new file mode 100644
index 0000000000..0d876f439d
--- /dev/null
+++ b/js/src/wasm/WasmBuiltins.h
@@ -0,0 +1,324 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ *
+ * Copyright 2017 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef wasm_builtins_h
+#define wasm_builtins_h
+
+#include "intgemm/IntegerGemmIntrinsic.h"
+#include "jit/IonTypes.h"
+#include "wasm/WasmIntrinsicGenerated.h"
+
+namespace js {
+namespace jit {
+struct ResumeFromException;
+}
+namespace wasm {
+
+class WasmFrameIter;
+class CodeRange;
+class FuncType;
+
+// A wasm::SymbolicAddress represents a pointer to a well-known function/global
+// that is embedded in wasm code. Since wasm code is serialized and later
+// deserialized into a different address space, symbolic addresses must be used
+// for *all* pointers into the address space. The MacroAssembler records a list
+// of all SymbolicAddresses and the offsets of their use in the code for later
+// patching during static linking.
+
+enum class SymbolicAddress {
+ ToInt32,
+#if defined(JS_CODEGEN_ARM)
+ aeabi_idivmod,
+ aeabi_uidivmod,
+#endif
+ ModD,
+ SinNativeD,
+ SinFdlibmD,
+ CosNativeD,
+ CosFdlibmD,
+ TanNativeD,
+ TanFdlibmD,
+ ASinD,
+ ACosD,
+ ATanD,
+ CeilD,
+ CeilF,
+ FloorD,
+ FloorF,
+ TruncD,
+ TruncF,
+ NearbyIntD,
+ NearbyIntF,
+ ExpD,
+ LogD,
+ PowD,
+ ATan2D,
+ HandleDebugTrap,
+ HandleThrow,
+ HandleTrap,
+ ReportV128JSCall,
+ CallImport_General,
+ CoerceInPlace_ToInt32,
+ CoerceInPlace_ToNumber,
+ CoerceInPlace_JitEntry,
+ CoerceInPlace_ToBigInt,
+ AllocateBigInt,
+ BoxValue_Anyref,
+ DivI64,
+ UDivI64,
+ ModI64,
+ UModI64,
+ TruncateDoubleToInt64,
+ TruncateDoubleToUint64,
+ SaturatingTruncateDoubleToInt64,
+ SaturatingTruncateDoubleToUint64,
+ Uint64ToFloat32,
+ Uint64ToDouble,
+ Int64ToFloat32,
+ Int64ToDouble,
+ MemoryGrowM32,
+ MemoryGrowM64,
+ MemorySizeM32,
+ MemorySizeM64,
+ WaitI32M32,
+ WaitI32M64,
+ WaitI64M32,
+ WaitI64M64,
+ WakeM32,
+ WakeM64,
+ MemCopyM32,
+ MemCopySharedM32,
+ MemCopyM64,
+ MemCopySharedM64,
+ DataDrop,
+ MemFillM32,
+ MemFillSharedM32,
+ MemFillM64,
+ MemFillSharedM64,
+ MemDiscardM32,
+ MemDiscardSharedM32,
+ MemDiscardM64,
+ MemDiscardSharedM64,
+ MemInitM32,
+ MemInitM64,
+ TableCopy,
+ ElemDrop,
+ TableFill,
+ TableGet,
+ TableGrow,
+ TableInit,
+ TableSet,
+ TableSize,
+ RefFunc,
+ PostBarrier,
+ PostBarrierPrecise,
+ PostBarrierPreciseWithOffset,
+ ExceptionNew,
+ ThrowException,
+ StructNew,
+ StructNewUninit,
+ ArrayNew,
+ ArrayNewUninit,
+ ArrayNewData,
+ ArrayNewElem,
+ ArrayCopy,
+#define DECL_INTRINSIC_SA(op, export, sa_name, abitype, entry, idx) sa_name,
+ FOR_EACH_INTRINSIC(DECL_INTRINSIC_SA)
+#undef DECL_INTRINSIC_SA
+#ifdef WASM_CODEGEN_DEBUG
+ PrintI32,
+ PrintPtr,
+ PrintF32,
+ PrintF64,
+ PrintText,
+#endif
+ Limit
+};
+
+// The FailureMode indicates whether, immediately after a call to a builtin
+// returns, the return value should be checked against an error condition
+// (and if so, which one) which signals that the C++ calle has already
+// reported an error and thus wasm needs to wasmTrap(Trap::ThrowReported).
+
+enum class FailureMode : uint8_t {
+ Infallible,
+ FailOnNegI32,
+ FailOnNullPtr,
+ FailOnInvalidRef
+};
+
+// SymbolicAddressSignature carries type information for a function referred
+// to by a SymbolicAddress. In order that |argTypes| can be written out as a
+// static initialiser, it has to have fixed length. At present
+// SymbolicAddressType is used to describe functions with at most 14 arguments,
+// so |argTypes| has 15 entries in order to allow the last value to be
+// MIRType::None, in the hope of catching any accidental overruns of the
+// defined section of the array.
+
+static constexpr size_t SymbolicAddressSignatureMaxArgs = 14;
+
+struct SymbolicAddressSignature {
+ // The SymbolicAddress that is described.
+ const SymbolicAddress identity;
+ // The return type, or MIRType::None to denote 'void'.
+ const jit::MIRType retType;
+ // The failure mode, which is checked by masm.wasmCallBuiltinInstanceMethod.
+ const FailureMode failureMode;
+ // The number of arguments, 0 .. SymbolicAddressSignatureMaxArgs only.
+ const uint8_t numArgs;
+ // The argument types; SymbolicAddressSignatureMaxArgs + 1 guard, which
+ // should be MIRType::None.
+ const jit::MIRType argTypes[SymbolicAddressSignatureMaxArgs + 1];
+};
+
+// The 32 in this assertion is derived as follows: SymbolicAddress is probably
+// size-4 aligned-4, but it's at the start of the struct, so there's no
+// alignment hole before it. All other components (MIRType and uint8_t) are
+// size-1 aligned-1, and there are 18 in total, so it is reasonable to assume
+// that they also don't create any alignment holes. Hence it is also
+// reasonable to assume that the actual size is 1 * 4 + 18 * 1 == 22. The
+// worst-plausible-case rounding will take that up to 32. Hence, the
+// assertion uses 32.
+
+static_assert(sizeof(SymbolicAddressSignature) <= 32,
+ "SymbolicAddressSignature unexpectedly large");
+
+// These provide argument type information for a subset of the SymbolicAddress
+// targets, for which type info is needed to generate correct stackmaps.
+
+extern const SymbolicAddressSignature SASigSinNativeD;
+extern const SymbolicAddressSignature SASigSinFdlibmD;
+extern const SymbolicAddressSignature SASigCosNativeD;
+extern const SymbolicAddressSignature SASigCosFdlibmD;
+extern const SymbolicAddressSignature SASigTanNativeD;
+extern const SymbolicAddressSignature SASigTanFdlibmD;
+extern const SymbolicAddressSignature SASigASinD;
+extern const SymbolicAddressSignature SASigACosD;
+extern const SymbolicAddressSignature SASigATanD;
+extern const SymbolicAddressSignature SASigCeilD;
+extern const SymbolicAddressSignature SASigCeilF;
+extern const SymbolicAddressSignature SASigFloorD;
+extern const SymbolicAddressSignature SASigFloorF;
+extern const SymbolicAddressSignature SASigTruncD;
+extern const SymbolicAddressSignature SASigTruncF;
+extern const SymbolicAddressSignature SASigNearbyIntD;
+extern const SymbolicAddressSignature SASigNearbyIntF;
+extern const SymbolicAddressSignature SASigExpD;
+extern const SymbolicAddressSignature SASigLogD;
+extern const SymbolicAddressSignature SASigPowD;
+extern const SymbolicAddressSignature SASigATan2D;
+extern const SymbolicAddressSignature SASigMemoryGrowM32;
+extern const SymbolicAddressSignature SASigMemoryGrowM64;
+extern const SymbolicAddressSignature SASigMemorySizeM32;
+extern const SymbolicAddressSignature SASigMemorySizeM64;
+extern const SymbolicAddressSignature SASigWaitI32M32;
+extern const SymbolicAddressSignature SASigWaitI32M64;
+extern const SymbolicAddressSignature SASigWaitI64M32;
+extern const SymbolicAddressSignature SASigWaitI64M64;
+extern const SymbolicAddressSignature SASigWakeM32;
+extern const SymbolicAddressSignature SASigWakeM64;
+extern const SymbolicAddressSignature SASigMemCopyM32;
+extern const SymbolicAddressSignature SASigMemCopySharedM32;
+extern const SymbolicAddressSignature SASigMemCopyM64;
+extern const SymbolicAddressSignature SASigMemCopySharedM64;
+extern const SymbolicAddressSignature SASigDataDrop;
+extern const SymbolicAddressSignature SASigMemFillM32;
+extern const SymbolicAddressSignature SASigMemFillSharedM32;
+extern const SymbolicAddressSignature SASigMemFillM64;
+extern const SymbolicAddressSignature SASigMemFillSharedM64;
+extern const SymbolicAddressSignature SASigMemDiscardM32;
+extern const SymbolicAddressSignature SASigMemDiscardSharedM32;
+extern const SymbolicAddressSignature SASigMemDiscardM64;
+extern const SymbolicAddressSignature SASigMemDiscardSharedM64;
+extern const SymbolicAddressSignature SASigMemInitM32;
+extern const SymbolicAddressSignature SASigMemInitM64;
+extern const SymbolicAddressSignature SASigTableCopy;
+extern const SymbolicAddressSignature SASigElemDrop;
+extern const SymbolicAddressSignature SASigTableFill;
+extern const SymbolicAddressSignature SASigTableGet;
+extern const SymbolicAddressSignature SASigTableGrow;
+extern const SymbolicAddressSignature SASigTableInit;
+extern const SymbolicAddressSignature SASigTableSet;
+extern const SymbolicAddressSignature SASigTableSize;
+extern const SymbolicAddressSignature SASigRefFunc;
+extern const SymbolicAddressSignature SASigPostBarrier;
+extern const SymbolicAddressSignature SASigPostBarrierPrecise;
+extern const SymbolicAddressSignature SASigPostBarrierPreciseWithOffset;
+extern const SymbolicAddressSignature SASigExceptionNew;
+extern const SymbolicAddressSignature SASigThrowException;
+extern const SymbolicAddressSignature SASigStructNew;
+extern const SymbolicAddressSignature SASigStructNewUninit;
+extern const SymbolicAddressSignature SASigArrayNew;
+extern const SymbolicAddressSignature SASigArrayNewUninit;
+extern const SymbolicAddressSignature SASigArrayNewData;
+extern const SymbolicAddressSignature SASigArrayNewElem;
+extern const SymbolicAddressSignature SASigArrayCopy;
+#define EXT_INTR_SA_DECL(op, export, sa_name, abitype, entry, idx) \
+ extern const SymbolicAddressSignature SASig##sa_name;
+FOR_EACH_INTRINSIC(EXT_INTR_SA_DECL)
+#undef EXT_INTR_SA_DECL
+
+bool IsRoundingFunction(SymbolicAddress callee, jit::RoundingMode* mode);
+
+// A SymbolicAddress that NeedsBuiltinThunk() will call through a thunk to the
+// C++ function. This will be true for all normal calls from normal wasm
+// function code. Only calls to C++ from other exits/thunks do not need a thunk.
+// See "The Wasm-builtin ABIs in WasmFrame.h".
+
+bool NeedsBuiltinThunk(SymbolicAddress sym);
+
+// This function queries whether pc is in one of the process's builtin thunks
+// and, if so, returns the CodeRange and pointer to the code segment that the
+// CodeRange is relative to.
+
+bool LookupBuiltinThunk(void* pc, const CodeRange** codeRange,
+ uint8_t** codeBase);
+
+// EnsureBuiltinThunksInitialized() must be called, and must succeed, before
+// SymbolicAddressTarget() or MaybeGetBuiltinThunk(). This function creates all
+// thunks for the process. ReleaseBuiltinThunks() should be called before
+// ReleaseProcessExecutableMemory() so that the latter can assert that all
+// executable code has been released.
+
+bool EnsureBuiltinThunksInitialized();
+
+bool HandleThrow(JSContext* cx, WasmFrameIter& iter,
+ jit::ResumeFromException* rfe);
+
+void* SymbolicAddressTarget(SymbolicAddress sym);
+
+void* ProvisionalLazyJitEntryStub();
+
+void* MaybeGetBuiltinThunk(JSFunction* f, const FuncType& funcType);
+
+void ReleaseBuiltinThunks();
+
+void* AddressOf(SymbolicAddress imm, jit::ABIFunctionType* abiType);
+
+#ifdef WASM_CODEGEN_DEBUG
+void PrintI32(int32_t val);
+void PrintF32(float val);
+void PrintF64(double val);
+void PrintPtr(uint8_t* val);
+void PrintText(const char* out);
+#endif
+
+} // namespace wasm
+} // namespace js
+
+#endif // wasm_builtins_h