[SM91] Update to Spidermonkey 91.1.3 APIs
[0ad.git] / libraries / source / spidermonkey / include-win32-release / js / Utility.h
blobe649a64c502bec06dc8f520caea3c3b673cf7e9a
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 js_Utility_h
8 #define js_Utility_h
10 #include "mozilla/Assertions.h"
11 #include "mozilla/Atomics.h"
12 #include "mozilla/Attributes.h"
13 #include "mozilla/Compiler.h"
14 #include "mozilla/TemplateLib.h"
15 #include "mozilla/UniquePtr.h"
17 #include <stdlib.h>
18 #include <string.h>
19 #include <type_traits>
20 #include <utility>
22 #include "jstypes.h"
23 #include "mozmemory.h"
24 #include "js/TypeDecls.h"
26 /* The public JS engine namespace. */
27 namespace JS {}
29 /* The mozilla-shared reusable template/utility namespace. */
30 namespace mozilla {}
32 /* The private JS engine namespace. */
33 namespace js {}
35 extern MOZ_NORETURN MOZ_COLD JS_PUBLIC_API void JS_Assert(const char* s,
36 const char* file,
37 int ln);
40 * Custom allocator support for SpiderMonkey
42 #if defined JS_USE_CUSTOM_ALLOCATOR
43 # include "jscustomallocator.h"
44 #else
46 namespace js {
49 * Thread types are used to tag threads for certain kinds of testing (see
50 * below), and also used to characterize threads in the thread scheduler (see
51 * js/src/vm/HelperThreads.cpp).
53 * Please update oom::FirstThreadTypeToTest and oom::LastThreadTypeToTest when
54 * adding new thread types.
56 enum ThreadType {
57 THREAD_TYPE_NONE = 0, // 0
58 THREAD_TYPE_MAIN, // 1
59 THREAD_TYPE_WASM_COMPILE_TIER1, // 2
60 THREAD_TYPE_WASM_COMPILE_TIER2, // 3
61 THREAD_TYPE_ION, // 4
62 THREAD_TYPE_PARSE, // 5
63 THREAD_TYPE_COMPRESS, // 6
64 THREAD_TYPE_GCPARALLEL, // 7
65 THREAD_TYPE_PROMISE_TASK, // 8
66 THREAD_TYPE_ION_FREE, // 9
67 THREAD_TYPE_WASM_GENERATOR_TIER2, // 10
68 THREAD_TYPE_WORKER, // 11
69 THREAD_TYPE_MAX // Used to check shell function arguments
72 namespace oom {
75 * Theads are tagged only in certain debug contexts. Notably, to make testing
76 * OOM in certain helper threads more effective, we allow restricting the OOM
77 * testing to a certain helper thread type. This allows us to fail e.g. in
78 * off-thread script parsing without causing an OOM in the active thread first.
80 * Getter/Setter functions to encapsulate mozilla::ThreadLocal, implementation
81 * is in util/Utility.cpp.
83 # if defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
85 // Define the range of threads tested by simulated OOM testing and the
86 // like. Testing worker threads is not supported.
87 const ThreadType FirstThreadTypeToTest = THREAD_TYPE_MAIN;
88 const ThreadType LastThreadTypeToTest = THREAD_TYPE_WASM_GENERATOR_TIER2;
90 extern bool InitThreadType(void);
91 extern void SetThreadType(ThreadType);
92 extern JS_PUBLIC_API uint32_t GetThreadType(void);
94 # else
96 inline bool InitThreadType(void) { return true; }
97 inline void SetThreadType(ThreadType t){};
98 inline uint32_t GetThreadType(void) { return 0; }
99 inline uint32_t GetAllocationThreadType(void) { return 0; }
100 inline uint32_t GetStackCheckThreadType(void) { return 0; }
101 inline uint32_t GetInterruptCheckThreadType(void) { return 0; }
103 # endif
105 } /* namespace oom */
106 } /* namespace js */
108 # if defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
110 # ifdef JS_OOM_BREAKPOINT
111 # if defined(_MSC_VER)
112 static MOZ_NEVER_INLINE void js_failedAllocBreakpoint() {
113 __asm {}
116 # else
117 static MOZ_NEVER_INLINE void js_failedAllocBreakpoint() { asm(""); }
118 # endif
119 # define JS_OOM_CALL_BP_FUNC() js_failedAllocBreakpoint()
120 # else
121 # define JS_OOM_CALL_BP_FUNC() \
122 do { \
123 } while (0)
124 # endif
126 namespace js {
127 namespace oom {
130 * Out of memory testing support. We provide various testing functions to
131 * simulate OOM conditions and so we can test that they are handled correctly.
133 class FailureSimulator {
134 public:
135 enum class Kind : uint8_t { Nothing, OOM, StackOOM, Interrupt };
137 private:
138 Kind kind_ = Kind::Nothing;
139 uint32_t targetThread_ = 0;
140 uint64_t maxChecks_ = UINT64_MAX;
141 uint64_t counter_ = 0;
142 bool failAlways_ = true;
143 bool inUnsafeRegion_ = false;
145 public:
146 uint64_t maxChecks() const { return maxChecks_; }
147 uint64_t counter() const { return counter_; }
148 void setInUnsafeRegion(bool b) {
149 MOZ_ASSERT(inUnsafeRegion_ != b);
150 inUnsafeRegion_ = b;
152 uint32_t targetThread() const { return targetThread_; }
153 bool isThreadSimulatingAny() const {
154 return targetThread_ && targetThread_ == js::oom::GetThreadType() &&
155 !inUnsafeRegion_;
157 bool isThreadSimulating(Kind kind) const {
158 return kind_ == kind && isThreadSimulatingAny();
160 bool isSimulatedFailure(Kind kind) const {
161 if (!isThreadSimulating(kind)) {
162 return false;
164 return counter_ == maxChecks_ || (counter_ > maxChecks_ && failAlways_);
166 bool hadFailure(Kind kind) const {
167 return kind_ == kind && counter_ >= maxChecks_;
169 bool shouldFail(Kind kind) {
170 if (!isThreadSimulating(kind)) {
171 return false;
173 counter_++;
174 if (isSimulatedFailure(kind)) {
175 JS_OOM_CALL_BP_FUNC();
176 return true;
178 return false;
181 void simulateFailureAfter(Kind kind, uint64_t checks, uint32_t thread,
182 bool always);
183 void reset();
185 extern JS_PUBLIC_DATA FailureSimulator simulator;
187 inline bool IsSimulatedOOMAllocation() {
188 return simulator.isSimulatedFailure(FailureSimulator::Kind::OOM);
191 inline bool ShouldFailWithOOM() {
192 return simulator.shouldFail(FailureSimulator::Kind::OOM);
195 inline bool HadSimulatedOOM() {
196 return simulator.hadFailure(FailureSimulator::Kind::OOM);
200 * Out of stack space testing support, similar to OOM testing functions.
203 inline bool IsSimulatedStackOOMCheck() {
204 return simulator.isSimulatedFailure(FailureSimulator::Kind::StackOOM);
207 inline bool ShouldFailWithStackOOM() {
208 return simulator.shouldFail(FailureSimulator::Kind::StackOOM);
211 inline bool HadSimulatedStackOOM() {
212 return simulator.hadFailure(FailureSimulator::Kind::StackOOM);
216 * Interrupt testing support, similar to OOM testing functions.
219 inline bool IsSimulatedInterruptCheck() {
220 return simulator.isSimulatedFailure(FailureSimulator::Kind::Interrupt);
223 inline bool ShouldFailWithInterrupt() {
224 return simulator.shouldFail(FailureSimulator::Kind::Interrupt);
227 inline bool HadSimulatedInterrupt() {
228 return simulator.hadFailure(FailureSimulator::Kind::Interrupt);
231 } /* namespace oom */
232 } /* namespace js */
234 # define JS_OOM_POSSIBLY_FAIL() \
235 do { \
236 if (js::oom::ShouldFailWithOOM()) return nullptr; \
237 } while (0)
239 # define JS_OOM_POSSIBLY_FAIL_BOOL() \
240 do { \
241 if (js::oom::ShouldFailWithOOM()) return false; \
242 } while (0)
244 # define JS_STACK_OOM_POSSIBLY_FAIL() \
245 do { \
246 if (js::oom::ShouldFailWithStackOOM()) return false; \
247 } while (0)
249 # define JS_INTERRUPT_POSSIBLY_FAIL() \
250 do { \
251 if (MOZ_UNLIKELY(js::oom::ShouldFailWithInterrupt())) { \
252 cx->requestInterrupt(js::InterruptReason::CallbackUrgent); \
253 return cx->handleInterrupt(); \
255 } while (0)
257 # else
259 # define JS_OOM_POSSIBLY_FAIL() \
260 do { \
261 } while (0)
262 # define JS_OOM_POSSIBLY_FAIL_BOOL() \
263 do { \
264 } while (0)
265 # define JS_STACK_OOM_POSSIBLY_FAIL() \
266 do { \
267 } while (0)
268 # define JS_INTERRUPT_POSSIBLY_FAIL() \
269 do { \
270 } while (0)
271 namespace js {
272 namespace oom {
273 static inline bool IsSimulatedOOMAllocation() { return false; }
274 static inline bool ShouldFailWithOOM() { return false; }
275 } /* namespace oom */
276 } /* namespace js */
278 # endif /* DEBUG || JS_OOM_BREAKPOINT */
280 # ifdef FUZZING
281 namespace js {
282 namespace oom {
283 extern JS_PUBLIC_DATA size_t largeAllocLimit;
284 extern void InitLargeAllocLimit();
285 } /* namespace oom */
286 } /* namespace js */
288 # define JS_CHECK_LARGE_ALLOC(x) \
289 do { \
290 if (js::oom::largeAllocLimit && x > js::oom::largeAllocLimit) { \
291 if (getenv("MOZ_FUZZ_CRASH_ON_LARGE_ALLOC")) { \
292 MOZ_CRASH("Large allocation"); \
293 } else { \
294 return nullptr; \
297 } while (0)
298 # else
299 # define JS_CHECK_LARGE_ALLOC(x) \
300 do { \
301 } while (0)
302 # endif
304 namespace js {
306 /* Disable OOM testing in sections which are not OOM safe. */
307 struct MOZ_RAII JS_PUBLIC_DATA AutoEnterOOMUnsafeRegion {
308 MOZ_NORETURN MOZ_COLD void crash(const char* reason);
309 MOZ_NORETURN MOZ_COLD void crash(size_t size, const char* reason);
311 using AnnotateOOMAllocationSizeCallback = void (*)(size_t);
312 static mozilla::Atomic<AnnotateOOMAllocationSizeCallback, mozilla::Relaxed>
313 annotateOOMSizeCallback;
314 static void setAnnotateOOMAllocationSizeCallback(
315 AnnotateOOMAllocationSizeCallback callback) {
316 annotateOOMSizeCallback = callback;
319 # if defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
320 AutoEnterOOMUnsafeRegion()
321 : oomEnabled_(oom::simulator.isThreadSimulatingAny()) {
322 if (oomEnabled_) {
323 MOZ_ALWAYS_TRUE(owner_.compareExchange(nullptr, this));
324 oom::simulator.setInUnsafeRegion(true);
328 ~AutoEnterOOMUnsafeRegion() {
329 if (oomEnabled_) {
330 oom::simulator.setInUnsafeRegion(false);
331 MOZ_ALWAYS_TRUE(owner_.compareExchange(this, nullptr));
335 private:
336 // Used to catch concurrent use from other threads.
337 static mozilla::Atomic<AutoEnterOOMUnsafeRegion*> owner_;
339 bool oomEnabled_;
340 # endif
343 } /* namespace js */
345 // Malloc allocation.
347 namespace js {
349 extern JS_PUBLIC_DATA arena_id_t MallocArena;
350 extern JS_PUBLIC_DATA arena_id_t ArrayBufferContentsArena;
351 extern JS_PUBLIC_DATA arena_id_t StringBufferArena;
353 extern void InitMallocAllocator();
354 extern void ShutDownMallocAllocator();
356 // This is a no-op if built without MOZ_MEMORY and MOZ_DEBUG.
357 extern void AssertJSStringBufferInCorrectArena(const void* ptr);
359 } /* namespace js */
361 static inline void* js_arena_malloc(arena_id_t arena, size_t bytes) {
362 JS_OOM_POSSIBLY_FAIL();
363 JS_CHECK_LARGE_ALLOC(bytes);
364 return moz_arena_malloc(arena, bytes);
367 static inline void* js_malloc(size_t bytes) {
368 return js_arena_malloc(js::MallocArena, bytes);
371 static inline void* js_arena_calloc(arena_id_t arena, size_t bytes) {
372 JS_OOM_POSSIBLY_FAIL();
373 JS_CHECK_LARGE_ALLOC(bytes);
374 return moz_arena_calloc(arena, bytes, 1);
377 static inline void* js_arena_calloc(arena_id_t arena, size_t nmemb,
378 size_t size) {
379 JS_OOM_POSSIBLY_FAIL();
380 JS_CHECK_LARGE_ALLOC(nmemb * size);
381 return moz_arena_calloc(arena, nmemb, size);
384 static inline void* js_calloc(size_t bytes) {
385 return js_arena_calloc(js::MallocArena, bytes);
388 static inline void* js_calloc(size_t nmemb, size_t size) {
389 return js_arena_calloc(js::MallocArena, nmemb, size);
392 static inline void* js_arena_realloc(arena_id_t arena, void* p, size_t bytes) {
393 // realloc() with zero size is not portable, as some implementations may
394 // return nullptr on success and free |p| for this. We assume nullptr
395 // indicates failure and that |p| is still valid.
396 MOZ_ASSERT(bytes != 0);
398 JS_OOM_POSSIBLY_FAIL();
399 JS_CHECK_LARGE_ALLOC(bytes);
400 return moz_arena_realloc(arena, p, bytes);
403 static inline void* js_realloc(void* p, size_t bytes) {
404 return js_arena_realloc(js::MallocArena, p, bytes);
407 static inline void js_free(void* p) {
408 // TODO: This should call |moz_arena_free(js::MallocArena, p)| but we
409 // currently can't enforce that all memory freed here was allocated by
410 // js_malloc().
411 free(p);
413 #endif /* JS_USE_CUSTOM_ALLOCATOR */
415 #include <new>
418 * [SMDOC] Low-level memory management in SpiderMonkey
420 * ** Do not use the standard malloc/free/realloc: SpiderMonkey allows these
421 * to be redefined (via JS_USE_CUSTOM_ALLOCATOR) and Gecko even #define's
422 * these symbols.
424 * ** Do not use the builtin C++ operator new and delete: these throw on
425 * error and we cannot override them not to.
427 * Allocation:
429 * - If the lifetime of the allocation is tied to the lifetime of a GC-thing
430 * (that is, finalizing the GC-thing will free the allocation), call one of
431 * the following functions:
433 * JSContext::{pod_malloc,pod_calloc,pod_realloc}
434 * Zone::{pod_malloc,pod_calloc,pod_realloc}
436 * These functions accumulate the number of bytes allocated which is used as
437 * part of the GC-triggering heuristics.
439 * The difference between the JSContext and Zone versions is that the
440 * cx version report an out-of-memory error on OOM. (This follows from the
441 * general SpiderMonkey idiom that a JSContext-taking function reports its
442 * own errors.)
444 * If you don't want to report an error on failure, there are maybe_ versions
445 * of these methods available too, e.g. maybe_pod_malloc.
447 * The methods above use templates to allow allocating memory suitable for an
448 * array of a given type and number of elements. There are _with_extra
449 * versions to allow allocating an area of memory which is larger by a
450 * specified number of bytes, e.g. pod_malloc_with_extra.
452 * These methods are available on a JSRuntime, but calling them is
453 * discouraged. Memory attributed to a runtime can only be reclaimed by full
454 * GCs, and we try to avoid those where possible.
456 * - Otherwise, use js_malloc/js_realloc/js_calloc/js_new
458 * Deallocation:
460 * - Ordinarily, use js_free/js_delete.
462 * - For deallocations during GC finalization, use one of the following
463 * operations on the JSFreeOp provided to the finalizer:
465 * JSFreeOp::{free_,delete_}
469 * Given a class which should provide a 'new' method, add
470 * JS_DECLARE_NEW_METHODS (see js::MallocProvider for an example).
472 * Note: Do not add a ; at the end of a use of JS_DECLARE_NEW_METHODS,
473 * or the build will break.
475 #define JS_DECLARE_NEW_METHODS(NEWNAME, ALLOCATOR, QUALIFIERS) \
476 template <class T, typename... Args> \
477 QUALIFIERS T* MOZ_HEAP_ALLOCATOR NEWNAME(Args&&... args) { \
478 void* memory = ALLOCATOR(sizeof(T)); \
479 return MOZ_LIKELY(memory) ? new (memory) T(std::forward<Args>(args)...) \
480 : nullptr; \
484 * Given a class which should provide a 'new' method that takes an arena as
485 * its first argument, add JS_DECLARE_NEW_ARENA_METHODS
486 * (see js::MallocProvider for an example).
488 * Note: Do not add a ; at the end of a use of JS_DECLARE_NEW_ARENA_METHODS,
489 * or the build will break.
491 #define JS_DECLARE_NEW_ARENA_METHODS(NEWNAME, ALLOCATOR, QUALIFIERS) \
492 template <class T, typename... Args> \
493 QUALIFIERS T* MOZ_HEAP_ALLOCATOR NEWNAME(arena_id_t arena, Args&&... args) { \
494 void* memory = ALLOCATOR(arena, sizeof(T)); \
495 return MOZ_LIKELY(memory) ? new (memory) T(std::forward<Args>(args)...) \
496 : nullptr; \
500 * Given a class which should provide 'make' methods, add
501 * JS_DECLARE_MAKE_METHODS (see js::MallocProvider for an example). This
502 * method is functionally the same as JS_DECLARE_NEW_METHODS: it just declares
503 * methods that return mozilla::UniquePtr instances that will singly-manage
504 * ownership of the created object.
506 * Note: Do not add a ; at the end of a use of JS_DECLARE_MAKE_METHODS,
507 * or the build will break.
509 #define JS_DECLARE_MAKE_METHODS(MAKENAME, NEWNAME, QUALIFIERS) \
510 template <class T, typename... Args> \
511 QUALIFIERS mozilla::UniquePtr<T, JS::DeletePolicy<T>> MOZ_HEAP_ALLOCATOR \
512 MAKENAME(Args&&... args) { \
513 T* ptr = NEWNAME<T>(std::forward<Args>(args)...); \
514 return mozilla::UniquePtr<T, JS::DeletePolicy<T>>(ptr); \
517 JS_DECLARE_NEW_METHODS(js_new, js_malloc, static MOZ_ALWAYS_INLINE)
518 JS_DECLARE_NEW_ARENA_METHODS(js_arena_new, js_arena_malloc,
519 static MOZ_ALWAYS_INLINE)
521 namespace js {
524 * Calculate the number of bytes needed to allocate |numElems| contiguous
525 * instances of type |T|. Return false if the calculation overflowed.
527 template <typename T>
528 [[nodiscard]] inline bool CalculateAllocSize(size_t numElems,
529 size_t* bytesOut) {
530 *bytesOut = numElems * sizeof(T);
531 return (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) == 0;
535 * Calculate the number of bytes needed to allocate a single instance of type
536 * |T| followed by |numExtra| contiguous instances of type |Extra|. Return
537 * false if the calculation overflowed.
539 template <typename T, typename Extra>
540 [[nodiscard]] inline bool CalculateAllocSizeWithExtra(size_t numExtra,
541 size_t* bytesOut) {
542 *bytesOut = sizeof(T) + numExtra * sizeof(Extra);
543 return (numExtra & mozilla::tl::MulOverflowMask<sizeof(Extra)>::value) == 0 &&
544 *bytesOut >= sizeof(T);
547 } /* namespace js */
549 template <class T>
550 static MOZ_ALWAYS_INLINE void js_delete(const T* p) {
551 if (p) {
552 p->~T();
553 js_free(const_cast<T*>(p));
557 template <class T>
558 static MOZ_ALWAYS_INLINE void js_delete_poison(const T* p) {
559 if (p) {
560 p->~T();
561 memset(static_cast<void*>(const_cast<T*>(p)), 0x3B, sizeof(T));
562 js_free(const_cast<T*>(p));
566 template <class T>
567 static MOZ_ALWAYS_INLINE T* js_pod_arena_malloc(arena_id_t arena,
568 size_t numElems) {
569 size_t bytes;
570 if (MOZ_UNLIKELY(!js::CalculateAllocSize<T>(numElems, &bytes))) {
571 return nullptr;
573 return static_cast<T*>(js_arena_malloc(arena, bytes));
576 template <class T>
577 static MOZ_ALWAYS_INLINE T* js_pod_malloc(size_t numElems) {
578 return js_pod_arena_malloc<T>(js::MallocArena, numElems);
581 template <class T>
582 static MOZ_ALWAYS_INLINE T* js_pod_arena_calloc(arena_id_t arena,
583 size_t numElems) {
584 size_t bytes;
585 if (MOZ_UNLIKELY(!js::CalculateAllocSize<T>(numElems, &bytes))) {
586 return nullptr;
588 return static_cast<T*>(js_arena_calloc(arena, bytes, 1));
591 template <class T>
592 static MOZ_ALWAYS_INLINE T* js_pod_calloc(size_t numElems) {
593 return js_pod_arena_calloc<T>(js::MallocArena, numElems);
596 template <class T>
597 static MOZ_ALWAYS_INLINE T* js_pod_arena_realloc(arena_id_t arena, T* prior,
598 size_t oldSize,
599 size_t newSize) {
600 MOZ_ASSERT(!(oldSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value));
601 size_t bytes;
602 if (MOZ_UNLIKELY(!js::CalculateAllocSize<T>(newSize, &bytes))) {
603 return nullptr;
605 return static_cast<T*>(js_arena_realloc(arena, prior, bytes));
608 template <class T>
609 static MOZ_ALWAYS_INLINE T* js_pod_realloc(T* prior, size_t oldSize,
610 size_t newSize) {
611 return js_pod_arena_realloc<T>(js::MallocArena, prior, oldSize, newSize);
614 namespace JS {
616 template <typename T>
617 struct DeletePolicy {
618 constexpr DeletePolicy() = default;
620 template <typename U>
621 MOZ_IMPLICIT DeletePolicy(
622 DeletePolicy<U> other,
623 std::enable_if_t<std::is_convertible_v<U*, T*>, int> dummy = 0) {}
625 void operator()(const T* ptr) { js_delete(const_cast<T*>(ptr)); }
628 struct FreePolicy {
629 void operator()(const void* ptr) { js_free(const_cast<void*>(ptr)); }
632 typedef mozilla::UniquePtr<char[], JS::FreePolicy> UniqueChars;
633 typedef mozilla::UniquePtr<char16_t[], JS::FreePolicy> UniqueTwoByteChars;
634 typedef mozilla::UniquePtr<JS::Latin1Char[], JS::FreePolicy> UniqueLatin1Chars;
636 } // namespace JS
638 /* sixgill annotation defines */
639 #ifndef HAVE_STATIC_ANNOTATIONS
640 # define HAVE_STATIC_ANNOTATIONS
641 # ifdef XGILL_PLUGIN
642 # define STATIC_PRECONDITION(COND) __attribute__((precondition(# COND)))
643 # define STATIC_PRECONDITION_ASSUME(COND) \
644 __attribute__((precondition_assume(#COND)))
645 # define STATIC_POSTCONDITION(COND) __attribute__((postcondition(# COND)))
646 # define STATIC_POSTCONDITION_ASSUME(COND) \
647 __attribute__((postcondition_assume(#COND)))
648 # define STATIC_INVARIANT(COND) __attribute__((invariant(# COND)))
649 # define STATIC_INVARIANT_ASSUME(COND) \
650 __attribute__((invariant_assume(#COND)))
651 # define STATIC_ASSUME(COND) \
652 JS_BEGIN_MACRO \
653 __attribute__((assume_static(#COND), unused)) int STATIC_PASTE1( \
654 assume_static_, __COUNTER__); \
655 JS_END_MACRO
656 # else /* XGILL_PLUGIN */
657 # define STATIC_PRECONDITION(COND) /* nothing */
658 # define STATIC_PRECONDITION_ASSUME(COND) /* nothing */
659 # define STATIC_POSTCONDITION(COND) /* nothing */
660 # define STATIC_POSTCONDITION_ASSUME(COND) /* nothing */
661 # define STATIC_INVARIANT(COND) /* nothing */
662 # define STATIC_INVARIANT_ASSUME(COND) /* nothing */
663 # define STATIC_ASSUME(COND) \
664 JS_BEGIN_MACRO /* nothing */ \
665 JS_END_MACRO
666 # endif /* XGILL_PLUGIN */
667 # define STATIC_SKIP_INFERENCE STATIC_INVARIANT(skip_inference())
668 #endif /* HAVE_STATIC_ANNOTATIONS */
670 #endif /* js_Utility_h */