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:
4 * Copyright 2017 Mozilla Foundation
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #ifndef wasm_builtins_h
20 #define wasm_builtins_h
22 #include "intgemm/IntegerGemmIntrinsic.h"
23 #include "jit/IonTypes.h"
24 #include "wasm/WasmIntrinsicGenerated.h"
28 struct ResumeFromException
;
36 // A wasm::SymbolicAddress represents a pointer to a well-known function/global
37 // that is embedded in wasm code. Since wasm code is serialized and later
38 // deserialized into a different address space, symbolic addresses must be used
39 // for *all* pointers into the address space. The MacroAssembler records a list
40 // of all SymbolicAddresses and the offsets of their use in the code for later
41 // patching during static linking.
43 enum class SymbolicAddress
{
45 #if defined(JS_CODEGEN_ARM)
76 CoerceInPlace_ToInt32
,
77 CoerceInPlace_ToNumber
,
78 CoerceInPlace_JitEntry
,
79 CoerceInPlace_ToBigInt
,
86 TruncateDoubleToInt64
,
87 TruncateDoubleToUint64
,
88 SaturatingTruncateDoubleToInt64
,
89 SaturatingTruncateDoubleToUint64
,
131 PostBarrierPreciseWithOffset
,
145 #define DECL_INTRINSIC_SA(op, export, sa_name, abitype, entry, idx) sa_name,
146 FOR_EACH_INTRINSIC(DECL_INTRINSIC_SA
)
147 #undef DECL_INTRINSIC_SA
148 #ifdef WASM_CODEGEN_DEBUG
158 // The FailureMode indicates whether, immediately after a call to a builtin
159 // returns, the return value should be checked against an error condition
160 // (and if so, which one) which signals that the C++ calle has already
161 // reported an error and thus wasm needs to wasmTrap(Trap::ThrowReported).
163 enum class FailureMode
: uint8_t {
170 // SymbolicAddressSignature carries type information for a function referred
171 // to by a SymbolicAddress. In order that |argTypes| can be written out as a
172 // static initialiser, it has to have fixed length. At present
173 // SymbolicAddressType is used to describe functions with at most 14 arguments,
174 // so |argTypes| has 15 entries in order to allow the last value to be
175 // MIRType::None, in the hope of catching any accidental overruns of the
176 // defined section of the array.
178 static constexpr size_t SymbolicAddressSignatureMaxArgs
= 14;
180 struct SymbolicAddressSignature
{
181 // The SymbolicAddress that is described.
182 const SymbolicAddress identity
;
183 // The return type, or MIRType::None to denote 'void'.
184 const jit::MIRType retType
;
185 // The failure mode, which is checked by masm.wasmCallBuiltinInstanceMethod.
186 const FailureMode failureMode
;
187 // The number of arguments, 0 .. SymbolicAddressSignatureMaxArgs only.
188 const uint8_t numArgs
;
189 // The argument types; SymbolicAddressSignatureMaxArgs + 1 guard, which
190 // should be MIRType::None.
191 const jit::MIRType argTypes
[SymbolicAddressSignatureMaxArgs
+ 1];
194 // The 32 in this assertion is derived as follows: SymbolicAddress is probably
195 // size-4 aligned-4, but it's at the start of the struct, so there's no
196 // alignment hole before it. All other components (MIRType and uint8_t) are
197 // size-1 aligned-1, and there are 18 in total, so it is reasonable to assume
198 // that they also don't create any alignment holes. Hence it is also
199 // reasonable to assume that the actual size is 1 * 4 + 18 * 1 == 22. The
200 // worst-plausible-case rounding will take that up to 32. Hence, the
201 // assertion uses 32.
203 static_assert(sizeof(SymbolicAddressSignature
) <= 32,
204 "SymbolicAddressSignature unexpectedly large");
206 // These provide argument type information for a subset of the SymbolicAddress
207 // targets, for which type info is needed to generate correct stackmaps.
209 extern const SymbolicAddressSignature SASigSinNativeD
;
210 extern const SymbolicAddressSignature SASigSinFdlibmD
;
211 extern const SymbolicAddressSignature SASigCosNativeD
;
212 extern const SymbolicAddressSignature SASigCosFdlibmD
;
213 extern const SymbolicAddressSignature SASigTanNativeD
;
214 extern const SymbolicAddressSignature SASigTanFdlibmD
;
215 extern const SymbolicAddressSignature SASigASinD
;
216 extern const SymbolicAddressSignature SASigACosD
;
217 extern const SymbolicAddressSignature SASigATanD
;
218 extern const SymbolicAddressSignature SASigCeilD
;
219 extern const SymbolicAddressSignature SASigCeilF
;
220 extern const SymbolicAddressSignature SASigFloorD
;
221 extern const SymbolicAddressSignature SASigFloorF
;
222 extern const SymbolicAddressSignature SASigTruncD
;
223 extern const SymbolicAddressSignature SASigTruncF
;
224 extern const SymbolicAddressSignature SASigNearbyIntD
;
225 extern const SymbolicAddressSignature SASigNearbyIntF
;
226 extern const SymbolicAddressSignature SASigExpD
;
227 extern const SymbolicAddressSignature SASigLogD
;
228 extern const SymbolicAddressSignature SASigPowD
;
229 extern const SymbolicAddressSignature SASigATan2D
;
230 extern const SymbolicAddressSignature SASigMemoryGrowM32
;
231 extern const SymbolicAddressSignature SASigMemoryGrowM64
;
232 extern const SymbolicAddressSignature SASigMemorySizeM32
;
233 extern const SymbolicAddressSignature SASigMemorySizeM64
;
234 extern const SymbolicAddressSignature SASigWaitI32M32
;
235 extern const SymbolicAddressSignature SASigWaitI32M64
;
236 extern const SymbolicAddressSignature SASigWaitI64M32
;
237 extern const SymbolicAddressSignature SASigWaitI64M64
;
238 extern const SymbolicAddressSignature SASigWakeM32
;
239 extern const SymbolicAddressSignature SASigWakeM64
;
240 extern const SymbolicAddressSignature SASigMemCopyM32
;
241 extern const SymbolicAddressSignature SASigMemCopySharedM32
;
242 extern const SymbolicAddressSignature SASigMemCopyM64
;
243 extern const SymbolicAddressSignature SASigMemCopySharedM64
;
244 extern const SymbolicAddressSignature SASigMemCopyAny
;
245 extern const SymbolicAddressSignature SASigDataDrop
;
246 extern const SymbolicAddressSignature SASigMemFillM32
;
247 extern const SymbolicAddressSignature SASigMemFillSharedM32
;
248 extern const SymbolicAddressSignature SASigMemFillM64
;
249 extern const SymbolicAddressSignature SASigMemFillSharedM64
;
250 extern const SymbolicAddressSignature SASigMemDiscardM32
;
251 extern const SymbolicAddressSignature SASigMemDiscardSharedM32
;
252 extern const SymbolicAddressSignature SASigMemDiscardM64
;
253 extern const SymbolicAddressSignature SASigMemDiscardSharedM64
;
254 extern const SymbolicAddressSignature SASigMemInitM32
;
255 extern const SymbolicAddressSignature SASigMemInitM64
;
256 extern const SymbolicAddressSignature SASigTableCopy
;
257 extern const SymbolicAddressSignature SASigElemDrop
;
258 extern const SymbolicAddressSignature SASigTableFill
;
259 extern const SymbolicAddressSignature SASigTableGet
;
260 extern const SymbolicAddressSignature SASigTableGrow
;
261 extern const SymbolicAddressSignature SASigTableInit
;
262 extern const SymbolicAddressSignature SASigTableSet
;
263 extern const SymbolicAddressSignature SASigTableSize
;
264 extern const SymbolicAddressSignature SASigRefFunc
;
265 extern const SymbolicAddressSignature SASigPostBarrier
;
266 extern const SymbolicAddressSignature SASigPostBarrierPrecise
;
267 extern const SymbolicAddressSignature SASigPostBarrierPreciseWithOffset
;
268 extern const SymbolicAddressSignature SASigExceptionNew
;
269 extern const SymbolicAddressSignature SASigThrowException
;
270 extern const SymbolicAddressSignature SASigStructNewIL_true
;
271 extern const SymbolicAddressSignature SASigStructNewIL_false
;
272 extern const SymbolicAddressSignature SASigStructNewOOL_true
;
273 extern const SymbolicAddressSignature SASigStructNewOOL_false
;
274 extern const SymbolicAddressSignature SASigArrayNew_true
;
275 extern const SymbolicAddressSignature SASigArrayNew_false
;
276 extern const SymbolicAddressSignature SASigArrayNewData
;
277 extern const SymbolicAddressSignature SASigArrayNewElem
;
278 extern const SymbolicAddressSignature SASigArrayInitData
;
279 extern const SymbolicAddressSignature SASigArrayInitElem
;
280 extern const SymbolicAddressSignature SASigArrayCopy
;
281 #define EXT_INTR_SA_DECL(op, export, sa_name, abitype, entry, idx) \
282 extern const SymbolicAddressSignature SASig##sa_name;
283 FOR_EACH_INTRINSIC(EXT_INTR_SA_DECL
)
284 #undef EXT_INTR_SA_DECL
286 bool IsRoundingFunction(SymbolicAddress callee
, jit::RoundingMode
* mode
);
288 // A SymbolicAddress that NeedsBuiltinThunk() will call through a thunk to the
289 // C++ function. This will be true for all normal calls from normal wasm
290 // function code. Only calls to C++ from other exits/thunks do not need a thunk.
291 // See "The Wasm-builtin ABIs in WasmFrame.h".
293 bool NeedsBuiltinThunk(SymbolicAddress sym
);
295 // This function queries whether pc is in one of the process's builtin thunks
296 // and, if so, returns the CodeRange and pointer to the code segment that the
297 // CodeRange is relative to.
299 bool LookupBuiltinThunk(void* pc
, const CodeRange
** codeRange
,
302 // EnsureBuiltinThunksInitialized() must be called, and must succeed, before
303 // SymbolicAddressTarget() or MaybeGetBuiltinThunk(). This function creates all
304 // thunks for the process. ReleaseBuiltinThunks() should be called before
305 // ReleaseProcessExecutableMemory() so that the latter can assert that all
306 // executable code has been released.
308 bool EnsureBuiltinThunksInitialized();
310 bool HandleThrow(JSContext
* cx
, WasmFrameIter
& iter
,
311 jit::ResumeFromException
* rfe
);
313 void* SymbolicAddressTarget(SymbolicAddress sym
);
315 void* ProvisionalLazyJitEntryStub();
317 void* MaybeGetBuiltinThunk(JSFunction
* f
, const FuncType
& funcType
);
319 void ReleaseBuiltinThunks();
321 void* AddressOf(SymbolicAddress imm
, jit::ABIFunctionType
* abiType
);
323 #ifdef WASM_CODEGEN_DEBUG
324 void PrintI32(int32_t val
);
325 void PrintF32(float val
);
326 void PrintF64(double val
);
327 void PrintPtr(uint8_t* val
);
328 void PrintText(const char* out
);
334 #endif // wasm_builtins_h