Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / js / src / jit / VMFunctions.h
bloba68dd8279f3d6c4857c85bbe91fb45ff9f40c773
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 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef jit_VMFunctions_h
8 #define jit_VMFunctions_h
10 #include "mozilla/Assertions.h"
11 #include "mozilla/HashFunctions.h"
13 #include <stddef.h>
14 #include <stdint.h>
16 #include "jstypes.h"
17 #include "NamespaceImports.h"
19 #include "gc/AllocKind.h"
20 #include "js/ScalarType.h"
21 #include "js/TypeDecls.h"
23 class JSJitInfo;
24 class JSLinearString;
26 namespace js {
28 class AbstractGeneratorObject;
29 class ArrayObject;
30 class GlobalObject;
31 class InterpreterFrame;
32 class LexicalScope;
33 class ClassBodyScope;
34 class MapObject;
35 class NativeObject;
36 class PlainObject;
37 class PropertyName;
38 class SetObject;
39 class Shape;
40 class TypedArrayObject;
41 class WithScope;
42 class MegamorphicCacheEntry;
44 namespace gc {
46 struct Cell;
48 } // namespace gc
50 namespace wasm {
52 class AnyRef;
54 } // namespace wasm
56 namespace jit {
58 class BaselineFrame;
59 class InterpreterStubExitFrameLayout;
61 enum DataType : uint8_t {
62 Type_Void,
63 Type_Bool,
64 Type_Int32,
65 Type_Double,
66 Type_Pointer,
67 Type_Cell,
68 Type_Value,
69 Type_Handle
72 // [SMDOC] JIT-to-C++ Function Calls. (callVM)
74 // Sometimes it is easier to reuse C++ code by calling VM's functions. Calling a
75 // function from the VM can be achieved with the use of callWithABI but this is
76 // discouraged when the called functions might trigger exceptions and/or
77 // garbage collections which are expecting to walk the stack. VMFunctions and
78 // callVM are interfaces provided to handle the exception handling and register
79 // the stack end (JITActivation) such that walking the stack is made possible.
81 // VMFunctionData is a structure which contains the necessary information needed
82 // for generating a trampoline function to make a call (with generateVMWrapper)
83 // and to root the arguments of the function (in TraceJitExitFrame).
84 // VMFunctionData is created with the VMFunctionDataHelper template, which
85 // infers the VMFunctionData fields from the function signature. The rooting and
86 // trampoline code is therefore determined by the arguments of a function and
87 // their locations in the signature of a function.
89 // VM functions all expect a JSContext* as first argument. This argument is
90 // implicitly provided by the trampoline code (in generateVMWrapper) and used
91 // for creating new objects or reporting errors. If your function does not make
92 // use of a JSContext* argument, then you might probably use a callWithABI
93 // call.
95 // Functions described using the VMFunction system must conform to a simple
96 // protocol: the return type must have a special "failure" value (for example,
97 // false for bool, or nullptr for Objects). If the function is designed to
98 // return a value that does not meet this requirement - such as
99 // object-or-nullptr, or an integer, an optional, final outParam can be
100 // specified. In this case, the return type must be boolean to indicate
101 // failure.
103 // JIT Code usage:
105 // Different JIT compilers in SpiderMonkey have their own implementations of
106 // callVM to call VM functions. However, the general shape of them is that
107 // arguments (excluding the JSContext or trailing out-param) are pushed on to
108 // the stack from right to left (rightmost argument is pushed first).
110 // Regardless of return value protocol being used (final outParam, or return
111 // value) the generated trampolines ensure the return value ends up in
112 // JSReturnOperand, ReturnReg or ReturnDoubleReg.
114 // Example:
116 // The details will differ slightly between the different compilers in
117 // SpiderMonkey, but the general shape of our usage looks like this:
119 // Suppose we have a function Foo:
121 // bool Foo(JSContext* cx, HandleObject x, HandleId y,
122 // MutableHandleValue z);
124 // This function returns true on success, and z is the outparam return value.
126 // A VM function wrapper for this can be created by adding an entry to
127 // VM_FUNCTION_LIST in VMFunctionList-inl.h:
129 // _(Foo, js::Foo)
131 // In the compiler code the call would then be issued like this:
133 // masm.Push(id);
134 // masm.Push(obj);
136 // using Fn = bool (*)(JSContext*, HandleObject, HandleId,
137 // MutableHandleValue);
138 // if (!callVM<Fn, js::Foo>()) {
139 // return false;
140 // }
142 // After this, the result value is in the return value register.
144 // Data for a VM function. All VMFunctionDatas are stored in a constexpr array.
145 struct VMFunctionData {
146 #if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_ION_PERF)
147 // Informative name of the wrapped function. The name should not be present
148 // in release builds in order to save memory.
149 const char* name_;
150 #endif
152 // Note: a maximum of seven root types is supported.
153 enum RootType : uint8_t {
154 RootNone = 0,
155 RootObject,
156 RootString,
157 RootId,
158 RootValue,
159 RootCell,
160 RootBigInt
163 // Contains an combination of enumerated types used by the gc for marking
164 // arguments of the VM wrapper.
165 uint64_t argumentRootTypes;
167 enum ArgProperties {
168 WordByValue = 0,
169 DoubleByValue = 1,
170 WordByRef = 2,
171 DoubleByRef = 3,
172 // BitMask version.
173 Word = 0,
174 Double = 1,
175 ByRef = 2
178 // Contains properties about the first 16 arguments.
179 uint32_t argumentProperties;
181 // Which arguments should be passed in float register on platforms that
182 // have them.
183 uint32_t argumentPassedInFloatRegs;
185 // Number of arguments expected, excluding JSContext * as an implicit
186 // first argument and an outparam as a possible implicit final argument.
187 uint8_t explicitArgs;
189 // The root type of the out param if outParam == Type_Handle.
190 RootType outParamRootType;
192 // The outparam may be any Type_*, and must be the final argument to the
193 // function, if not Void. outParam != Void implies that the return type
194 // has a boolean failure mode.
195 DataType outParam;
197 // Type returned by the C function and used by the VMFunction wrapper to
198 // check for failures of the C function. Valid failure/return types are
199 // boolean and object pointers which are asserted inside the VMFunction
200 // constructor. If the C function use an outparam (!= Type_Void), then
201 // the only valid failure/return type is boolean -- object pointers are
202 // pointless because the wrapper will only use it to compare it against
203 // nullptr before discarding its value.
204 DataType returnType;
206 // Number of Values the VM wrapper should pop from the stack when it returns.
207 // Used by baseline IC stubs so that they can use tail calls to call the VM
208 // wrapper.
209 uint8_t extraValuesToPop;
211 uint32_t argc() const {
212 // JSContext * + args + (OutParam? *)
213 return 1 + explicitArgc() + ((outParam == Type_Void) ? 0 : 1);
216 DataType failType() const { return returnType; }
218 // Whether this function returns anything more than a boolean flag for
219 // failures.
220 bool returnsData() const {
221 return returnType == Type_Cell || outParam != Type_Void;
224 ArgProperties argProperties(uint32_t explicitArg) const {
225 return ArgProperties((argumentProperties >> (2 * explicitArg)) & 3);
228 RootType argRootType(uint32_t explicitArg) const {
229 return RootType((argumentRootTypes >> (3 * explicitArg)) & 7);
232 bool argPassedInFloatReg(uint32_t explicitArg) const {
233 return ((argumentPassedInFloatRegs >> explicitArg) & 1) == 1;
236 #if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_ION_PERF)
237 const char* name() const { return name_; }
238 #endif
240 // Return the stack size consumed by explicit arguments.
241 size_t explicitStackSlots() const {
242 size_t stackSlots = explicitArgs;
244 // Fetch all double-word flags of explicit arguments.
245 uint32_t n = ((1 << (explicitArgs * 2)) - 1) // = Explicit argument mask.
246 & 0x55555555 // = Mask double-size args.
247 & argumentProperties;
249 // Add the number of double-word flags. (expect a few loop
250 // iteration)
251 while (n) {
252 stackSlots++;
253 n &= n - 1;
255 return stackSlots;
258 // Double-size argument which are passed by value are taking the space
259 // of 2 C arguments. This function is used to compute the number of
260 // argument expected by the C function. This is not the same as
261 // explicitStackSlots because reference to stack slots may take one less
262 // register in the total count.
263 size_t explicitArgc() const {
264 size_t stackSlots = explicitArgs;
266 // Fetch all explicit arguments.
267 uint32_t n = ((1 << (explicitArgs * 2)) - 1) // = Explicit argument mask.
268 & argumentProperties;
270 // Filter double-size arguments (0x5 = 0b0101) and remove (& ~)
271 // arguments passed by reference (0b1010 >> 1 == 0b0101).
272 n = (n & 0x55555555) & ~(n >> 1);
274 // Add the number of double-word transfered by value. (expect a few
275 // loop iteration)
276 while (n) {
277 stackSlots++;
278 n &= n - 1;
280 return stackSlots;
283 size_t doubleByRefArgs() const {
284 size_t count = 0;
286 // Fetch all explicit arguments.
287 uint32_t n = ((1 << (explicitArgs * 2)) - 1) // = Explicit argument mask.
288 & argumentProperties;
290 // Filter double-size arguments (0x5 = 0b0101) and take (&) only
291 // arguments passed by reference (0b1010 >> 1 == 0b0101).
292 n = (n & 0x55555555) & (n >> 1);
294 // Add the number of double-word transfered by refference. (expect a
295 // few loop iterations)
296 while (n) {
297 count++;
298 n &= n - 1;
300 return count;
303 size_t sizeOfOutParamStackSlot() const;
305 constexpr VMFunctionData(const char* name, uint32_t explicitArgs,
306 uint32_t argumentProperties,
307 uint32_t argumentPassedInFloatRegs,
308 uint64_t argRootTypes, DataType outParam,
309 RootType outParamRootType, DataType returnType,
310 uint8_t extraValuesToPop = 0)
312 #if defined(DEBUG) || defined(JS_JITSPEW) || defined(JS_ION_PERF)
313 name_(name),
314 #endif
315 argumentRootTypes(argRootTypes),
316 argumentProperties(argumentProperties),
317 argumentPassedInFloatRegs(argumentPassedInFloatRegs),
318 explicitArgs(explicitArgs),
319 outParamRootType(outParamRootType),
320 outParam(outParam),
321 returnType(returnType),
322 extraValuesToPop(extraValuesToPop) {
323 // Check for valid failure/return type.
324 MOZ_ASSERT_IF(outParam != Type_Void,
325 returnType == Type_Void || returnType == Type_Bool);
326 MOZ_ASSERT(returnType == Type_Void || returnType == Type_Bool ||
327 returnType == Type_Cell);
330 constexpr VMFunctionData(const VMFunctionData& o) = default;
333 // Extract the last element of a list of types.
334 template <typename... ArgTypes>
335 struct LastArg;
337 template <>
338 struct LastArg<> {
339 using Type = void;
342 template <typename HeadType>
343 struct LastArg<HeadType> {
344 using Type = HeadType;
347 template <typename HeadType, typename... TailTypes>
348 struct LastArg<HeadType, TailTypes...> {
349 using Type = typename LastArg<TailTypes...>::Type;
352 [[nodiscard]] bool InvokeFunction(JSContext* cx, HandleObject obj0,
353 bool constructing, bool ignoresReturnValue,
354 uint32_t argc, Value* argv,
355 MutableHandleValue rval);
357 bool InvokeFromInterpreterStub(JSContext* cx,
358 InterpreterStubExitFrameLayout* frame);
359 void* GetContextSensitiveInterpreterStub();
361 bool CheckOverRecursed(JSContext* cx);
362 bool CheckOverRecursedBaseline(JSContext* cx, BaselineFrame* frame);
364 [[nodiscard]] bool MutatePrototype(JSContext* cx, Handle<PlainObject*> obj,
365 HandleValue value);
367 enum class EqualityKind : bool { NotEqual, Equal };
369 template <EqualityKind Kind>
370 bool StringsEqual(JSContext* cx, HandleString lhs, HandleString rhs, bool* res);
372 enum class ComparisonKind : bool { GreaterThanOrEqual, LessThan };
374 template <ComparisonKind Kind>
375 bool StringsCompare(JSContext* cx, HandleString lhs, HandleString rhs,
376 bool* res);
378 JSString* ArrayJoin(JSContext* cx, HandleObject array, HandleString sep);
379 [[nodiscard]] bool SetArrayLength(JSContext* cx, HandleObject obj,
380 HandleValue value, bool strict);
382 [[nodiscard]] bool CharCodeAt(JSContext* cx, HandleString str, int32_t index,
383 uint32_t* code);
384 [[nodiscard]] bool CodePointAt(JSContext* cx, HandleString str, int32_t index,
385 uint32_t* code);
386 JSLinearString* StringFromCharCodeNoGC(JSContext* cx, int32_t code);
387 JSLinearString* LinearizeForCharAccessPure(JSString* str);
388 JSLinearString* LinearizeForCharAccess(JSContext* cx, JSString* str);
389 int32_t StringTrimStartIndex(const JSString* str);
390 int32_t StringTrimEndIndex(const JSString* str, int32_t start);
391 JSString* CharCodeToLowerCase(JSContext* cx, int32_t code);
392 JSString* CharCodeToUpperCase(JSContext* cx, int32_t code);
394 [[nodiscard]] bool SetProperty(JSContext* cx, HandleObject obj,
395 Handle<PropertyName*> name, HandleValue value,
396 bool strict, jsbytecode* pc);
398 [[nodiscard]] bool InterruptCheck(JSContext* cx);
400 JSObject* NewStringObject(JSContext* cx, HandleString str);
402 bool OperatorIn(JSContext* cx, HandleValue key, HandleObject obj, bool* out);
404 [[nodiscard]] bool GetIntrinsicValue(JSContext* cx, Handle<PropertyName*> name,
405 MutableHandleValue rval);
407 [[nodiscard]] bool CreateThisFromIC(JSContext* cx, HandleObject callee,
408 HandleObject newTarget,
409 MutableHandleValue rval);
410 [[nodiscard]] bool CreateThisFromIon(JSContext* cx, HandleObject callee,
411 HandleObject newTarget,
412 MutableHandleValue rval);
414 void PostWriteBarrier(JSRuntime* rt, js::gc::Cell* cell);
415 void PostGlobalWriteBarrier(JSRuntime* rt, GlobalObject* obj);
417 void PostWriteElementBarrier(JSRuntime* rt, JSObject* obj, int32_t index);
419 // If |str| represents an int32, assign it to |result| and return true.
420 // Otherwise return false.
421 bool GetInt32FromStringPure(JSContext* cx, JSString* str, int32_t* result);
423 // If |str| is an index in the range [0, INT32_MAX], return it. If the string
424 // is not an index in this range, return -1.
425 int32_t GetIndexFromString(JSString* str);
427 JSObject* WrapObjectPure(JSContext* cx, JSObject* obj);
429 [[nodiscard]] bool DebugPrologue(JSContext* cx, BaselineFrame* frame);
430 [[nodiscard]] bool DebugEpilogue(JSContext* cx, BaselineFrame* frame,
431 const jsbytecode* pc, bool ok);
432 [[nodiscard]] bool DebugEpilogueOnBaselineReturn(JSContext* cx,
433 BaselineFrame* frame,
434 const jsbytecode* pc);
435 void FrameIsDebuggeeCheck(BaselineFrame* frame);
437 JSObject* CreateGeneratorFromFrame(JSContext* cx, BaselineFrame* frame);
438 JSObject* CreateGenerator(JSContext* cx, HandleFunction, HandleScript,
439 HandleObject, HandleObject);
441 [[nodiscard]] bool NormalSuspend(JSContext* cx, HandleObject obj,
442 BaselineFrame* frame, uint32_t frameSize,
443 const jsbytecode* pc);
444 [[nodiscard]] bool FinalSuspend(JSContext* cx, HandleObject obj,
445 const jsbytecode* pc);
446 [[nodiscard]] bool InterpretResume(JSContext* cx, HandleObject obj,
447 Value* stackValues, MutableHandleValue rval);
448 [[nodiscard]] bool DebugAfterYield(JSContext* cx, BaselineFrame* frame);
449 [[nodiscard]] bool GeneratorThrowOrReturn(
450 JSContext* cx, BaselineFrame* frame,
451 Handle<AbstractGeneratorObject*> genObj, HandleValue arg,
452 int32_t resumeKindArg);
454 [[nodiscard]] bool GlobalDeclInstantiationFromIon(JSContext* cx,
455 HandleScript script,
456 const jsbytecode* pc);
457 [[nodiscard]] bool InitFunctionEnvironmentObjects(JSContext* cx,
458 BaselineFrame* frame);
460 [[nodiscard]] bool NewArgumentsObject(JSContext* cx, BaselineFrame* frame,
461 MutableHandleValue res);
463 ArrayObject* NewArrayObjectEnsureDenseInitLength(JSContext* cx, int32_t count);
465 ArrayObject* InitRestParameter(JSContext* cx, uint32_t length, Value* rest,
466 Handle<ArrayObject*> arrRes);
468 [[nodiscard]] bool HandleDebugTrap(JSContext* cx, BaselineFrame* frame,
469 const uint8_t* retAddr);
470 [[nodiscard]] bool OnDebuggerStatement(JSContext* cx, BaselineFrame* frame);
471 [[nodiscard]] bool GlobalHasLiveOnDebuggerStatement(JSContext* cx);
473 [[nodiscard]] bool EnterWith(JSContext* cx, BaselineFrame* frame,
474 HandleValue val, Handle<WithScope*> templ);
475 [[nodiscard]] bool LeaveWith(JSContext* cx, BaselineFrame* frame);
477 [[nodiscard]] bool PushLexicalEnv(JSContext* cx, BaselineFrame* frame,
478 Handle<LexicalScope*> scope);
479 [[nodiscard]] bool PushClassBodyEnv(JSContext* cx, BaselineFrame* frame,
480 Handle<ClassBodyScope*> scope);
481 [[nodiscard]] bool DebugLeaveThenPopLexicalEnv(JSContext* cx,
482 BaselineFrame* frame,
483 const jsbytecode* pc);
484 [[nodiscard]] bool FreshenLexicalEnv(JSContext* cx, BaselineFrame* frame);
485 [[nodiscard]] bool DebuggeeFreshenLexicalEnv(JSContext* cx,
486 BaselineFrame* frame,
487 const jsbytecode* pc);
488 [[nodiscard]] bool RecreateLexicalEnv(JSContext* cx, BaselineFrame* frame);
489 [[nodiscard]] bool DebuggeeRecreateLexicalEnv(JSContext* cx,
490 BaselineFrame* frame,
491 const jsbytecode* pc);
492 [[nodiscard]] bool DebugLeaveLexicalEnv(JSContext* cx, BaselineFrame* frame,
493 const jsbytecode* pc);
495 [[nodiscard]] bool PushVarEnv(JSContext* cx, BaselineFrame* frame,
496 Handle<Scope*> scope);
498 [[nodiscard]] bool InitBaselineFrameForOsr(BaselineFrame* frame,
499 InterpreterFrame* interpFrame,
500 uint32_t numStackValues);
502 JSString* StringReplace(JSContext* cx, HandleString string,
503 HandleString pattern, HandleString repl);
505 void AssertValidBigIntPtr(JSContext* cx, JS::BigInt* bi);
506 void AssertValidObjectPtr(JSContext* cx, JSObject* obj);
507 void AssertValidStringPtr(JSContext* cx, JSString* str);
508 void AssertValidSymbolPtr(JSContext* cx, JS::Symbol* sym);
509 void AssertValidValue(JSContext* cx, Value* v);
511 void JitValuePreWriteBarrier(JSRuntime* rt, Value* vp);
512 void JitStringPreWriteBarrier(JSRuntime* rt, JSString** stringp);
513 void JitObjectPreWriteBarrier(JSRuntime* rt, JSObject** objp);
514 void JitShapePreWriteBarrier(JSRuntime* rt, Shape** shapep);
515 void JitWasmAnyRefPreWriteBarrier(JSRuntime* rt, wasm::AnyRef* refp);
517 bool ObjectIsCallable(JSObject* obj);
518 bool ObjectIsConstructor(JSObject* obj);
519 JSObject* ObjectKeys(JSContext* cx, HandleObject obj);
520 bool ObjectKeysLength(JSContext* cx, HandleObject obj, int32_t* length);
522 [[nodiscard]] bool ThrowRuntimeLexicalError(JSContext* cx,
523 unsigned errorNumber);
525 [[nodiscard]] bool ThrowBadDerivedReturnOrUninitializedThis(JSContext* cx,
526 HandleValue v);
528 [[nodiscard]] bool BaselineGetFunctionThis(JSContext* cx, BaselineFrame* frame,
529 MutableHandleValue res);
531 [[nodiscard]] bool CallNativeGetter(JSContext* cx, HandleFunction callee,
532 HandleValue receiver,
533 MutableHandleValue result);
535 bool CallDOMGetter(JSContext* cx, const JSJitInfo* jitInfo, HandleObject obj,
536 MutableHandleValue result);
538 bool CallDOMSetter(JSContext* cx, const JSJitInfo* jitInfo, HandleObject obj,
539 HandleValue value);
541 [[nodiscard]] bool CallNativeSetter(JSContext* cx, HandleFunction callee,
542 HandleObject obj, HandleValue rhs);
544 [[nodiscard]] bool EqualStringsHelperPure(JSString* str1, JSString* str2);
546 void HandleCodeCoverageAtPC(BaselineFrame* frame, jsbytecode* pc);
547 void HandleCodeCoverageAtPrologue(BaselineFrame* frame);
549 bool CheckProxyGetByValueResult(JSContext* cx, HandleObject obj, HandleValue id,
550 HandleValue value, MutableHandleValue result);
552 bool GetNativeDataPropertyPure(JSContext* cx, JSObject* obj, PropertyKey id,
553 MegamorphicCacheEntry* entry, Value* vp);
555 bool GetNativeDataPropertyPureWithCacheLookup(JSContext* cx, JSObject* obj,
556 PropertyKey id,
557 MegamorphicCacheEntry* entry,
558 Value* vp);
560 bool GetNativeDataPropertyByValuePure(JSContext* cx, JSObject* obj,
561 MegamorphicCacheEntry* cacheEntry,
562 Value* vp);
564 template <bool HasOwn>
565 bool HasNativeDataPropertyPure(JSContext* cx, JSObject* obj,
566 MegamorphicCacheEntry* cacheEntry, Value* vp);
568 bool HasNativeElementPure(JSContext* cx, NativeObject* obj, int32_t index,
569 Value* vp);
571 bool ObjectHasGetterSetterPure(JSContext* cx, JSObject* objArg, jsid id,
572 GetterSetter* getterSetter);
574 template <bool Cached>
575 bool SetElementMegamorphic(JSContext* cx, HandleObject obj, HandleValue index,
576 HandleValue value, bool strict);
578 template <bool Cached>
579 bool SetPropertyMegamorphic(JSContext* cx, HandleObject obj, HandleId id,
580 HandleValue value, bool strict);
582 JSString* TypeOfNameObject(JSObject* obj, JSRuntime* rt);
584 bool GetPrototypeOf(JSContext* cx, HandleObject target,
585 MutableHandleValue rval);
587 bool DoConcatStringObject(JSContext* cx, HandleValue lhs, HandleValue rhs,
588 MutableHandleValue res);
590 bool IsPossiblyWrappedTypedArray(JSContext* cx, JSObject* obj, bool* result);
592 void* AllocateDependentString(JSContext* cx);
593 void* AllocateFatInlineString(JSContext* cx);
594 void* AllocateBigIntNoGC(JSContext* cx, bool requestMinorGC);
595 void AllocateAndInitTypedArrayBuffer(JSContext* cx, TypedArrayObject* obj,
596 int32_t count);
598 #ifdef JS_GC_PROBES
599 void TraceCreateObject(JSObject* obj);
600 #endif
602 bool DoStringToInt64(JSContext* cx, HandleString str, uint64_t* res);
604 #if JS_BITS_PER_WORD == 32
605 BigInt* CreateBigIntFromInt64(JSContext* cx, uint32_t low, uint32_t high);
606 BigInt* CreateBigIntFromUint64(JSContext* cx, uint32_t low, uint32_t high);
607 #else
608 BigInt* CreateBigIntFromInt64(JSContext* cx, uint64_t i64);
609 BigInt* CreateBigIntFromUint64(JSContext* cx, uint64_t i64);
610 #endif
612 template <EqualityKind Kind>
613 bool BigIntEqual(BigInt* x, BigInt* y);
615 template <ComparisonKind Kind>
616 bool BigIntCompare(BigInt* x, BigInt* y);
618 template <EqualityKind Kind>
619 bool BigIntNumberEqual(BigInt* x, double y);
621 template <ComparisonKind Kind>
622 bool BigIntNumberCompare(BigInt* x, double y);
624 template <ComparisonKind Kind>
625 bool NumberBigIntCompare(double x, BigInt* y);
627 template <EqualityKind Kind>
628 bool BigIntStringEqual(JSContext* cx, HandleBigInt x, HandleString y,
629 bool* res);
631 template <ComparisonKind Kind>
632 bool BigIntStringCompare(JSContext* cx, HandleBigInt x, HandleString y,
633 bool* res);
635 template <ComparisonKind Kind>
636 bool StringBigIntCompare(JSContext* cx, HandleString x, HandleBigInt y,
637 bool* res);
639 BigInt* BigIntAsIntN(JSContext* cx, HandleBigInt x, int32_t bits);
640 BigInt* BigIntAsUintN(JSContext* cx, HandleBigInt x, int32_t bits);
642 using AtomicsCompareExchangeFn = int32_t (*)(TypedArrayObject*, size_t, int32_t,
643 int32_t);
645 using AtomicsReadWriteModifyFn = int32_t (*)(TypedArrayObject*, size_t,
646 int32_t);
648 AtomicsCompareExchangeFn AtomicsCompareExchange(Scalar::Type elementType);
649 AtomicsReadWriteModifyFn AtomicsExchange(Scalar::Type elementType);
650 AtomicsReadWriteModifyFn AtomicsAdd(Scalar::Type elementType);
651 AtomicsReadWriteModifyFn AtomicsSub(Scalar::Type elementType);
652 AtomicsReadWriteModifyFn AtomicsAnd(Scalar::Type elementType);
653 AtomicsReadWriteModifyFn AtomicsOr(Scalar::Type elementType);
654 AtomicsReadWriteModifyFn AtomicsXor(Scalar::Type elementType);
656 BigInt* AtomicsLoad64(JSContext* cx, TypedArrayObject* typedArray,
657 size_t index);
659 void AtomicsStore64(TypedArrayObject* typedArray, size_t index,
660 const BigInt* value);
662 BigInt* AtomicsCompareExchange64(JSContext* cx, TypedArrayObject* typedArray,
663 size_t index, const BigInt* expected,
664 const BigInt* replacement);
666 BigInt* AtomicsExchange64(JSContext* cx, TypedArrayObject* typedArray,
667 size_t index, const BigInt* value);
669 BigInt* AtomicsAdd64(JSContext* cx, TypedArrayObject* typedArray, size_t index,
670 const BigInt* value);
671 BigInt* AtomicsAnd64(JSContext* cx, TypedArrayObject* typedArray, size_t index,
672 const BigInt* value);
673 BigInt* AtomicsOr64(JSContext* cx, TypedArrayObject* typedArray, size_t index,
674 const BigInt* value);
675 BigInt* AtomicsSub64(JSContext* cx, TypedArrayObject* typedArray, size_t index,
676 const BigInt* value);
677 BigInt* AtomicsXor64(JSContext* cx, TypedArrayObject* typedArray, size_t index,
678 const BigInt* value);
680 JSAtom* AtomizeStringNoGC(JSContext* cx, JSString* str);
682 bool SetObjectHas(JSContext* cx, HandleObject obj, HandleValue key, bool* rval);
683 bool MapObjectHas(JSContext* cx, HandleObject obj, HandleValue key, bool* rval);
684 bool MapObjectGet(JSContext* cx, HandleObject obj, HandleValue key,
685 MutableHandleValue rval);
687 void AssertSetObjectHash(JSContext* cx, SetObject* obj, const Value* value,
688 mozilla::HashNumber actualHash);
689 void AssertMapObjectHash(JSContext* cx, MapObject* obj, const Value* value,
690 mozilla::HashNumber actualHash);
692 void AssertPropertyLookup(NativeObject* obj, PropertyKey id, uint32_t slot);
694 // Functions used when JS_MASM_VERBOSE is enabled.
695 void AssumeUnreachable(const char* output);
696 void Printf0(const char* output);
697 void Printf1(const char* output, uintptr_t value);
699 enum class VMFunctionId;
701 extern const VMFunctionData& GetVMFunction(VMFunctionId id);
703 extern size_t NumVMFunctions();
705 } // namespace jit
706 } // namespace js
708 #if defined(JS_CODEGEN_ARM)
709 extern "C" {
710 extern MOZ_EXPORT int64_t __aeabi_idivmod(int, int);
711 extern MOZ_EXPORT int64_t __aeabi_uidivmod(int, int);
713 #endif
715 #endif /* jit_VMFunctions_h */