diff --git a/include/AL/al.h b/include-old/AL/al.h similarity index 100% rename from include/AL/al.h rename to include-old/AL/al.h diff --git a/include/AL/alc.h b/include-old/AL/alc.h similarity index 100% rename from include/AL/alc.h rename to include-old/AL/alc.h diff --git a/include/AL/alext.h b/include-old/AL/alext.h similarity index 100% rename from include/AL/alext.h rename to include-old/AL/alext.h diff --git a/include/AL/efx-creative.h b/include-old/AL/efx-creative.h similarity index 100% rename from include/AL/efx-creative.h rename to include-old/AL/efx-creative.h diff --git a/include/AL/efx-presets.h b/include-old/AL/efx-presets.h similarity index 100% rename from include/AL/efx-presets.h rename to include-old/AL/efx-presets.h diff --git a/include/AL/efx.h b/include-old/AL/efx.h similarity index 100% rename from include/AL/efx.h rename to include-old/AL/efx.h diff --git a/include/espeak/speak_lib.h b/include-old/espeak/speak_lib.h similarity index 100% rename from include/espeak/speak_lib.h rename to include-old/espeak/speak_lib.h diff --git a/include/png.h b/include-old/png.h similarity index 100% rename from include/png.h rename to include-old/png.h diff --git a/include/pngconf.h b/include-old/pngconf.h similarity index 100% rename from include/pngconf.h rename to include-old/pngconf.h diff --git a/include/vorbis/codec.h b/include-old/vorbis/codec.h similarity index 100% rename from include/vorbis/codec.h rename to include-old/vorbis/codec.h diff --git a/include/vorbis/vorbisenc.h b/include-old/vorbis/vorbisenc.h similarity index 100% rename from include/vorbis/vorbisenc.h rename to include-old/vorbis/vorbisenc.h diff --git a/include/vorbis/vorbisfile.h b/include-old/vorbis/vorbisfile.h similarity index 100% rename from include/vorbis/vorbisfile.h rename to include-old/vorbis/vorbisfile.h diff --git a/include/zconf.h b/include-old/zconf.h similarity index 100% rename from include/zconf.h rename to include-old/zconf.h diff --git a/include/zlib.h b/include-old/zlib.h similarity index 100% rename from include/zlib.h rename to include-old/zlib.h diff --git a/include/zutil.h b/include-old/zutil.h similarity index 100% rename from include/zutil.h rename to include-old/zutil.h diff --git a/oolite.src b/oolite.src index 6012dc2..901bb20 100755 --- a/oolite.src +++ b/oolite.src @@ -52,7 +52,7 @@ export GNUSTEP_HOST_VENDOR=pc # export GNUSTEP_LOCAL_ROOT=${OOLITE_ROOT}/oolite-deps/GNUstep/Local export LD_LIBRARY_PATH=${OOLITE_ROOT}/oolite-deps/lib -export ESPEAK_DATA_PATH=${OOLITE_ROOT}/oolite.app/Resources/ +# export ESPEAK_DATA_PATH=${OOLITE_ROOT}/oolite.app/Resources/ cd ${OOLITE_ROOT}/ ./oolite.app/oolite "$@" diff --git a/x86/lib/libSDL-1.2.so.0 b/x86/lib/libSDL-1.2.so.0 deleted file mode 100755 index ff6ae8b..0000000 Binary files a/x86/lib/libSDL-1.2.so.0 and /dev/null differ diff --git a/x86/lib/libespeak.so.1 b/x86/lib/libespeak.so.1 deleted file mode 100755 index 496288d..0000000 Binary files a/x86/lib/libespeak.so.1 and /dev/null differ diff --git a/x86/lib/libespeak.so.1.pulseaudio b/x86/lib/libespeak.so.1.pulseaudio deleted file mode 100755 index eff9aa9..0000000 Binary files a/x86/lib/libespeak.so.1.pulseaudio and /dev/null differ diff --git a/x86/lib/libffi.so.4 b/x86/lib/libffi.so.4 deleted file mode 100644 index f0be56e..0000000 Binary files a/x86/lib/libffi.so.4 and /dev/null differ diff --git a/x86/lib/libgcrypt.so.20 b/x86/lib/libgcrypt.so.20 deleted file mode 100755 index ea0b258..0000000 Binary files a/x86/lib/libgcrypt.so.20 and /dev/null differ diff --git a/x86/lib/libgmp.so.10 b/x86/lib/libgmp.so.10 deleted file mode 100755 index 0c10613..0000000 Binary files a/x86/lib/libgmp.so.10 and /dev/null differ diff --git a/x86/lib/libgnustep-base.so.1.20 b/x86/lib/libgnustep-base.so.1.20 deleted file mode 100755 index d4bd42b..0000000 Binary files a/x86/lib/libgnustep-base.so.1.20 and /dev/null differ diff --git a/x86/lib/libgnutls.so.30 b/x86/lib/libgnutls.so.30 deleted file mode 100755 index 9a3c9d9..0000000 Binary files a/x86/lib/libgnutls.so.30 and /dev/null differ diff --git a/x86/lib/libgpg-error.so.0 b/x86/lib/libgpg-error.so.0 deleted file mode 100755 index eeba4c1..0000000 Binary files a/x86/lib/libgpg-error.so.0 and /dev/null differ diff --git a/x86/lib/libhogweed.so.4 b/x86/lib/libhogweed.so.4 deleted file mode 100755 index d613471..0000000 Binary files a/x86/lib/libhogweed.so.4 and /dev/null differ diff --git a/x86/lib/libnettle.so.6 b/x86/lib/libnettle.so.6 deleted file mode 100755 index b8c73e8..0000000 Binary files a/x86/lib/libnettle.so.6 and /dev/null differ diff --git a/x86/lib/libnsl.so.1 b/x86/lib/libnsl.so.1 deleted file mode 100644 index c9e93db..0000000 Binary files a/x86/lib/libnsl.so.1 and /dev/null differ diff --git a/x86/lib/libnspr4.so.0d b/x86/lib/libnspr4.so.0d deleted file mode 100644 index d35f18f..0000000 Binary files a/x86/lib/libnspr4.so.0d and /dev/null differ diff --git a/x86/lib/libobjc.so.2 b/x86/lib/libobjc.so.2 deleted file mode 100644 index f0f60d0..0000000 Binary files a/x86/lib/libobjc.so.2 and /dev/null differ diff --git a/x86/lib/libogg.so.0 b/x86/lib/libogg.so.0 deleted file mode 100755 index e4c17a9..0000000 Binary files a/x86/lib/libogg.so.0 and /dev/null differ diff --git a/x86/lib/libopenal.so.1 b/x86/lib/libopenal.so.1 deleted file mode 100755 index 26a609b..0000000 Binary files a/x86/lib/libopenal.so.1 and /dev/null differ diff --git a/x86/lib/libplc4.so.0d b/x86/lib/libplc4.so.0d deleted file mode 100644 index b60483b..0000000 Binary files a/x86/lib/libplc4.so.0d and /dev/null differ diff --git a/x86/lib/libplds4.so.0d b/x86/lib/libplds4.so.0d deleted file mode 100644 index 1d35ef2..0000000 Binary files a/x86/lib/libplds4.so.0d and /dev/null differ diff --git a/x86/lib/libpng14.so.14 b/x86/lib/libpng14.so.14 deleted file mode 100755 index 724cece..0000000 Binary files a/x86/lib/libpng14.so.14 and /dev/null differ diff --git a/x86/lib/libportaudio.so.2 b/x86/lib/libportaudio.so.2 deleted file mode 100755 index e958308..0000000 Binary files a/x86/lib/libportaudio.so.2 and /dev/null differ diff --git a/x86/lib/libvorbis.so.0 b/x86/lib/libvorbis.so.0 deleted file mode 100755 index a4bbbf8..0000000 Binary files a/x86/lib/libvorbis.so.0 and /dev/null differ diff --git a/x86/lib/libvorbisfile.so.3 b/x86/lib/libvorbisfile.so.3 deleted file mode 100755 index 423e3ee..0000000 Binary files a/x86/lib/libvorbisfile.so.3 and /dev/null differ diff --git a/x86/lib/libz.so.1 b/x86/lib/libz.so.1 deleted file mode 100755 index 87d4551..0000000 Binary files a/x86/lib/libz.so.1 and /dev/null differ diff --git a/x86/lib_linker/make_so_links.sh b/x86/lib_linker/make_so_links.sh deleted file mode 100755 index 7b7f892..0000000 --- a/x86/lib_linker/make_so_links.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh - -if ! [ -f 'libespeak.so' ]; then - ln -s ../lib/libespeak.so.1 libespeak.so -fi - -if ! [ -f 'libpng.so' ]; then - ln -s ../lib/libpng14.so.14 libpng.so -fi - -if ! [ -f 'libSDL.so' ]; then - ln -s ../lib/libSDL-1.2.so.0 libSDL.so -fi - -if ! [ -f 'libopenal.so' ]; then - ln -s ../lib/libopenal.so.1 libopenal.so -fi - -if ! [ -f 'libogg.so' ]; then - ln -s ../lib/libogg.so.0 libogg.so -fi - -if ! [ -f 'libvorbis.so' ]; then - ln -s ../lib/libvorbis.so.0 libvorbis.so -fi - -if ! [ -f 'libvorbisfile.so' ]; then - ln -s ../lib/libvorbisfile.so.3 libvorbisfile.so -fi - -if ! [ -f 'libz.so' ]; then - ln -s ../lib/libz.so.1 libz.so -fi - -exit; - diff --git a/x86/mozilla/include/Allocator.h b/x86/mozilla/include/Allocator.h deleted file mode 100644 index 8aab15f..0000000 --- a/x86/mozilla/include/Allocator.h +++ /dev/null @@ -1,140 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ -/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is [Open Source Virtual Machine]. - * - * The Initial Developer of the Original Code is - * Adobe System Incorporated. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Adobe AS3 Team - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef __nanojit_Allocator__ -#define __nanojit_Allocator__ - -namespace nanojit -{ - /** - * Allocator is a bump-pointer allocator with an SPI for getting more - * memory from embedder-implemented allocator, such as malloc()/free(). - * - * alloc() never returns NULL. The implementation of allocChunk() - * is expected to perform a longjmp or exception when an allocation can't - * proceed. fallibleAlloc() (and fallibleAllocChunk()) may return NULL. - * They should be used for large allocations whose failure can be handled - * without too much difficulty. - */ - class Allocator { - public: - Allocator(); - ~Allocator(); - - // Usable space in the minimum chunk size; there are also a few bytes - // used for administration. - static const size_t MIN_CHUNK_SZB = 2000; - - void reset(); - - /** alloc memory, never return null. */ - void* alloc(size_t nbytes) { - void* p; - nbytes = (nbytes + 7) & ~7; // round up - if (current_top + nbytes <= current_limit) { - p = current_top; - current_top += nbytes; - } else { - p = allocSlow(nbytes, /* fallible = */false); - NanoAssert(p); - } - return p; - } - - /** alloc memory, maybe return null. */ - void* fallibleAlloc(size_t nbytes) { - void* p; - nbytes = (nbytes + 7) & ~7; // round up - if (current_top + nbytes <= current_limit) { - p = current_top; - current_top += nbytes; - } else { - p = allocSlow(nbytes, /* fallible = */true); - } - return p; - } - - protected: - void* allocSlow(size_t nbytes, bool fallible = false); - bool fill(size_t minbytes, bool fallible); - - class Chunk { - public: - Chunk* prev; - int64_t data[1]; // int64_t forces 8-byte alignment. - }; - - Chunk* current_chunk; - char* current_top; - char* current_limit; - - // allocator SPI - - /** allocate another block from a host provided allocator */ - void* allocChunk(size_t nbytes, bool fallible); - - /** free back to the same allocator */ - void freeChunk(void*); - - /** hook for post-reset action. */ - void postReset(); - }; -} - -/** global new overload enabling this pattern: new (allocator) T(...) */ -inline void* operator new(size_t size, nanojit::Allocator &a) { - return a.alloc(size); -} - -/** global new overload enabling this pattern: new (allocator) T(...) */ -inline void* operator new(size_t size, nanojit::Allocator *a) { - return a->alloc(size); -} - -/** global new[] overload enabling this pattern: new (allocator) T[] */ -inline void* operator new[](size_t size, nanojit::Allocator& a) { - return a.alloc(size); -} - -/** global new[] overload enabling this pattern: new (allocator) T[] */ -inline void* operator new[](size_t size, nanojit::Allocator* a) { - return a->alloc(size); -} - -#endif // __nanojit_Allocator__ diff --git a/x86/mozilla/include/Assembler.h b/x86/mozilla/include/Assembler.h deleted file mode 100644 index a82d73c..0000000 --- a/x86/mozilla/include/Assembler.h +++ /dev/null @@ -1,553 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ -/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is [Open Source Virtual Machine]. - * - * The Initial Developer of the Original Code is - * Adobe System Incorporated. - * Portions created by the Initial Developer are Copyright (C) 2004-2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Adobe AS3 Team - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - - -#ifndef __nanojit_Assembler__ -#define __nanojit_Assembler__ - - -namespace nanojit -{ - /** - * Some notes on this Assembler (Emitter). - * - * The class RegAlloc is essentially the register allocator from MIR - * - * The Assembler class parses the LIR instructions starting at any point and converts - * them to machine code. It does the translation using expression trees which are simply - * LIR instructions in the stream that have side-effects. Any other instruction in the - * stream is simply ignored. - * This approach is interesting in that dead code elimination occurs for 'free', strength - * reduction occurs fairly naturally, along with some other optimizations. - * - * A negative is that we require state as we 'push' and 'pop' nodes along the tree. - * Also, this is most easily performed using recursion which may not be desirable in - * the mobile environment. - * - */ - - #define STACK_GRANULARITY sizeof(void *) - - // Basics: - // - 'entry' records the state of the native machine stack at particular - // points during assembly. Each entry represents four bytes. - // - // - Parts of the stack can be allocated by LIR_allocp, in which case each - // slot covered by the allocation contains a pointer to the LIR_allocp - // LIns. - // - // - The stack also holds spilled values, in which case each slot holding - // a spilled value (one slot for 32-bit values, two slots for 64-bit - // values) contains a pointer to the instruction defining the spilled - // value. - // - // - Each LIns has a "reservation" which includes a stack index, - // 'arIndex'. Combined with AR, it provides a two-way mapping between - // stack slots and LIR instructions. - // - // - Invariant: the two-way mapping between active stack slots and their - // defining/allocating instructions must hold in both directions and be - // unambiguous. More specifically: - // - // * An LIns can appear in at most one contiguous sequence of slots in - // AR, and the length of that sequence depends on the opcode (1 slot - // for instructions producing 32-bit values, 2 slots for instructions - // producing 64-bit values, N slots for LIR_allocp). - // - // * An LIns named by 'entry[i]' must have an in-use reservation with - // arIndex==i (or an 'i' indexing the start of the same contiguous - // sequence that 'entry[i]' belongs to). - // - // * And vice versa: an LIns with an in-use reservation with arIndex==i - // must be named by 'entry[i]'. - // - // * If an LIns's reservation names has arIndex==0 then LIns should not - // be in 'entry[]'. - // - class AR - { - private: - uint32_t _highWaterMark; /* index of highest entry used since last clear() */ - LIns* _entries[ NJ_MAX_STACK_ENTRY ]; /* maps to 4B contiguous locations relative to the frame pointer. - NB: _entries[0] is always unused */ - - #ifdef _DEBUG - static LIns* const BAD_ENTRY; - #endif - - bool isEmptyRange(uint32_t start, uint32_t nStackSlots) const; - static uint32_t nStackSlotsFor(LIns* ins); - - public: - AR(); - - uint32_t stackSlotsNeeded() const; - - void clear(); - void freeEntryAt(uint32_t i); - uint32_t reserveEntry(LIns* ins); /* return 0 if unable to reserve the entry */ - - #ifdef _DEBUG - void validateQuick(); - void validateFull(); - void validate(); - bool isValidEntry(uint32_t idx, LIns* ins) const; /* return true iff idx and ins are matched */ - void checkForResourceConsistency(const RegAlloc& regs); - void checkForResourceLeaks() const; - #endif - - class Iter - { - private: - const AR& _ar; - // '_i' points to the start of the entries for an LIns, or to the first NULL entry. - uint32_t _i; - public: - inline Iter(const AR& ar) : _ar(ar), _i(1) { } - bool next(LIns*& ins, uint32_t& nStackSlots, int32_t& offset); // get the next one (moves iterator forward) - }; - }; - - inline AR::AR() - { - _entries[0] = NULL; - clear(); - } - - inline /*static*/ uint32_t AR::nStackSlotsFor(LIns* ins) - { - uint32_t n = 0; - if (ins->isop(LIR_allocp)) { - n = ins->size() >> 2; - } else { - switch (ins->retType()) { - case LTy_I: n = 1; break; - CASE64(LTy_Q:) - case LTy_D: n = 2; break; - case LTy_V: NanoAssert(0); break; - default: NanoAssert(0); break; - } - } - return n; - } - - inline uint32_t AR::stackSlotsNeeded() const - { - // NB: _highWaterMark is an index, not a count - return _highWaterMark+1; - } - - #ifndef AVMPLUS_ALIGN16 - #ifdef _MSC_VER - #define AVMPLUS_ALIGN16(type) __declspec(align(16)) type - #else - #define AVMPLUS_ALIGN16(type) type __attribute__ ((aligned (16))) - #endif - #endif - - class Noise - { - public: - virtual ~Noise() {} - - // produce a random number from 0-maxValue for the JIT to use in attack mitigation - virtual uint32_t getValue(uint32_t maxValue) = 0; - }; - - // error codes - enum AssmError - { - None = 0 - ,StackFull - ,UnknownBranch - ,BranchTooFar - }; - - typedef SeqBuilder NInsList; - typedef HashMap NInsMap; -#if NJ_USES_IMMD_POOL - typedef HashMap ImmDPoolMap; -#endif - -#ifdef VMCFG_VTUNE - class avmplus::CodegenLIR; -#endif - - class LabelState - { - public: - RegAlloc regs; - NIns *addr; - LabelState(NIns *a, RegAlloc &r) : regs(r), addr(a) - {} - }; - - class LabelStateMap - { - Allocator& alloc; - HashMap labels; - public: - LabelStateMap(Allocator& alloc) : alloc(alloc), labels(alloc) - {} - - void clear() { labels.clear(); } - void add(LIns *label, NIns *addr, RegAlloc ®s); - LabelState *get(LIns *); - }; - - /** map tracking the register allocation state at each bailout point - * (represented by SideExit*) in a trace fragment. */ - typedef HashMap RegAllocMap; - - /** - * Information about the activation record for the method is built up - * as we generate machine code. As part of the prologue, we issue - * a stack adjustment instruction and then later patch the adjustment - * value. Temporary values can be placed into the AR as method calls - * are issued. Also LIR_allocp instructions will consume space. - */ - class Assembler - { - friend class VerboseBlockReader; - #ifdef NJ_VERBOSE - public: - // Buffer for holding text as we generate it in reverse order. - StringList* _outputCache; - - // Outputs the format string and 'outlineEOL', and resets - // 'outline' and 'outlineEOL'. - void outputf(const char* format, ...); - - private: - // Log controller object. Contains what-stuff-should-we-print - // bits, and a sink function for debug printing. - LogControl* _logc; - - // Buffer used in most of the output function. It must big enough - // to hold both the output line and the 'outlineEOL' buffer, which - // is concatenated onto 'outline' just before it is printed. - static char outline[8192]; - // Buffer used to hold extra text to be printed at the end of some - // lines. - static char outlineEOL[512]; - - // Outputs 'outline' and 'outlineEOL', and resets them both. - // Output goes to '_outputCache' if it's non-NULL, or is printed - // directly via '_logc'. - void output(); - - // Sets 'outlineEOL'. - void setOutputForEOL(const char* format, ...); - - void printRegState(); - void printActivationState(); - #endif // NJ_VERBOSE - - public: - #ifdef VMCFG_VTUNE - void* vtuneHandle; - #endif - - Assembler(CodeAlloc& codeAlloc, Allocator& dataAlloc, Allocator& alloc, AvmCore* core, LogControl* logc, const Config& config); - - void compile(Fragment *frag, Allocator& alloc, bool optimize - verbose_only(, LInsPrinter*)); - - void endAssembly(Fragment* frag); - void assemble(Fragment* frag, LirFilter* reader); - void beginAssembly(Fragment *frag); - - void setNoiseGenerator(Noise* noise) { _noise = noise; } // used for attack mitigation; setting to 0 disables all mitigations - - void releaseRegisters(); - void patch(GuardRecord *lr); - void patch(SideExit *exit); -#ifdef NANOJIT_IA32 - void patch(SideExit *exit, SwitchInfo* si); -#endif - AssmError error() { return _err; } - void setError(AssmError e) { _err = e; } - void cleanupAfterError(); - void clearNInsPtrs(); - void reset(); - - debug_only ( void pageValidate(); ) - - // support calling out from a fragment ; used to debug the jit - debug_only( void resourceConsistencyCheck(); ) - debug_only( void registerConsistencyCheck(); ) - - private: - void gen(LirFilter* toCompile); - NIns* genPrologue(); - NIns* genEpilogue(); - - uint32_t arReserve(LIns* ins); - void arFree(LIns* ins); - void arReset(); - - Register registerAlloc(LIns* ins, RegisterMask allow, RegisterMask prefer); - Register registerAllocTmp(RegisterMask allow); - void registerResetAll(); - void evictAllActiveRegs() { - // The evicted set will be be intersected with activeSet(), - // so use an all-1s mask to avoid an extra load or call. - evictSomeActiveRegs(~RegisterMask(0)); - } - void evictSomeActiveRegs(RegisterMask regs); - void evictScratchRegsExcept(RegisterMask ignore); - void intersectRegisterState(RegAlloc& saved); - void unionRegisterState(RegAlloc& saved); - void assignSaved(RegAlloc &saved, RegisterMask skip); - LIns* findVictim(RegisterMask allow); - - Register getBaseReg(LIns *ins, int &d, RegisterMask allow); - void getBaseReg2(RegisterMask allowValue, LIns* value, Register& rv, - RegisterMask allowBase, LIns* base, Register& rb, int &d); -#if NJ_USES_IMMD_POOL - const uint64_t* - findImmDFromPool(uint64_t q); -#endif - int findMemFor(LIns* ins); - Register findRegFor(LIns* ins, RegisterMask allow); - void findRegFor2(RegisterMask allowa, LIns* ia, Register &ra, - RegisterMask allowb, LIns *ib, Register &rb); - Register findSpecificRegFor(LIns* ins, Register r); - Register findSpecificRegForUnallocated(LIns* ins, Register r); - Register deprecated_prepResultReg(LIns *ins, RegisterMask allow); - Register prepareResultReg(LIns *ins, RegisterMask allow); - void deprecated_freeRsrcOf(LIns *ins); - void freeResourcesOf(LIns *ins); - void evictIfActive(Register r); - void evict(LIns* vic); - RegisterMask hint(LIns* ins); - - void getBaseIndexScale(LIns* addp, LIns** base, LIns** index, int* scale); - - void codeAlloc(NIns *&start, NIns *&end, NIns *&eip - verbose_only(, size_t &nBytes) - , size_t byteLimit=0); - - // These instructions don't have to be saved & reloaded to spill, - // they can just be recalculated cheaply. - // - // WARNING: this function must match asm_restore() -- it should return - // true for the instructions that are handled explicitly without a spill - // in asm_restore(), and false otherwise. - // - // If it doesn't match asm_restore(), the register allocator's decisions - // about which values to evict will be suboptimal. - static bool canRemat(LIns*); - - bool deprecated_isKnownReg(Register r) { - return r != deprecated_UnknownReg; - } - - Allocator& alloc; // for items with same lifetime as this Assembler - CodeAlloc& _codeAlloc; // for code we generate - Allocator& _dataAlloc; // for data used by generated code - Fragment* _thisfrag; - RegAllocMap _branchStateMap; - NInsMap _patches; - LabelStateMap _labels; - Noise* _noise; // object to generate random noise used when hardening enabled. - #if NJ_USES_IMMD_POOL - ImmDPoolMap _immDPool; - #endif - - // We generate code into two places: normal code chunks, and exit - // code chunks (for exit stubs). We use a hack to avoid having to - // parameterise the code that does the generating -- we let that - // code assume that it's always generating into a normal code - // chunk (most of the time it is), and when we instead need to - // generate into an exit code chunk, we set _inExit to true and - // temporarily swap all the code/exit variables below (using - // swapCodeChunks()). Afterwards we swap them all back and set - // _inExit to false again. - CodeList* codeList; // finished blocks of code. - bool _inExit, vpad2[3]; - NIns *codeStart, *codeEnd; // current normal code chunk - NIns *exitStart, *exitEnd; // current exit code chunk - NIns* _nIns; // current instruction in current normal code chunk - NIns* _nExitIns; // current instruction in current exit code chunk - // note: _nExitIns == NULL until the first side exit is seen. - #ifdef NJ_VERBOSE - NIns* _nInsAfter; // next instruction (ascending) in current normal/exit code chunk (for verbose output) - size_t codeBytes; // bytes allocated in normal code chunks - size_t exitBytes; // bytes allocated in exit code chunks - #endif - - #define SWAP(t, a, b) do { t tmp = a; a = b; b = tmp; } while (0) - void swapCodeChunks(); - - NIns* _epilogue; - AssmError _err; // 0 = means assemble() appears ok, otherwise it failed - #if PEDANTIC - NIns* pedanticTop; - #endif - - // Holds the current instruction during gen(). - LIns* currIns; - - AR _activation; - RegAlloc _allocator; - - verbose_only( void asm_inc_m32(uint32_t*); ) - void asm_mmq(Register rd, int dd, Register rs, int ds); - void asm_jmp(LIns* ins, InsList& pending_lives); - void asm_jcc(LIns* ins, InsList& pending_lives); - void asm_jov(LIns* ins, InsList& pending_lives); - void asm_x(LIns* ins); - void asm_xcc(LIns* ins); - NIns* asm_exit(LIns* guard); - NIns* asm_leave_trace(LIns* guard); - void asm_store32(LOpcode op, LIns *val, int d, LIns *base); - void asm_store64(LOpcode op, LIns *val, int d, LIns *base); - - // WARNING: the implementation of asm_restore() should emit fast code - // to rematerialize instructions where canRemat() returns true. - // Otherwise, register allocation decisions will be suboptimal. - void asm_restore(LIns*, Register); - - bool asm_maybe_spill(LIns* ins, bool pop); -#ifdef NANOJIT_IA32 - void asm_spill(Register rr, int d, bool pop); -#else - void asm_spill(Register rr, int d, bool quad); -#endif - void asm_load64(LIns* ins); - void asm_ret(LIns* ins); -#ifdef NANOJIT_64BIT - void asm_immq(LIns* ins); -#endif - void asm_immd(LIns* ins); - void asm_condd(LIns* ins); - void asm_cond(LIns* ins); - void asm_arith(LIns* ins); - void asm_neg_not(LIns* ins); - void asm_load32(LIns* ins); - void asm_cmov(LIns* ins); - void asm_param(LIns* ins); - void asm_immi(LIns* ins); -#if NJ_SOFTFLOAT_SUPPORTED - void asm_qlo(LIns* ins); - void asm_qhi(LIns* ins); - void asm_qjoin(LIns *ins); -#endif - void asm_fneg(LIns* ins); - void asm_fop(LIns* ins); - void asm_i2d(LIns* ins); - void asm_ui2d(LIns* ins); - void asm_d2i(LIns* ins); -#ifdef NANOJIT_64BIT - void asm_q2i(LIns* ins); - void asm_ui2uq(LIns *ins); - void asm_dasq(LIns *ins); - void asm_qasd(LIns *ins); -#endif - void asm_nongp_copy(Register r, Register s); - void asm_call(LIns*); - Register asm_binop_rhs_reg(LIns* ins); - NIns* asm_branch(bool branchOnFalse, LIns* cond, NIns* targ); - NIns* asm_branch_ov(LOpcode op, NIns* targ); - void asm_switch(LIns* ins, NIns* target); - void asm_jtbl(LIns* ins, NIns** table); - void asm_insert_random_nop(); - void emitJumpTable(SwitchInfo* si, NIns* target); - void assignSavedRegs(); - void reserveSavedRegs(); - void assignParamRegs(); - void handleLoopCarriedExprs(InsList& pending_lives); - - // platform specific implementation (see NativeXXX.cpp file) - void nInit(AvmCore *); - void nBeginAssembly(); - Register nRegisterAllocFromSet(RegisterMask set); - void nRegisterResetAll(RegAlloc& a); - void nPatchBranch(NIns* branch, NIns* location); - void nFragExit(LIns* guard); - - static RegisterMask nHints[LIR_sentinel+1]; - RegisterMask nHint(LIns* ins); - - // A special entry for hints[]; if an opcode has this value, we call - // nHint() in the back-end. Used for cases where you need to look at more - // than just the opcode to decide. - static const RegisterMask PREFER_SPECIAL = 0xffffffff; - - // platform specific methods - public: - const static Register savedRegs[NumSavedRegs+1]; // Allocate an extra element in case NumSavedRegs == 0 - DECLARE_PLATFORM_ASSEMBLER() - - private: -#ifdef NANOJIT_IA32 - debug_only( int32_t _fpuStkDepth; ) - debug_only( int32_t _sv_fpuStkDepth; ) - - // The FPU stack depth is the number of pushes in excess of the number of pops. - // Since we generate backwards, we track the FPU stack depth as a negative number. - // We use the top of the x87 stack as the single allocatable FP register, FST0. - // Thus, between LIR instructions, the depth of the FPU stack must be either 0 or -1, - // depending on whether FST0 is in use. Within the expansion of a single LIR - // instruction, however, deeper levels of the stack may be used as unmanaged - // temporaries. Hence, we allow for all eight levels in the assertions below. - inline void fpu_push() { - debug_only( ++_fpuStkDepth; NanoAssert(_fpuStkDepth <= 0); ) - } - inline void fpu_pop() { - debug_only( --_fpuStkDepth; NanoAssert(_fpuStkDepth >= -7); ) - } -#endif - const Config& _config; - }; - - inline int32_t arDisp(LIns* ins) - { - // even on 64bit cpu's, we allocate stack area in 4byte chunks - return -4 * int32_t(ins->getArIndex()); - } - // XXX: deprecated, use arDisp() instead. See bug 538924. - inline int32_t deprecated_disp(LIns* ins) - { - // even on 64bit cpu's, we allocate stack area in 4byte chunks - return -4 * int32_t(ins->deprecated_getArIndex()); - } -} -#endif // __nanojit_Assembler__ diff --git a/x86/mozilla/include/CodeAlloc.h b/x86/mozilla/include/CodeAlloc.h deleted file mode 100644 index b5cb2c6..0000000 --- a/x86/mozilla/include/CodeAlloc.h +++ /dev/null @@ -1,237 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ -/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is [Open Source Virtual Machine]. - * - * The Initial Developer of the Original Code is - * Adobe System Incorporated. - * Portions created by the Initial Developer are Copyright (C) 2004-2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Adobe AS3 Team - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef __nanojit_CodeAlloc__ -#define __nanojit_CodeAlloc__ - -namespace nanojit -{ - /** - * CodeList is a single block of code. The next field is used to - * form linked lists of non-contiguous blocks of code. Clients use CodeList* - * to point to the first block in a list. - */ - class CodeList - { - friend class CodeAlloc; - - /** for making singly linked lists of blocks in any order */ - CodeList* next; - - /** adjacent block at lower address. This field plus higher - form a doubly linked list of blocks in address order, used - for splitting and coalescing blocks. */ - CodeList* lower; - - /** pointer to the heapblock terminal that represents the code chunk containing this block */ - CodeList* terminator; - - /** true if block is free, false otherwise */ - bool isFree; - - /** (only valid for terminator blocks). Set true just before calling - * markCodeChunkExec() and false just after markCodeChunkWrite() */ - bool isExec; - - union { - // this union is used in leu of pointer punning in code - // the end of this block is always the address of the next higher block - CodeList* higher; // adjacent block at higher address - NIns* end; // points just past the end - }; - - /** code holds this block's payload of binary code, from - here to this->end */ - NIns code[1]; // more follows - - /** return the starting address for this block only */ - NIns* start() { return &code[0]; } - - /** return just the usable size of this block */ - size_t size() const { return uintptr_t(end) - uintptr_t(&code[0]); } - - /** return the whole size of this block including overhead */ - size_t blockSize() const { return uintptr_t(end) - uintptr_t(this); } - - public: - /** true is the given NIns is contained within this block */ - bool isInBlock(NIns* n) { return (n >= this->start() && n < this->end); } - }; - - /** - * Code memory allocator is a long lived manager for many code blocks that - * manages interaction with an underlying code memory allocator, - * sets page permissions. CodeAlloc provides APIs for allocating and freeing - * individual blocks of code memory (for methods, stubs, or compiled - * traces), static functions for managing lists of allocated code, and has - * a few pure virtual methods that embedders must implement to provide - * memory to the allocator. - * - * A "chunk" is a region of memory obtained from allocCodeChunk; it must - * be page aligned and be a multiple of the system page size. - * - * A "block" is a region of memory within a chunk. It can be arbitrarily - * sized and aligned, but is always contained within a single chunk. - * class CodeList represents one block; the members of CodeList track the - * extent of the block and support creating lists of blocks. - * - * The allocator coalesces free blocks when it can, in free(), but never - * coalesces chunks. - */ - class CodeAlloc - { - static const size_t sizeofMinBlock = offsetof(CodeList, code); - static const size_t minAllocSize = LARGEST_UNDERRUN_PROT; - - // Return the number of bytes needed for the header of 'n' blocks - static size_t headerSpaceFor(uint32_t nbrBlks) { return nbrBlks * sizeofMinBlock; } - - // Return the number of bytes needed in order to safely construct 'n' blocks - static size_t blkSpaceFor(uint32_t nbrBlks) { return (nbrBlks * minAllocSize) + headerSpaceFor(nbrBlks); } - - /** Terminator blocks. All active and free allocations - are reachable by traversing this chain and each - element's lower chain. */ - CodeList* heapblocks; - - /** Reusable blocks. */ - CodeList* availblocks; - size_t totalAllocated; - - /** Cached value of VMPI_getVMPageSize */ - const size_t bytesPerPage; - - /** Number of bytes to request from VMPI layer, always a multiple of the page size */ - const size_t bytesPerAlloc; - - /** remove one block from a list */ - static CodeList* removeBlock(CodeList* &list); - - /** add one block to a list */ - static void addBlock(CodeList* &blocks, CodeList* b); - - /** compute the CodeList pointer from a [start, end) range */ - static CodeList* getBlock(NIns* start, NIns* end); - - /** add raw memory to the free list */ - void addMem(); - - /** make sure all the higher/lower pointers are correct for every block */ - void sanity_check(); - - /** find the beginning of the heapblock terminated by term */ - CodeList* firstBlock(CodeList* term); - - // - // CodeAlloc's SPI (Service Provider Interface). Implementations must be - // defined by nanojit embedder. Allocation failures should cause an exception - // or longjmp; nanojit intentionally does not check for null. - // - - /** allocate nbytes of memory to hold code. Never return null! */ - void* allocCodeChunk(size_t nbytes); - - /** free a block previously allocated by allocCodeMem. nbytes will - * match the previous allocCodeMem, but is provided here as well - * to mirror the mmap()/munmap() api. markCodeChunkWrite() will have - * been called if necessary, so it is not necessary for freeCodeChunk() - * to do it again. */ - void freeCodeChunk(void* addr, size_t nbytes); - - /** make this specific extent ready to execute (might remove write) */ - void markCodeChunkExec(void* addr, size_t nbytes); - - /** make this extent ready to modify (might remove exec) */ - void markCodeChunkWrite(void* addr, size_t nbytes); - - public: - CodeAlloc(); - ~CodeAlloc(); - - /** return all the memory allocated through this allocator to the gcheap. */ - void reset(); - - /** allocate some memory (up to 'byteLimit' bytes) for code returning pointers to the region. A zero 'byteLimit' means no limit */ - void alloc(NIns* &start, NIns* &end, size_t byteLimit); - - /** free a block of memory previously returned by alloc() */ - void free(NIns* start, NIns* end); - - /** free several blocks */ - void freeAll(CodeList* &code); - - /** flush the icache for all code in the list, before executing */ - static void flushICache(CodeList* &blocks); - - /** flush the icache for a specific extent */ - static void flushICache(void *start, size_t len); - - /** add the ranges [start, holeStart) and [holeEnd, end) to code, and - free [holeStart, holeEnd) if the hole is >= minsize */ - void addRemainder(CodeList* &code, NIns* start, NIns* end, NIns* holeStart, NIns* holeEnd); - - /** add a block previously returned by alloc(), to code */ - static void add(CodeList* &code, NIns* start, NIns* end); - - /** return the number of bytes in all the code blocks in "code", including block overhead */ -#ifdef PERFM - static size_t size(const CodeList* code); -#endif - - /** return the total number of bytes held by this CodeAlloc. */ - size_t size(); - - /** print out stats about heap usage */ - void logStats(); - - /** protect all code managed by this CodeAlloc */ - void markAllExec(); - - /** protect all mem in the block list */ - void markExec(CodeList* &blocks); - - /** protect an entire chunk */ - void markChunkExec(CodeList* term); - - /** unprotect the code chunk containing just this one block */ - void markBlockWrite(CodeList* b); - }; -} - -#endif // __nanojit_CodeAlloc__ diff --git a/x86/mozilla/include/Containers.h b/x86/mozilla/include/Containers.h deleted file mode 100644 index cd4fe66..0000000 --- a/x86/mozilla/include/Containers.h +++ /dev/null @@ -1,465 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ -/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is [Open Source Virtual Machine]. - * - * The Initial Developer of the Original Code is - * Adobe System Incorporated. - * Portions created by the Initial Developer are Copyright (C) 2004-2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Adobe AS3 Team - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef __nanojit_Containers__ -#define __nanojit_Containers__ - -namespace nanojit -{ - /** simple linear bit array, memory taken from Allocator - * warning: when bit array grows, old memory is wasted since it - * was allocated from Allocator. pre-size the bitmap when possible - * by passing nbits to the constructor. */ - class BitSet { - Allocator &allocator; - int cap; - int64_t *bits; - static const int64_t ONE = 1; - static const int SHIFT = 6; - - inline int bitnum2word(int i) { - return i >> 6; - } - inline int64_t bitnum2mask(int i) { - return ONE << (i & 63); - } - - /** keep doubling array to fit at least w words */ - void grow(int w); - - public: - BitSet(Allocator& allocator, int nbits=128); - - /** clear all bits */ - void reset(); - - /** perform a bitwise or with BitSet other, return true if - * this bitset was modified */ - bool setFrom(BitSet& other); - - /** return bit i as a bool */ - bool get(int i) { - NanoAssert(i >= 0); - int w = bitnum2word(i); - if (w < cap) - return (bits[w] & bitnum2mask(i)) != 0; - return false; - } - - /** set bit i */ - void set(int i) { - NanoAssert(i >= 0); - int w = bitnum2word(i); - if (w >= cap) - grow(w); - bits[w] |= bitnum2mask(i); - } - - /** clear bit i */ - void clear(int i) { - NanoAssert(i >= 0); - int w = bitnum2word(i); - if (w < cap) - bits[w] &= ~bitnum2mask(i); - } - }; - - /** Seq is a single node in a linked list */ - template class Seq { - public: - Seq(T head, Seq* tail=NULL) : head(head), tail(tail) {} - T head; - Seq* tail; - }; - - /** SeqBuilder is used to create a linked list of Seq by inserting - * nodes either at the beginning, with insert(), or at the end, with - * add(). Once built, the actual list can be retained while this - * SeqBuilder can be discarded. */ - template class SeqBuilder { - public: - SeqBuilder(Allocator& allocator) - : allocator(allocator) - , items(NULL) - , last(NULL) - { } - - /** add item to beginning of list */ - void insert(T item) { - Seq* e = new (allocator) Seq(item, items); - if (last == NULL) - last = e; - items = e; - } - - /** add item to end of list */ - void add(T item) { - Seq* e = new (allocator) Seq(item); - if (last == NULL) - items = e; - else - last->tail = e; - last = e; - } - - /** return first item in sequence */ - Seq* get() const { - return items; - } - - /** self explanitory */ - bool isEmpty() const { - return items == NULL; - } - - /** de-reference all items */ - void clear() { - items = last = NULL; - } - - private: - Allocator& allocator; - Seq* items; - Seq* last; - }; - -#ifdef NANOJIT_64BIT - static inline size_t murmurhash(const void *key, size_t len) { - const uint64_t m = 0xc6a4a7935bd1e995; - const int r = 47; - uint64_t h = 0; - - const uint64_t *data = (const uint64_t*)key; - const uint64_t *end = data + (len/8); - - while(data != end) - { - uint64_t k = *data++; - - k *= m; - k ^= k >> r; - k *= m; - - h ^= k; - h *= m; - } - - const unsigned char *data2 = (const unsigned char*)data; - - switch(len & 7) { - case 7: h ^= uint64_t(data2[6]) << 48; - case 6: h ^= uint64_t(data2[5]) << 40; - case 5: h ^= uint64_t(data2[4]) << 32; - case 4: h ^= uint64_t(data2[3]) << 24; - case 3: h ^= uint64_t(data2[2]) << 16; - case 2: h ^= uint64_t(data2[1]) << 8; - case 1: h ^= uint64_t(data2[0]); - h *= m; - }; - - h ^= h >> r; - h *= m; - h ^= h >> r; - - return (size_t)h; - } -#else - static inline size_t murmurhash(const void * key, size_t len) { - const uint32_t m = 0x5bd1e995; - const int r = 24; - uint32_t h = 0; - - const unsigned char * data = (const unsigned char *)key; - while(len >= 4) { - uint32_t k = *(size_t *)(void*)data; - - k *= m; - k ^= k >> r; - k *= m; - - h *= m; - h ^= k; - - data += 4; - len -= 4; - } - - switch(len) { - case 3: h ^= data[2] << 16; - case 2: h ^= data[1] << 8; - case 1: h ^= data[0]; - h *= m; - }; - - h ^= h >> 13; - h *= m; - h ^= h >> 15; - - return (size_t)h; - } -#endif - - template struct DefaultHash { - static size_t hash(const K &k) { - // (const void*) cast is required by ARM RVCT 2.2 - return murmurhash((const void*) &k, sizeof(K)); - } - }; - - template struct DefaultHash { - static size_t hash(K* k) { - uintptr_t h = (uintptr_t) k; - // move the low 3 bits higher up since they're often 0 - h = (h>>3) ^ (h<<((sizeof(uintptr_t) * 8) - 3)); - return (size_t) h; - } - }; - - /** Bucket hashtable with a fixed # of buckets (never rehash) - * Intended for use when a reasonable # of buckets can be estimated ahead of time. - * Note that operator== is used to compare keys. - */ - template > class HashMap { - Allocator& allocator; - size_t nbuckets; - class Node { - public: - K key; - T value; - Node(K k, T v) : key(k), value(v) { } - }; - Seq** buckets; - - /** return the node containing K, and the bucket index, or NULL if not found */ - Node* find(K k, size_t &i) { - i = H::hash(k) % nbuckets; - for (Seq* p = buckets[i]; p != NULL; p = p->tail) { - if (p->head.key == k) - return &p->head; - } - return NULL; - } - public: - HashMap(Allocator& a, size_t nbuckets = 16) - : allocator(a) - , nbuckets(nbuckets) - , buckets(new (a) Seq*[nbuckets]) - { - NanoAssert(nbuckets > 0); - clear(); - } - - /** clear all buckets. Since we allocate all memory from Allocator, - * nothing needs to be freed. */ - void clear() { - VMPI_memset(buckets, 0, sizeof(Seq*) * nbuckets); - } - - /** add (k,v) to the map. If k is already in the map, replace the value */ - void put(const K& k, const T& v) { - size_t i; - Node* n = find(k, i); - if (n) { - n->value = v; - return; - } - buckets[i] = new (allocator) Seq(Node(k,v), buckets[i]); - } - - /** return v for element k, or T(0) if k is not present */ - T get(const K& k) { - size_t i; - Node* n = find(k, i); - return n ? n->value : 0; - } - - /** returns true if k is in the map. */ - bool containsKey(const K& k) { - size_t i; - return find(k, i) != 0; - } - - /** remove k from the map, if it is present. if not, remove() - * silently returns */ - void remove(const K& k) { - size_t i = H::hash(k) % nbuckets; - Seq** prev = &buckets[i]; - for (Seq* p = buckets[i]; p != NULL; p = p->tail) { - if (p->head.key == k) { - (*prev) = p->tail; - return; - } - prev = &p->tail; - } - } - - /** Iter is an iterator for HashMap, intended to be instantiated on - * the stack. Iteration order is undefined. Mutating the hashmap - * while iteration is in progress gives undefined results. All iteration - * state is in class Iter, so multiple iterations can be in progress - * at the same time. for example: - * - * HashMap::Iter iter(map); - * while (iter.next()) { - * K *k = iter.key(); - * T *t = iter.value(); - * } - */ - class Iter { - friend class HashMap; - const HashMap ↦ - int bucket; - const Seq* current; - - public: - Iter(HashMap& map) : map(map), bucket((int)map.nbuckets-1), current(NULL) - { } - - /** return true if more (k,v) remain to be visited */ - bool next() { - if (current) - current = current->tail; - while (bucket >= 0 && !current) - current = map.buckets[bucket--]; - return current != NULL; - } - - /** return the current key */ - const K& key() const { - NanoAssert(current != NULL); - return current->head.key; - } - - /** return the current value */ - const T& value() const { - NanoAssert(current != NULL); - return current->head.value; - } - }; - - /** return true if the hashmap has no elements */ - bool isEmpty() { - Iter iter(*this); - return !iter.next(); - } - }; - - /** - * Simple binary tree. No balancing is performed under the assumption - * that the only users of this structure are not performance critical. - */ - template class TreeMap { - Allocator& alloc; - class Node { - public: - Node* left; - Node* right; - K key; - T value; - Node(K k, T v) : left(NULL), right(NULL), key(k), value(v) - { } - }; - Node* root; - - /** - * helper method to recursively insert (k,v) below Node n or a child - * of n so that the binary search tree remains well formed. - */ - void insert(Node* &n, K k, T v) { - if (!n) - n = new (alloc) Node(k, v); - else if (k == n->key) - n->value = v; - else if (k < n->key) - insert(n->left, k, v); - else - insert(n->right, k, v); - } - - /** - * search for key k below Node n and return n if found, or the - * closest parent n where k should be inserted. - */ - Node* find(Node* n, K k) { - if (!n) - return NULL; - if (k == n->key) - return n; - if (k < n->key) - return find(n->left, k); - if (n->right) - return find(n->right, k); - return n; - } - - public: - TreeMap(Allocator& alloc) : alloc(alloc), root(NULL) - { } - - /** set k = v in the map. if k already exists, replace its value */ - void put(K k, T v) { - insert(root, k, v); - } - - /** return the closest key that is <= k, or NULL if k - is smaller than every key in the Map. */ - K findNear(K k) { - Node* n = find(root, k); - return n ? n->key : 0; - } - - /** returns the value for k or NULL */ - T get(K k) { - Node* n = find(root, k); - return (n && n->key == k) ? n->value : 0; - } - - /** returns true iff k is in the Map. */ - bool containsKey(K k) { - Node* n = find(root, k); - return n && n->key == k; - } - - /** make the tree empty. trivial since we dont manage elements */ - void clear() { - root = NULL; - } - }; -} -#endif // __nanojit_Containers__ diff --git a/x86/mozilla/include/Fragmento.h b/x86/mozilla/include/Fragmento.h deleted file mode 100644 index f4bbe7a..0000000 --- a/x86/mozilla/include/Fragmento.h +++ /dev/null @@ -1,135 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ -/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is [Open Source Virtual Machine]. - * - * The Initial Developer of the Original Code is - * Adobe System Incorporated. - * Portions created by the Initial Developer are Copyright (C) 2004-2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Adobe AS3 Team - * Mozilla TraceMonkey Team - * Asko Tontti - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - - -#ifndef __nanojit_Fragmento__ -#define __nanojit_Fragmento__ - -namespace nanojit -{ - struct GuardRecord; - - /** - * Fragments are linear sequences of native code that have a single entry - * point at the start of the fragment and may have one or more exit points - * - * It may turn out that that this arrangement causes too much traffic - * between d and i-caches and that we need to carve up the structure differently. - */ - class Fragment - { - public: - Fragment(const void* - verbose_only(, uint32_t profFragID)); - - NIns* code() { return _code; } - void setCode(NIns* codee) { _code = codee; } - int32_t& hits() { return _hits; } - - LirBuffer* lirbuf; - LIns* lastIns; - - const void* ip; - uint32_t recordAttempts; - NIns* fragEntry; - - // for fragment entry and exit profiling. See detailed - // how-to-use comment below. - verbose_only( LIns* loopLabel; ) // where's the loop top? - verbose_only( uint32_t profFragID; ) - verbose_only( uint32_t profCount; ) - verbose_only( uint32_t nStaticExits; ) - verbose_only( size_t nCodeBytes; ) - verbose_only( size_t nExitBytes; ) - verbose_only( uint32_t guardNumberer; ) - verbose_only( GuardRecord* guardsForFrag; ) - - private: - NIns* _code; // ptr to start of code - int32_t _hits; - }; -} - -/* - * How to use fragment profiling - * - * Fragprofiling adds code to count how many times each fragment is - * entered, and how many times each guard (exit) is taken. Using this - * it's possible to easily find which fragments are hot, which ones - * typically exit early, etc. The fragprofiler also gathers some - * simple static info: for each fragment, the number of code bytes, - * number of exit-block bytes, and number of guards (exits). - * - * Fragments and guards are given unique IDs (FragID, GuardID) which - * are shown in debug printouts, so as to facilitate navigating from - * the accumulated statistics to the associated bits of code. - * GuardIDs are issued automatically, but FragIDs you must supply when - * calling Fragment::Fragment. Supply values >= 1, and supply a - * different value for each new fragment (doesn't matter what, they - * just have to be unique and >= 1); else - * js_FragProfiling_FragFinalizer will assert. - * - * How to use/embed: - * - * - use a debug build (one with NJ_VERBOSE). Without it, none of - * this code is compiled in. - * - * - set LC_FragProfile in the lcbits of the LogControl* object handed - * to Nanojit - * - * When enabled, Fragment::profCount is incremented every time the - * fragment is entered, and GuardRecord::profCount is incremented - * every time that guard exits. However, NJ has no way to know where - * the fragment entry/loopback point is. So you must set - * Fragment::loopLabel before running the assembler, so as to indicate - * where the fragment-entry counter increment should be placed. If - * the fragment does not naturally have a loop label then you will - * need to artificially add one. - * - * It is the embedder's problem to fish out, collate and present the - * accumulated stats at the end of the Fragment's lifetime. A - * Fragment contains stats indicating its entry count and static code - * sizes. It also has a ::guardsForFrag field, which is a linked list - * of GuardRecords, and by traversing them you can get hold of the - * exit counts. - */ - -#endif // __nanojit_Fragmento__ diff --git a/x86/mozilla/include/LIR.h b/x86/mozilla/include/LIR.h deleted file mode 100644 index 4d6f03f..0000000 --- a/x86/mozilla/include/LIR.h +++ /dev/null @@ -1,2443 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ -/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is [Open Source Virtual Machine]. - * - * The Initial Developer of the Original Code is - * Adobe System Incorporated. - * Portions created by the Initial Developer are Copyright (C) 2004-2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Adobe AS3 Team - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef __nanojit_LIR__ -#define __nanojit_LIR__ - -namespace nanojit -{ - enum LOpcode -#if defined(_MSC_VER) && _MSC_VER >= 1400 -#pragma warning(disable:4480) // nonstandard extension used: specifying underlying type for enum - : unsigned -#endif - { -#define OP___(op, number, repKind, retType, isCse) \ - LIR_##op = (number), -#include "LIRopcode.tbl" - LIR_sentinel, -#undef OP___ - -#ifdef NANOJIT_64BIT -# define PTR_SIZE(a,b) b -#else -# define PTR_SIZE(a,b) a -#endif - - // Pointer-sized synonyms. - - LIR_paramp = PTR_SIZE(LIR_parami, LIR_paramq), - - LIR_retp = PTR_SIZE(LIR_reti, LIR_retq), - - LIR_livep = PTR_SIZE(LIR_livei, LIR_liveq), - - LIR_ldp = PTR_SIZE(LIR_ldi, LIR_ldq), - - LIR_stp = PTR_SIZE(LIR_sti, LIR_stq), - - LIR_callp = PTR_SIZE(LIR_calli, LIR_callq), - - LIR_eqp = PTR_SIZE(LIR_eqi, LIR_eqq), - LIR_ltp = PTR_SIZE(LIR_lti, LIR_ltq), - LIR_gtp = PTR_SIZE(LIR_gti, LIR_gtq), - LIR_lep = PTR_SIZE(LIR_lei, LIR_leq), - LIR_gep = PTR_SIZE(LIR_gei, LIR_geq), - LIR_ltup = PTR_SIZE(LIR_ltui, LIR_ltuq), - LIR_gtup = PTR_SIZE(LIR_gtui, LIR_gtuq), - LIR_leup = PTR_SIZE(LIR_leui, LIR_leuq), - LIR_geup = PTR_SIZE(LIR_geui, LIR_geuq), - - LIR_addp = PTR_SIZE(LIR_addi, LIR_addq), - LIR_subp = PTR_SIZE(LIR_subi, LIR_subq), - LIR_addjovp = PTR_SIZE(LIR_addjovi, LIR_addjovq), - - LIR_andp = PTR_SIZE(LIR_andi, LIR_andq), - LIR_orp = PTR_SIZE(LIR_ori, LIR_orq), - LIR_xorp = PTR_SIZE(LIR_xori, LIR_xorq), - - LIR_lshp = PTR_SIZE(LIR_lshi, LIR_lshq), - LIR_rshp = PTR_SIZE(LIR_rshi, LIR_rshq), - LIR_rshup = PTR_SIZE(LIR_rshui, LIR_rshuq), - - LIR_cmovp = PTR_SIZE(LIR_cmovi, LIR_cmovq) - }; - - // 32-bit integer comparisons must be contiguous, as must 64-bit integer - // comparisons and 64-bit float comparisons. - NanoStaticAssert(LIR_eqi + 1 == LIR_lti && - LIR_eqi + 2 == LIR_gti && - LIR_eqi + 3 == LIR_lei && - LIR_eqi + 4 == LIR_gei && - LIR_eqi + 5 == LIR_ltui && - LIR_eqi + 6 == LIR_gtui && - LIR_eqi + 7 == LIR_leui && - LIR_eqi + 8 == LIR_geui); -#ifdef NANOJIT_64BIT - NanoStaticAssert(LIR_eqq + 1 == LIR_ltq && - LIR_eqq + 2 == LIR_gtq && - LIR_eqq + 3 == LIR_leq && - LIR_eqq + 4 == LIR_geq && - LIR_eqq + 5 == LIR_ltuq && - LIR_eqq + 6 == LIR_gtuq && - LIR_eqq + 7 == LIR_leuq && - LIR_eqq + 8 == LIR_geuq); -#endif - NanoStaticAssert(LIR_eqd + 1 == LIR_ltd && - LIR_eqd + 2 == LIR_gtd && - LIR_eqd + 3 == LIR_led && - LIR_eqd + 4 == LIR_ged); - - // Various opcodes must be changeable to their opposite with op^1 - // (although we use invertXyz() when possible, ie. outside static - // assertions). - NanoStaticAssert((LIR_jt^1) == LIR_jf && (LIR_jf^1) == LIR_jt); - - NanoStaticAssert((LIR_xt^1) == LIR_xf && (LIR_xf^1) == LIR_xt); - - NanoStaticAssert((LIR_lti^1) == LIR_gti && (LIR_gti^1) == LIR_lti); - NanoStaticAssert((LIR_lei^1) == LIR_gei && (LIR_gei^1) == LIR_lei); - NanoStaticAssert((LIR_ltui^1) == LIR_gtui && (LIR_gtui^1) == LIR_ltui); - NanoStaticAssert((LIR_leui^1) == LIR_geui && (LIR_geui^1) == LIR_leui); - -#ifdef NANOJIT_64BIT - NanoStaticAssert((LIR_ltq^1) == LIR_gtq && (LIR_gtq^1) == LIR_ltq); - NanoStaticAssert((LIR_leq^1) == LIR_geq && (LIR_geq^1) == LIR_leq); - NanoStaticAssert((LIR_ltuq^1) == LIR_gtuq && (LIR_gtuq^1) == LIR_ltuq); - NanoStaticAssert((LIR_leuq^1) == LIR_geuq && (LIR_geuq^1) == LIR_leuq); -#endif - - NanoStaticAssert((LIR_ltd^1) == LIR_gtd && (LIR_gtd^1) == LIR_ltd); - NanoStaticAssert((LIR_led^1) == LIR_ged && (LIR_ged^1) == LIR_led); - - - struct GuardRecord; - struct SideExit; - - enum AbiKind { - ABI_FASTCALL, - ABI_THISCALL, - ABI_STDCALL, - ABI_CDECL - }; - - // This is much the same as LTy, but we need to distinguish signed and - // unsigned 32-bit ints so that they will be extended to 64-bits correctly - // on 64-bit platforms. - // - // All values must fit into three bits. See CallInfo for details. - enum ArgType { - ARGTYPE_V = 0, // void - ARGTYPE_I = 1, // int32_t - ARGTYPE_UI = 2, // uint32_t -#ifdef NANOJIT_64BIT - ARGTYPE_Q = 3, // uint64_t -#endif - ARGTYPE_D = 4, // double - - // aliases - ARGTYPE_P = PTR_SIZE(ARGTYPE_I, ARGTYPE_Q), // pointer - ARGTYPE_B = ARGTYPE_I // bool - }; - - enum IndirectCall { - CALL_INDIRECT = 0 - }; - - //----------------------------------------------------------------------- - // Aliasing - // -------- - // *Aliasing* occurs when a single memory location can be accessed through - // multiple names. For example, consider this code: - // - // ld a[0] - // sti b[0] - // ld a[0] - // - // In general, it's possible that a[0] and b[0] may refer to the same - // memory location. This means, for example, that you cannot safely - // perform CSE on the two loads. However, if you know that 'a' cannot be - // an alias of 'b' (ie. the two loads do not alias with the store) then - // you can safely perform CSE. - // - // Access regions - // -------------- - // Doing alias analysis precisely is difficult. But it turns out that - // keeping track of aliasing at a coarse level is enough to help with many - // optimisations. So we conceptually divide the memory that is accessible - // from LIR into a small number of "access regions" (aka. "Acc"). An - // access region may be non-contiguous. No two access regions can - // overlap. The union of all access regions covers all memory accessible - // from LIR. - // - // In general a (static) load or store may be executed more than once, and - // thus may access multiple regions; however, in practice almost all - // loads and stores will obviously access only a single region. A - // function called from LIR may load and/or store multiple access regions - // (even if executed only once). - // - // If two loads/stores/calls are known to not access the same region(s), - // then they do not alias. - // - // All regions are defined by the embedding. It makes sense to add new - // embedding-specific access regions when doing so will help with one or - // more optimisations. - // - // Access region sets and instruction markings - // ------------------------------------------- - // Each load/store is marked with an "access region set" (aka. "AccSet"), - // which is a set of one or more access regions. This indicates which - // parts of LIR-accessible memory the load/store may touch. - // - // Each function called from LIR is also marked with an access region set - // for memory stored to by the function. (We could also have a marking - // for memory loads done by the function, but there's no need at the - // moment.) These markings apply to the function itself, not the call - // site, ie. they're not context-sensitive. - // - // These load/store/call markings MUST BE ACCURATE -- if not then invalid - // optimisations might occur that change the meaning of the code. - // However, they can safely be imprecise (ie. conservative), ie. a - // load/store/call can be marked with an access region set that is a - // superset of the actual access region set. Such imprecision is safe but - // may reduce optimisation opportunities. - // - // Optimisations that use access region info - // ----------------------------------------- - // Currently only CseFilter uses this, and only for determining whether - // loads can be CSE'd. Note that CseFilter treats loads that are marked - // with a single access region precisely, but all loads marked with - // multiple access regions get lumped together. So if you can't mark a - // load with a single access region, you might as well use ACC_LOAD_ANY. - //----------------------------------------------------------------------- - - // An access region set is represented as a bitset. Using a uint32_t - // restricts us to at most 32 alias regions for the moment. This could be - // expanded to a uint64_t easily if needed. - typedef uint32_t AccSet; - static const int NUM_ACCS = sizeof(AccSet) * 8; - - // Some common (non-singleton) access region sets. ACCSET_NONE does not make - // sense for loads or stores (which must access at least one region), it - // only makes sense for calls. - // - static const AccSet ACCSET_NONE = 0x0; - static const AccSet ACCSET_ALL = 0xffffffff; - static const AccSet ACCSET_LOAD_ANY = ACCSET_ALL; // synonym - static const AccSet ACCSET_STORE_ANY = ACCSET_ALL; // synonym - - inline bool isSingletonAccSet(AccSet accSet) { - // This is a neat way of testing if a value has only one bit set. - return (accSet & (accSet - 1)) == 0; - } - - // Full AccSets don't fit into load and store instructions. But - // load/store AccSets almost always contain a single access region. We - // take advantage of this to create a compressed AccSet, MiniAccSet, that - // does fit. - // - // The 32 single-region AccSets get compressed into a number in the range - // 0..31 (according to the position of the set bit), and all other - // (multi-region) AccSets get converted into MINI_ACCSET_MULTIPLE. So the - // representation is lossy in the latter case, but that case is rare for - // loads/stores. We use a full AccSet for the storeAccSets of calls, for - // which multi-region AccSets are common. - // - // We wrap the uint8_t inside a struct to avoid the possiblity of subtle - // bugs caused by mixing up AccSet and MiniAccSet, which is easy to do. - // However, the struct gets padded inside LInsLd in an inconsistent way on - // Windows, so we actually store a MiniAccSetVal inside LInsLd. Sigh. - // But we use MiniAccSet everywhere else. - // - typedef uint8_t MiniAccSetVal; - struct MiniAccSet { MiniAccSetVal val; }; - static const MiniAccSet MINI_ACCSET_MULTIPLE = { 99 }; - - static MiniAccSet compressAccSet(AccSet accSet) { - if (isSingletonAccSet(accSet)) { - MiniAccSet ret = { uint8_t(msbSet32(accSet)) }; - return ret; - } - - // If we got here, it must be a multi-region AccSet. - return MINI_ACCSET_MULTIPLE; - } - - static AccSet decompressMiniAccSet(MiniAccSet miniAccSet) { - return (miniAccSet.val == MINI_ACCSET_MULTIPLE.val) ? ACCSET_ALL : (1 << miniAccSet.val); - } - - // The LoadQual affects how a load can be optimised: - // - // - CONST: These loads are guaranteed to always return the same value - // during a single execution of a fragment (but the value is allowed to - // change between executions of the fragment). This means that the - // location is never stored to by the LIR, and is never modified by an - // external entity while the fragment is running. - // - // - NORMAL: These loads may be stored to by the LIR, but are never - // modified by an external entity while the fragment is running. - // - // - VOLATILE: These loads may be stored to by the LIR, and may be - // modified by an external entity while the fragment is running. - // - // This gives a lattice with the ordering: CONST < NORMAL < VOLATILE. - // As usual, it's safe to mark a load with a value higher (less precise) - // that actual, but it may result in fewer optimisations occurring. - // - // Generally CONST loads are highly amenable to optimisation (eg. CSE), - // VOLATILE loads are entirely unoptimisable, and NORMAL loads are in - // between and require some alias analysis to optimise. - // - // Note that CONST has a stronger meaning to "const" in C and C++; in C - // and C++ a "const" variable may be modified by an external entity, such - // as hardware. Hence "const volatile" makes sense in C and C++, but - // CONST+VOLATILE doesn't make sense in LIR. - // - // Note also that a 2-bit bitfield in LInsLd is used to hold LoadQual - // values, so you can one add one more value without expanding it. - // - enum LoadQual { - LOAD_CONST = 0, - LOAD_NORMAL = 1, - LOAD_VOLATILE = 2 - }; - - struct CallInfo - { - private: - // In CallInfo::_typesig, each entry is three bits. - static const int TYPESIG_FIELDSZB = 3; - static const int TYPESIG_FIELDMASK = 7; - - public: - uintptr_t _address; - uint32_t _typesig:27; // 9 3-bit fields indicating arg type, by ARGTYPE above (including ret type): a1 a2 a3 a4 a5 ret - AbiKind _abi:3; - uint32_t _isPure:1; // _isPure=1 means no side-effects, result only depends on args - AccSet _storeAccSet; // access regions stored by the function - verbose_only ( const char* _name; ) - - // The following encode 'r func()' through to 'r func(a1, a2, a3, a4, a5, a6, a7, a8)'. - static inline uint32_t typeSig0(ArgType r) { - return r; - } - static inline uint32_t typeSig1(ArgType r, ArgType a1) { - return a1 << TYPESIG_FIELDSZB*1 | typeSig0(r); - } - static inline uint32_t typeSig2(ArgType r, ArgType a1, ArgType a2) { - return a1 << TYPESIG_FIELDSZB*2 | typeSig1(r, a2); - } - static inline uint32_t typeSig3(ArgType r, ArgType a1, ArgType a2, ArgType a3) { - return a1 << TYPESIG_FIELDSZB*3 | typeSig2(r, a2, a3); - } - static inline uint32_t typeSig4(ArgType r, ArgType a1, ArgType a2, ArgType a3, ArgType a4) { - return a1 << TYPESIG_FIELDSZB*4 | typeSig3(r, a2, a3, a4); - } - static inline uint32_t typeSig5(ArgType r, ArgType a1, ArgType a2, ArgType a3, - ArgType a4, ArgType a5) { - return a1 << TYPESIG_FIELDSZB*5 | typeSig4(r, a2, a3, a4, a5); - } - static inline uint32_t typeSig6(ArgType r, ArgType a1, ArgType a2, ArgType a3, - ArgType a4, ArgType a5, ArgType a6) { - return a1 << TYPESIG_FIELDSZB*6 | typeSig5(r, a2, a3, a4, a5, a6); - } - static inline uint32_t typeSig7(ArgType r, ArgType a1, ArgType a2, ArgType a3, - ArgType a4, ArgType a5, ArgType a6, ArgType a7) { - return a1 << TYPESIG_FIELDSZB*7 | typeSig6(r, a2, a3, a4, a5, a6, a7); - } - static inline uint32_t typeSig8(ArgType r, ArgType a1, ArgType a2, ArgType a3, ArgType a4, - ArgType a5, ArgType a6, ArgType a7, ArgType a8) { - return a1 << TYPESIG_FIELDSZB*8 | typeSig7(r, a2, a3, a4, a5, a6, a7, a8); - } - // Encode 'r func(a1, ..., aN))' - static inline uint32_t typeSigN(ArgType r, int N, ArgType a[]) { - uint32_t typesig = r; - for (int i = 0; i < N; i++) { - typesig |= a[i] << TYPESIG_FIELDSZB*(N-i); - } - return typesig; - } - - uint32_t count_args() const; - uint32_t count_int32_args() const; - // Nb: uses right-to-left order, eg. sizes[0] is the size of the right-most arg. - // XXX: See bug 525815 for fixing this. - uint32_t getArgTypes(ArgType* types) const; - - inline ArgType returnType() const { - return ArgType(_typesig & TYPESIG_FIELDMASK); - } - - inline bool isIndirect() const { - return _address < 256; - } - }; - - /* - * Record for extra data used to compile switches as jump tables. - */ - struct SwitchInfo - { - NIns** table; // Jump table; a jump address is NIns* - uint32_t count; // Number of table entries - // Index value at last execution of the switch. The index value - // is the offset into the jump table. Thus it is computed as - // (switch expression) - (lowest case value). - uint32_t index; - }; - - // Array holding the 'isCse' field from LIRopcode.tbl. - extern const int8_t isCses[]; // cannot be uint8_t, some values are negative - - inline bool isCseOpcode(LOpcode op) { - NanoAssert(isCses[op] != -1); // see LIRopcode.tbl to understand this - return isCses[op] == 1; - } - inline bool isLiveOpcode(LOpcode op) { - return -#if defined NANOJIT_64BIT - op == LIR_liveq || -#endif - op == LIR_livei || op == LIR_lived; - } - inline bool isRetOpcode(LOpcode op) { - return -#if defined NANOJIT_64BIT - op == LIR_retq || -#endif - op == LIR_reti || op == LIR_retd; - } - inline bool isCmovOpcode(LOpcode op) { - return -#if defined NANOJIT_64BIT - op == LIR_cmovq || -#endif - op == LIR_cmovi || - op == LIR_cmovd; - } - inline bool isCmpIOpcode(LOpcode op) { - return LIR_eqi <= op && op <= LIR_geui; - } - inline bool isCmpSIOpcode(LOpcode op) { - return LIR_eqi <= op && op <= LIR_gei; - } - inline bool isCmpUIOpcode(LOpcode op) { - return LIR_eqi == op || (LIR_ltui <= op && op <= LIR_geui); - } -#ifdef NANOJIT_64BIT - inline bool isCmpQOpcode(LOpcode op) { - return LIR_eqq <= op && op <= LIR_geuq; - } - inline bool isCmpSQOpcode(LOpcode op) { - return LIR_eqq <= op && op <= LIR_geq; - } - inline bool isCmpUQOpcode(LOpcode op) { - return LIR_eqq == op || (LIR_ltuq <= op && op <= LIR_geuq); - } -#endif - inline bool isCmpDOpcode(LOpcode op) { - return LIR_eqd <= op && op <= LIR_ged; - } - inline bool isCmpOpcode(LOpcode op) { - return isCmpIOpcode(op) || -#if defined NANOJIT_64BIT - isCmpQOpcode(op) || -#endif - isCmpDOpcode(op); - } - - inline LOpcode invertCondJmpOpcode(LOpcode op) { - NanoAssert(op == LIR_jt || op == LIR_jf); - return LOpcode(op ^ 1); - } - inline LOpcode invertCondGuardOpcode(LOpcode op) { - NanoAssert(op == LIR_xt || op == LIR_xf); - return LOpcode(op ^ 1); - } - inline LOpcode invertCmpOpcode(LOpcode op) { - NanoAssert(isCmpOpcode(op)); - return LOpcode(op ^ 1); - } - - inline LOpcode getCallOpcode(const CallInfo* ci) { - LOpcode op = LIR_callp; - switch (ci->returnType()) { - case ARGTYPE_V: op = LIR_callv; break; - case ARGTYPE_I: - case ARGTYPE_UI: op = LIR_calli; break; -#ifdef NANOJIT_64BIT - case ARGTYPE_Q: op = LIR_callq; break; -#endif - case ARGTYPE_D: op = LIR_calld; break; - default: NanoAssert(0); break; - } - return op; - } - - LOpcode arithOpcodeD2I(LOpcode op); -#ifdef NANOJIT_64BIT - LOpcode cmpOpcodeI2Q(LOpcode op); -#endif - LOpcode cmpOpcodeD2I(LOpcode op); - LOpcode cmpOpcodeD2UI(LOpcode op); - - // Array holding the 'repKind' field from LIRopcode.tbl. - extern const uint8_t repKinds[]; - - enum LTy { - LTy_V, // void: no value/no type - LTy_I, // int: 32-bit integer -#ifdef NANOJIT_64BIT - LTy_Q, // quad: 64-bit integer -#endif - LTy_D, // double: 64-bit float - - LTy_P = PTR_SIZE(LTy_I, LTy_Q) // word-sized integer - }; - - // Array holding the 'retType' field from LIRopcode.tbl. - extern const LTy retTypes[]; - - inline RegisterMask rmask(Register r) - { - return RegisterMask(1) << REGNUM(r); - } - - //----------------------------------------------------------------------- - // Low-level instructions. This is a bit complicated, because we have a - // variable-width representation to minimise space usage. - // - // - Instruction size is always an integral multiple of word size. - // - // - Every instruction has at least one word, holding the opcode and the - // reservation info ("SharedFields"). That word is in class LIns. - // - // - Beyond that, most instructions have 1, 2 or 3 extra words. These - // extra words are in classes LInsOp1, LInsOp2, etc (collectively called - // "LInsXYZ" in what follows). Each LInsXYZ class also contains an LIns, - // accessible by the 'ins' member, which holds the LIns data. - // - // - LIR is written forward, but read backwards. When reading backwards, - // in order to find the opcode, it must be in a predictable place in the - // LInsXYZ isn't affected by instruction width. Therefore, the LIns - // word (which contains the opcode) is always the *last* word in an - // instruction. - // - // - Each instruction is created by casting pre-allocated bytes from a - // LirBuffer to the LInsXYZ type. Therefore there are no constructors - // for LIns or LInsXYZ. - // - // - The standard handle for an instruction is a LIns*. This actually - // points to the LIns word, ie. to the final word in the instruction. - // This is a bit odd, but it allows the instruction's opcode to be - // easily accessed. Once you've looked at the opcode and know what kind - // of instruction it is, if you want to access any of the other words, - // you need to use toLInsXYZ(), which takes the LIns* and gives you an - // LInsXYZ*, ie. the pointer to the actual start of the instruction's - // bytes. From there you can access the instruction-specific extra - // words. - // - // - However, from outside class LIns, LInsXYZ isn't visible, nor is - // toLInsXYZ() -- from outside LIns, all LIR instructions are handled - // via LIns pointers and get/set methods are used for all LIns/LInsXYZ - // accesses. In fact, all data members in LInsXYZ are private and can - // only be accessed by LIns, which is a friend class. The only thing - // anyone outside LIns can do with a LInsXYZ is call getLIns(). - // - // - An example Op2 instruction and the likely pointers to it (each line - // represents a word, and pointers to a line point to the start of the - // word on that line): - // - // [ oprnd_2 <-- LInsOp2* insOp2 == toLInsOp2(ins) - // oprnd_1 - // opcode + resv ] <-- LIns* ins - // - // - LIR_skip instructions are used to link code chunks. If the first - // instruction on a chunk isn't a LIR_start, it will be a skip, and the - // skip's operand will point to the last LIns on the preceding chunk. - // LInsSk has the same layout as LInsOp1, but we represent it as a - // different class because there are some places where we treat - // skips specially and so having it separate seems like a good idea. - // - // - Various things about the size and layout of LIns and LInsXYZ are - // statically checked in staticSanityCheck(). In particular, this is - // worthwhile because there's nothing that guarantees that all the - // LInsXYZ classes have a size that is a multiple of word size (but in - // practice all sane compilers use a layout that results in this). We - // also check that every LInsXYZ is word-aligned in - // LirBuffer::makeRoom(); this seems sensible to avoid potential - // slowdowns due to misalignment. It relies on chunks themselves being - // word-aligned, which is extremely likely. - // - // - There is an enum, LInsRepKind, with one member for each of the - // LInsXYZ kinds. Each opcode is categorised with its LInsRepKind value - // in LIRopcode.tbl, and this is used in various places. - //----------------------------------------------------------------------- - - enum LInsRepKind { - // LRK_XYZ corresponds to class LInsXYZ. - LRK_Op0, - LRK_Op1, - LRK_Op2, - LRK_Op3, - LRK_Ld, - LRK_St, - LRK_Sk, - LRK_C, - LRK_P, - LRK_I, - LRK_QorD, - LRK_Jtbl, - LRK_None // this one is used for unused opcode numbers - }; - - class LInsOp0; - class LInsOp1; - class LInsOp2; - class LInsOp3; - class LInsLd; - class LInsSt; - class LInsSk; - class LInsC; - class LInsP; - class LInsI; - class LInsQorD; - class LInsJtbl; - - class LIns - { - private: - // SharedFields: fields shared by all LIns kinds. - // - // The .inReg, .regnum, .inAr and .arIndex fields form a "reservation" - // that is used temporarily during assembly to record information - // relating to register allocation. See class RegAlloc for more - // details. Note: all combinations of .inReg/.inAr are possible, ie. - // 0/0, 0/1, 1/0, 1/1. - // - // The .isResultLive field is only used for instructions that return - // results. It indicates if the result is live. It's set (if - // appropriate) and used only during the codegen pass. - // - struct SharedFields { - uint32_t inReg:1; // if 1, 'reg' is active - uint32_t regnum:7; - uint32_t inAr:1; // if 1, 'arIndex' is active - uint32_t isResultLive:1; // if 1, the instruction's result is live - - uint32_t arIndex:14; // index into stack frame; displ is -4*arIndex - - LOpcode opcode:8; // instruction's opcode - }; - - union { - SharedFields sharedFields; - // Force sizeof(LIns)==8 and 8-byte alignment on 64-bit machines. - // This is necessary because sizeof(SharedFields)==4 and we want all - // instances of LIns to be pointer-aligned. - void* wholeWord; - }; - - inline void initSharedFields(LOpcode opcode) - { - // We must zero .inReg, .inAR and .isResultLive, but zeroing the - // whole word is easier. Then we set the opcode. - wholeWord = 0; - sharedFields.opcode = opcode; - } - - // LIns-to-LInsXYZ converters. - inline LInsOp0* toLInsOp0() const; - inline LInsOp1* toLInsOp1() const; - inline LInsOp2* toLInsOp2() const; - inline LInsOp3* toLInsOp3() const; - inline LInsLd* toLInsLd() const; - inline LInsSt* toLInsSt() const; - inline LInsSk* toLInsSk() const; - inline LInsC* toLInsC() const; - inline LInsP* toLInsP() const; - inline LInsI* toLInsI() const; - inline LInsQorD* toLInsQorD() const; - inline LInsJtbl*toLInsJtbl()const; - - void staticSanityCheck(); - - public: - // LIns initializers. - inline void initLInsOp0(LOpcode opcode); - inline void initLInsOp1(LOpcode opcode, LIns* oprnd1); - inline void initLInsOp2(LOpcode opcode, LIns* oprnd1, LIns* oprnd2); - inline void initLInsOp3(LOpcode opcode, LIns* oprnd1, LIns* oprnd2, LIns* oprnd3); - inline void initLInsLd(LOpcode opcode, LIns* val, int32_t d, AccSet accSet, LoadQual loadQual); - inline void initLInsSt(LOpcode opcode, LIns* val, LIns* base, int32_t d, AccSet accSet); - inline void initLInsSk(LIns* prevLIns); - // Nb: args[] must be allocated and initialised before being passed in; - // initLInsC() just copies the pointer into the LInsC. - inline void initLInsC(LOpcode opcode, LIns** args, const CallInfo* ci); - inline void initLInsP(int32_t arg, int32_t kind); - inline void initLInsI(LOpcode opcode, int32_t immI); - inline void initLInsQorD(LOpcode opcode, uint64_t immQorD); - inline void initLInsJtbl(LIns* index, uint32_t size, LIns** table); - - LOpcode opcode() const { return sharedFields.opcode; } - - // Generally, void instructions (statements) are always live and - // non-void instructions (expressions) are live if used by another - // live instruction. But there are some trickier cases. - // Any non-void instruction can be marked isResultLive=1 even - // when it is unreachable, e.g. due to an always-taken branch. - // The assembler marks it live if it sees any uses, regardless of - // whether those uses are in reachable code or not. - bool isLive() const { - return isV() || - sharedFields.isResultLive || - (isCall() && !callInfo()->_isPure) || // impure calls are always live - isop(LIR_paramp); // LIR_paramp is always live - } - void setResultLive() { - NanoAssert(!isV()); - sharedFields.isResultLive = 1; - } - - // XXX: old reservation manipulating functions. See bug 538924. - // Replacement strategy: - // - deprecated_markAsClear() --> clearReg() and/or clearArIndex() - // - deprecated_hasKnownReg() --> isInReg() - // - deprecated_getReg() --> getReg() after checking isInReg() - // - void deprecated_markAsClear() { - sharedFields.inReg = 0; - sharedFields.inAr = 0; - } - bool deprecated_hasKnownReg() { - NanoAssert(isExtant()); - return isInReg(); - } - Register deprecated_getReg() { - NanoAssert(isExtant()); - if (isInReg()) { - Register r = { sharedFields.regnum }; - return r; - } else { - return deprecated_UnknownReg; - } - } - uint32_t deprecated_getArIndex() { - NanoAssert(isExtant()); - return ( isInAr() ? sharedFields.arIndex : 0 ); - } - - // Reservation manipulation. - // - // "Extant" mean "in existence, still existing, surviving". In other - // words, has the value been computed explicitly (not folded into - // something else) and is it still available (in a register or spill - // slot) for use? - bool isExtant() { - return isInReg() || isInAr(); - } - bool isInReg() { - return sharedFields.inReg; - } - bool isInRegMask(RegisterMask allow) { - return isInReg() && (rmask(getReg()) & allow); - } - Register getReg() { - NanoAssert(isInReg()); - Register r = { sharedFields.regnum }; - return r; - } - void setReg(Register r) { - sharedFields.inReg = 1; - sharedFields.regnum = REGNUM(r); - } - void clearReg() { - sharedFields.inReg = 0; - } - bool isInAr() { - return sharedFields.inAr; - } - uint32_t getArIndex() { - NanoAssert(isInAr()); - return sharedFields.arIndex; - } - void setArIndex(uint32_t arIndex) { - sharedFields.inAr = 1; - sharedFields.arIndex = arIndex; - } - void clearArIndex() { - sharedFields.inAr = 0; - } - - // For various instruction kinds. - inline LIns* oprnd1() const; - inline LIns* oprnd2() const; - inline LIns* oprnd3() const; - - // For branches. - inline LIns* getTarget() const; - inline void setTarget(LIns* label); - - // For guards. - inline GuardRecord* record() const; - - // For loads. - inline LoadQual loadQual() const; - - // For loads/stores. - inline int32_t disp() const; - inline MiniAccSet miniAccSet() const; - inline AccSet accSet() const; - - // For LInsSk. - inline LIns* prevLIns() const; - - // For LInsP. - inline uint8_t paramArg() const; - inline uint8_t paramKind() const; - - // For LInsI. - inline int32_t immI() const; - - // For LInsQorD. -#ifdef NANOJIT_64BIT - inline int32_t immQlo() const; - inline uint64_t immQ() const; -#endif - inline int32_t immDlo() const; - inline int32_t immDhi() const; - inline double immD() const; - inline uint64_t immDasQ() const; - - // For LIR_allocp. - inline int32_t size() const; - inline void setSize(int32_t nbytes); - - // For LInsC. - inline LIns* arg(uint32_t i) const; // right-to-left-order: arg(0) is rightmost - inline uint32_t argc() const; - inline LIns* callArgN(uint32_t n) const; - inline const CallInfo* callInfo() const; - - // For LIR_jtbl - inline uint32_t getTableSize() const; - inline LIns* getTarget(uint32_t index) const; - inline void setTarget(uint32_t index, LIns* label) const; - - // isLInsXYZ() returns true if the instruction has the LInsXYZ form. - // Note that there is some overlap with other predicates, eg. - // isStore()==isLInsSt(), isCall()==isLInsC(), but that's ok; these - // ones are used mostly to check that opcodes are appropriate for - // instruction layouts, the others are used for non-debugging - // purposes. - bool isLInsOp0() const { - NanoAssert(LRK_None != repKinds[opcode()]); - return LRK_Op0 == repKinds[opcode()]; - } - bool isLInsOp1() const { - NanoAssert(LRK_None != repKinds[opcode()]); - return LRK_Op1 == repKinds[opcode()]; - } - bool isLInsOp2() const { - NanoAssert(LRK_None != repKinds[opcode()]); - return LRK_Op2 == repKinds[opcode()]; - } - bool isLInsOp3() const { - NanoAssert(LRK_None != repKinds[opcode()]); - return LRK_Op3 == repKinds[opcode()]; - } - bool isLInsLd() const { - NanoAssert(LRK_None != repKinds[opcode()]); - return LRK_Ld == repKinds[opcode()]; - } - bool isLInsSt() const { - NanoAssert(LRK_None != repKinds[opcode()]); - return LRK_St == repKinds[opcode()]; - } - bool isLInsSk() const { - NanoAssert(LRK_None != repKinds[opcode()]); - return LRK_Sk == repKinds[opcode()]; - } - bool isLInsC() const { - NanoAssert(LRK_None != repKinds[opcode()]); - return LRK_C == repKinds[opcode()]; - } - bool isLInsP() const { - NanoAssert(LRK_None != repKinds[opcode()]); - return LRK_P == repKinds[opcode()]; - } - bool isLInsI() const { - NanoAssert(LRK_None != repKinds[opcode()]); - return LRK_I == repKinds[opcode()]; - } - bool isLInsQorD() const { - NanoAssert(LRK_None != repKinds[opcode()]); - return LRK_QorD == repKinds[opcode()]; - } - bool isLInsJtbl() const { - NanoAssert(LRK_None != repKinds[opcode()]); - return LRK_Jtbl == repKinds[opcode()]; - } - - // LIns predicates. - bool isop(LOpcode o) const { - return opcode() == o; - } - bool isRet() const { - return isRetOpcode(opcode()); - } - bool isCmp() const { - return isCmpOpcode(opcode()); - } - bool isCall() const { - return isop(LIR_callv) || - isop(LIR_calli) || -#if defined NANOJIT_64BIT - isop(LIR_callq) || -#endif - isop(LIR_calld); - } - bool isCmov() const { - return isCmovOpcode(opcode()); - } - bool isStore() const { - return isLInsSt(); - } - bool isLoad() const { - return isLInsLd(); - } - bool isGuard() const { - return isop(LIR_x) || isop(LIR_xf) || isop(LIR_xt) || - isop(LIR_xbarrier) || isop(LIR_xtbl) || - isop(LIR_addxovi) || isop(LIR_subxovi) || isop(LIR_mulxovi); - } - bool isJov() const { - return -#ifdef NANOJIT_64BIT - isop(LIR_addjovq) || isop(LIR_subjovq) || -#endif - isop(LIR_addjovi) || isop(LIR_subjovi) || isop(LIR_muljovi); - } - // True if the instruction is a 32-bit integer immediate. - bool isImmI() const { - return isop(LIR_immi); - } - // True if the instruction is a 32-bit integer immediate and - // has the value 'val' when treated as a 32-bit signed integer. - bool isImmI(int32_t val) const { - return isImmI() && immI()==val; - } -#ifdef NANOJIT_64BIT - // True if the instruction is a 64-bit integer immediate. - bool isImmQ() const { - return isop(LIR_immq); - } -#endif - // True if the instruction is a pointer-sized integer immediate. - bool isImmP() const - { -#ifdef NANOJIT_64BIT - return isImmQ(); -#else - return isImmI(); -#endif - } - // True if the instruction is a 64-bit float immediate. - bool isImmD() const { - return isop(LIR_immd); - } - // True if the instruction is a 64-bit integer or float immediate. - bool isImmQorD() const { - return -#ifdef NANOJIT_64BIT - isImmQ() || -#endif - isImmD(); - } - // True if the instruction an any type of immediate. - bool isImmAny() const { - return isImmI() || isImmQorD(); - } - - bool isBranch() const { - return isop(LIR_jt) || isop(LIR_jf) || isop(LIR_j) || isop(LIR_jtbl) || isJov(); - } - - LTy retType() const { - return retTypes[opcode()]; - } - bool isV() const { - return retType() == LTy_V; - } - bool isI() const { - return retType() == LTy_I; - } -#ifdef NANOJIT_64BIT - bool isQ() const { - return retType() == LTy_Q; - } -#endif - bool isD() const { - return retType() == LTy_D; - } - bool isQorD() const { - return -#ifdef NANOJIT_64BIT - isQ() || -#endif - isD(); - } - bool isP() const { -#ifdef NANOJIT_64BIT - return isQ(); -#else - return isI(); -#endif - } - - inline void* immP() const - { - #ifdef NANOJIT_64BIT - return (void*)immQ(); - #else - return (void*)immI(); - #endif - } - }; - - typedef SeqBuilder InsList; - typedef SeqBuilder StringList; - - - // 0-operand form. Used for LIR_start and LIR_label. - class LInsOp0 - { - private: - friend class LIns; - - LIns ins; - - public: - LIns* getLIns() { return &ins; }; - }; - - // 1-operand form. Used for LIR_reti, unary arithmetic/logic ops, etc. - class LInsOp1 - { - private: - friend class LIns; - - LIns* oprnd_1; - - LIns ins; - - public: - LIns* getLIns() { return &ins; }; - }; - - // 2-operand form. Used for guards, branches, comparisons, binary - // arithmetic/logic ops, etc. - class LInsOp2 - { - private: - friend class LIns; - - LIns* oprnd_2; - - LIns* oprnd_1; - - LIns ins; - - public: - LIns* getLIns() { return &ins; }; - }; - - // 3-operand form. Used for conditional moves, jov branches, and xov guards. - class LInsOp3 - { - private: - friend class LIns; - - LIns* oprnd_3; - - LIns* oprnd_2; - - LIns* oprnd_1; - - LIns ins; - - public: - LIns* getLIns() { return &ins; }; - }; - - // Used for all loads. - class LInsLd - { - private: - friend class LIns; - - // Nb: the LIR writer pipeline handles things if a displacement - // exceeds 16 bits. This is rare, but does happen occasionally. We - // could go to 24 bits but then it would happen so rarely that the - // handler code would be difficult to test and thus untrustworthy. - // - // Nb: the types of these bitfields are all 32-bit integers to ensure - // they are fully packed on Windows, sigh. Also, 'loadQual' is - // unsigned to ensure the values 0, 1, and 2 all fit in 2 bits. - // - // Nb: explicit signed keyword for bitfield types is required, - // some compilers may treat them as unsigned without it. - // See Bugzilla 584219 comment #18 - signed int disp:16; - signed int miniAccSetVal:8; - uint32_t loadQual:2; - - LIns* oprnd_1; - - LIns ins; - - public: - LIns* getLIns() { return &ins; }; - }; - - // Used for all stores. - class LInsSt - { - private: - friend class LIns; - - int16_t disp; - MiniAccSetVal miniAccSetVal; - - LIns* oprnd_2; - - LIns* oprnd_1; - - LIns ins; - - public: - LIns* getLIns() { return &ins; }; - }; - - // Used for LIR_skip. - class LInsSk - { - private: - friend class LIns; - - LIns* prevLIns; - - LIns ins; - - public: - LIns* getLIns() { return &ins; }; - }; - - // Used for all variants of LIR_call. - class LInsC - { - private: - friend class LIns; - - // Arguments in reverse order, just like insCall() (ie. args[0] holds - // the rightmost arg). The array should be allocated by the same - // allocator as the LIR buffers, because it has the same lifetime. - LIns** args; - - const CallInfo* ci; - - LIns ins; - - public: - LIns* getLIns() { return &ins; }; - }; - - // Used for LIR_paramp. - class LInsP - { - private: - friend class LIns; - - uintptr_t arg:8; - uintptr_t kind:8; - - LIns ins; - - public: - LIns* getLIns() { return &ins; }; - }; - - // Used for LIR_immi and LIR_allocp. - class LInsI - { - private: - friend class LIns; - - int32_t immI; - - LIns ins; - - public: - LIns* getLIns() { return &ins; }; - }; - - // Used for LIR_immq and LIR_immd. - class LInsQorD - { - private: - friend class LIns; - - int32_t immQorDlo; - - int32_t immQorDhi; - - LIns ins; - - public: - LIns* getLIns() { return &ins; }; - }; - - // Used for LIR_jtbl. 'oprnd_1' must be a uint32_t index in - // the range 0 <= index < size; no range check is performed. - // 'table' is an array of labels. - class LInsJtbl - { - private: - friend class LIns; - - uint32_t size; // number of entries in table - LIns** table; // pointer to table[size] with same lifetime as this LInsJtbl - LIns* oprnd_1; // uint32_t index expression - - LIns ins; - - public: - LIns* getLIns() { return &ins; } - }; - - // Used only as a placeholder for OP___ macros for unused opcodes in - // LIRopcode.tbl. - class LInsNone - { - }; - - LInsOp0* LIns::toLInsOp0() const { return (LInsOp0* )(uintptr_t(this+1) - sizeof(LInsOp0 )); } - LInsOp1* LIns::toLInsOp1() const { return (LInsOp1* )(uintptr_t(this+1) - sizeof(LInsOp1 )); } - LInsOp2* LIns::toLInsOp2() const { return (LInsOp2* )(uintptr_t(this+1) - sizeof(LInsOp2 )); } - LInsOp3* LIns::toLInsOp3() const { return (LInsOp3* )(uintptr_t(this+1) - sizeof(LInsOp3 )); } - LInsLd* LIns::toLInsLd() const { return (LInsLd* )(uintptr_t(this+1) - sizeof(LInsLd )); } - LInsSt* LIns::toLInsSt() const { return (LInsSt* )(uintptr_t(this+1) - sizeof(LInsSt )); } - LInsSk* LIns::toLInsSk() const { return (LInsSk* )(uintptr_t(this+1) - sizeof(LInsSk )); } - LInsC* LIns::toLInsC() const { return (LInsC* )(uintptr_t(this+1) - sizeof(LInsC )); } - LInsP* LIns::toLInsP() const { return (LInsP* )(uintptr_t(this+1) - sizeof(LInsP )); } - LInsI* LIns::toLInsI() const { return (LInsI* )(uintptr_t(this+1) - sizeof(LInsI )); } - LInsQorD* LIns::toLInsQorD() const { return (LInsQorD*)(uintptr_t(this+1) - sizeof(LInsQorD)); } - LInsJtbl* LIns::toLInsJtbl() const { return (LInsJtbl*)(uintptr_t(this+1) - sizeof(LInsJtbl)); } - - void LIns::initLInsOp0(LOpcode opcode) { - initSharedFields(opcode); - NanoAssert(isLInsOp0()); - } - void LIns::initLInsOp1(LOpcode opcode, LIns* oprnd1) { - initSharedFields(opcode); - toLInsOp1()->oprnd_1 = oprnd1; - NanoAssert(isLInsOp1()); - } - void LIns::initLInsOp2(LOpcode opcode, LIns* oprnd1, LIns* oprnd2) { - initSharedFields(opcode); - toLInsOp2()->oprnd_1 = oprnd1; - toLInsOp2()->oprnd_2 = oprnd2; - NanoAssert(isLInsOp2()); - } - void LIns::initLInsOp3(LOpcode opcode, LIns* oprnd1, LIns* oprnd2, LIns* oprnd3) { - initSharedFields(opcode); - toLInsOp3()->oprnd_1 = oprnd1; - toLInsOp3()->oprnd_2 = oprnd2; - toLInsOp3()->oprnd_3 = oprnd3; - NanoAssert(isLInsOp3()); - } - void LIns::initLInsLd(LOpcode opcode, LIns* val, int32_t d, AccSet accSet, LoadQual loadQual) { - initSharedFields(opcode); - toLInsLd()->oprnd_1 = val; - NanoAssert(d == int16_t(d)); - toLInsLd()->disp = int16_t(d); - toLInsLd()->miniAccSetVal = compressAccSet(accSet).val; - toLInsLd()->loadQual = loadQual; - NanoAssert(isLInsLd()); - } - void LIns::initLInsSt(LOpcode opcode, LIns* val, LIns* base, int32_t d, AccSet accSet) { - initSharedFields(opcode); - toLInsSt()->oprnd_1 = val; - toLInsSt()->oprnd_2 = base; - NanoAssert(d == int16_t(d)); - toLInsSt()->disp = int16_t(d); - toLInsSt()->miniAccSetVal = compressAccSet(accSet).val; - NanoAssert(isLInsSt()); - } - void LIns::initLInsSk(LIns* prevLIns) { - initSharedFields(LIR_skip); - toLInsSk()->prevLIns = prevLIns; - NanoAssert(isLInsSk()); - } - void LIns::initLInsC(LOpcode opcode, LIns** args, const CallInfo* ci) { - initSharedFields(opcode); - toLInsC()->args = args; - toLInsC()->ci = ci; - NanoAssert(isLInsC()); - } - void LIns::initLInsP(int32_t arg, int32_t kind) { - initSharedFields(LIR_paramp); - NanoAssert(isU8(arg) && isU8(kind)); - toLInsP()->arg = arg; - toLInsP()->kind = kind; - NanoAssert(isLInsP()); - } - void LIns::initLInsI(LOpcode opcode, int32_t immI) { - initSharedFields(opcode); - toLInsI()->immI = immI; - NanoAssert(isLInsI()); - } - void LIns::initLInsQorD(LOpcode opcode, uint64_t immQorD) { - initSharedFields(opcode); - toLInsQorD()->immQorDlo = int32_t(immQorD); - toLInsQorD()->immQorDhi = int32_t(immQorD >> 32); - NanoAssert(isLInsQorD()); - } - void LIns::initLInsJtbl(LIns* index, uint32_t size, LIns** table) { - initSharedFields(LIR_jtbl); - toLInsJtbl()->oprnd_1 = index; - toLInsJtbl()->table = table; - toLInsJtbl()->size = size; - NanoAssert(isLInsJtbl()); - } - - LIns* LIns::oprnd1() const { - NanoAssert(isLInsOp1() || isLInsOp2() || isLInsOp3() || isLInsLd() || isLInsSt() || isLInsJtbl()); - return toLInsOp2()->oprnd_1; - } - LIns* LIns::oprnd2() const { - NanoAssert(isLInsOp2() || isLInsOp3() || isLInsSt()); - return toLInsOp2()->oprnd_2; - } - LIns* LIns::oprnd3() const { - NanoAssert(isLInsOp3()); - return toLInsOp3()->oprnd_3; - } - - LIns* LIns::getTarget() const { - NanoAssert(isBranch() && !isop(LIR_jtbl)); - if (isJov()) - return oprnd3(); - else - return oprnd2(); - } - - void LIns::setTarget(LIns* label) { - NanoAssert(label && label->isop(LIR_label)); - NanoAssert(isBranch() && !isop(LIR_jtbl)); - if (isJov()) - toLInsOp3()->oprnd_3 = label; - else - toLInsOp2()->oprnd_2 = label; - } - - LIns* LIns::getTarget(uint32_t index) const { - NanoAssert(isop(LIR_jtbl)); - NanoAssert(index < toLInsJtbl()->size); - return toLInsJtbl()->table[index]; - } - - void LIns::setTarget(uint32_t index, LIns* label) const { - NanoAssert(label && label->isop(LIR_label)); - NanoAssert(isop(LIR_jtbl)); - NanoAssert(index < toLInsJtbl()->size); - toLInsJtbl()->table[index] = label; - } - - GuardRecord *LIns::record() const { - NanoAssert(isGuard()); - switch (opcode()) { - case LIR_x: - case LIR_xt: - case LIR_xf: - case LIR_xtbl: - case LIR_xbarrier: - return (GuardRecord*)oprnd2(); - - case LIR_addxovi: - case LIR_subxovi: - case LIR_mulxovi: - return (GuardRecord*)oprnd3(); - - default: - NanoAssert(0); - return NULL; - } - } - - LoadQual LIns::loadQual() const { - NanoAssert(isLInsLd()); - return (LoadQual)toLInsLd()->loadQual; - } - - int32_t LIns::disp() const { - if (isLInsSt()) { - return toLInsSt()->disp; - } else { - NanoAssert(isLInsLd()); - return toLInsLd()->disp; - } - } - - MiniAccSet LIns::miniAccSet() const { - MiniAccSet miniAccSet; - if (isLInsSt()) { - miniAccSet.val = toLInsSt()->miniAccSetVal; - } else { - NanoAssert(isLInsLd()); - miniAccSet.val = toLInsLd()->miniAccSetVal; - } - return miniAccSet; - } - - AccSet LIns::accSet() const { - return decompressMiniAccSet(miniAccSet()); - } - - LIns* LIns::prevLIns() const { - NanoAssert(isLInsSk()); - return toLInsSk()->prevLIns; - } - - inline uint8_t LIns::paramArg() const { NanoAssert(isop(LIR_paramp)); return toLInsP()->arg; } - inline uint8_t LIns::paramKind() const { NanoAssert(isop(LIR_paramp)); return toLInsP()->kind; } - - inline int32_t LIns::immI() const { NanoAssert(isImmI()); return toLInsI()->immI; } - -#ifdef NANOJIT_64BIT - inline int32_t LIns::immQlo() const { NanoAssert(isImmQ()); return toLInsQorD()->immQorDlo; } - uint64_t LIns::immQ() const { - NanoAssert(isImmQ()); - return (uint64_t(toLInsQorD()->immQorDhi) << 32) | uint32_t(toLInsQorD()->immQorDlo); - } -#endif - inline int32_t LIns::immDlo() const { NanoAssert(isImmD()); return toLInsQorD()->immQorDlo; } - inline int32_t LIns::immDhi() const { NanoAssert(isImmD()); return toLInsQorD()->immQorDhi; } - double LIns::immD() const { - NanoAssert(isImmD()); - union { - double f; - uint64_t q; - } u; - u.q = immDasQ(); - return u.f; - } - uint64_t LIns::immDasQ() const { - NanoAssert(isImmD()); - return (uint64_t(toLInsQorD()->immQorDhi) << 32) | uint32_t(toLInsQorD()->immQorDlo); - } - - int32_t LIns::size() const { - NanoAssert(isop(LIR_allocp)); - return toLInsI()->immI << 2; - } - - void LIns::setSize(int32_t nbytes) { - NanoAssert(isop(LIR_allocp)); - NanoAssert(nbytes > 0); - toLInsI()->immI = (nbytes+3)>>2; // # of required 32bit words - } - - // Index args in reverse order, i.e. arg(0) returns the rightmost arg. - // Nb: this must be kept in sync with insCall(). - LIns* LIns::arg(uint32_t i) const - { - NanoAssert(isCall()); - NanoAssert(i < callInfo()->count_args()); - return toLInsC()->args[i]; // args[] is in right-to-left order as well - } - - uint32_t LIns::argc() const { - return callInfo()->count_args(); - } - - LIns* LIns::callArgN(uint32_t n) const - { - return arg(argc()-n-1); - } - - const CallInfo* LIns::callInfo() const - { - NanoAssert(isCall()); - return toLInsC()->ci; - } - - uint32_t LIns::getTableSize() const - { - NanoAssert(isLInsJtbl()); - return toLInsJtbl()->size; - } - - class LirWriter - { - public: - LirWriter *out; - - LirWriter(LirWriter* out) - : out(out) {} - virtual ~LirWriter() {} - - virtual LIns* ins0(LOpcode v) { - return out->ins0(v); - } - virtual LIns* ins1(LOpcode v, LIns* a) { - return out->ins1(v, a); - } - virtual LIns* ins2(LOpcode v, LIns* a, LIns* b) { - return out->ins2(v, a, b); - } - virtual LIns* ins3(LOpcode v, LIns* a, LIns* b, LIns* c) { - return out->ins3(v, a, b, c); - } - virtual LIns* insGuard(LOpcode v, LIns *c, GuardRecord *gr) { - return out->insGuard(v, c, gr); - } - virtual LIns* insGuardXov(LOpcode v, LIns *a, LIns* b, GuardRecord *gr) { - return out->insGuardXov(v, a, b, gr); - } - virtual LIns* insBranch(LOpcode v, LIns* condition, LIns* to) { - return out->insBranch(v, condition, to); - } - virtual LIns* insBranchJov(LOpcode v, LIns* a, LIns* b, LIns* to) { - return out->insBranchJov(v, a, b, to); - } - // arg: 0=first, 1=second, ... - // kind: 0=arg 1=saved-reg - virtual LIns* insParam(int32_t arg, int32_t kind) { - return out->insParam(arg, kind); - } - virtual LIns* insImmI(int32_t imm) { - return out->insImmI(imm); - } -#ifdef NANOJIT_64BIT - virtual LIns* insImmQ(uint64_t imm) { - return out->insImmQ(imm); - } -#endif - virtual LIns* insImmD(double d) { - return out->insImmD(d); - } - virtual LIns* insLoad(LOpcode op, LIns* base, int32_t d, AccSet accSet, LoadQual loadQual) { - return out->insLoad(op, base, d, accSet, loadQual); - } - virtual LIns* insStore(LOpcode op, LIns* value, LIns* base, int32_t d, AccSet accSet) { - return out->insStore(op, value, base, d, accSet); - } - // args[] is in reverse order, ie. args[0] holds the rightmost arg. - virtual LIns* insCall(const CallInfo *call, LIns* args[]) { - return out->insCall(call, args); - } - virtual LIns* insAlloc(int32_t size) { - NanoAssert(size != 0); - return out->insAlloc(size); - } - virtual LIns* insJtbl(LIns* index, uint32_t size) { - return out->insJtbl(index, size); - } - virtual LIns* insComment(const char* str) { - return out->insComment(str); - } - - // convenience functions - - // Inserts a conditional to execute and branches to execute if - // the condition is true and false respectively. - LIns* insChoose(LIns* cond, LIns* iftrue, LIns* iffalse, bool use_cmov); - - // Inserts an integer comparison to 0 - LIns* insEqI_0(LIns* oprnd1) { - return ins2ImmI(LIR_eqi, oprnd1, 0); - } - - // Inserts a pointer comparison to 0 - LIns* insEqP_0(LIns* oprnd1) { - return ins2(LIR_eqp, oprnd1, insImmWord(0)); - } - - // Inserts a binary operation where the second operand is an - // integer immediate. - LIns* ins2ImmI(LOpcode v, LIns* oprnd1, int32_t imm) { - return ins2(v, oprnd1, insImmI(imm)); - } - - LIns* insImmP(const void *ptr) { -#ifdef NANOJIT_64BIT - return insImmQ((uint64_t)ptr); -#else - return insImmI((int32_t)ptr); -#endif - } - - LIns* insImmWord(intptr_t value) { -#ifdef NANOJIT_64BIT - return insImmQ(value); -#else - return insImmI(value); -#endif - } - - // Sign-extend integers to native integers. On 32-bit this is a no-op. - LIns* insI2P(LIns* intIns) { -#ifdef NANOJIT_64BIT - return ins1(LIR_i2q, intIns); -#else - return intIns; -#endif - } - - // Zero-extend integers to native integers. On 32-bit this is a no-op. - LIns* insUI2P(LIns* uintIns) { - #ifdef NANOJIT_64BIT - return ins1(LIR_ui2uq, uintIns); - #else - return uintIns; - #endif - } - - // Do a load with LoadQual==LOAD_NORMAL. - LIns* insLoad(LOpcode op, LIns* base, int32_t d, AccSet accSet) { - return insLoad(op, base, d, accSet, LOAD_NORMAL); - } - - // Chooses LIR_sti, LIR_stq or LIR_std according to the type of 'value'. - LIns* insStore(LIns* value, LIns* base, int32_t d, AccSet accSet); - }; - - -#ifdef NJ_VERBOSE - extern const char* lirNames[]; - - // Maps address ranges to meaningful names. - class AddrNameMap - { - Allocator& allocator; - class Entry - { - public: - Entry(int) : name(0), size(0), align(0) {} - Entry(char *n, size_t s, size_t a) : name(n), size(s), align(a) {} - char* name; - size_t size:29, align:3; - }; - TreeMap names; // maps code regions to names - public: - AddrNameMap(Allocator& allocator); - void addAddrRange(const void *p, size_t size, size_t align, const char *name); - void lookupAddr(void *p, char*& name, int32_t& offset); - }; - - // Maps LIR instructions to meaningful names. - class LirNameMap - { - private: - Allocator& alloc; - - // A small string-wrapper class, required because we need '==' to - // compare string contents, not string pointers, when strings are used - // as keys in CountMap. - struct Str { - Allocator& alloc; - char* s; - - Str(Allocator& alloc_, const char* s_) : alloc(alloc_) { - s = new (alloc) char[1+strlen(s_)]; - strcpy(s, s_); - } - - bool operator==(const Str& str) const { - return (0 == strcmp(this->s, str.s)); - } - }; - - // Similar to 'struct Str' -- we need to hash the string's contents, - // not its pointer. - template struct StrHash { - static size_t hash(const Str &k) { - // (const void*) cast is required by ARM RVCT 2.2 - return murmurhash((const void*)k.s, strlen(k.s)); - } - }; - - template > - class CountMap: public HashMap { - public: - CountMap(Allocator& alloc) : HashMap(alloc, 128) {} - int add(Key k) { - int c = 1; - if (this->containsKey(k)) { - c = 1+this->get(k); - } - this->put(k,c); - return c; - } - }; - - CountMap lircounts; - CountMap funccounts; - CountMap > namecounts; - - void addNameWithSuffix(LIns* i, const char *s, int suffix, bool ignoreOneSuffix); - - class Entry - { - public: - Entry(int) : name(0) {} - Entry(char* n) : name(n) {} - char* name; - }; - - HashMap names; - - public: - LirNameMap(Allocator& alloc) - : alloc(alloc), - lircounts(alloc), - funccounts(alloc), - namecounts(alloc), - names(alloc) - {} - - void addName(LIns* ins, const char *s); // gives 'ins' a special name - const char* createName(LIns* ins); // gives 'ins' a generic name - const char* lookupName(LIns* ins); - }; - - // We use big buffers for cases where we need to fit a whole instruction, - // and smaller buffers for all the others. These should easily be long - // enough, but for safety the formatXyz() functions check and won't exceed - // those limits. - class InsBuf { - public: - static const size_t len = 1000; - char buf[len]; - }; - class RefBuf { - public: - static const size_t len = 200; - char buf[len]; - }; - - class LInsPrinter - { - private: - Allocator& alloc; - const int EMB_NUM_USED_ACCS; - - char *formatImmI(RefBuf* buf, int32_t c); -#ifdef NANOJIT_64BIT - char *formatImmQ(RefBuf* buf, uint64_t c); -#endif - char *formatImmD(RefBuf* buf, double c); - void formatGuard(InsBuf* buf, LIns* ins); // defined by the embedder - void formatGuardXov(InsBuf* buf, LIns* ins); // defined by the embedder - - public: - static const char* accNames[]; // defined by the embedder - - LInsPrinter(Allocator& alloc, int embNumUsedAccs) - : alloc(alloc), EMB_NUM_USED_ACCS(embNumUsedAccs) - { - addrNameMap = new (alloc) AddrNameMap(alloc); - lirNameMap = new (alloc) LirNameMap(alloc); - } - - char *formatAddr(RefBuf* buf, void* p); - char *formatRef(RefBuf* buf, LIns* ref, bool showImmValue = true); - char *formatIns(InsBuf* buf, LIns* ins); - char *formatAccSet(RefBuf* buf, AccSet accSet); - - AddrNameMap* addrNameMap; - LirNameMap* lirNameMap; - }; - - - class VerboseWriter : public LirWriter - { - InsList code; - LInsPrinter* printer; - LogControl* logc; - const char* const prefix; - bool const always_flush; - public: - VerboseWriter(Allocator& alloc, LirWriter *out, LInsPrinter* printer, LogControl* logc, - const char* prefix = "", bool always_flush = false) - : LirWriter(out), code(alloc), printer(printer), logc(logc), prefix(prefix), always_flush(always_flush) - {} - - LIns* add(LIns* i) { - if (i) { - code.add(i); - if (always_flush) - flush(); - } - return i; - } - - LIns* add_flush(LIns* i) { - if ((i = add(i)) != 0) - flush(); - return i; - } - - void flush() - { - if (!code.isEmpty()) { - InsBuf b; - for (Seq* p = code.get(); p != NULL; p = p->tail) - logc->printf("%s %s\n", prefix, printer->formatIns(&b, p->head)); - code.clear(); - } - } - - LIns* insGuard(LOpcode op, LIns* cond, GuardRecord *gr) { - return add_flush(out->insGuard(op,cond,gr)); - } - - LIns* insGuardXov(LOpcode op, LIns* a, LIns* b, GuardRecord *gr) { - return add(out->insGuardXov(op,a,b,gr)); - } - - LIns* insBranch(LOpcode v, LIns* condition, LIns* to) { - return add_flush(out->insBranch(v, condition, to)); - } - - LIns* insBranchJov(LOpcode v, LIns* a, LIns* b, LIns* to) { - return add(out->insBranchJov(v, a, b, to)); - } - - LIns* insJtbl(LIns* index, uint32_t size) { - return add_flush(out->insJtbl(index, size)); - } - - LIns* ins0(LOpcode v) { - if (v == LIR_label || v == LIR_start) { - flush(); - } - return add(out->ins0(v)); - } - - LIns* ins1(LOpcode v, LIns* a) { - return isRetOpcode(v) ? add_flush(out->ins1(v, a)) : add(out->ins1(v, a)); - } - LIns* ins2(LOpcode v, LIns* a, LIns* b) { - return add(out->ins2(v, a, b)); - } - LIns* ins3(LOpcode v, LIns* a, LIns* b, LIns* c) { - return add(out->ins3(v, a, b, c)); - } - LIns* insCall(const CallInfo *call, LIns* args[]) { - return add_flush(out->insCall(call, args)); - } - LIns* insParam(int32_t i, int32_t kind) { - return add(out->insParam(i, kind)); - } - LIns* insLoad(LOpcode v, LIns* base, int32_t disp, AccSet accSet, LoadQual loadQual) { - return add(out->insLoad(v, base, disp, accSet, loadQual)); - } - LIns* insStore(LOpcode op, LIns* v, LIns* b, int32_t d, AccSet accSet) { - return add_flush(out->insStore(op, v, b, d, accSet)); - } - LIns* insAlloc(int32_t size) { - return add(out->insAlloc(size)); - } - LIns* insImmI(int32_t imm) { - return add(out->insImmI(imm)); - } -#ifdef NANOJIT_64BIT - LIns* insImmQ(uint64_t imm) { - return add(out->insImmQ(imm)); - } -#endif - LIns* insImmD(double d) { - return add(out->insImmD(d)); - } - - LIns* insComment(const char* str) { - return add_flush(out->insComment(str)); - } - }; - -#endif - - class ExprFilter: public LirWriter - { - public: - ExprFilter(LirWriter *out) : LirWriter(out) {} - LIns* ins1(LOpcode v, LIns* a); - LIns* ins2(LOpcode v, LIns* a, LIns* b); - LIns* ins3(LOpcode v, LIns* a, LIns* b, LIns* c); - LIns* insGuard(LOpcode, LIns* cond, GuardRecord *); - LIns* insGuardXov(LOpcode, LIns* a, LIns* b, GuardRecord *); - LIns* insBranch(LOpcode, LIns* cond, LIns* target); - LIns* insBranchJov(LOpcode, LIns* a, LIns* b, LIns* target); - LIns* insLoad(LOpcode op, LIns* base, int32_t off, AccSet accSet, LoadQual loadQual); - private: - LIns* simplifyOverflowArith(LOpcode op, LIns** opnd1, LIns** opnd2); - }; - - class CseFilter: public LirWriter - { - enum NLKind { - // We divide instruction kinds into groups. LIns0 isn't present - // because we don't need to record any 0-ary instructions. Loads - // aren't here, they're handled separately. - NLImmISmall = 0, - NLImmILarge = 1, - NLImmQ = 2, // only occurs on 64-bit platforms - NLImmD = 3, - NL1 = 4, - NL2 = 5, - NL3 = 6, - NLCall = 7, - - NLFirst = 0, - NLLast = 7, - // Need a value after "last" to outsmart compilers that insist last+1 is impossible. - NLInvalid = 8 - }; - #define nextNLKind(kind) NLKind(kind+1) - - // There is one table for each NLKind. This lets us size the lists - // appropriately (some instruction kinds are more common than others). - // It also lets us have NLKind-specific find/add/grow functions, which - // are faster than generic versions. - // - // Nb: m_listNL and m_capNL sizes must be a power of 2. - // Don't start m_capNL too small, or we'll waste time growing and rehashing. - // Don't start m_capNL too large, will waste memory. - // - LIns** m_listNL[NLLast + 1]; - uint32_t m_capNL[ NLLast + 1]; - uint32_t m_usedNL[NLLast + 1]; - typedef uint32_t (CseFilter::*find_t)(LIns*); - find_t m_findNL[NLLast + 1]; - - // Similarly, for loads, there is one table for each CseAcc. A CseAcc - // is like a normal access region, but there are two extra possible - // values: CSE_ACC_CONST, which is where we put all CONST-qualified - // loads, and CSE_ACC_MULTIPLE, where we put all multi-region loads. - // All remaining loads are single-region and go in the table entry for - // their region. - // - // This arrangement makes the removal of invalidated loads fast -- we - // can invalidate all loads from a single region by clearing that - // region's table. - // - typedef uint8_t CseAcc; // same type as MiniAccSet - - static const uint8_t CSE_NUM_ACCS = NUM_ACCS + 2; - - // These values would be 'static const' except they are defined in - // terms of EMB_NUM_USED_ACCS which is itself not 'static const' - // because it's passed in by the embedding. - const uint8_t EMB_NUM_USED_ACCS; // number of access regions used by the embedding - const uint8_t CSE_NUM_USED_ACCS; // EMB_NUM_USED_ACCS + 2 - const CseAcc CSE_ACC_CONST; // EMB_NUM_USED_ACCS + 0 - const CseAcc CSE_ACC_MULTIPLE; // EMB_NUM_USED_ACCS + 1 - - // We will only use CSE_NUM_USED_ACCS of these entries, ie. the - // number of lists allocated depends on the number of access regions - // in use by the embedding. - LIns** m_listL[CSE_NUM_ACCS]; - uint32_t m_capL[ CSE_NUM_ACCS]; - uint32_t m_usedL[CSE_NUM_ACCS]; - - AccSet storesSinceLastLoad; // regions stored to since the last load - - Allocator& alloc; - - // After a conditional guard such as "xf cmp", we know that 'cmp' must - // be true, else we would have side-exited. So if we see 'cmp' again - // we can treat it like a constant. This table records such - // comparisons. - HashMap knownCmpValues; - - // If true, we will not add new instructions to the CSE tables, but we - // will continue to CSE instructions that match existing table - // entries. Load instructions will still be removed if aliasing - // stores are encountered. - bool suspended; - - CseAcc miniAccSetToCseAcc(MiniAccSet miniAccSet, LoadQual loadQual) { - NanoAssert(miniAccSet.val < NUM_ACCS || miniAccSet.val == MINI_ACCSET_MULTIPLE.val); - return (loadQual == LOAD_CONST) ? CSE_ACC_CONST : - (miniAccSet.val == MINI_ACCSET_MULTIPLE.val) ? CSE_ACC_MULTIPLE : - miniAccSet.val; - } - - static uint32_t hash8(uint32_t hash, const uint8_t data); - static uint32_t hash32(uint32_t hash, const uint32_t data); - static uint32_t hashptr(uint32_t hash, const void* data); - static uint32_t hashfinish(uint32_t hash); - - static uint32_t hashImmI(int32_t); - static uint32_t hashImmQorD(uint64_t); // not NANOJIT_64BIT-only -- used by findImmD() - static uint32_t hash1(LOpcode op, LIns*); - static uint32_t hash2(LOpcode op, LIns*, LIns*); - static uint32_t hash3(LOpcode op, LIns*, LIns*, LIns*); - static uint32_t hashLoad(LOpcode op, LIns*, int32_t); - static uint32_t hashCall(const CallInfo *call, uint32_t argc, LIns* args[]); - - // These versions are used before an LIns has been created. - LIns* findImmISmall(int32_t a, uint32_t &k); - LIns* findImmILarge(int32_t a, uint32_t &k); -#ifdef NANOJIT_64BIT - LIns* findImmQ(uint64_t a, uint32_t &k); -#endif - LIns* findImmD(uint64_t d, uint32_t &k); - LIns* find1(LOpcode v, LIns* a, uint32_t &k); - LIns* find2(LOpcode v, LIns* a, LIns* b, uint32_t &k); - LIns* find3(LOpcode v, LIns* a, LIns* b, LIns* c, uint32_t &k); - LIns* findLoad(LOpcode v, LIns* a, int32_t b, MiniAccSet miniAccSet, LoadQual loadQual, - uint32_t &k); - LIns* findCall(const CallInfo *call, uint32_t argc, LIns* args[], uint32_t &k); - - // These versions are used after an LIns has been created; they are - // used for rehashing after growing. They just call onto the - // multi-arg versions above. - uint32_t findImmISmall(LIns* ins); - uint32_t findImmILarge(LIns* ins); -#ifdef NANOJIT_64BIT - uint32_t findImmQ(LIns* ins); -#endif - uint32_t findImmD(LIns* ins); - uint32_t find1(LIns* ins); - uint32_t find2(LIns* ins); - uint32_t find3(LIns* ins); - uint32_t findCall(LIns* ins); - uint32_t findLoad(LIns* ins); - - // These return false if they failed to grow due to OOM. - bool growNL(NLKind kind); - bool growL(CseAcc cseAcc); - - void addNLImmISmall(LIns* ins, uint32_t k); - // 'k' is the index found by findXYZ(). - void addNL(NLKind kind, LIns* ins, uint32_t k); - void addL(LIns* ins, uint32_t k); - - void clearAll(); // clears all tables - void clearNL(NLKind); // clears one non-load table - void clearL(CseAcc); // clears one load table - - public: - CseFilter(LirWriter *out, uint8_t embNumUsedAccs, Allocator&); - - // CseFilter does some largish fallible allocations at start-up. If - // they fail, the constructor sets this field to 'true'. It should be - // checked after creation, and if set the CseFilter cannot be used. - // (But the check can be skipped if allocChunk() always succeeds.) - // - // FIXME: This fallibility is a sop to TraceMonkey's implementation of - // infallible malloc -- by avoiding some largish infallible - // allocations, it reduces the size of the reserve space needed. - // Bug 624590 is open to fix this. - bool initOOM; - - LIns* insImmI(int32_t imm); -#ifdef NANOJIT_64BIT - LIns* insImmQ(uint64_t q); -#endif - LIns* insImmD(double d); - LIns* ins0(LOpcode v); - LIns* ins1(LOpcode v, LIns*); - LIns* ins2(LOpcode v, LIns*, LIns*); - LIns* ins3(LOpcode v, LIns*, LIns*, LIns*); - LIns* insLoad(LOpcode op, LIns* base, int32_t d, AccSet accSet, LoadQual loadQual); - LIns* insStore(LOpcode op, LIns* value, LIns* base, int32_t d, AccSet accSet); - LIns* insCall(const CallInfo *call, LIns* args[]); - LIns* insGuard(LOpcode op, LIns* cond, GuardRecord *gr); - LIns* insGuardXov(LOpcode op, LIns* a, LIns* b, GuardRecord *gr); - - // These functions provide control over CSE in the face of control - // flow. A suspend()/resume() pair may be put around a synthetic - // control flow diamond, preventing the inserted label from resetting - // the CSE state. A suspend() call must be dominated by a resume() - // call, else incorrect code could result. - void suspend() { suspended = true; } - void resume() { suspended = false; } - }; - - class LirBuffer - { - public: - LirBuffer(Allocator& alloc); - void clear(); - uintptr_t makeRoom(size_t szB); // make room for an instruction - - debug_only (void validate() const;) - verbose_only(LInsPrinter* printer;) - - int32_t insCount(); - - // stats - struct - { - uint32_t lir; // # instructions - } - _stats; - - AbiKind abi; - LIns *state, *param1, *sp, *rp; - LIns* savedRegs[NumSavedRegs+1]; // Allocate an extra element in case NumSavedRegs == 0 - - /** Each chunk is just a raw area of LIns instances, with no header - and no more than 8-byte alignment. The chunk size is somewhat arbitrary. */ - static const size_t CHUNK_SZB = 8000; - - protected: - friend class LirBufWriter; - - /** Get CHUNK_SZB more memory for LIR instructions. */ - void chunkAlloc(); - void moveToNewChunk(uintptr_t addrOfLastLInsOnCurrentChunk); - - Allocator& _allocator; - uintptr_t _unused; // next unused instruction slot in the current LIR chunk - uintptr_t _limit; // one past the last usable byte of the current LIR chunk - }; - - class LirBufWriter : public LirWriter - { - LirBuffer* _buf; // underlying buffer housing the instructions - const Config& _config; - - public: - LirBufWriter(LirBuffer* buf, const Config& config) - : LirWriter(0), _buf(buf), _config(config) { - } - - // LirWriter interface - LIns* insLoad(LOpcode op, LIns* base, int32_t disp, AccSet accSet, LoadQual loadQual); - LIns* insStore(LOpcode op, LIns* o1, LIns* o2, int32_t disp, AccSet accSet); - LIns* ins0(LOpcode op); - LIns* ins1(LOpcode op, LIns* o1); - LIns* ins2(LOpcode op, LIns* o1, LIns* o2); - LIns* ins3(LOpcode op, LIns* o1, LIns* o2, LIns* o3); - LIns* insParam(int32_t i, int32_t kind); - LIns* insImmI(int32_t imm); -#ifdef NANOJIT_64BIT - LIns* insImmQ(uint64_t imm); -#endif - LIns* insImmD(double d); - LIns* insCall(const CallInfo *call, LIns* args[]); - LIns* insGuard(LOpcode op, LIns* cond, GuardRecord *gr); - LIns* insGuardXov(LOpcode op, LIns* a, LIns* b, GuardRecord *gr); - LIns* insBranch(LOpcode v, LIns* condition, LIns* to); - LIns* insBranchJov(LOpcode v, LIns* a, LIns* b, LIns* to); - LIns* insAlloc(int32_t size); - LIns* insJtbl(LIns* index, uint32_t size); - LIns* insComment(const char* str); - }; - - class LirFilter - { - public: - LirFilter *in; - LirFilter(LirFilter *in) : in(in) {} - virtual ~LirFilter(){} - - // It's crucial that once this reaches the LIR_start at the beginning - // of the buffer, that it just keeps returning that LIR_start LIns on - // any subsequent calls. - virtual LIns* read() { - return in->read(); - } - virtual LIns* finalIns() { - return in->finalIns(); - } - }; - - // concrete - class LirReader : public LirFilter - { - LIns* _ins; // next instruction to be read; invariant: is never a skip - LIns* _finalIns; // final instruction in the stream; ie. the first one to be read - - public: - LirReader(LIns* ins) : LirFilter(0), _ins(ins), _finalIns(ins) - { - // The last instruction for a fragment shouldn't be a skip. - // (Actually, if the last *inserted* instruction exactly fills up - // a chunk, a new chunk will be created, and thus the last *written* - // instruction will be a skip -- the one needed for the - // cross-chunk link. But the last *inserted* instruction is what - // is recorded and used to initialise each LirReader, and that is - // what is seen here, and therefore this assertion holds.) - NanoAssert(ins && !ins->isop(LIR_skip)); - } - virtual ~LirReader() {} - - // Returns next instruction and advances to the prior instruction. - // Invariant: never returns a skip. - LIns* read(); - - LIns* finalIns() { - return _finalIns; - } - }; - - verbose_only(void live(LirFilter* in, Allocator& alloc, Fragment* frag, LogControl*);) - - // WARNING: StackFilter assumes that all stack entries are eight bytes. - // Some of its optimisations aren't valid if that isn't true. See - // StackFilter::read() for more details. - class StackFilter: public LirFilter - { - LIns* sp; - BitSet stk; - int top; - int getTop(LIns* br); - - public: - StackFilter(LirFilter *in, Allocator& alloc, LIns* sp); - LIns* read(); - }; - - // This type is used to perform a simple interval analysis of 32-bit - // add/sub/mul. It lets us avoid overflow checks in some cases. - struct Interval - { - // The bounds are 64-bit integers so that any overflow from a 32-bit - // operation can be safely detected. - // - // If 'hasOverflowed' is false, 'lo' and 'hi' must be in the range - // I32_MIN..I32_MAX. If 'hasOverflowed' is true, 'lo' and 'hi' should - // not be trusted (and in debug builds we set them both to a special - // value UNTRUSTWORTHY that is outside the I32_MIN..I32_MAX range to - // facilitate sanity checking). - // - int64_t lo; - int64_t hi; - bool hasOverflowed; - - static const int64_t I32_MIN = int64_t(int32_t(0x80000000)); - static const int64_t I32_MAX = int64_t(int32_t(0x7fffffff)); - -#ifdef DEBUG - static const int64_t UNTRUSTWORTHY = int64_t(0xdeafdeadbeeffeedLL); - - bool isSane() { - return (hasOverflowed && lo == UNTRUSTWORTHY && hi == UNTRUSTWORTHY) || - (!hasOverflowed && lo <= hi && I32_MIN <= lo && hi <= I32_MAX); - } -#endif - - Interval(int64_t lo_, int64_t hi_) { - if (lo_ < I32_MIN || I32_MAX < hi_) { - hasOverflowed = true; -#ifdef DEBUG - lo = UNTRUSTWORTHY; - hi = UNTRUSTWORTHY; -#endif - } else { - hasOverflowed = false; - lo = lo_; - hi = hi_; - } - NanoAssert(isSane()); - } - - static Interval OverflowInterval() { - Interval interval(0, 0); -#ifdef DEBUG - interval.lo = UNTRUSTWORTHY; - interval.hi = UNTRUSTWORTHY; -#endif - interval.hasOverflowed = true; - return interval; - } - - static Interval of(LIns* ins, int32_t lim); - - static Interval add(Interval x, Interval y); - static Interval sub(Interval x, Interval y); - static Interval mul(Interval x, Interval y); - - bool canBeZero() { - NanoAssert(isSane()); - return hasOverflowed || (lo <= 0 && 0 <= hi); - } - - bool canBeNegative() { - NanoAssert(isSane()); - return hasOverflowed || (lo < 0); - } - }; - -#if NJ_SOFTFLOAT_SUPPORTED - struct SoftFloatOps - { - const CallInfo* opmap[LIR_sentinel]; - SoftFloatOps(); - }; - - extern const SoftFloatOps softFloatOps; - - // Replaces fpu ops with function calls, for platforms lacking float - // hardware (eg. some ARM machines). - class SoftFloatFilter: public LirWriter - { - public: - static const CallInfo* opmap[LIR_sentinel]; - - SoftFloatFilter(LirWriter *out); - LIns *split(LIns *a); - LIns *split(const CallInfo *call, LIns* args[]); - LIns *callD1(const CallInfo *call, LIns *a); - LIns *callD2(const CallInfo *call, LIns *a, LIns *b); - LIns *callI1(const CallInfo *call, LIns *a); - LIns *cmpD(const CallInfo *call, LIns *a, LIns *b); - LIns *ins1(LOpcode op, LIns *a); - LIns *ins2(LOpcode op, LIns *a, LIns *b); - LIns *insCall(const CallInfo *ci, LIns* args[]); - }; -#endif - -#ifdef DEBUG - // This class does thorough checking of LIR. It checks *implicit* LIR - // instructions, ie. LIR instructions specified via arguments -- to - // methods like insLoad() -- that have not yet been converted into - // *explicit* LIns objects in a LirBuffer. The reason for this is that if - // we wait until the LIR instructions are explicit, they will have gone - // through the entire writer pipeline and been optimised. By checking - // implicit LIR instructions we can check the LIR code at the start of the - // writer pipeline, exactly as it is generated by the compiler front-end. - // - // A general note about the errors produced by this class: for - // TraceMonkey, they won't include special names for instructions that - // have them unless TMFLAGS is specified. - class ValidateWriter : public LirWriter - { - private: - LInsPrinter* printer; - const char* whereInPipeline; - - const char* type2string(LTy type); - void typeCheckArgs(LOpcode op, int nArgs, LTy formals[], LIns* args[]); - void errorStructureShouldBe(LOpcode op, const char* argDesc, int argN, LIns* arg, - const char* shouldBeDesc); - void errorAccSet(const char* what, AccSet accSet, const char* shouldDesc); - void errorLoadQual(const char* what, LoadQual loadQual); - void checkLInsHasOpcode(LOpcode op, int argN, LIns* ins, LOpcode op2); - void checkLInsIsACondOrConst(LOpcode op, int argN, LIns* ins); - void checkLInsIsNull(LOpcode op, int argN, LIns* ins); - void checkAccSet(LOpcode op, LIns* base, int32_t disp, AccSet accSet); // defined by the embedder - - // These can be set by the embedder and used in checkAccSet(). - void** checkAccSetExtras; - - public: - ValidateWriter(LirWriter* out, LInsPrinter* printer, const char* where); - void setCheckAccSetExtras(void** extras) { checkAccSetExtras = extras; } - - LIns* insLoad(LOpcode op, LIns* base, int32_t d, AccSet accSet, LoadQual loadQual); - LIns* insStore(LOpcode op, LIns* value, LIns* base, int32_t d, AccSet accSet); - LIns* ins0(LOpcode v); - LIns* ins1(LOpcode v, LIns* a); - LIns* ins2(LOpcode v, LIns* a, LIns* b); - LIns* ins3(LOpcode v, LIns* a, LIns* b, LIns* c); - LIns* insParam(int32_t arg, int32_t kind); - LIns* insImmI(int32_t imm); -#ifdef NANOJIT_64BIT - LIns* insImmQ(uint64_t imm); -#endif - LIns* insImmD(double d); - LIns* insCall(const CallInfo *call, LIns* args[]); - LIns* insGuard(LOpcode v, LIns *c, GuardRecord *gr); - LIns* insGuardXov(LOpcode v, LIns* a, LIns* b, GuardRecord* gr); - LIns* insBranch(LOpcode v, LIns* condition, LIns* to); - LIns* insBranchJov(LOpcode v, LIns* a, LIns* b, LIns* to); - LIns* insAlloc(int32_t size); - LIns* insJtbl(LIns* index, uint32_t size); - }; - - // This just checks things that aren't possible to check in - // ValidateWriter, eg. whether all branch targets are set and are labels. - class ValidateReader: public LirFilter { - public: - ValidateReader(LirFilter* in); - LIns* read(); - }; -#endif - -#ifdef NJ_VERBOSE - /* A listing filter for LIR, going through backwards. It merely - passes its input to its output, but notes it down too. When - finish() is called, prints out what went through. Is intended to be - used to print arbitrary intermediate transformation stages of - LIR. */ - class ReverseLister : public LirFilter - { - Allocator& _alloc; - LInsPrinter* _printer; - const char* _title; - StringList _strs; - LogControl* _logc; - LIns* _prevIns; - public: - ReverseLister(LirFilter* in, Allocator& alloc, - LInsPrinter* printer, LogControl* logc, const char* title) - : LirFilter(in) - , _alloc(alloc) - , _printer(printer) - , _title(title) - , _strs(alloc) - , _logc(logc) - , _prevIns(NULL) - { } - - void finish(); - LIns* read(); - }; -#endif - -} -#endif // __nanojit_LIR__ diff --git a/x86/mozilla/include/LIRopcode.tbl b/x86/mozilla/include/LIRopcode.tbl deleted file mode 100644 index 4a30079..0000000 --- a/x86/mozilla/include/LIRopcode.tbl +++ /dev/null @@ -1,367 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=0 ft=c: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is SpiderMonkey nanojit. - * - * The Initial Developer of the Original Code is - * the Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Jeff Walden - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * This file is best viewed with 128 columns: -12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678 - * - * Definitions of LIR opcodes. If you need to allocate an opcode, look - * for one defined using OP_UN() and claim it. - * - * Includers must define an OPxyz macro of the following form: - * - * #define OPxyz(op, number, repKind, retType) ... - * - * Selected arguments can then be used within the macro expansions. - * - op Opcode name, token-pasted after "LIR_" to form an LOpcode. - * - number Opcode number, used as the LOpcode enum value. - * - repKind Indicates how the instruction is represented in memory; XYZ - * corresponds to LInsXYZ and LRK_XYZ. - * - retType Type (LTy) of the value returned by the instruction. - * - isCse 0 if the opcode can never be CSE'd safely, 1 if it always - * can, -1 if things are more complicated -- in which case - * isCseOpcode() shouldn't be called on this opcode. - * - * Opcodes use type-indicators suffixes that are loosly based on C type names: - * - 'c': "char", ie. 8-bit integer - * - 's': "short", ie. 16-bit integer - * - 'i': "int", ie. 32-bit integer - * - 'q': "quad", ie. 64-bit integer - * - 'u': "unsigned", is used as a prefix on integer type-indicators when necessary - * - 'f': "float", ie. 32-bit floating point value - * - 'd': "double", ie. 64-bit floating point value - * - 'p': "pointer", ie. a int on 32-bit machines, a quad on 64-bit machines - * - * 'p' opcodes are all aliases of int and quad opcodes, they're given in LIR.h - * and chosen according to the platform pointer size. - * - * Certain opcodes aren't supported on all platforms, so OPxyz must be one of - * the following: - * - * OP___: for opcodes supported on all platforms. - * OP_UN: for opcodes not yet used on any platform. - * OP_32: for opcodes supported only on 32-bit platforms. - * OP_64: for opcodes supported only on 64-bit platforms. - * OP_SF: for opcodes supported only on SoftFloat platforms. - * OP_86: for opcodes supported only on i386/X64. - */ - -#define OP_UN(n) OP___(__##n, n, None, V, -1) - -#ifdef NANOJIT_64BIT -# define OP_32(a, b, c, d, e) OP_UN(b) -# define OP_64 OP___ -#else -# define OP_32 OP___ -# define OP_64(a, b, c, d, e) OP_UN(b) -#endif - -#if NJ_SOFTFLOAT_SUPPORTED -# define OP_SF OP___ -#else -# define OP_SF(a, b, c, d, e) OP_UN(b) -#endif - -#if defined NANOJIT_IA32 || defined NANOJIT_X64 -# define OP_86 OP___ -#else -# define OP_86(a, b, c, d, e) OP_UN(b) -#endif - -//--------------------------------------------------------------------------- -// Miscellaneous operations -//--------------------------------------------------------------------------- -OP___(start, 0, Op0, V, 0) // start of a fragment - -// A register fence causes no code to be generated, but it affects register -// allocation so that no registers are live when it is reached. -OP___(regfence, 1, Op0, V, 0) - -OP___(skip, 2, Sk, V, 0) // links code chunks - -OP_32(parami, 3, P, I, 0) // load an int parameter (register or stack location) -OP_64(paramq, 4, P, Q, 0) // load a quad parameter (register or stack location) - -OP___(allocp, 5, I, P, 0) // allocate stack space (result is an address) - -OP___(reti, 6, Op1, V, 0) // return an int -OP_64(retq, 7, Op1, V, 0) // return a quad -OP___(retd, 8, Op1, V, 0) // return a double - -OP___(livei, 9, Op1, V, 0) // extend live range of an int -OP_64(liveq, 10, Op1, V, 0) // extend live range of a quad -OP___(lived, 11, Op1, V, 0) // extend live range of a double - -OP___(file, 12, Op1, V, 0) // source filename for debug symbols -OP___(line, 13, Op1, V, 0) // source line number for debug symbols - -OP___(comment, 14, Op1, V, 0) // a comment shown, on its own line, in LIR dumps -OP_UN(15) -OP_UN(16) - -//--------------------------------------------------------------------------- -// Loads and stores -//--------------------------------------------------------------------------- -OP___(ldc2i, 17, Ld, I, -1) // load char and sign-extend to an int -OP___(lds2i, 18, Ld, I, -1) // load short and sign-extend to an int -OP___(lduc2ui, 19, Ld, I, -1) // load unsigned char and zero-extend to an unsigned int -OP___(ldus2ui, 20, Ld, I, -1) // load unsigned short and zero-extend to an unsigned int -OP___(ldi, 21, Ld, I, -1) // load int -OP_64(ldq, 22, Ld, Q, -1) // load quad -OP___(ldd, 23, Ld, D, -1) // load double -OP___(ldf2d, 24, Ld, D, -1) // load float and extend to a double - -OP___(sti2c, 25, St, V, 0) // store int truncated to char -OP___(sti2s, 26, St, V, 0) // store int truncated to short -OP___(sti, 27, St, V, 0) // store int -OP_64(stq, 28, St, V, 0) // store quad -OP___(std, 29, St, V, 0) // store double -OP___(std2f, 30, St, V, 0) // store double as a float (losing precision) - -OP_UN(31) -OP_UN(32) - -//--------------------------------------------------------------------------- -// Calls -//--------------------------------------------------------------------------- -OP___(callv, 33, C, V, -1) // call subroutine that returns void -OP___(calli, 34, C, I, -1) // call subroutine that returns an int -OP_64(callq, 35, C, Q, -1) // call subroutine that returns a quad -OP___(calld, 36, C, D, -1) // call subroutine that returns a double - -//--------------------------------------------------------------------------- -// Branches and labels -//--------------------------------------------------------------------------- -// 'jt' and 'jf' must be adjacent so that (op ^ 1) gives the opposite one. -// Static assertions in LIR.h check this requirement. -OP___(j, 37, Op2, V, 0) // jump always -OP___(jt, 38, Op2, V, 0) // jump if true -OP___(jf, 39, Op2, V, 0) // jump if false -OP___(jtbl, 40, Jtbl, V, 0) // jump to address in table - -OP___(label, 41, Op0, V, 0) // a jump target (no machine code is emitted for this) - -OP_UN(42) - -//--------------------------------------------------------------------------- -// Guards -//--------------------------------------------------------------------------- -// 'xt' and 'xf' must be adjacent so that (op ^ 1) gives the opposite one. -// Static assertions in LIR.h check this requirement. -OP___(x, 43, Op2, V, 0) // exit always -OP___(xt, 44, Op2, V, 1) // exit if true -OP___(xf, 45, Op2, V, 1) // exit if false -OP___(xtbl, 46, Op2, V, 0) // exit via indirect jump -// A LIR_xbarrier cause no code to be generated, but it acts like a never-taken -// guard in that it inhibits certain optimisations, such as dead stack store -// elimination. -OP___(xbarrier, 47, Op2, V, 0) - -OP_UN(48) - -//--------------------------------------------------------------------------- -// Immediates -//--------------------------------------------------------------------------- -OP___(immi, 49, I, I, 1) // int immediate -OP_64(immq, 50, QorD, Q, 1) // quad immediate -OP___(immd, 51, QorD, D, 1) // double immediate - -OP_UN(52) - -//--------------------------------------------------------------------------- -// Comparisons -//--------------------------------------------------------------------------- - -// All comparisons return an int: 0 on failure and 1 on success. -// -// Within each type group, order must be preserved so that, except for eq*, (op -// ^ 1) gives the opposite one (eg. lt ^ 1 == gt). eq* must have odd numbers -// for this to work. They must also remain contiguous so that opcode range -// checking works correctly. Static assertions in LIR.h check these -// requirements. -OP___(eqi, 53, Op2, I, 1) // int equality -OP___(lti, 54, Op2, I, 1) // signed int less-than -OP___(gti, 55, Op2, I, 1) // signed int greater-than -OP___(lei, 56, Op2, I, 1) // signed int less-than-or-equal -OP___(gei, 57, Op2, I, 1) // signed int greater-than-or-equal -OP___(ltui, 58, Op2, I, 1) // unsigned int less-than -OP___(gtui, 59, Op2, I, 1) // unsigned int greater-than -OP___(leui, 60, Op2, I, 1) // unsigned int less-than-or-equal -OP___(geui, 61, Op2, I, 1) // unsigned int greater-than-or-equal - -OP_UN(62) - -OP_64(eqq, 63, Op2, I, 1) // quad equality -OP_64(ltq, 64, Op2, I, 1) // signed quad less-than -OP_64(gtq, 65, Op2, I, 1) // signed quad greater-than -OP_64(leq, 66, Op2, I, 1) // signed quad less-than-or-equal -OP_64(geq, 67, Op2, I, 1) // signed quad greater-than-or-equal -OP_64(ltuq, 68, Op2, I, 1) // unsigned quad less-than -OP_64(gtuq, 69, Op2, I, 1) // unsigned quad greater-than -OP_64(leuq, 70, Op2, I, 1) // unsigned quad less-than-or-equal -OP_64(geuq, 71, Op2, I, 1) // unsigned quad greater-than-or-equal - -OP_UN(72) - -OP___(eqd, 73, Op2, I, 1) // double equality -OP___(ltd, 74, Op2, I, 1) // double less-than -OP___(gtd, 75, Op2, I, 1) // double greater-than -OP___(led, 76, Op2, I, 1) // double less-than-or-equal -OP___(ged, 77, Op2, I, 1) // double greater-than-or-equal - -//--------------------------------------------------------------------------- -// Arithmetic -//--------------------------------------------------------------------------- -OP___(negi, 78, Op1, I, 1) // negate int -OP___(addi, 79, Op2, I, 1) // add int -OP___(subi, 80, Op2, I, 1) // subtract int -OP___(muli, 81, Op2, I, 1) // multiply int -OP_86(divi, 82, Op2, I, 1) // divide int -// LIR_modi is a hack. It's only used on i386/X64. The operand is the result -// of a LIR_divi because on i386/X64 div and mod results are computed by the -// same instruction. -OP_86(modi, 83, Op1, I, 1) // modulo int - -OP___(noti, 84, Op1, I, 1) // bitwise-NOT int -OP___(andi, 85, Op2, I, 1) // bitwise-AND int -OP___(ori, 86, Op2, I, 1) // bitwise-OR int -OP___(xori, 87, Op2, I, 1) // bitwise-XOR int - -// For all three integer shift operations, only the bottom five bits of the -// second operand are used, and they are treated as unsigned. This matches -// x86 semantics. -OP___(lshi, 88, Op2, I, 1) // left shift int -OP___(rshi, 89, Op2, I, 1) // right shift int (>>) -OP___(rshui, 90, Op2, I, 1) // right shift unsigned int (>>>) - -OP_64(addq, 91, Op2, Q, 1) // add quad -OP_64(subq, 92, Op2, Q, 1) // subtract quad - -OP_64(andq, 93, Op2, Q, 1) // bitwise-AND quad -OP_64(orq, 94, Op2, Q, 1) // bitwise-OR quad -OP_64(xorq, 95, Op2, Q, 1) // bitwise-XOR quad - -// For all three quad shift operations, only the bottom six bits of the -// second operand are used, and they are treated as unsigned. This matches -// x86-64 semantics. -OP_64(lshq, 96, Op2, Q, 1) // left shift quad; 2nd operand is an int -OP_64(rshq, 97, Op2, Q, 1) // right shift quad; 2nd operand is an int -OP_64(rshuq, 98, Op2, Q, 1) // right shift unsigned quad; 2nd operand is an int - -OP___(negd, 99, Op1, D, 1) // negate double -OP___(addd, 100, Op2, D, 1) // add double -OP___(subd, 101, Op2, D, 1) // subtract double -OP___(muld, 102, Op2, D, 1) // multiply double -OP___(divd, 103, Op2, D, 1) // divide double -// LIR_modd is just a place-holder opcode, ie. the back-ends cannot generate -// code for it. It's used in TraceMonkey briefly but is always demoted to a -// LIR_modl or converted to a function call before Nanojit has to do anything -// serious with it. -OP___(modd, 104, Op2, D, 1) // modulo double - -OP___(cmovi, 105, Op3, I, 1) // conditional move int -OP_64(cmovq, 106, Op3, Q, 1) // conditional move quad -OP___(cmovd, 107, Op3, D, 1) // conditional move double - -//--------------------------------------------------------------------------- -// Conversions -//--------------------------------------------------------------------------- -OP_64(i2q, 108, Op1, Q, 1) // sign-extend int to quad -OP_64(ui2uq, 109, Op1, Q, 1) // zero-extend unsigned int to unsigned quad -OP_64(q2i, 110, Op1, I, 1) // truncate quad to int (removes the high 32 bits) - -OP___(i2d, 111, Op1, D, 1) // convert int to double -OP___(ui2d, 112, Op1, D, 1) // convert unsigned int to double - -// The rounding behavior of LIR_d2i is platform specific. -// -// Platform Asm code Behavior -// -------- -------- -------- -// x86 w/ x87 fist uses current FP control word (default is rounding) -// x86 w/ SSE cvttsd2si performs round to zero (truncate) -// x64 (SSE) cvttsd2si performs round to zero (truncate) -// PowerPC unsupported -// ARM ftosid round to nearest -// MIPS trunc.w.d performs round to zero (truncate) -// SH4 frtc performs round to zero (truncate) -// SPARC fdtoi performs round to zero (truncate) -// -// round to zero examples: 1.9 -> 1, 1.1 -> 1, -1.1 -> -1, -1.9 -> -1 -// round to nearest examples: 1.9 -> 2, 1.1 -> 1, -1.1 -> -1, -1.9 -> -2 -OP___(d2i, 113, Op1, I, 1) // convert double to int (no exceptions raised) - -OP_64(dasq, 114, Op1, Q, 1) // interpret the bits of a double as a quad -OP_64(qasd, 115, Op1, D, 1) // interpret the bits of a quad as a double - -//--------------------------------------------------------------------------- -// Overflow arithmetic -//--------------------------------------------------------------------------- -// These all exit if overflow occurred. The result is valid on either path. -OP___(addxovi, 116, Op3, I, 1) // add int and exit on overflow -OP___(subxovi, 117, Op3, I, 1) // subtract int and exit on overflow -OP___(mulxovi, 118, Op3, I, 1) // multiply int and exit on overflow - -// These all branch if overflow occurred. The result is valid on either path. -OP___(addjovi, 119, Op3, I, 1) // add int and branch on overflow -OP___(subjovi, 120, Op3, I, 1) // subtract int and branch on overflow -OP___(muljovi, 121, Op3, I, 1) // multiply int and branch on overflow - -OP_64(addjovq, 122, Op3, Q, 1) // add quad and branch on overflow -OP_64(subjovq, 123, Op3, Q, 1) // subtract quad and branch on overflow - -//--------------------------------------------------------------------------- -// SoftFloat -//--------------------------------------------------------------------------- -OP_SF(dlo2i, 124, Op1, I, 1) // get the low 32 bits of a double as an int -OP_SF(dhi2i, 125, Op1, I, 1) // get the high 32 bits of a double as an int -OP_SF(ii2d, 126, Op2, D, 1) // join two ints (1st arg is low bits, 2nd is high) - -// LIR_hcalli is a hack that's only used on 32-bit platforms that use -// SoftFloat. Its operand is always a LIR_calli, but one that specifies a -// function that returns a double. It indicates that the double result is -// returned via two 32-bit integer registers. The result is always used as the -// second operand of a LIR_ii2d. -OP_SF(hcalli, 127, Op1, I, 1) - -#undef OP_UN -#undef OP_32 -#undef OP_64 -#undef OP_SF -#undef OP_86 diff --git a/x86/mozilla/include/Native.h b/x86/mozilla/include/Native.h deleted file mode 100644 index dc67b13..0000000 --- a/x86/mozilla/include/Native.h +++ /dev/null @@ -1,193 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ -/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is [Open Source Virtual Machine]. - * - * The Initial Developer of the Original Code is - * Adobe System Incorporated. - * Portions created by the Initial Developer are Copyright (C) 2004-2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Adobe AS3 Team - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - - -#ifndef __nanojit_Native__ -#define __nanojit_Native__ - -// define PEDANTIC=1 to ignore specialized forms, force general forms -// for everything, far branches, extra page-linking, etc. This will -// flush out many corner cases. - -#define PEDANTIC 0 -#if PEDANTIC -# define UNLESS_PEDANTIC(...) -# define IF_PEDANTIC(...) __VA_ARGS__ -#else -# define UNLESS_PEDANTIC(...) __VA_ARGS__ -# define IF_PEDANTIC(...) -#endif - -#ifdef NANOJIT_IA32 -#include "Nativei386.h" -#elif defined(NANOJIT_ARM) -#include "NativeARM.h" -#elif defined(NANOJIT_PPC) -#include "NativePPC.h" -#elif defined(NANOJIT_SPARC) -#include "NativeSparc.h" -#elif defined(NANOJIT_X64) -#include "NativeX64.h" -#elif defined(NANOJIT_SH4) -#include "NativeSH4.h" -#elif defined(NANOJIT_MIPS) -#include "NativeMIPS.h" -#else -#error "unknown nanojit architecture" -#endif - -#ifndef NJ_USES_IMMD_POOL -# define NJ_USES_IMMD_POOL 0 -#endif - -#ifndef NJ_JTBL_SUPPORTED -# define NJ_JTBL_SUPPORTED 0 -#endif - -#ifndef NJ_EXPANDED_LOADSTORE_SUPPORTED -# define NJ_EXPANDED_LOADSTORE_SUPPORTED 0 -#endif - -#ifndef NJ_F2I_SUPPORTED -# define NJ_F2I_SUPPORTED 0 -#endif - -#ifndef NJ_SOFTFLOAT_SUPPORTED -# define NJ_SOFTFLOAT_SUPPORTED 0 -#endif - -#ifndef NJ_DIVI_SUPPORTED -# define NJ_DIVI_SUPPORTED 0 -#endif - -#if NJ_SOFTFLOAT_SUPPORTED - #define CASESF(x) case x -#else - #define CASESF(x) -#endif - -namespace nanojit { - - class Fragment; - struct SideExit; - struct SwitchInfo; - - struct GuardRecord - { - void* jmp; - GuardRecord* next; - SideExit* exit; - // profiling stuff - verbose_only( uint32_t profCount; ) - verbose_only( uint32_t profGuardID; ) - verbose_only( GuardRecord* nextInFrag; ) - }; - - struct SideExit - { - GuardRecord* guards; - Fragment* from; - Fragment* target; - SwitchInfo* switchInfo; - - void addGuard(GuardRecord* gr) - { - NanoAssert(gr->next == NULL); - NanoAssert(guards != gr); - gr->next = guards; - guards = gr; - } - }; -} - - #define isSPorFP(r) ( (r)==SP || (r)==FP ) - - #ifdef NJ_NO_VARIADIC_MACROS - static void asm_output(const char *f, ...) {} - #define gpn(r) regNames[(REGNUM(n))] - #elif defined(NJ_VERBOSE) - inline char cvaltoa(unsigned char u) { - return u<10 ? u+'0' : u+'a'-10; - } - - inline char* appendHexVals(char* str, char* valFrom, char* valTo) { - NanoAssert(valFrom <= valTo); - str += VMPI_strlen(str); - for(char* ch = valFrom; ch < valTo; ch++) { - unsigned char u = (unsigned char)*ch; - *str++ = cvaltoa(u >> 4); - *str++ = cvaltoa(u & 0xf); - *str++ = ' '; - } - *str = '\0'; - return str; - } - - inline char* padTo(char* str, int n, char c=' ') { - char* start = str + VMPI_strlen(str); - char* end = &str[n]; - while(start < end) - *start++ = c; - *end = '\0'; - return end; - } - - // Used for printing native instructions. Like Assembler::outputf(), - // but only outputs if LC_Native is set. Also prepends the output - // with the address of the current native instruction. - #define asm_output(...) do { \ - if (_logc->lcbits & LC_Native) { \ - outline[0]='\0'; \ - VMPI_sprintf(outline, "%p ", _nIns); \ - if (_logc->lcbits & LC_Bytes) { \ - appendHexVals(outline, (char*)_nIns, (char*)_nInsAfter); \ - padTo(outline, 3*15); \ - } \ - VMPI_sprintf(outline + VMPI_strlen(outline), ##__VA_ARGS__); \ - output(); \ - _nInsAfter = _nIns; \ - } \ - } while (0) /* no semi */ - #define gpn(r) regNames[(REGNUM(r))] - #else - #define asm_output(...) - #define gpn(r) - #endif /* NJ_VERBOSE */ - -#endif // __nanojit_Native__ diff --git a/x86/mozilla/include/NativeCommon.h b/x86/mozilla/include/NativeCommon.h deleted file mode 100644 index aed175b..0000000 --- a/x86/mozilla/include/NativeCommon.h +++ /dev/null @@ -1,122 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ -/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is [Open Source Virtual Machine]. - * - * The Initial Developer of the Original Code is - * Adobe System Incorporated. - * Portions created by the Initial Developer are Copyright (C) 2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Adobe AS3 Team - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef __nanojit_NativeCommon__ -#define __nanojit_NativeCommon__ - -namespace nanojit -{ - // In debug builds, Register is defined as a non-integer type to avoid - // possible mix-ups with RegisterMask and integer offsets. In non-debug - // builds, it's defined as an integer just in case some compilers fail to - // optimize single-element structs in the obvious way. - // - // Note that in either case, a Register can be initialized like so: - // - // Register r = { 0 }; - // - // In the debug case it's a struct initializer, in the non-debug case it's - // a scalar initializer. - // - // XXX: The exception to all the above is that if NJ_USE_UINT32_REGISTER - // is defined, the back-end is responsible for defining its own Register - // type, which will probably be an enum. This is just to give all the - // back-ends a chance to transition smoothly. -#if defined(NJ_USE_UINT32_REGISTER) - #define REGNUM(r) (r) - -#elif defined(DEBUG) || defined(__SUNPRO_CC) - // Always use struct declaration for 'Register' with - // Solaris Studio C++ compiler, because it has a bug: - // Scalar type can not be initialized by '{1}'. - // See bug 603560. - - struct Register { - uint32_t n; // the register number - }; - - static inline uint32_t REGNUM(Register r) { - return r.n; - } - - static inline Register operator+(Register r, int c) - { - r.n += c; - return r; - } - - static inline bool operator==(Register r1, Register r2) - { - return r1.n == r2.n; - } - - static inline bool operator!=(Register r1, Register r2) - { - return r1.n != r2.n; - } - - static inline bool operator<=(Register r1, Register r2) - { - return r1.n <= r2.n; - } - - static inline bool operator<(Register r1, Register r2) - { - return r1.n < r2.n; - } - - static inline bool operator>=(Register r1, Register r2) - { - return r1.n >= r2.n; - } - - static inline bool operator>(Register r1, Register r2) - { - return r1.n > r2.n; - } -#else - typedef uint32_t Register; - - static inline uint32_t REGNUM(Register r) { - return r; - } -#endif -} // namespace nanojit - -#endif // __nanojit_NativeCommon__ diff --git a/x86/mozilla/include/Nativei386.h b/x86/mozilla/include/Nativei386.h deleted file mode 100644 index a88dbf1..0000000 --- a/x86/mozilla/include/Nativei386.h +++ /dev/null @@ -1,472 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ -/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is [Open Source Virtual Machine]. - * - * The Initial Developer of the Original Code is - * Adobe System Incorporated. - * Portions created by the Initial Developer are Copyright (C) 2004-2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Adobe AS3 Team - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - - -#ifndef __nanojit_Nativei386__ -#define __nanojit_Nativei386__ - -#include "NativeCommon.h" - -#ifdef PERFM -#define DOPROF -#include "../vprof/vprof.h" -#define count_instr() _nvprof("x86",1) -#define count_ret() _nvprof("x86-ret",1); count_instr(); -#define count_push() _nvprof("x86-push",1); count_instr(); -#define count_pop() _nvprof("x86-pop",1); count_instr(); -#define count_st() _nvprof("x86-st",1); count_instr(); -#define count_stq() _nvprof("x86-stq",1); count_instr(); -#define count_ld() _nvprof("x86-ld",1); count_instr(); -#define count_ldq() _nvprof("x86-ldq",1); count_instr(); -#define count_call() _nvprof("x86-call",1); count_instr(); -#define count_calli() _nvprof("x86-calli",1); count_instr(); -#define count_prolog() _nvprof("x86-prolog",1); count_instr(); -#define count_alu() _nvprof("x86-alu",1); count_instr(); -#define count_mov() _nvprof("x86-mov",1); count_instr(); -#define count_fpu() _nvprof("x86-fpu",1); count_instr(); -#define count_jmp() _nvprof("x86-jmp",1); count_instr(); -#define count_jcc() _nvprof("x86-jcc",1); count_instr(); -#define count_fpuld() _nvprof("x86-ldq",1); _nvprof("x86-fpu",1); count_instr() -#define count_aluld() _nvprof("x86-ld",1); _nvprof("x86-alu",1); count_instr() -#define count_alust() _nvprof("x86-ld",1); _nvprof("x86-alu",1); _nvprof("x86-st",1); count_instr() -#define count_pushld() _nvprof("x86-ld",1); _nvprof("x86-push",1); count_instr() -#define count_imt() _nvprof("x86-imt",1) count_instr() -#else -#define count_instr() -#define count_ret() -#define count_push() -#define count_pop() -#define count_st() -#define count_stq() -#define count_ld() -#define count_ldq() -#define count_call() -#define count_calli() -#define count_prolog() -#define count_alu() -#define count_mov() -#define count_fpu() -#define count_jmp() -#define count_jcc() -#define count_fpuld() -#define count_aluld() -#define count_alust() -#define count_pushld() -#define count_imt() -#endif - -namespace nanojit -{ - const int NJ_MAX_REGISTERS = 24; // gpregs, x87 regs, xmm regs - - #define NJ_MAX_STACK_ENTRY 4096 - #define NJ_MAX_PARAMETERS 1 - - #define NJ_USES_IMMD_POOL 1 - - #define NJ_JTBL_SUPPORTED 1 - #define NJ_EXPANDED_LOADSTORE_SUPPORTED 1 - #define NJ_F2I_SUPPORTED 1 - #define NJ_SOFTFLOAT_SUPPORTED 0 - #define NJ_DIVI_SUPPORTED 1 - - // Preserve a 16-byte stack alignment, to support the use of - // SSE instructions like MOVDQA (if not by Tamarin itself, - // then by the C functions it calls). - const int NJ_ALIGN_STACK = 16; - - const int32_t LARGEST_UNDERRUN_PROT = 32; // largest value passed to underrunProtect - - typedef uint8_t NIns; - - // Bytes of icache to flush after patch - const size_t LARGEST_BRANCH_PATCH = 16 * sizeof(NIns); - - static const Register - // General purpose 32 bit registers. The names are rEAX, rEBX, etc, - // because EAX, EBX, et al clash with on Solaris (sigh). - // See bug 570726 for details. - rEAX = { 0 }, // return value, scratch - rECX = { 1 }, // this/arg0, scratch - rEDX = { 2 }, // arg1, return-msw, scratch - rEBX = { 3 }, - rESP = { 4 }, // stack pointer - rEBP = { 5 }, // frame pointer - rESI = { 6 }, - rEDI = { 7 }, - - SP = rESP, // alias SP to ESP for convenience - FP = rEBP, // alias FP to EBP for convenience - - // SSE regs come before X87 so we prefer them - XMM0 = { 8 }, - XMM1 = { 9 }, - XMM2 = { 10 }, - XMM3 = { 11 }, - XMM4 = { 12 }, - XMM5 = { 13 }, - XMM6 = { 14 }, - XMM7 = { 15 }, - - // X87 regs - FST0 = { 16 }, - - deprecated_UnknownReg = { 17 }, // XXX: remove eventually, see bug 538924 - UnspecifiedReg = { 17 }; - - static const uint32_t FirstRegNum = 0; - static const uint32_t LastRegNum = 16; - - typedef int RegisterMask; - - static const int NumSavedRegs = 3; - static const RegisterMask SavedRegs = 1<> 8) & 0xff); \ - }; \ - void FPUm(int32_t o, int32_t d, Register b); \ - void FPUdm(int32_t o, const double* const m); \ - void TEST_AH(int32_t i); \ - void TEST_AX(int32_t i); \ - void FNSTSW_AX(); \ - void FCHS(); \ - void FLD1(); \ - void FLDZ(); \ - void FST32(bool p, int32_t d, Register b); \ - void FSTQ(bool p, int32_t d, Register b); \ - void FSTPQ(int32_t d, Register b); \ - void FCOM(bool p, int32_t d, Register b); \ - void FCOMdm(bool p, const double* dm); \ - void FLD32(int32_t d, Register b); \ - void FLDQ(int32_t d, Register b); \ - void FLDQdm(const double* dm); \ - void FILDQ(int32_t d, Register b); \ - void FILD(int32_t d, Register b); \ - void FIST(bool p, int32_t d, Register b); \ - void FADD( int32_t d, Register b); \ - void FSUB( int32_t d, Register b); \ - void FSUBR(int32_t d, Register b); \ - void FMUL( int32_t d, Register b); \ - void FDIV( int32_t d, Register b); \ - void FDIVR(int32_t d, Register b); \ - void FADDdm( const double *dm); \ - void FSUBRdm(const double* dm); \ - void FMULdm( const double* dm); \ - void FDIVRdm(const double* dm); \ - void FSTP(Register r) { \ - count_fpu(); \ - FPU(0xddd8, r); \ - asm_output("fstp %s", gpn(r)); \ - fpu_pop(); \ - }; \ - void FCOMP(); \ - void FCOMPP(); \ - void FLDr(Register r); \ - void EMMS(); \ - void CALL(const CallInfo* ci); \ - void CALLr(const CallInfo* ci, Register r); -} - - - -#endif // __nanojit_Nativei386__ diff --git a/x86/mozilla/include/RegAlloc.h b/x86/mozilla/include/RegAlloc.h deleted file mode 100644 index ad3e9da..0000000 --- a/x86/mozilla/include/RegAlloc.h +++ /dev/null @@ -1,211 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ -/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is [Open Source Virtual Machine]. - * - * The Initial Developer of the Original Code is - * Adobe System Incorporated. - * Portions created by the Initial Developer are Copyright (C) 2004-2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Adobe AS3 Team - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - - -#ifndef __nanojit_RegAlloc__ -#define __nanojit_RegAlloc__ - - -namespace nanojit -{ - class RegAlloc - { - public: - RegAlloc() - { - clear(); - } - - void clear() - { - VMPI_memset(this, 0, sizeof(*this)); - } - - bool isFree(Register r) const - { - NanoAssert(r != deprecated_UnknownReg); - return (free & rmask(r)) != 0; - } - - void addFree(Register r) - { - NanoAssert(!isFree(r)); - free |= rmask(r); - } - - void removeFree(Register r) - { - NanoAssert(isFree(r)); - free &= ~rmask(r); - } - - void addActive(Register r, LIns* v) - { - // Count++; - NanoAssert(v); - NanoAssert(r != deprecated_UnknownReg); - NanoAssert(active[REGNUM(r)] == NULL); - active[REGNUM(r)] = v; - useActive(r); - } - - void useActive(Register r) - { - NanoAssert(r != deprecated_UnknownReg); - NanoAssert(active[REGNUM(r)] != NULL); - usepri[REGNUM(r)] = priority++; - } - - void removeActive(Register r) - { - //registerReleaseCount++; - NanoAssert(r != deprecated_UnknownReg); - NanoAssert(active[REGNUM(r)] != NULL); - - // remove the given register from the active list - active[REGNUM(r)] = NULL; - } - - void retire(Register r) - { - NanoAssert(r != deprecated_UnknownReg); - NanoAssert(active[REGNUM(r)] != NULL); - active[REGNUM(r)] = NULL; - free |= rmask(r); - } - - int32_t getPriority(Register r) { - NanoAssert(r != deprecated_UnknownReg && active[REGNUM(r)]); - return usepri[REGNUM(r)]; - } - - LIns* getActive(Register r) const { - NanoAssert(r != deprecated_UnknownReg); - return active[REGNUM(r)]; - } - - // Return a mask containing the active registers. For each register - // in this set, getActive(register) will be a nonzero LIns pointer. - RegisterMask activeMask() const { - return ~free & managed; - } - - debug_only( bool isConsistent(Register r, LIns* v) const; ) - - // Some basics: - // - // - 'active' indicates which registers are active at a particular - // point, and for each active register, which instruction - // defines the value it holds. At the start of register - // allocation no registers are active. - // - // - 'free' indicates which registers are free at a particular point - // and thus available for use. At the start of register - // allocation most registers are free; those that are not - // aren't available for general use, e.g. the stack pointer and - // frame pointer registers. - // - // - 'managed' is exactly this list of initially free registers, - // ie. the registers managed by the register allocator. - // - // - Each LIns has a "reservation" which includes a register value, - // 'reg'. Combined with 'active', this provides a two-way - // mapping between registers and LIR instructions. - // - // - Invariant 1: each register must be in exactly one of the - // following states at all times: unmanaged, free, or active. - // In terms of the relevant fields: - // - // * A register in 'managed' must be in 'active' or 'free' but - // not both. - // - // * A register not in 'managed' must be in neither 'active' nor - // 'free'. - // - // - Invariant 2: the two-way mapping between active registers and - // their defining instructions must always hold in both - // directions and be unambiguous. More specifically: - // - // * An LIns can appear at most once in 'active'. - // - // * An LIns named by 'active[R]' must have an in-use - // reservation that names R. - // - // * And vice versa: an LIns with an in-use reservation that - // names R must be named by 'active[R]'. - // - // * If an LIns's reservation names 'deprecated_UnknownReg' then LIns - // should not be in 'active'. - // - LIns* active[LastRegNum + 1]; // active[REGNUM(r)] = LIns that defines r - int32_t usepri[LastRegNum + 1]; // used priority. lower = more likely to spill. - RegisterMask free; // Registers currently free. - RegisterMask managed; // Registers under management (invariant). - int32_t priority; - - DECLARE_PLATFORM_REGALLOC() - }; - - // Return the lowest numbered Register in mask. - inline Register lsReg(RegisterMask mask) { - // This is faster than it looks; we rely on the C++ optimizer - // to strip the dead branch and inline just one alternative. - Register r = { (sizeof(RegisterMask) == 4) ? lsbSet32(mask) : lsbSet64(mask) }; - return r; - } - - // Return the highest numbered Register in mask. - inline Register msReg(RegisterMask mask) { - // This is faster than it looks; we rely on the C++ optimizer - // to strip the dead branch and inline just one alternative. - Register r = { (sizeof(RegisterMask) == 4) ? msbSet32(mask) : msbSet64(mask) }; - return r; - } - - // Clear bit r in mask, then return lsReg(mask). - inline Register nextLsReg(RegisterMask& mask, Register r) { - return lsReg(mask &= ~rmask(r)); - } - - // Clear bit r in mask, then return msReg(mask). - inline Register nextMsReg(RegisterMask& mask, Register r) { - return msReg(mask &= ~rmask(r)); - } -} -#endif // __nanojit_RegAlloc__ diff --git a/x86/mozilla/include/VMPI.h b/x86/mozilla/include/VMPI.h deleted file mode 100644 index 429ed11..0000000 --- a/x86/mozilla/include/VMPI.h +++ /dev/null @@ -1,139 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ -/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is [Open Source Virtual Machine]. - * - * The Initial Developer of the Original Code is - * Adobe System Incorporated. - * Portions created by the Initial Developer are Copyright (C) 2004-2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Adobe AS3 Team - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * Stub VMPI implementation to support standalone nanojit repository. - * - * Really only works if you *don't* have a busted-up C library. - */ - -#ifndef __VMPI_h__ -#define __VMPI_h__ - -#if defined(HAVE_CONFIG_H) && defined(NANOJIT_CENTRAL) -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include - -#if defined(AVMPLUS_UNIX) || defined(AVMPLUS_OS2) -#include -#include -#endif - -#ifdef AVMPLUS_WIN32 -#if ! defined(_STDINT_H) -typedef signed char int8_t; -typedef signed short int16_t; -typedef signed int int32_t; -typedef signed __int64 int64_t; -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -typedef unsigned __int64 uint64_t; -#endif -#else -#include -#include -#endif - -#define VMPI_strlen strlen -#define VMPI_strcat strcat -#define VMPI_strcmp strcmp -#define VMPI_strncat strncat -#define VMPI_strcpy strcpy -#define VMPI_sprintf sprintf -#ifdef _MSC_VER -# define VMPI_snprintf sprintf_s -#else -# define VMPI_snprintf snprintf -#endif -#define VMPI_vfprintf vfprintf -#define VMPI_memset memset -#define VMPI_isdigit isdigit -#define VMPI_getDate() - -extern size_t VMPI_getVMPageSize(); - -extern void VMPI_setPageProtection(void *address, - size_t size, - bool executableFlag, - bool writeableFlag); - -// Keep this warning-set relatively in sync with platform/win32/win32-platform.h in tamarin. - -#ifdef _MSC_VER - #pragma warning(disable:4201) // nonstandard extension used : nameless struct/union - #pragma warning(disable:4512) // assignment operator could not be generated - #pragma warning(disable:4511) // can't generate copy ctor - #pragma warning(disable:4127) // conditional expression is constant - appears to be compiler noise primarily - #pragma warning(disable:4611) // interaction between _setjmp and destruct - #pragma warning(disable:4725) // instruction may be inaccurate on some Pentiums - #pragma warning(disable:4611) // interaction between '_setjmp' and C++ object destruction is non-portable - #pragma warning(disable:4251) // X needs to have dll-interface to be used by clients of class Y - - // enable some that are off even in /W4 mode, but are still handy - #pragma warning(default:4265) // 'class' : class has virtual functions, but destructor is not virtual - #pragma warning(default:4905) // wide string literal cast to 'LPSTR' - #pragma warning(default:4906) // string literal cast to 'LPWSTR' - #pragma warning(default:4263) // 'function' : member function does not override any base class virtual member function - #pragma warning(default:4264) // 'virtual_function' : no override available for virtual member function from base 'class'; function is hidden - #pragma warning(default:4266) // 'function' : no override available for virtual member function from base 'type'; function is hidden - #pragma warning(default:4242) // 'identifier' : conversion from 'type1' to 'type2', possible loss of data - #pragma warning(default:4263) // member function does not override any base class virtual member function - #pragma warning(default:4296) // expression is always true (false) (Generally, an unsigned variable was used in a comparison operation with zero.) -#endif - -// This part defined in avmshell.h but similarly required for a warning-free nanojit experience. -#ifdef _MSC_VER -#pragma warning(disable:4996) // 'scanf' was declared deprecated -#endif - -// This part is inhibited manually by the CFLAGS in the tamarin configury. -#ifdef _MSC_VER -#pragma warning(disable:4291) // presence of a 'new' operator in nanojit/Allocator.h without matching 'delete' -#endif - -#endif diff --git a/x86/mozilla/include/Writer.h b/x86/mozilla/include/Writer.h deleted file mode 100644 index 1d6a546..0000000 --- a/x86/mozilla/include/Writer.h +++ /dev/null @@ -1,1232 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=4 sw=4 et tw=99 ft=cpp: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released - * May 28, 2008. - * - * The Initial Developer of the Original Code is - * the Mozilla Corporation. - * - * Contributor(s): - * Nicholas Nethercote - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef tracejit_Writer_h___ -#define tracejit_Writer_h___ - -#include "jsiter.h" -#include "jsobj.h" -#include "jsstr.h" -#include "jstypedarray.h" -#include "nanojit.h" - -namespace js { -namespace tjit { - -namespace nj = nanojit; - -#if defined(DEBUG) && !defined(JS_JIT_SPEW) -#define JS_JIT_SPEW -#endif - -#if defined(JS_JIT_SPEW) || defined(NJ_NO_VARIADIC_MACROS) - -enum LC_TMBits { - /* - * Output control bits for all non-Nanojit code. Only use bits 16 and - * above, since Nanojit uses 0 .. 15 itself. - */ - LC_TMMinimal = 1<<16, - LC_TMTracer = 1<<17, - LC_TMRecorder = 1<<18, - LC_TMAbort = 1<<19, - LC_TMStats = 1<<20, - LC_TMTreeVis = 1<<21, - LC_TMProfiler = 1<<22 -}; - -#endif - -/* - * See LIR.h for the definition of the AccSet type. - * - * *** WARNING WARNING WARNING *** - * - * Any incorrect access region annotations on loads/stores/calls could lead to - * subtle bugs that manifest rarely, eg. when two loads are CSE'd that - * shouldn't be. - * - * If you add a new access region you will need to add some sanity checking to - * ValidateWriter::checkAccSet(). Do not skimp on this checking! Make it as - * strong as you can. Look at the existing cases for inspiration. This - * checking helps prevent these subtle bugs. - * - * Furthermore, do not add a "catch-all" region such as "ACCSET_OTHER". There - * are two reasons for this. First, no checking could be done on loads/stores - * bearing it. Second, it would be too easy for someone in the future who - * doesn't understand how AccSets work to use it inappropriately. Only - * ACCSET_ALL (the union of all access regions) should be used as a catch-all, - * it can always be used safely, but it reduces optimization possibilities. - * - * Most of the access regions are type-based, ie. all structs of a particular - * type combined together form a region. This is less precise than - * considering each struct separately, but also much simpler. - * - * - ACCSET_STATE: The TracerState struct. - * - ACCSET_STACK: The stack. - * - ACCSET_RSTACK: The return stack. - * - ACCSET_CX: All JSContext structs. - * - ACCSET_TM: All TraceMonitor structs. - * - ACCSET_EOS: The globals area. - * - ACCSET_ALLOC: All memory blocks allocated with LIR_allocp (in - * other words, this region is the AR space). - * - ACCSET_FRAMEREGS: All JSFrameRegs structs. - * - ACCSET_STACKFRAME: All JSStackFrame objects. - * - ACCSET_RUNTIME: The JSRuntime object. - * - ACCSET_OBJ_CLASP: The 'clasp' field of all JSObjects. - * - ACCSET_OBJ_FLAGS: The 'flags' field of all JSObjects. - * - ACCSET_OBJ_SHAPE: The 'shape' field of all JSObjects. - * - ACCSET_OBJ_PROTO: The 'proto' field of all JSObjects. - * - ACCSET_OBJ_PARENT: The 'parent' field of all JSObjects. - * - ACCSET_OBJ_PRIVATE: The 'private' field of all JSObjects. - * - ACCSET_OBJ_CAPACITY: The 'capacity' field of all JSObjects. - * - ACCSET_OBJ_SLOTS: The 'slots' field of all JSObjects. - * - ACCSET_SLOTS: The slots (be they fixed or dynamic) of all JSObjects. - * - ACCSET_TARRAY: All TypedArray structs. - * - ACCSET_TARRAY_DATA: All TypedArray data arrays. - * - ACCSET_ITER: All NativeIterator structs. - * - ACCSET_ITER_PROPS: The props_arrays of all NativeIterator structs. - * - ACCSET_STRING: All JSString structs. - * - ACCSET_STRING_MCHARS: All JSString mchars arrays. - * - ACCSET_TYPEMAP: All typemaps form a single region. - * - ACCSET_FCSLOTS: All fcslots arrays form a single region. - * - ACCSET_ARGS_DATA: All Arguments data arrays form a single region. - */ -static const nanojit::AccSet ACCSET_STATE = (1 << 0); -static const nanojit::AccSet ACCSET_STACK = (1 << 1); -static const nanojit::AccSet ACCSET_RSTACK = (1 << 2); -static const nanojit::AccSet ACCSET_CX = (1 << 3); -static const nanojit::AccSet ACCSET_TM = (1 << 4); -static const nanojit::AccSet ACCSET_EOS = (1 << 5); -static const nanojit::AccSet ACCSET_ALLOC = (1 << 6); -static const nanojit::AccSet ACCSET_FRAMEREGS = (1 << 7); -static const nanojit::AccSet ACCSET_STACKFRAME = (1 << 8); -static const nanojit::AccSet ACCSET_RUNTIME = (1 << 9); - -// Nb: JSObject::{lastProp,map,flags} don't have an AccSet because they are never accessed on trace -static const nanojit::AccSet ACCSET_OBJ_CLASP = (1 << 10); -static const nanojit::AccSet ACCSET_OBJ_FLAGS = (1 << 11); -static const nanojit::AccSet ACCSET_OBJ_SHAPE = (1 << 12); -static const nanojit::AccSet ACCSET_OBJ_PROTO = (1 << 13); -static const nanojit::AccSet ACCSET_OBJ_PARENT = (1 << 14); -static const nanojit::AccSet ACCSET_OBJ_PRIVATE = (1 << 15); -static const nanojit::AccSet ACCSET_OBJ_CAPACITY = (1 << 16); -static const nanojit::AccSet ACCSET_OBJ_SLOTS = (1 << 17); // the pointer to the slots - -static const nanojit::AccSet ACCSET_SLOTS = (1 << 18); // the slots themselves -static const nanojit::AccSet ACCSET_TARRAY = (1 << 19); -static const nanojit::AccSet ACCSET_TARRAY_DATA = (1 << 20); -static const nanojit::AccSet ACCSET_ITER = (1 << 21); -static const nanojit::AccSet ACCSET_ITER_PROPS = (1 << 22); -static const nanojit::AccSet ACCSET_STRING = (1 << 23); -static const nanojit::AccSet ACCSET_STRING_MCHARS = (1 << 24); -static const nanojit::AccSet ACCSET_TYPEMAP = (1 << 25); -static const nanojit::AccSet ACCSET_FCSLOTS = (1 << 26); -static const nanojit::AccSet ACCSET_ARGS_DATA = (1 << 27); - -static const uint8_t TM_NUM_USED_ACCS = 28; // number of access regions used by TraceMonkey - -/* - * An Address describes everything about a loaded/stored memory location. One - * only be created via the sub-classes below and only accessed via class - * Writer; this is so that AccSets are encapsulated as much as possible. - */ -struct Address -{ - friend class Writer; - - private: - nj::LIns *base; - int32 offset; - nj::AccSet accSet; - - protected: - Address(nj::LIns *base, int32 offset, nj::AccSet accSet) - : base(base), offset(offset), accSet(accSet) {} - - Address(Address addr, int32 offset) - : base(addr.base), offset(addr.offset + offset), accSet(addr.accSet) {} - - public: - Address() {} -}; - - -/* Addresses, ordered by AccSet. */ - -struct StackAddress : Address -{ - StackAddress(nj::LIns *base, int32 offset) - : Address(base, offset, ACCSET_STACK) {} -}; - -struct CxAddress : Address -{ - CxAddress(nj::LIns *base, int32 offset) - : Address(base, offset, ACCSET_CX) {} -}; -#define CxAddress(fieldname) \ - CxAddress(cx_ins, offsetof(JSContext, fieldname)) - -struct EosAddress : Address -{ - EosAddress(nj::LIns *base, int32 offset) - : Address(base, offset, ACCSET_EOS) {} -}; - -struct AllocSlotsAddress : Address -{ - AllocSlotsAddress(nj::LIns *base, unsigned slot = 0) - : Address(base, slot * sizeof(Value), ACCSET_ALLOC) {} -}; - -struct StackFrameAddress : Address -{ - StackFrameAddress(nj::LIns *base, int32 offset) - : Address(base, offset, ACCSET_STACKFRAME) {} -}; - -struct FSlotsAddress : Address -{ - FSlotsAddress(nj::LIns *base, unsigned slot) - : Address(base, JSObject::getFixedSlotOffset(slot), ACCSET_SLOTS) {} -}; - -struct DSlotsAddress : Address -{ - DSlotsAddress(nj::LIns *base, unsigned slot = 0) - : Address(base, slot * sizeof(Value), ACCSET_SLOTS) {} -}; - -struct IterPropsAddress : Address -{ - IterPropsAddress(nj::LIns *base) - : Address(base, 0, ACCSET_ITER_PROPS) {} -}; - -struct FCSlotsAddress : Address -{ - FCSlotsAddress(nj::LIns *base, unsigned slot = 0) - : Address(base, slot * sizeof(Value), ACCSET_FCSLOTS) {} -}; - -struct ArgsSlotOffsetAddress : Address -{ - ArgsSlotOffsetAddress(nj::LIns *base, unsigned offset = 0) - : Address(base, offset, ACCSET_ARGS_DATA) {} -}; - -struct AnyAddress : Address -{ - AnyAddress(nj::LIns *base, int32 offset = 0) - : Address(base, offset, nj::ACCSET_ALL) - { - JS_ASSERT(nj::ACCSET_LOAD_ANY == nj::ACCSET_STORE_ANY && - nj::ACCSET_LOAD_ANY == nj::ACCSET_ALL); - } -}; - -/* An offset from a previous Address. */ -struct OffsetAddress : Address -{ - OffsetAddress(Address addr, int32 offset) - : Address(addr, offset) {} -}; - -bool IsPromotedInt32(nj::LIns *ins); -bool IsPromotedUint32(nj::LIns *ins); -bool IsPromotedInt32OrUint32(nj::LIns *ins); -nj::LIns *DemoteToInt32(nj::LirWriter *out, nj::LIns *ins); -nj::LIns *DemoteToUint32(nj::LirWriter *out, nj::LIns *ins); - -/* These would be private to class Writer if they weren't used in AccSet checking. */ -static const size_t sPayloadOffset = offsetof(jsval_layout, s.payload); -#if JS_BITS_PER_WORD == 32 -static const size_t sTagOffset = offsetof(jsval_layout, s.tag); -#endif - -struct MaybeBranch { - bool set; - nj::LIns *br; - MaybeBranch() : set(false), br(NULL) {} - MaybeBranch(nj::LIns *ins) : set(true), br(ins) {} - operator bool() { return set; } - typedef nj::LIns* LInsp; - operator LInsp() { - JS_ASSERT(set); - return br; - } -}; - -/* - * This class provides a layer above Nanojit's basic LirWriter interface. - * The goals of this layer are as follows. - * - * - More concise than the vanilla NJ interface, to promote readability. - * - * - But still a relatively thin layer. - * - * - Completely occludes NJ's interface so that there is no possibility of - * using a combination of both interfaces. This is good because there are - * some cases where the NJ interface is error-prone when used with - * TraceMonkey (eg. when using the NJ interface it's easy to forget to - * handle the cases where a conditional branch is always or never taken). - * - * - Requires only basic Nanojit state (eg. LirBuffer); doesn't rely on state - * from TraceRecorder. - * - * - There should be one or more functions for every opcode that's used (if - * one is missing, please add it), plus minimal generic ones (eg. ins2()). - * This makes for a lot of functions, but promotes readability. - * - * - Loads/stores get special treatment, due to AccSets. AccSets aren't - * exposed at all, although someone using the interface will still need to - * understand them; the goal is not to completely hide their presence but - * to make their use indirect so that it is difficult to get them wrong. - * - * Type/field-specific load/store functions are used where possible. When - * this isn't possible, details about memory locations are abstracted in the - * Address type, which encapsulates a base pointer, an offset and an AccSet. - * - * The only place where AccSets need to be used directly is when specifying - * the .storeAccSet of a CallInfo. - * - * - Functions that insert moderately complex LIR sequences (eg. multiple - * loads) have a 'get' prefix in their name. - */ -class Writer -{ - private: - nj::Allocator *alloc; - nj::LirBuffer *lirbuf; // passed in from outside - nj::LirWriter *const lir; // created in this class - nj::CseFilter *const cse; // created in this class - - nj::LogControl *logc; // passed in from outside - - public: - Writer(nj::Allocator *alloc, nj::LirBuffer *lirbuf) - : alloc(alloc), lirbuf(lirbuf), lir(NULL), cse(NULL), logc(NULL) {} - - void init(nj::LogControl *logc); - - nj::LIns *name(nj::LIns *ins, const char *name) const { -#ifdef JS_JIT_SPEW - /* No point adding names unless .lcbits > 0. */ - if (logc->lcbits > 0) - lirbuf->printer->lirNameMap->addName(ins, name); -#endif - return ins; - } - - /* - * These two don't generate any code, they control the internal state of - * the CseFilter. They can be put around a control-flow diamond if it's - * important that CSE work across the diamond. (If they aren't used, the - * diamond will reset all CSE state.) Duplicated expressions within the - * diamond will be CSE'd, but expressions defined within the diamond won't - * be added to the tables of CSEable expressions. Loads are still - * invalidated if they alias any stores that occur within diamonds. - */ - void pauseAddingCSEValues() { if (cse) cse->suspend(); } - void resumeAddingCSEValues() { if (cse) cse->resume(); } - - /* Miscellaneous operations */ - - nj::LIns *start() const { - return lir->ins0(nj::LIR_start); - } - - nj::LIns *paramp(int32 arg, int32 kind) const { - return lir->insParam(arg, kind); - } - - nj::LIns *allocp(int32 size) const { - return lir->insAlloc(size); - } - - nj::LIns *livep(nj::LIns *x) const { - return lir->ins1(nj::LIR_livep, x); - } - - void comment(const char *str) { - #ifdef JS_JIT_SPEW - lir->insComment(str); - #endif - } - - /* Specific loads and stores (those not taking an Address argument). Ordered by AccSets.*/ - - nj::LIns *ldStateFieldHelper(nj::LOpcode op, nj::LIns *state, int32 offset) const { - return lir->insLoad(op, state, offset, ACCSET_STATE); - } - #define ldiStateField(fieldname) \ - name(w.ldStateFieldHelper(LIR_ldi, lirbuf->state, offsetof(TracerState, fieldname)), \ - #fieldname) - #define ldpStateField(fieldname) \ - name(w.ldStateFieldHelper(LIR_ldp, lirbuf->state, offsetof(TracerState, fieldname)), \ - #fieldname) - - nj::LIns *stStateFieldHelper(nj::LIns *value, nj::LIns *state, int32 offset) const { - return lir->insStore(value, state, offset, ACCSET_STATE); - } - #define stStateField(value, fieldname) \ - stStateFieldHelper(value, lirbuf->state, offsetof(TracerState, fieldname)) - - nj::LIns *ldpRstack(nj::LIns *rp, int32 offset) const { - return lir->insLoad(nj::LIR_ldp, rp, offset, ACCSET_RSTACK); - } - - nj::LIns *stRstack(nj::LIns *value, nj::LIns *rp, int32 offset) const { - return lir->insStore(value, rp, offset, ACCSET_RSTACK); - } - - nj::LIns *ldpContextFieldHelper(nj::LIns *cx, int32 offset, nj::LoadQual loadQual) const { - return lir->insLoad(nj::LIR_ldp, cx, offset, ACCSET_CX, loadQual); - } - #define ldpContextField(fieldname) \ - name(w.ldpContextFieldHelper(cx_ins, offsetof(JSContext, fieldname), LOAD_NORMAL), \ - #fieldname) - #define ldpConstContextField(fieldname) \ - name(w.ldpContextFieldHelper(cx_ins, offsetof(JSContext, fieldname), LOAD_CONST), \ - #fieldname) - - nj::LIns *stContextField(nj::LIns *value, nj::LIns *cx, int32 offset) const { - return lir->insStore(value, cx, offset, ACCSET_CX); - } - #define stContextField(value, fieldname) \ - stContextField((value), cx_ins, offsetof(JSContext, fieldname)) - - nj::LIns *stTraceMonitorField(nj::LIns *value, void *dest, const char *destName) const { - return lir->insStore(value, name(lir->insImmP(dest), destName), 0, ACCSET_TM); - } - #define stTraceMonitorField(value, fieldname) \ - stTraceMonitorField(value, &traceMonitor->fieldname, #fieldname) - - nj::LIns *ldiAlloc(nj::LIns *alloc) const { - return lir->insLoad(nj::LIR_ldi, alloc, 0, ACCSET_ALLOC); - } - - nj::LIns *ldpAlloc(nj::LIns *alloc) const { - return lir->insLoad(nj::LIR_ldp, alloc, 0, ACCSET_ALLOC); - } - - nj::LIns *lddAlloc(nj::LIns *alloc) const { - return lir->insLoad(nj::LIR_ldd, alloc, 0, ACCSET_ALLOC); - } - - nj::LIns *stAlloc(nj::LIns *value, nj::LIns *alloc) const { - return lir->insStore(value, alloc, 0, ACCSET_ALLOC); - } - - nj::LIns *ldpFrameFp(nj::LIns *regs) const { - return lir->insLoad(nj::LIR_ldp, regs, offsetof(JSFrameRegs, fp), ACCSET_FRAMEREGS); - } - - nj::LIns *ldpStackFrameScopeChain(nj::LIns *frame) const { - return lir->insLoad(nj::LIR_ldp, frame, JSStackFrame::offsetOfScopeChain(), - ACCSET_STACKFRAME); - } - - nj::LIns *ldiRuntimeProtoHazardShape(nj::LIns *runtime) const { - return name(lir->insLoad(nj::LIR_ldi, runtime, offsetof(JSRuntime, protoHazardShape), - ACCSET_RUNTIME), - "protoHazardShape"); - } - - nj::LIns *ldpObjClasp(nj::LIns *obj, nj::LoadQual loadQual) const { - return name(lir->insLoad(nj::LIR_ldp, obj, offsetof(JSObject, clasp), ACCSET_OBJ_CLASP, - loadQual), - "clasp"); - } - - nj::LIns *ldiObjFlags(nj::LIns *obj) const { - return name(lir->insLoad(nj::LIR_ldi, obj, offsetof(JSObject, flags), ACCSET_OBJ_FLAGS), - "flags"); - } - - nj::LIns *ldiObjShape(nj::LIns *obj) const { - return name(lir->insLoad(nj::LIR_ldi, obj, offsetof(JSObject, objShape), ACCSET_OBJ_SHAPE), - "objShape"); - } - - nj::LIns *ldpObjProto(nj::LIns *obj) const { - return name(lir->insLoad(nj::LIR_ldp, obj, offsetof(JSObject, proto), ACCSET_OBJ_PROTO), - "proto"); - } - - nj::LIns *ldpObjParent(nj::LIns *obj) const { - return name(lir->insLoad(nj::LIR_ldp, obj, offsetof(JSObject, parent), ACCSET_OBJ_PARENT), - "parent"); - } - - nj::LIns *ldpObjPrivate(nj::LIns *obj) const { - return name(lir->insLoad(nj::LIR_ldp, obj, offsetof(JSObject, privateData), - ACCSET_OBJ_PRIVATE), - "private"); - } - - nj::LIns *lduiObjPrivate(nj::LIns *obj) const { - return name(lir->insLoad(nj::LIR_ldi, obj, offsetof(JSObject, privateData), - ACCSET_OBJ_PRIVATE), - "private_uint32"); - } - - nj::LIns *stuiObjPrivate(nj::LIns *obj, nj::LIns *value) const { - return name(lir->insStore(nj::LIR_sti, value, obj, offsetof(JSObject, privateData), - ACCSET_OBJ_PRIVATE), - "private_uint32"); - } - - nj::LIns *ldiDenseArrayCapacity(nj::LIns *array) const { - return name(lir->insLoad(nj::LIR_ldi, array, offsetof(JSObject, capacity), - ACCSET_OBJ_CAPACITY), - "capacity"); - } - - nj::LIns *ldpObjSlots(nj::LIns *obj) const { - return name(lir->insLoad(nj::LIR_ldp, obj, offsetof(JSObject, slots), ACCSET_OBJ_SLOTS), - "slots"); - } - - nj::LIns *ldiConstTypedArrayLength(nj::LIns *array) const { - return name(lir->insLoad(nj::LIR_ldi, array, js::TypedArray::lengthOffset(), ACCSET_TARRAY, - nj::LOAD_CONST), - "typedArrayLength"); - } - - nj::LIns *ldpConstTypedArrayData(nj::LIns *array) const { - return name(lir->insLoad(nj::LIR_ldp, array, js::TypedArray::dataOffset(), ACCSET_TARRAY, - nj::LOAD_CONST), - "typedElems"); - } - - nj::LIns *ldc2iTypedArrayElement(nj::LIns *elems, nj::LIns *index) const { - return lir->insLoad(nj::LIR_ldc2i, addp(elems, index), 0, ACCSET_TARRAY_DATA); - } - - nj::LIns *lduc2uiTypedArrayElement(nj::LIns *elems, nj::LIns *index) const { - return lir->insLoad(nj::LIR_lduc2ui, addp(elems, index), 0, ACCSET_TARRAY_DATA); - } - - nj::LIns *lds2iTypedArrayElement(nj::LIns *elems, nj::LIns *index) const { - return lir->insLoad(nj::LIR_lds2i, addp(elems, lshpN(index, 1)), 0, ACCSET_TARRAY_DATA); - } - - nj::LIns *ldus2uiTypedArrayElement(nj::LIns *elems, nj::LIns *index) const { - return lir->insLoad(nj::LIR_ldus2ui, addp(elems, lshpN(index, 1)), 0, ACCSET_TARRAY_DATA); - } - - nj::LIns *ldiTypedArrayElement(nj::LIns *elems, nj::LIns *index) const { - return lir->insLoad(nj::LIR_ldi, addp(elems, lshpN(index, 2)), 0, ACCSET_TARRAY_DATA); - } - - nj::LIns *ldf2dTypedArrayElement(nj::LIns *elems, nj::LIns *index) const { - return lir->insLoad(nj::LIR_ldf2d, addp(elems, lshpN(index, 2)), 0, ACCSET_TARRAY_DATA); - } - - nj::LIns *lddTypedArrayElement(nj::LIns *elems, nj::LIns *index) const { - return lir->insLoad(nj::LIR_ldd, addp(elems, lshpN(index, 3)), 0, ACCSET_TARRAY_DATA); - } - - nj::LIns *sti2cTypedArrayElement(nj::LIns *value, nj::LIns *elems, nj::LIns *index) const { - return lir->insStore(nj::LIR_sti2c, value, addp(elems, index), 0, ACCSET_TARRAY_DATA); - } - - nj::LIns *sti2sTypedArrayElement(nj::LIns *value, nj::LIns *elems, nj::LIns *index) const { - return lir->insStore(nj::LIR_sti2s, value, addp(elems, lshpN(index, 1)), 0, - ACCSET_TARRAY_DATA); - } - - nj::LIns *stiTypedArrayElement(nj::LIns *value, nj::LIns *elems, nj::LIns *index) const { - return lir->insStore(nj::LIR_sti, value, addp(elems, lshpN(index, 2)), 0, - ACCSET_TARRAY_DATA); - } - - nj::LIns *std2fTypedArrayElement(nj::LIns *value, nj::LIns *elems, nj::LIns *index) const { - return lir->insStore(nj::LIR_std2f, value, addp(elems, lshpN(index, 2)), 0, - ACCSET_TARRAY_DATA); - } - - nj::LIns *stdTypedArrayElement(nj::LIns *value, nj::LIns *elems, nj::LIns *index) const { - return lir->insStore(nj::LIR_std, value, addp(elems, lshpN(index, 3)), 0, - ACCSET_TARRAY_DATA); - } - - nj::LIns *ldpIterCursor(nj::LIns *iter) const { - return name(lir->insLoad(nj::LIR_ldp, iter, offsetof(NativeIterator, props_cursor), - ACCSET_ITER), - "cursor"); - } - - nj::LIns *ldpIterEnd(nj::LIns *iter) const { - return name(lir->insLoad(nj::LIR_ldp, iter, offsetof(NativeIterator, props_end), - ACCSET_ITER), - "end"); - } - - nj::LIns *stpIterCursor(nj::LIns *cursor, nj::LIns *iter) const { - return lir->insStore(nj::LIR_stp, cursor, iter, offsetof(NativeIterator, props_cursor), - ACCSET_ITER); - } - - nj::LIns *ldpStringLengthAndFlags(nj::LIns *str) const { - return name(lir->insLoad(nj::LIR_ldp, str, JSString::offsetOfLengthAndFlags(), - ACCSET_STRING), - "lengthAndFlags"); - } - - nj::LIns *ldpStringChars(nj::LIns *str) const { - return name(lir->insLoad(nj::LIR_ldp, str, JSString::offsetOfChars(), ACCSET_STRING), - "chars"); - } - - nj::LIns *lduc2uiConstTypeMapEntry(nj::LIns *typemap, nj::LIns *index) const { - nj::LIns *entry = addp(typemap, ui2p(muli(index, name(immi(sizeof(JSValueType)), - "sizeof(JSValueType)")))); - return lir->insLoad(nj::LIR_lduc2ui, entry, 0, ACCSET_TYPEMAP, nj::LOAD_CONST); - } - - nj::LIns *ldiVolatile(nj::LIns *base) const { - return lir->insLoad(nj::LIR_ldi, base, 0, nj::ACCSET_LOAD_ANY, nj::LOAD_VOLATILE); - } - - nj::LIns *stiVolatile(nj::LIns *value, nj::LIns *base) const { - return lir->insStore(nj::LIR_sti, value, base, 0, nj::ACCSET_STORE_ANY); - } - - nj::LIns *ldiVMSideExitFieldHelper(nj::LIns *lr, int32 offset) const { - return lir->insLoad(nj::LIR_ldi, lr, offset, nj::ACCSET_LOAD_ANY); - } - #define ldiVMSideExitField(lr, fieldname) \ - name(w.ldiVMSideExitFieldHelper((lr), offsetof(VMSideExit, fieldname)), #fieldname) - - nj::LIns *ldpGuardRecordExit(nj::LIns *gr) const { - /* - * We use ACCSET_LOAD_ANY for the GuardRecord and VMSideExit loads; - * they're immediately after a fragment call, and so won't be - * optimizable anyway. - */ - return name(lir->insLoad(nj::LIR_ldp, gr, offsetof(nj::GuardRecord, exit), - nj::ACCSET_LOAD_ANY), - "exit"); - } - - nj::LIns *stTprintArg(nj::LIns *insa[], nj::LIns *args, int index) const { - JS_ASSERT(insa[index]); - /* The AccSet doesn't matter much here, this is debug-only code. */ - return lir->insStore(insa[index], args, sizeof(double) * index, nj::ACCSET_STORE_ANY); - } - - /* Generic loads and stores (those taking an Address argument). */ - -#if JS_BITS_PER_WORD == 32 - nj::LIns *ldiValueTag(Address addr) const { - return name(lir->insLoad(nj::LIR_ldi, addr.base, addr.offset + sTagOffset, addr.accSet), - "tag"); - } - - nj::LIns *stiValueTag(nj::LIns *tag, Address addr) const { - JS_ASSERT(tag->isI()); - return lir->insStore(tag, addr.base, addr.offset + sTagOffset, addr.accSet); - } - - nj::LIns *ldiValuePayload(Address addr) const { - return name(lir->insLoad(nj::LIR_ldi, addr.base, addr.offset + sPayloadOffset, - addr.accSet), - "payload"); - } - - nj::LIns *stiValuePayload(nj::LIns *payload, Address addr) const { - JS_ASSERT(payload->isI()); - return lir->insStore(payload, addr.base, addr.offset + sPayloadOffset, addr.accSet); - } -#endif // JS_BITS_PER_WORD == 32 - - nj::LIns *ldi(Address addr) const { - return lir->insLoad(nj::LIR_ldi, addr.base, addr.offset, addr.accSet); - } - -#ifdef NANOJIT_64BIT - nj::LIns *ldq(Address addr) const { - return lir->insLoad(nj::LIR_ldq, addr.base, addr.offset, addr.accSet); - } - - nj::LIns *stq(nj::LIns *value, Address addr) const { - return lir->insStore(nj::LIR_stq, value, addr.base, addr.offset, addr.accSet); - } -#endif - - nj::LIns *ldp(Address addr) const { - return lir->insLoad(nj::LIR_ldp, addr.base, addr.offset, addr.accSet); - } - - nj::LIns *ldd(Address addr) const { - return lir->insLoad(nj::LIR_ldd, addr.base, addr.offset, addr.accSet); - } - - nj::LIns *std(nj::LIns *value, Address addr) const { - return lir->insStore(nj::LIR_std, value, addr.base, addr.offset, addr.accSet); - } - - nj::LIns *st(nj::LIns *value, Address addr) const { - return lir->insStore(value, addr.base, addr.offset, addr.accSet); - } - - /* Calls */ - - nj::LIns *call(const nj::CallInfo *call, nj::LIns *args[]) const { - return lir->insCall(call, args); - } - - /* Branches and labels */ - - nj::LIns *j(nj::LIns *target) const { - return lir->insBranch(nj::LIR_j, /* cond = */NULL, target); - } - - /* - * If the branch is always taken, return false; the code jumped over by the - * branch need not be generated. If the branch is never taken, return true - * and put NULL in *brOut. Otherwise, return true and put the branch in - * *brOut. - */ - MaybeBranch jt(nj::LIns *cond) { - if (cond->isImmI(1)) - return MaybeBranch(); /* branch is always taken */ - return MaybeBranch(lir->insBranch(nj::LIR_jt, cond, NULL)); /* NULL if never taken */ - } - - /* Like jt(). */ - MaybeBranch jf(nj::LIns *cond) { - if (cond->isImmI(0)) - return MaybeBranch(); /* branch is always taken */ - return MaybeBranch(lir->insBranch(nj::LIR_jf, cond, NULL)); /* NULL if never taken */ - } - - /* - * Like jf(), but for when we know the branch condition cannot be - * optimized to a constant, eg. because one of the operands is the result - * of a volatile load. - */ - nj::LIns *jfUnoptimizable(nj::LIns *cond) const { - JS_ASSERT(!cond->isImmI()); - return lir->insBranch(nj::LIR_jf, cond, /* target = */NULL); - } - - /* Like jfUnoptimizable(). */ - nj::LIns *jtUnoptimizable(nj::LIns *cond) const { - JS_ASSERT(!cond->isImmI()); - return lir->insBranch(nj::LIR_jt, cond, /* target = */NULL); - } - - nj::LIns *label() const { - return lir->ins0(nj::LIR_label); - } - - /* - * Inserts a label and updates 'branch' to branch to it, if 'branch' is non-NULL. - * ('branch' may be NULL if it was a conditional branch and its condition was - * a constant value that resulted in the branch never being taken.) - */ - void label(nj::LIns *br) { - if (br) { - JS_ASSERT(br->isop(nj::LIR_j) || br->isop(nj::LIR_jt) || br->isop(nj::LIR_jf)); - br->setTarget(label()); - } - } - - /* Similar to label(LIns *), but for two branches. */ - void label(nj::LIns *br1, nj::LIns *br2) { - if (br1 || br2) { - nj::LIns *label_ = label(); - if (br1) { - JS_ASSERT(br1->isop(nj::LIR_j) || br1->isop(nj::LIR_jt) || br1->isop(nj::LIR_jf)); - br1->setTarget(label_); - } - if (br2) { - JS_ASSERT(br2->isop(nj::LIR_j) || br2->isop(nj::LIR_jt) || br2->isop(nj::LIR_jf)); - br2->setTarget(label_); - } - } - } - - /* Guards */ - - nj::LIns *x(nj::GuardRecord *gr) const { - return lir->insGuard(nj::LIR_x, /* cond = */NULL, gr); - } - - nj::LIns *xf(nj::LIns *cond, nj::GuardRecord *gr) const { - return lir->insGuard(nj::LIR_xf, cond, gr); - } - - nj::LIns *xt(nj::LIns *cond, nj::GuardRecord *gr) const { - return lir->insGuard(nj::LIR_xt, cond, gr); - } - - nj::LIns *xtbl(nj::LIns *index, nj::GuardRecord *gr) const { - return lir->insGuard(nj::LIR_xtbl, index, gr); - } - - nj::LIns *xbarrier(nj::GuardRecord *gr) const { - return lir->insGuard(nj::LIR_xbarrier, /* cond = */NULL, gr); - } - - /* Immediates */ - - nj::LIns *immi(int32 i) const { - return lir->insImmI(i); - } - - nj::LIns *immiUndefined() const { - return name(immi(0), "undefined"); - } - - /* - * These must be macros because they stringify their argument. Likewise - * with similar 'nameXYZ' operations below, - * - * These nameXYZ() macros have the 'name' prefix to distinguish them from the - * non-naming XYZ() functions. - */ - #define nameImmi(i) name(w.immi(i), #i) - #define nameImmui(ui) name(w.immi((uint32_t)ui), #ui) - -#ifdef NANOJIT_64BIT - nj::LIns *immq(uint64 q) const { - return lir->insImmQ(q); - } - - #define nameImmq(q) name(w.immq(q), #q) -#endif - - /* - * immpNonGC() can be used to embed arbitrary pointers into the native - * code. It should not be used directly to embed GC thing pointers unless - * they've already been rooted(hence the name). Instead, the - * TraceRecorder::immpXyzGC() variants should be used because they ensure - * that the embedded pointer will be kept alive across GCs. These types - * make it difficult to inadvertently get this wrong. - */ - nj::LIns *immpNonGC(const void *p) const { - return lir->insImmP(p); - } - - nj::LIns *immw(intptr_t i) const { - return lir->insImmP((void *)i); - } - - #define nameImmpNonGC(p) name(w.immpNonGC(p), #p) - #define nameImmw(ww) name(w.immpNonGC((void *) (ww)), #ww) - - nj::LIns *immpNull() const { - return name(immpNonGC(NULL), "NULL"); - } - - #define immpMagicWhy(why) name(w.immpNonGC((void *)(size_t)(why)), #why) - - nj::LIns *immpMagicNull() const { - return name(immpNonGC(NULL), "MAGIC_NULL"); - } - - nj::LIns *immd(double d) const { - return lir->insImmD(d); - } - - /* Comparisons */ - - nj::LIns *eqi(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_eqi, x, y); - } - - nj::LIns *eqi0(nj::LIns *x) const { - return lir->insEqI_0(x); - } - - nj::LIns *eqiN(nj::LIns *x, int32 imm) const { - return lir->ins2ImmI(nj::LIR_eqi, x, imm); - } - - nj::LIns *lti(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_lti, x, y); - } - - nj::LIns *ltiN(nj::LIns *x, int32 imm) const { - return lir->ins2ImmI(nj::LIR_lti, x, imm); - } - - nj::LIns *gti(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_gti, x, y); - } - - nj::LIns *gtiN(nj::LIns *x, int32 imm) const { - return lir->ins2ImmI(nj::LIR_gti, x, imm); - } - - nj::LIns *geiN(nj::LIns *x, int32 imm) const { - return lir->ins2ImmI(nj::LIR_gei, x, imm); - } - - nj::LIns *ltui(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_ltui, x, y); - } - - nj::LIns *ltuiN(nj::LIns *x, int32 imm) const { - return lir->ins2ImmI(nj::LIR_ltui, x, imm); - } - - nj::LIns *gtui(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_gtui, x, y); - } - - nj::LIns *leui(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_leui, x, y); - } - - nj::LIns *geui(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_geui, x, y); - } - -#ifdef NANOJIT_64BIT - nj::LIns *eqq(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_eqq, x, y); - } - - nj::LIns *ltuq(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_ltuq, x, y); - } - - nj::LIns *leuq(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_leuq, x, y); - } - - nj::LIns *geuq(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_geuq, x, y); - } -#endif - - nj::LIns *eqp(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_eqp, x, y); - } - - nj::LIns *eqp0(nj::LIns *x) const { - return lir->insEqP_0(x); - } - - nj::LIns *ltp(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_ltp, x, y); - } - - nj::LIns *ltup(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_ltup, x, y); - } - - nj::LIns *eqd(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_eqd, x, y); - } - - nj::LIns *eqd0(nj::LIns *x) const { - return lir->ins2(nj::LIR_eqd, x, immd(0)); - } - - nj::LIns *ltdN(nj::LIns *x, jsdouble imm) const { - return lir->ins2(nj::LIR_ltd, x, immd(imm)); - } - - /* Arithmetic */ - - nj::LIns *negi(nj::LIns *x) const { - return lir->ins1(nj::LIR_negi, x); - } - - nj::LIns *addi(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_addi, x, y); - } - - nj::LIns *addiN(nj::LIns *x, int32 imm) const { - return lir->ins2ImmI(nj::LIR_addi, x, imm); - } - - nj::LIns *subi(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_subi, x, y); - } - - nj::LIns *muli(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_muli, x, y); - } - - nj::LIns *muliN(nj::LIns *x, int32 imm) const { - return lir->ins2ImmI(nj::LIR_muli, x, imm); - } - -#if defined NANOJIT_IA32 || defined NANOJIT_X64 - nj::LIns *divi(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_divi, x, y); - } - - nj::LIns *modi(nj::LIns *x) const { - return lir->ins1(nj::LIR_modi, x); - } -#endif - - nj::LIns *andi(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_andi, x, y); - } - - nj::LIns *andiN(nj::LIns *x, int32 imm) const { - return lir->ins2ImmI(nj::LIR_andi, x, imm); - } - - nj::LIns *ori(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_ori, x, y); - } - - nj::LIns *xoriN(nj::LIns *x, int32 imm) const { - return lir->ins2ImmI(nj::LIR_xori, x, imm); - } - - nj::LIns *lshiN(nj::LIns *x, int32 imm) const { - return lir->ins2ImmI(nj::LIR_lshi, x, imm); - } - - nj::LIns *rshiN(nj::LIns *x, int32 imm) const { - return lir->ins2ImmI(nj::LIR_rshi, x, imm); - } - -#ifdef NANOJIT_64BIT - nj::LIns *andq(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_andq, x, y); - } - - nj::LIns *orq(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_orq, x, y); - } - - nj::LIns *lshqN(nj::LIns *x, int32 imm) const { - return lir->ins2ImmI(nj::LIR_lshq, x, imm); - } - - nj::LIns *rshuqN(nj::LIns *x, int32 imm) const { - return lir->ins2ImmI(nj::LIR_rshuq, x, imm); - } -#endif - - nj::LIns *addp(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_addp, x, y); - } - - nj::LIns *andp(nj::LIns *x, nj::LIns *y) const { - return lir->ins2(nj::LIR_andp, x, y); - } - - nj::LIns *lshpN(nj::LIns *x, int32 imm) const { - return lir->ins2ImmI(nj::LIR_lshp, x, imm); - } - - nj::LIns *rshupN(nj::LIns *x, int32 imm) const { - return lir->ins2ImmI(nj::LIR_rshup, x, imm); - } - - nj::LIns *negd(nj::LIns *x) const { - return lir->ins1(nj::LIR_negd, x); - } - - nj::LIns *cmovi(nj::LIns *cond, nj::LIns *t, nj::LIns *f) const { - /* We can only use cmovi if the configuration says we can. */ - NanoAssert(t->isI() && f->isI()); - return lir->insChoose(cond, t, f, avmplus::AvmCore::use_cmov()); - } - - nj::LIns *cmovp(nj::LIns *cond, nj::LIns *t, nj::LIns *f) const { - /* We can only use cmovp if the configuration says we can. */ - NanoAssert(t->isP() && f->isP()); - return lir->insChoose(cond, t, f, avmplus::AvmCore::use_cmov()); - } - - nj::LIns *cmovd(nj::LIns *cond, nj::LIns *t, nj::LIns *f) const { - /* We can always use cmovd. */ - NanoAssert(t->isD() && f->isD()); - return lir->insChoose(cond, t, f, /* use_cmov = */true); - } - - /* Conversions */ - -#ifdef NANOJIT_64BIT - nj::LIns *ui2uq(nj::LIns *ins) const { - return lir->ins1(nj::LIR_ui2uq, ins); - } - - nj::LIns *q2i(nj::LIns *ins) const { - return lir->ins1(nj::LIR_q2i, ins); - } -#endif - - nj::LIns *i2p(nj::LIns *x) const { - return lir->insI2P(x); - } - - nj::LIns *ui2p(nj::LIns *x) const { - return lir->insUI2P(x); - } - - nj::LIns *p2i(nj::LIns *x) const { - #ifdef NANOJIT_64BIT - return lir->ins1(nj::LIR_q2i, x); - #else - return x; - #endif - } - - nj::LIns *i2d(nj::LIns *ins) const { - return lir->ins1(nj::LIR_i2d, ins); - } - - nj::LIns *ui2d(nj::LIns *ins) const { - return lir->ins1(nj::LIR_ui2d, ins); - } - - /* - * This is not called d2i() because that could be easily confused with - * TraceRecorder::d2i(), which is usually what should be used. - */ - nj::LIns *rawD2i(nj::LIns *ins) const { - return lir->ins1(nj::LIR_d2i, ins); - } - -#ifdef NANOJIT_64BIT - nj::LIns *dasq(nj::LIns *ins) const { - return lir->ins1(nj::LIR_dasq, ins); - } - - nj::LIns *qasd(nj::LIns *ins) const { - return lir->ins1(nj::LIR_qasd, ins); - } -#endif - - nj::LIns *demoteToInt32(nj::LIns *ins) const { - return DemoteToInt32(lir, ins); - } - - nj::LIns *demoteToUint32(nj::LIns *ins) const { - return DemoteToUint32(lir, ins); - } - - /* Overflow arithmetic */ - - nj::LIns *addxovi(nj::LIns *x, nj::LIns *y, nj::GuardRecord *gr) const { - return lir->insGuardXov(nj::LIR_addxovi, x, y, gr); - } - - nj::LIns *subxovi(nj::LIns *x, nj::LIns *y, nj::GuardRecord *gr) const { - return lir->insGuardXov(nj::LIR_subxovi, x, y, gr); - } - - nj::LIns *mulxovi(nj::LIns *x, nj::LIns *y, nj::GuardRecord *gr) const { - return lir->insGuardXov(nj::LIR_mulxovi, x, y, gr); - } - - /* - * Ones not specific to a single opcode. These should not be used if an - * opcode-specific function can be used instead. - */ - - nj::LIns *ins1(nj::LOpcode op, nj::LIns *x) const { - return lir->ins1(op, x); - } - - nj::LIns *ins2(nj::LOpcode op, nj::LIns *x, nj::LIns *y) const { - return lir->ins2(op, x, y); - } - - /* Operations involving non-trivial combinations of multiple instructions. */ - - /* - * Nb: this "Privatized" refers to the Private API in jsvalue.h. It - * doesn't refer to the JSObj::privateData slot! Confusing. - */ - nj::LIns *getObjPrivatizedSlot(nj::LIns *obj, uint32 slot) const { -#if JS_BITS_PER_WORD == 32 - nj::LIns *vaddr_ins = ldpObjSlots(obj); - return lir->insLoad(nj::LIR_ldi, vaddr_ins, - slot * sizeof(Value) + sPayloadOffset, ACCSET_SLOTS, nj::LOAD_CONST); - -#elif JS_BITS_PER_WORD == 64 - /* N.B. On 64-bit, privatized value are encoded differently from other pointers. */ - nj::LIns *vaddr_ins = ldpObjSlots(obj); - nj::LIns *v_ins = lir->insLoad(nj::LIR_ldq, vaddr_ins, - slot * sizeof(Value) + sPayloadOffset, - ACCSET_SLOTS, nj::LOAD_CONST); - return lshqN(v_ins, 1); -#endif - } - - nj::LIns *getDslotAddress(nj::LIns *obj, nj::LIns *idx) const { - JS_ASSERT(sizeof(Value) == 8); // The |3| in the following statement requires this. - nj::LIns *offset = lshpN(ui2p(idx), 3); - nj::LIns *slots = ldpObjSlots(obj); - return addp(slots, offset); - } - - nj::LIns *getStringLength(nj::LIns *str) const { - return name(rshupN(ldpStringLengthAndFlags(str), JSString::LENGTH_SHIFT), - "strLength"); - } - - nj::LIns *getStringChar(nj::LIns *str, nj::LIns *idx) const { - nj::LIns *chars = ldpStringChars(str); - return name(lir->insLoad(nj::LIR_ldus2ui, addp(chars, lshpN(idx, 1)), 0, - ACCSET_STRING_MCHARS, nj::LOAD_CONST), - "strChar"); - } - - nj::LIns *getArgsLength(nj::LIns *args) const { - uint32 slot = JSObject::JSSLOT_ARGS_LENGTH; - nj::LIns *vaddr_ins = ldpObjSlots(args); - return name(lir->insLoad(nj::LIR_ldi, vaddr_ins, slot * sizeof(Value) + sPayloadOffset, - ACCSET_SLOTS), - "argsLength"); - } -}; - -} /* namespace tjit */ -} /* namespace js */ - -#endif /* tracejit_Writer_h___ */ - diff --git a/x86/mozilla/include/avmplus.h b/x86/mozilla/include/avmplus.h deleted file mode 100644 index c0b842c..0000000 --- a/x86/mozilla/include/avmplus.h +++ /dev/null @@ -1,347 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ -/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT - * WARRANTY OF ANY KIND, either express or implied. See the License for the specific - * language governing rights and limitations under the License. - * - * The Original Code is [Open Source Virtual Machine.] - * - * The Initial Developer of the Original Code is Adobe System Incorporated. Portions created - * by the Initial Developer are Copyright (C)[ 2004-2006 ] Adobe Systems Incorporated. All Rights - * Reserved. - * - * Contributor(s): Adobe AS3 Team - * Andreas Gal - * Asko Tontti - * - * Alternatively, the contents of this file may be used under the terms of either the GNU - * General Public License Version 2 or later (the "GPL"), or the GNU Lesser General Public - * License Version 2.1 or later (the "LGPL"), in which case the provisions of the GPL or the - * LGPL are applicable instead of those above. If you wish to allow use of your version of this - * file only under the terms of either the GPL or the LGPL, and not to allow others to use your - * version of this file under the terms of the MPL, indicate your decision by deleting provisions - * above and replace them with the notice and other provisions required by the GPL or the - * LGPL. If you do not delete the provisions above, a recipient may use your version of this file - * under the terms of any one of the MPL, the GPL or the LGPL. - * - ***** END LICENSE BLOCK ***** */ - -#ifndef avm_h___ -#define avm_h___ - -#include "VMPI.h" -#include "njcpudetect.h" -#include "njconfig.h" - -#if !defined(AVMPLUS_LITTLE_ENDIAN) && !defined(AVMPLUS_BIG_ENDIAN) -#ifdef IS_BIG_ENDIAN -#define AVMPLUS_BIG_ENDIAN -#else -#define AVMPLUS_LITTLE_ENDIAN -#endif -#endif - -#if defined(_MSC_VER) && defined(_M_IX86) -#define FASTCALL __fastcall -#elif defined(__GNUC__) && defined(__i386__) && \ - ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -#define FASTCALL __attribute__((fastcall)) -#else -#define FASTCALL -#define NO_FASTCALL -#endif - -#if defined(NO_FASTCALL) -#if defined(AVMPLUS_IA32) -#define SIMULATE_FASTCALL(lr, state_ptr, frag_ptr, func_addr) \ - asm volatile( \ - "call *%%esi" \ - : "=a" (lr) \ - : "c" (state_ptr), "d" (frag_ptr), "S" (func_addr) \ - : "memory", "cc" \ - ); -#endif /* defined(AVMPLUS_IA32) */ -#endif /* defined(NO_FASTCALL) */ - -#ifdef WIN32 -#include -#elif defined(AVMPLUS_OS2) -#define INCL_DOSMEMMGR -#include -#endif - -#if defined(__SUNPRO_CC) -#define __asm__ asm -#define __volatile__ volatile -#define __inline__ inline -#endif - -#if defined(DEBUG) || defined(NJ_NO_VARIADIC_MACROS) -#if !defined _DEBUG -#define _DEBUG -#endif -#define NJ_VERBOSE 1 -#include -#endif - -#ifdef _DEBUG -namespace avmplus { - void AvmAssertFail(const char* msg); -} -#endif - -#if defined(AVMPLUS_IA32) -#if defined(_MSC_VER) - -# define AVMPLUS_HAS_RDTSC 1 - -__declspec(naked) static inline __int64 rdtsc() -{ - __asm - { - rdtsc; - ret; - } -} - -#elif defined(__i386__) || defined(__i386) - -# define AVMPLUS_HAS_RDTSC 1 - -static __inline__ unsigned long long rdtsc(void) -{ - unsigned long long int x; - __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); - return x; -} - -#endif /* compilers */ - -#elif defined(__x86_64__) - -# define AVMPLUS_HAS_RDTSC 1 - -static __inline__ uint64_t rdtsc(void) -{ - unsigned hi, lo; - __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); - return ( (uint64_t)lo)|( ((uint64_t)hi)<<32 ); -} - -#elif defined(_MSC_VER) && defined(_M_AMD64) - -# define AVMPLUS_HAS_RDTSC 1 - -#include -#pragma intrinsic(__rdtsc) - -static inline unsigned __int64 rdtsc(void) -{ - return __rdtsc(); -} - -#elif defined(__powerpc__) - -# define AVMPLUS_HAS_RDTSC 1 - -typedef unsigned long long int unsigned long long; - -static __inline__ unsigned long long rdtsc(void) -{ - unsigned long long int result=0; - unsigned long int upper, lower,tmp; - __asm__ volatile( - "0: \n" - "\tmftbu %0 \n" - "\tmftb %1 \n" - "\tmftbu %2 \n" - "\tcmpw %2,%0 \n" - "\tbne 0b \n" - : "=r"(upper),"=r"(lower),"=r"(tmp) - ); - result = upper; - result = result<<32; - result = result|lower; - - return(result); -} - -#endif /* architecture */ - -#ifndef AVMPLUS_HAS_RDTSC -# define AVMPLUS_HAS_RDTSC 0 -#endif - -struct JSContext; - -#ifdef PERFM -# define PERFM_NVPROF(n,v) _nvprof(n,v) -# define PERFM_NTPROF(n) _ntprof(n) -# define PERFM_TPROF_END() _tprof_end() -#else -# define PERFM_NVPROF(n,v) -# define PERFM_NTPROF(n) -# define PERFM_TPROF_END() -#endif - -namespace avmplus { - - typedef int FunctionID; - - extern void AvmLog(char const *msg, ...); - - static const int kstrconst_emptyString = 0; - - class AvmInterpreter - { - class Labels { - public: - const char* format(const void* ip) - { - static char buf[33]; - sprintf(buf, "%p", ip); - return buf; - } - }; - - Labels _labels; - public: - Labels* labels; - - AvmInterpreter() - { - labels = &_labels; - } - - }; - - class AvmConsole - { - public: - AvmConsole& operator<<(const char* s) - { - fprintf(stdout, "%s", s); - return *this; - } - }; - - class AvmCore - { - public: - AvmInterpreter interp; - AvmConsole console; - - static nanojit::Config config; - -#ifdef AVMPLUS_IA32 - static inline bool - use_sse2() - { - return config.i386_sse2; - } -#endif - - static inline bool - use_cmov() - { -#ifdef AVMPLUS_IA32 - return config.i386_use_cmov; -#else - return true; -#endif - } - }; - - /** - * Bit vectors are an efficent method of keeping True/False information - * on a set of items or conditions. Class BitSet provides functions - * to manipulate individual bits in the vector. - * - * This object is not optimized for a fixed sized bit vector - * it instead allows for dynamically growing the bit vector. - */ - class BitSet - { - public: - enum { kUnit = 8*sizeof(long), - kDefaultCapacity = 4 }; - - BitSet() - { - capacity = kDefaultCapacity; - ar = (long*)calloc(capacity, sizeof(long)); - reset(); - } - - ~BitSet() - { - free(ar); - } - - void reset() - { - for (int i = 0; i < capacity; i++) - ar[i] = 0; - } - - void set(int bitNbr) - { - int index = bitNbr / kUnit; - int bit = bitNbr % kUnit; - if (index >= capacity) - grow(index+1); - - ar[index] |= (1< header is present and - useable. See jstypes.h and jsstdint.h. */ -#define JS_HAVE_STDINT_H 1 - -/* Define to 1 if the defines int8_t, etc. */ -/* #undef JS_SYS_TYPES_H_DEFINES_EXACT_SIZE_TYPES */ - -/* Define to 1 if the N-byte __intN types are defined by the - compiler. */ -/* #undef JS_HAVE___INTN */ - -/* Define to 1 if #including provides definitions for - intptr_t and uintptr_t. */ -/* #undef JS_STDDEF_H_HAS_INTPTR_T */ - -/* Define to 1 if #including provides definitions for - intptr_t and uintptr_t. */ -/* #undef JS_CRTDEFS_H_HAS_INTPTR_T */ - -/* The configure script defines these if it doesn't #define - JS_HAVE_STDINT_H. */ -/* #undef JS_INT8_TYPE */ -/* #undef JS_INT16_TYPE */ -/* #undef JS_INT32_TYPE */ -/* #undef JS_INT64_TYPE */ -/* #undef JS_INTPTR_TYPE */ -#define JS_BYTES_PER_WORD 4 - -/* Some mozilla code uses JS-friend APIs that depend on JS_TRACER and - JS_METHODJIT being correct. */ -#define JS_TRACER 1 -#define JS_METHODJIT 1 - -#endif /* js_config_h___ */ diff --git a/x86/mozilla/include/js.msg b/x86/mozilla/include/js.msg deleted file mode 100644 index 6f3c67a..0000000 --- a/x86/mozilla/include/js.msg +++ /dev/null @@ -1,351 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * This is the JavaScript error message file. - * - * The format for each JS error message is: - * - * MSG_DEF(, , , , - * ) - * - * where ; - * is a legal C identifer that will be used in the - * JS engine source. - * - * is an unique integral value identifying this error. - * - * is an integer literal specifying the total number of - * replaceable arguments in the following format string. - * - * is an exception index from the enum in jsexn.c; - * JSEXN_NONE for none. The given exception index will be raised by the - * engine when the corresponding error occurs. - * - * is a string literal, optionally containing sequences - * {X} where X is an integer representing the argument number that will - * be replaced with a string value when the error is reported. - * - * e.g. - * - * MSG_DEF(JSMSG_NOT_A_SUBSPECIES, 73, JSEXN_NONE, 2, - * "{0} is not a member of the {1} family") - * - * can be used: - * - * JS_ReportErrorNumber(JSMSG_NOT_A_SUBSPECIES, "Rhino", "Monkey"); - * - * to report: - * - * "Rhino is not a member of the Monkey family" - * - * Before adding a new MSG_DEF at the end, look for JSMSG_UNUSED free - * index placeholders in the middle of the list. - */ - -MSG_DEF(JSMSG_NOT_AN_ERROR, 0, 0, JSEXN_NONE, "") -MSG_DEF(JSMSG_NOT_DEFINED, 1, 1, JSEXN_REFERENCEERR, "{0} is not defined") -MSG_DEF(JSMSG_INACTIVE, 2, 0, JSEXN_INTERNALERR, "nothing active on context") -MSG_DEF(JSMSG_MORE_ARGS_NEEDED, 3, 3, JSEXN_TYPEERR, "{0} requires more than {1} argument{2}") -MSG_DEF(JSMSG_BAD_CHAR, 4, 1, JSEXN_INTERNALERR, "invalid format character {0}") -MSG_DEF(JSMSG_BAD_TYPE, 5, 1, JSEXN_TYPEERR, "unknown type {0}") -MSG_DEF(JSMSG_ALLOC_OVERFLOW, 6, 0, JSEXN_INTERNALERR, "allocation size overflow") -MSG_DEF(JSMSG_MISSING_HEXDIGITS, 7, 0, JSEXN_SYNTAXERR, "missing hexadecimal digits after '0x'") -MSG_DEF(JSMSG_INCOMPATIBLE_PROTO, 8, 3, JSEXN_TYPEERR, "{0}.prototype.{1} called on incompatible {2}") -MSG_DEF(JSMSG_NO_CONSTRUCTOR, 9, 1, JSEXN_TYPEERR, "{0} has no constructor") -MSG_DEF(JSMSG_CANT_ALIAS, 10, 3, JSEXN_TYPEERR, "can't alias {0} to {1} in class {2}") -MSG_DEF(JSMSG_NOT_SCRIPTED_FUNCTION, 11, 1, JSEXN_TYPEERR, "{0} is not a scripted function") -MSG_DEF(JSMSG_BAD_SORT_ARG, 12, 0, JSEXN_TYPEERR, "invalid Array.prototype.sort argument") -MSG_DEF(JSMSG_BAD_ATOMIC_NUMBER, 13, 1, JSEXN_INTERNALERR, "internal error: no index for atom {0}") -MSG_DEF(JSMSG_TOO_MANY_LITERALS, 14, 0, JSEXN_INTERNALERR, "too many literals") -MSG_DEF(JSMSG_CANT_WATCH, 15, 1, JSEXN_TYPEERR, "can't watch non-native objects of class {0}") -MSG_DEF(JSMSG_STACK_UNDERFLOW, 16, 2, JSEXN_INTERNALERR, "internal error compiling {0}: stack underflow at pc {1}") -MSG_DEF(JSMSG_NEED_DIET, 17, 1, JSEXN_INTERNALERR, "{0} too large") -MSG_DEF(JSMSG_TOO_MANY_LOCAL_ROOTS, 18, 0, JSEXN_ERR, "out of local root space") -MSG_DEF(JSMSG_READ_ONLY, 19, 1, JSEXN_TYPEERR, "{0} is read-only") -MSG_DEF(JSMSG_BAD_FORMAL, 20, 0, JSEXN_SYNTAXERR, "malformed formal parameter") -MSG_DEF(JSMSG_CANT_DELETE, 21, 1, JSEXN_TYPEERR, "property {0} is non-configurable and can't be deleted") -MSG_DEF(JSMSG_NOT_FUNCTION, 22, 1, JSEXN_TYPEERR, "{0} is not a function") -MSG_DEF(JSMSG_NOT_CONSTRUCTOR, 23, 1, JSEXN_TYPEERR, "{0} is not a constructor") -MSG_DEF(JSMSG_SCRIPT_STACK_QUOTA, 24, 0, JSEXN_INTERNALERR, "script stack space quota is exhausted") -MSG_DEF(JSMSG_TOO_DEEP, 25, 1, JSEXN_INTERNALERR, "{0} nested too deeply") -MSG_DEF(JSMSG_OVER_RECURSED, 26, 0, JSEXN_INTERNALERR, "too much recursion") -MSG_DEF(JSMSG_IN_NOT_OBJECT, 27, 1, JSEXN_TYPEERR, "invalid 'in' operand {0}") -MSG_DEF(JSMSG_BAD_NEW_RESULT, 28, 1, JSEXN_TYPEERR, "invalid new expression result {0}") -MSG_DEF(JSMSG_BAD_SHARP_DEF, 29, 1, JSEXN_ERR, "invalid sharp variable definition #{0}=") -MSG_DEF(JSMSG_BAD_SHARP_USE, 30, 1, JSEXN_ERR, "invalid sharp variable use #{0}#") -MSG_DEF(JSMSG_BAD_INSTANCEOF_RHS, 31, 1, JSEXN_TYPEERR, "invalid 'instanceof' operand {0}") -MSG_DEF(JSMSG_BAD_BYTECODE, 32, 1, JSEXN_INTERNALERR, "unimplemented JavaScript bytecode {0}") -MSG_DEF(JSMSG_BAD_RADIX, 33, 1, JSEXN_ERR, "illegal radix {0}") -MSG_DEF(JSMSG_PAREN_BEFORE_LET, 34, 0, JSEXN_SYNTAXERR, "missing ( before let head") -MSG_DEF(JSMSG_CANT_CONVERT, 35, 1, JSEXN_ERR, "can't convert {0} to an integer") -MSG_DEF(JSMSG_CYCLIC_VALUE, 36, 1, JSEXN_TYPEERR, "cyclic {0} value") -MSG_DEF(JSMSG_COMPILE_EXECED_SCRIPT, 37, 0, JSEXN_TYPEERR, "can't compile over a script that is currently executing") -MSG_DEF(JSMSG_CANT_CONVERT_TO, 38, 2, JSEXN_TYPEERR, "can't convert {0} to {1}") -MSG_DEF(JSMSG_NO_PROPERTIES, 39, 1, JSEXN_TYPEERR, "{0} has no properties") -MSG_DEF(JSMSG_CANT_FIND_CLASS, 40, 1, JSEXN_TYPEERR, "can't find class id {0}") -MSG_DEF(JSMSG_CANT_XDR_CLASS, 41, 1, JSEXN_TYPEERR, "can't XDR class {0}") -MSG_DEF(JSMSG_BYTECODE_TOO_BIG, 42, 2, JSEXN_INTERNALERR, "bytecode {0} too large (limit {1})") -MSG_DEF(JSMSG_UNKNOWN_FORMAT, 43, 1, JSEXN_INTERNALERR, "unknown bytecode format {0}") -MSG_DEF(JSMSG_TOO_MANY_CON_ARGS, 44, 0, JSEXN_SYNTAXERR, "too many constructor arguments") -MSG_DEF(JSMSG_TOO_MANY_FUN_ARGS, 45, 0, JSEXN_SYNTAXERR, "too many function arguments") -MSG_DEF(JSMSG_BAD_QUANTIFIER, 46, 0, JSEXN_SYNTAXERR, "invalid quantifier") -MSG_DEF(JSMSG_MIN_TOO_BIG, 47, 1, JSEXN_SYNTAXERR, "overlarge minimum {0}") -MSG_DEF(JSMSG_MAX_TOO_BIG, 48, 1, JSEXN_SYNTAXERR, "overlarge maximum {0}") -MSG_DEF(JSMSG_OUT_OF_ORDER, 49, 1, JSEXN_SYNTAXERR, "maximum {0} less than minimum") -MSG_DEF(JSMSG_BAD_DESTRUCT_DECL, 50, 0, JSEXN_SYNTAXERR, "missing = in destructuring declaration") -MSG_DEF(JSMSG_BAD_DESTRUCT_ASS, 51, 0, JSEXN_REFERENCEERR, "invalid destructuring assignment operator") -MSG_DEF(JSMSG_PAREN_AFTER_LET, 52, 0, JSEXN_SYNTAXERR, "missing ) after let head") -MSG_DEF(JSMSG_CURLY_AFTER_LET, 53, 0, JSEXN_SYNTAXERR, "missing } after let block") -MSG_DEF(JSMSG_MISSING_PAREN, 54, 0, JSEXN_SYNTAXERR, "unterminated parenthetical") -MSG_DEF(JSMSG_UNTERM_CLASS, 55, 1, JSEXN_SYNTAXERR, "unterminated character class {0}") -MSG_DEF(JSMSG_TRAILING_SLASH, 56, 0, JSEXN_SYNTAXERR, "trailing \\ in regular expression") -MSG_DEF(JSMSG_BAD_CLASS_RANGE, 57, 0, JSEXN_SYNTAXERR, "invalid range in character class") -MSG_DEF(JSMSG_BAD_REGEXP_FLAG, 58, 1, JSEXN_SYNTAXERR, "invalid regular expression flag {0}") -MSG_DEF(JSMSG_NO_INPUT, 59, 5, JSEXN_SYNTAXERR, "no input for /{0}/{1}{2}{3}{4}") -MSG_DEF(JSMSG_CANT_OPEN, 60, 2, JSEXN_ERR, "can't open {0}: {1}") -MSG_DEF(JSMSG_BAD_STRING_MASK, 61, 1, JSEXN_ERR, "invalid string escape mask {0}") -MSG_DEF(JSMSG_UNMATCHED_RIGHT_PAREN, 62, 0, JSEXN_SYNTAXERR, "unmatched ) in regular expression") -MSG_DEF(JSMSG_END_OF_DATA, 63, 0, JSEXN_INTERNALERR, "unexpected end of data") -MSG_DEF(JSMSG_SEEK_BEYOND_START, 64, 0, JSEXN_INTERNALERR, "illegal seek beyond start") -MSG_DEF(JSMSG_SEEK_BEYOND_END, 65, 0, JSEXN_INTERNALERR, "illegal seek beyond end") -MSG_DEF(JSMSG_END_SEEK, 66, 0, JSEXN_INTERNALERR, "illegal end-based seek") -MSG_DEF(JSMSG_WHITHER_WHENCE, 67, 1, JSEXN_INTERNALERR, "unknown seek whence: {0}") -MSG_DEF(JSMSG_BAD_SCRIPT_MAGIC, 68, 0, JSEXN_INTERNALERR, "bad script XDR magic number") -MSG_DEF(JSMSG_PAREN_BEFORE_FORMAL, 69, 0, JSEXN_SYNTAXERR, "missing ( before formal parameters") -MSG_DEF(JSMSG_MISSING_FORMAL, 70, 0, JSEXN_SYNTAXERR, "missing formal parameter") -MSG_DEF(JSMSG_PAREN_AFTER_FORMAL, 71, 0, JSEXN_SYNTAXERR, "missing ) after formal parameters") -MSG_DEF(JSMSG_CURLY_BEFORE_BODY, 72, 0, JSEXN_SYNTAXERR, "missing { before function body") -MSG_DEF(JSMSG_CURLY_AFTER_BODY, 73, 0, JSEXN_SYNTAXERR, "missing } after function body") -MSG_DEF(JSMSG_PAREN_BEFORE_COND, 74, 0, JSEXN_SYNTAXERR, "missing ( before condition") -MSG_DEF(JSMSG_PAREN_AFTER_COND, 75, 0, JSEXN_SYNTAXERR, "missing ) after condition") -MSG_DEF(JSMSG_DESTRUCT_DUP_ARG, 76, 0, JSEXN_SYNTAXERR, "duplicate argument is mixed with destructuring pattern") -MSG_DEF(JSMSG_NAME_AFTER_DOT, 77, 0, JSEXN_SYNTAXERR, "missing name after . operator") -MSG_DEF(JSMSG_BRACKET_IN_INDEX, 78, 0, JSEXN_SYNTAXERR, "missing ] in index expression") -MSG_DEF(JSMSG_XML_WHOLE_PROGRAM, 79, 0, JSEXN_SYNTAXERR, "XML can't be the whole program") -MSG_DEF(JSMSG_PAREN_BEFORE_SWITCH, 80, 0, JSEXN_SYNTAXERR, "missing ( before switch expression") -MSG_DEF(JSMSG_PAREN_AFTER_SWITCH, 81, 0, JSEXN_SYNTAXERR, "missing ) after switch expression") -MSG_DEF(JSMSG_CURLY_BEFORE_SWITCH, 82, 0, JSEXN_SYNTAXERR, "missing { before switch body") -MSG_DEF(JSMSG_COLON_AFTER_CASE, 83, 0, JSEXN_SYNTAXERR, "missing : after case label") -MSG_DEF(JSMSG_WHILE_AFTER_DO, 84, 0, JSEXN_SYNTAXERR, "missing while after do-loop body") -MSG_DEF(JSMSG_PAREN_AFTER_FOR, 85, 0, JSEXN_SYNTAXERR, "missing ( after for") -MSG_DEF(JSMSG_SEMI_AFTER_FOR_INIT, 86, 0, JSEXN_SYNTAXERR, "missing ; after for-loop initializer") -MSG_DEF(JSMSG_SEMI_AFTER_FOR_COND, 87, 0, JSEXN_SYNTAXERR, "missing ; after for-loop condition") -MSG_DEF(JSMSG_PAREN_AFTER_FOR_CTRL, 88, 0, JSEXN_SYNTAXERR, "missing ) after for-loop control") -MSG_DEF(JSMSG_CURLY_BEFORE_TRY, 89, 0, JSEXN_SYNTAXERR, "missing { before try block") -MSG_DEF(JSMSG_CURLY_AFTER_TRY, 90, 0, JSEXN_SYNTAXERR, "missing } after try block") -MSG_DEF(JSMSG_PAREN_BEFORE_CATCH, 91, 0, JSEXN_SYNTAXERR, "missing ( before catch") -MSG_DEF(JSMSG_CATCH_IDENTIFIER, 92, 0, JSEXN_SYNTAXERR, "missing identifier in catch") -MSG_DEF(JSMSG_PAREN_AFTER_CATCH, 93, 0, JSEXN_SYNTAXERR, "missing ) after catch") -MSG_DEF(JSMSG_CURLY_BEFORE_CATCH, 94, 0, JSEXN_SYNTAXERR, "missing { before catch block") -MSG_DEF(JSMSG_CURLY_AFTER_CATCH, 95, 0, JSEXN_SYNTAXERR, "missing } after catch block") -MSG_DEF(JSMSG_CURLY_BEFORE_FINALLY, 96, 0, JSEXN_SYNTAXERR, "missing { before finally block") -MSG_DEF(JSMSG_CURLY_AFTER_FINALLY, 97, 0, JSEXN_SYNTAXERR, "missing } after finally block") -MSG_DEF(JSMSG_CATCH_OR_FINALLY, 98, 0, JSEXN_SYNTAXERR, "missing catch or finally after try") -MSG_DEF(JSMSG_PAREN_BEFORE_WITH, 99, 0, JSEXN_SYNTAXERR, "missing ( before with-statement object") -MSG_DEF(JSMSG_PAREN_AFTER_WITH, 100, 0, JSEXN_SYNTAXERR, "missing ) after with-statement object") -MSG_DEF(JSMSG_CURLY_IN_COMPOUND, 101, 0, JSEXN_SYNTAXERR, "missing } in compound statement") -MSG_DEF(JSMSG_NO_VARIABLE_NAME, 102, 0, JSEXN_SYNTAXERR, "missing variable name") -MSG_DEF(JSMSG_COLON_IN_COND, 103, 0, JSEXN_SYNTAXERR, "missing : in conditional expression") -MSG_DEF(JSMSG_PAREN_AFTER_ARGS, 104, 0, JSEXN_SYNTAXERR, "missing ) after argument list") -MSG_DEF(JSMSG_BRACKET_AFTER_LIST, 105, 0, JSEXN_SYNTAXERR, "missing ] after element list") -MSG_DEF(JSMSG_COLON_AFTER_ID, 106, 0, JSEXN_SYNTAXERR, "missing : after property id") -MSG_DEF(JSMSG_CURLY_AFTER_LIST, 107, 0, JSEXN_SYNTAXERR, "missing } after property list") -MSG_DEF(JSMSG_PAREN_IN_PAREN, 108, 0, JSEXN_SYNTAXERR, "missing ) in parenthetical") -MSG_DEF(JSMSG_SEMI_BEFORE_STMNT, 109, 0, JSEXN_SYNTAXERR, "missing ; before statement") -MSG_DEF(JSMSG_NO_RETURN_VALUE, 110, 1, JSEXN_TYPEERR, "function {0} does not always return a value") -MSG_DEF(JSMSG_DUPLICATE_FORMAL, 111, 1, JSEXN_SYNTAXERR, "duplicate formal argument {0}") -MSG_DEF(JSMSG_EQUAL_AS_ASSIGN, 112, 1, JSEXN_SYNTAXERR, "test for equality (==) mistyped as assignment (=)?{0}") -MSG_DEF(JSMSG_OPTIMIZED_CLOSURE_LEAK, 113, 0, JSEXN_INTERNALERR, "can't access optimized closure") -MSG_DEF(JSMSG_TOO_MANY_DEFAULTS, 114, 0, JSEXN_SYNTAXERR, "more than one switch default") -MSG_DEF(JSMSG_TOO_MANY_CASES, 115, 0, JSEXN_INTERNALERR, "too many switch cases") -MSG_DEF(JSMSG_BAD_SWITCH, 116, 0, JSEXN_SYNTAXERR, "invalid switch statement") -MSG_DEF(JSMSG_BAD_FOR_LEFTSIDE, 117, 0, JSEXN_SYNTAXERR, "invalid for/in left-hand side") -MSG_DEF(JSMSG_CATCH_AFTER_GENERAL, 118, 0, JSEXN_SYNTAXERR, "catch after unconditional catch") -MSG_DEF(JSMSG_CATCH_WITHOUT_TRY, 119, 0, JSEXN_SYNTAXERR, "catch without try") -MSG_DEF(JSMSG_FINALLY_WITHOUT_TRY, 120, 0, JSEXN_SYNTAXERR, "finally without try") -MSG_DEF(JSMSG_LABEL_NOT_FOUND, 121, 0, JSEXN_SYNTAXERR, "label not found") -MSG_DEF(JSMSG_TOUGH_BREAK, 122, 0, JSEXN_SYNTAXERR, "unlabeled break must be inside loop or switch") -MSG_DEF(JSMSG_BAD_CONTINUE, 123, 0, JSEXN_SYNTAXERR, "continue must be inside loop") -MSG_DEF(JSMSG_BAD_RETURN_OR_YIELD, 124, 1, JSEXN_SYNTAXERR, "{0} not in function") -MSG_DEF(JSMSG_BAD_LABEL, 125, 0, JSEXN_SYNTAXERR, "invalid label") -MSG_DEF(JSMSG_DUPLICATE_LABEL, 126, 0, JSEXN_SYNTAXERR, "duplicate label") -MSG_DEF(JSMSG_VAR_HIDES_ARG, 127, 1, JSEXN_TYPEERR, "variable {0} redeclares argument") -MSG_DEF(JSMSG_BAD_VAR_INIT, 128, 0, JSEXN_SYNTAXERR, "invalid variable initialization") -MSG_DEF(JSMSG_BAD_LEFTSIDE_OF_ASS, 129, 0, JSEXN_REFERENCEERR, "invalid assignment left-hand side") -MSG_DEF(JSMSG_BAD_OPERAND, 130, 1, JSEXN_SYNTAXERR, "invalid {0} operand") -MSG_DEF(JSMSG_BAD_PROP_ID, 131, 0, JSEXN_SYNTAXERR, "invalid property id") -MSG_DEF(JSMSG_RESERVED_ID, 132, 1, JSEXN_SYNTAXERR, "{0} is a reserved identifier") -MSG_DEF(JSMSG_SYNTAX_ERROR, 133, 0, JSEXN_SYNTAXERR, "syntax error") -MSG_DEF(JSMSG_BAD_SHARP_VAR_DEF, 134, 0, JSEXN_SYNTAXERR, "invalid sharp variable definition") -MSG_DEF(JSMSG_BAD_PROTOTYPE, 135, 1, JSEXN_TYPEERR, "'prototype' property of {0} is not an object") -MSG_DEF(JSMSG_MISSING_EXPONENT, 136, 0, JSEXN_SYNTAXERR, "missing exponent") -MSG_DEF(JSMSG_OUT_OF_MEMORY, 137, 0, JSEXN_ERR, "out of memory") -MSG_DEF(JSMSG_UNTERMINATED_STRING, 138, 0, JSEXN_SYNTAXERR, "unterminated string literal") -MSG_DEF(JSMSG_TOO_MANY_PARENS, 139, 0, JSEXN_INTERNALERR, "too many parentheses in regular expression") -MSG_DEF(JSMSG_UNTERMINATED_COMMENT, 140, 0, JSEXN_SYNTAXERR, "unterminated comment") -MSG_DEF(JSMSG_UNTERMINATED_REGEXP, 141, 0, JSEXN_SYNTAXERR, "unterminated regular expression literal") -MSG_DEF(JSMSG_BAD_CLONE_FUNOBJ_SCOPE, 142, 0, JSEXN_TYPEERR, "bad cloned function scope chain") -MSG_DEF(JSMSG_SHARPVAR_TOO_BIG, 143, 0, JSEXN_SYNTAXERR, "overlarge sharp variable number") -MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 144, 0, JSEXN_SYNTAXERR, "illegal character") -MSG_DEF(JSMSG_BAD_OCTAL, 145, 1, JSEXN_SYNTAXERR, "{0} is not a legal ECMA-262 octal constant") -MSG_DEF(JSMSG_BAD_INDIRECT_CALL, 146, 1, JSEXN_EVALERR, "function {0} must be called directly, and not by way of a function of another name") -MSG_DEF(JSMSG_UNCAUGHT_EXCEPTION, 147, 1, JSEXN_INTERNALERR, "uncaught exception: {0}") -MSG_DEF(JSMSG_INVALID_BACKREF, 148, 0, JSEXN_SYNTAXERR, "non-octal digit in an escape sequence that doesn't match a back-reference") -MSG_DEF(JSMSG_BAD_BACKREF, 149, 0, JSEXN_SYNTAXERR, "back-reference exceeds number of capturing parentheses") -MSG_DEF(JSMSG_PRECISION_RANGE, 150, 1, JSEXN_RANGEERR, "precision {0} out of range") -MSG_DEF(JSMSG_BAD_GETTER_OR_SETTER, 151, 1, JSEXN_SYNTAXERR, "invalid {0} usage") -MSG_DEF(JSMSG_BAD_ARRAY_LENGTH, 152, 0, JSEXN_RANGEERR, "invalid array length") -MSG_DEF(JSMSG_CANT_DESCRIBE_PROPS, 153, 1, JSEXN_TYPEERR, "can't describe non-native properties of class {0}") -MSG_DEF(JSMSG_BAD_APPLY_ARGS, 154, 1, JSEXN_TYPEERR, "second argument to Function.prototype.{0} must be an array") -MSG_DEF(JSMSG_REDECLARED_VAR, 155, 2, JSEXN_TYPEERR, "redeclaration of {0} {1}") -MSG_DEF(JSMSG_UNDECLARED_VAR, 156, 1, JSEXN_REFERENCEERR, "assignment to undeclared variable {0}") -MSG_DEF(JSMSG_ANON_NO_RETURN_VALUE, 157, 0, JSEXN_TYPEERR, "anonymous function does not always return a value") -MSG_DEF(JSMSG_DEPRECATED_USAGE, 158, 1, JSEXN_REFERENCEERR, "deprecated {0} usage") -MSG_DEF(JSMSG_BAD_URI, 159, 0, JSEXN_URIERR, "malformed URI sequence") -MSG_DEF(JSMSG_GETTER_ONLY, 160, 0, JSEXN_TYPEERR, "setting a property that has only a getter") -MSG_DEF(JSMSG_IDSTART_AFTER_NUMBER, 161, 0, JSEXN_SYNTAXERR, "identifier starts immediately after numeric literal") -MSG_DEF(JSMSG_UNDEFINED_PROP, 162, 1, JSEXN_REFERENCEERR, "reference to undefined property {0}") -MSG_DEF(JSMSG_USELESS_EXPR, 163, 0, JSEXN_TYPEERR, "useless expression") -MSG_DEF(JSMSG_REDECLARED_PARAM, 164, 1, JSEXN_TYPEERR, "redeclaration of formal parameter {0}") -MSG_DEF(JSMSG_NEWREGEXP_FLAGGED, 165, 0, JSEXN_TYPEERR, "can't supply flags when constructing one RegExp from another") -MSG_DEF(JSMSG_RESERVED_SLOT_RANGE, 166, 0, JSEXN_RANGEERR, "reserved slot index out of range") -MSG_DEF(JSMSG_CANT_DECODE_PRINCIPALS, 167, 0, JSEXN_INTERNALERR, "can't decode JSPrincipals") -MSG_DEF(JSMSG_CANT_SEAL_OBJECT, 168, 1, JSEXN_ERR, "can't seal {0} objects") -MSG_DEF(JSMSG_TOO_MANY_CATCH_VARS, 169, 0, JSEXN_SYNTAXERR, "too many catch variables") -MSG_DEF(JSMSG_BAD_XML_MARKUP, 170, 0, JSEXN_SYNTAXERR, "invalid XML markup") -MSG_DEF(JSMSG_BAD_XML_CHARACTER, 171, 0, JSEXN_SYNTAXERR, "illegal XML character") -MSG_DEF(JSMSG_BAD_DEFAULT_XML_NAMESPACE,172,0,JSEXN_SYNTAXERR, "invalid default XML namespace") -MSG_DEF(JSMSG_BAD_XML_NAME_SYNTAX, 173, 0, JSEXN_SYNTAXERR, "invalid XML name") -MSG_DEF(JSMSG_BRACKET_AFTER_ATTR_EXPR,174, 0, JSEXN_SYNTAXERR, "missing ] after attribute expression") -MSG_DEF(JSMSG_NESTING_GENERATOR, 175, 1, JSEXN_TYPEERR, "already executing generator {0}") -MSG_DEF(JSMSG_CURLY_IN_XML_EXPR, 176, 0, JSEXN_SYNTAXERR, "missing } in XML expression") -MSG_DEF(JSMSG_BAD_XML_NAMESPACE, 177, 1, JSEXN_TYPEERR, "invalid XML namespace {0}") -MSG_DEF(JSMSG_BAD_XML_ATTR_NAME, 178, 1, JSEXN_TYPEERR, "invalid XML attribute name {0}") -MSG_DEF(JSMSG_BAD_XML_NAME, 179, 1, JSEXN_TYPEERR, "invalid XML name {0}") -MSG_DEF(JSMSG_BAD_XML_CONVERSION, 180, 1, JSEXN_TYPEERR, "can't convert {0} to XML") -MSG_DEF(JSMSG_BAD_XMLLIST_CONVERSION, 181, 1, JSEXN_TYPEERR, "can't convert {0} to XMLList") -MSG_DEF(JSMSG_BAD_GENERATOR_SEND, 182, 1, JSEXN_TYPEERR, "attempt to send {0} to newborn generator") -MSG_DEF(JSMSG_NO_ASSIGN_IN_XML_ATTR, 183, 0, JSEXN_SYNTAXERR, "missing = in XML attribute") -MSG_DEF(JSMSG_BAD_XML_ATTR_VALUE, 184, 0, JSEXN_SYNTAXERR, "invalid XML attribute value") -MSG_DEF(JSMSG_XML_TAG_NAME_MISMATCH, 185, 1, JSEXN_SYNTAXERR, "XML tag name mismatch (expected {0})") -MSG_DEF(JSMSG_BAD_XML_TAG_SYNTAX, 186, 0, JSEXN_SYNTAXERR, "invalid XML tag syntax") -MSG_DEF(JSMSG_BAD_XML_LIST_SYNTAX, 187, 0, JSEXN_SYNTAXERR, "invalid XML list syntax") -MSG_DEF(JSMSG_INCOMPATIBLE_METHOD, 188, 3, JSEXN_TYPEERR, "{0} {1} called on incompatible {2}") -MSG_DEF(JSMSG_CANT_SET_XML_ATTRS, 189, 0, JSEXN_INTERNALERR, "can't set XML property attributes") -MSG_DEF(JSMSG_END_OF_XML_SOURCE, 190, 0, JSEXN_SYNTAXERR, "unexpected end of XML source") -MSG_DEF(JSMSG_END_OF_XML_ENTITY, 191, 0, JSEXN_SYNTAXERR, "unexpected end of XML entity") -MSG_DEF(JSMSG_BAD_XML_QNAME, 192, 0, JSEXN_SYNTAXERR, "invalid XML qualified name") -MSG_DEF(JSMSG_BAD_FOR_EACH_LOOP, 193, 0, JSEXN_SYNTAXERR, "invalid for each loop") -MSG_DEF(JSMSG_BAD_XMLLIST_PUT, 194, 1, JSEXN_TYPEERR, "can't set property {0} in XMLList") -MSG_DEF(JSMSG_UNKNOWN_XML_ENTITY, 195, 1, JSEXN_TYPEERR, "unknown XML entity {0}") -MSG_DEF(JSMSG_BAD_XML_NCR, 196, 1, JSEXN_TYPEERR, "malformed XML character {0}") -MSG_DEF(JSMSG_UNDEFINED_XML_NAME, 197, 1, JSEXN_REFERENCEERR, "reference to undefined XML name {0}") -MSG_DEF(JSMSG_DUPLICATE_XML_ATTR, 198, 1, JSEXN_TYPEERR, "duplicate XML attribute {0}") -MSG_DEF(JSMSG_TOO_MANY_LOCALS, 199, 0, JSEXN_SYNTAXERR, "too many local variables") -MSG_DEF(JSMSG_ARRAY_INIT_TOO_BIG, 200, 0, JSEXN_INTERNALERR, "array initialiser too large") -MSG_DEF(JSMSG_REGEXP_TOO_COMPLEX, 201, 0, JSEXN_INTERNALERR, "regular expression too complex") -MSG_DEF(JSMSG_BUFFER_TOO_SMALL, 202, 0, JSEXN_INTERNALERR, "buffer too small") -MSG_DEF(JSMSG_BAD_SURROGATE_CHAR, 203, 1, JSEXN_TYPEERR, "bad surrogate character {0}") -MSG_DEF(JSMSG_UTF8_CHAR_TOO_LARGE, 204, 1, JSEXN_TYPEERR, "UTF-8 character {0} too large") -MSG_DEF(JSMSG_MALFORMED_UTF8_CHAR, 205, 1, JSEXN_TYPEERR, "malformed UTF-8 character sequence at offset {0}") -MSG_DEF(JSMSG_USER_DEFINED_ERROR, 206, 0, JSEXN_ERR, "JS_ReportError was called") -MSG_DEF(JSMSG_WRONG_CONSTRUCTOR, 207, 1, JSEXN_TYPEERR, "wrong constructor called for {0}") -MSG_DEF(JSMSG_BAD_GENERATOR_RETURN, 208, 1, JSEXN_TYPEERR, "generator function {0} returns a value") -MSG_DEF(JSMSG_BAD_ANON_GENERATOR_RETURN, 209, 0, JSEXN_TYPEERR, "anonymous generator function returns a value") -MSG_DEF(JSMSG_NAME_AFTER_FOR_PAREN, 210, 0, JSEXN_SYNTAXERR, "missing name after for (") -MSG_DEF(JSMSG_IN_AFTER_FOR_NAME, 211, 0, JSEXN_SYNTAXERR, "missing in after for") -MSG_DEF(JSMSG_BAD_TRAP_RETURN_VALUE, 212, 2, JSEXN_TYPEERR,"trap {1} for {0} returned a primitive value") -MSG_DEF(JSMSG_KEYWORD_NOT_NS, 213, 0, JSEXN_SYNTAXERR, "keyword is used as namespace") -MSG_DEF(JSMSG_BAD_GENERATOR_YIELD, 214, 1, JSEXN_TYPEERR, "yield from closing generator {0}") -MSG_DEF(JSMSG_BAD_GENERATOR_SYNTAX, 215, 1, JSEXN_SYNTAXERR, "{0} expression must be parenthesized") -MSG_DEF(JSMSG_ARRAY_COMP_LEFTSIDE, 216, 0, JSEXN_SYNTAXERR, "invalid array comprehension left-hand side") -MSG_DEF(JSMSG_NON_XML_FILTER, 217, 1, JSEXN_TYPEERR, "XML filter is applied to non-XML value {0}") -MSG_DEF(JSMSG_EMPTY_ARRAY_REDUCE, 218, 0, JSEXN_TYPEERR, "reduce of empty array with no initial value") -MSG_DEF(JSMSG_NON_LIST_XML_METHOD, 219, 2, JSEXN_TYPEERR, "can't call {0} method on an XML list with {1} elements") -MSG_DEF(JSMSG_BAD_DELETE_OPERAND, 220, 0, JSEXN_REFERENCEERR, "invalid delete operand") -MSG_DEF(JSMSG_BAD_INCOP_OPERAND, 221, 0, JSEXN_REFERENCEERR, "invalid increment/decrement operand") -MSG_DEF(JSMSG_UNEXPECTED_TYPE, 222, 2, JSEXN_TYPEERR, "{0} is {1}") -MSG_DEF(JSMSG_LET_DECL_NOT_IN_BLOCK, 223, 0, JSEXN_SYNTAXERR, "let declaration not directly within block") -MSG_DEF(JSMSG_BAD_OBJECT_INIT, 224, 0, JSEXN_SYNTAXERR, "invalid object initializer") -MSG_DEF(JSMSG_CANT_SET_ARRAY_ATTRS, 225, 0, JSEXN_INTERNALERR, "can't set attributes on indexed array properties") -MSG_DEF(JSMSG_EVAL_ARITY, 226, 0, JSEXN_TYPEERR, "eval accepts only one parameter") -MSG_DEF(JSMSG_MISSING_FUN_ARG, 227, 2, JSEXN_TYPEERR, "missing argument {0} when calling function {1}") -MSG_DEF(JSMSG_JSON_BAD_PARSE, 228, 0, JSEXN_SYNTAXERR, "JSON.parse") -MSG_DEF(JSMSG_JSON_BAD_STRINGIFY, 229, 0, JSEXN_ERR, "JSON.stringify") -MSG_DEF(JSMSG_XDR_CLOSURE_WRAPPER, 230, 1, JSEXN_INTERNALERR, "can't XDR closure wrapper for function {0}") -MSG_DEF(JSMSG_NOT_NONNULL_OBJECT, 231, 0, JSEXN_TYPEERR, "value is not a non-null object") -MSG_DEF(JSMSG_DEPRECATED_OCTAL, 232, 0, JSEXN_SYNTAXERR, "octal literals and octal escape sequences are deprecated") -MSG_DEF(JSMSG_STRICT_CODE_WITH, 233, 0, JSEXN_SYNTAXERR, "strict mode code may not contain 'with' statements") -MSG_DEF(JSMSG_DUPLICATE_PROPERTY, 234, 1, JSEXN_SYNTAXERR, "property name {0} appears more than once in object literal") -MSG_DEF(JSMSG_DEPRECATED_DELETE_OPERAND, 235, 0, JSEXN_SYNTAXERR, "applying the 'delete' operator to an unqualified name is deprecated") -MSG_DEF(JSMSG_DEPRECATED_ASSIGN, 236, 1, JSEXN_SYNTAXERR, "assignment to {0} is deprecated") -MSG_DEF(JSMSG_BAD_BINDING, 237, 1, JSEXN_SYNTAXERR, "redefining {0} is deprecated") -MSG_DEF(JSMSG_INVALID_DESCRIPTOR, 238, 0, JSEXN_TYPEERR, "property descriptors must not specify a value or be writable when a getter or setter has been specified") -MSG_DEF(JSMSG_OBJECT_NOT_EXTENSIBLE, 239, 1, JSEXN_TYPEERR, "{0} is not extensible") -MSG_DEF(JSMSG_CANT_REDEFINE_PROP, 240, 1, JSEXN_TYPEERR, "can't redefine non-configurable property '{0}'") -MSG_DEF(JSMSG_CANT_APPEND_TO_ARRAY, 241, 0, JSEXN_TYPEERR, "can't add elements past the end of an array if its length property is unwritable") -MSG_DEF(JSMSG_CANT_DEFINE_ARRAY_LENGTH,242, 0, JSEXN_INTERNALERR, "defining the length property on an array is not currently supported") -MSG_DEF(JSMSG_CANT_DEFINE_ARRAY_INDEX,243, 0, JSEXN_TYPEERR, "can't define array index property") -MSG_DEF(JSMSG_TYPED_ARRAY_BAD_INDEX, 244, 0, JSEXN_ERR, "invalid or out-of-range index") -MSG_DEF(JSMSG_TYPED_ARRAY_NEGATIVE_ARG, 245, 1, JSEXN_ERR, "argument {0} must be >= 0") -MSG_DEF(JSMSG_TYPED_ARRAY_BAD_ARGS, 246, 0, JSEXN_ERR, "invalid arguments") -MSG_DEF(JSMSG_CSP_BLOCKED_FUNCTION, 247, 0, JSEXN_ERR, "call to Function() blocked by CSP") -MSG_DEF(JSMSG_BAD_GET_SET_FIELD, 248, 1, JSEXN_TYPEERR, "property descriptor's {0} field is neither undefined nor a function") -MSG_DEF(JSMSG_BAD_PROXY_FIX, 249, 0, JSEXN_TYPEERR, "proxy was fixed while executing the handler") -MSG_DEF(JSMSG_INVALID_EVAL_SCOPE_ARG, 250, 0, JSEXN_EVALERR, "invalid eval scope argument") -MSG_DEF(JSMSG_ACCESSOR_WRONG_ARGS, 251, 3, JSEXN_SYNTAXERR, "{0} functions must have {1} argument{2}") -MSG_DEF(JSMSG_THROW_TYPE_ERROR, 252, 0, JSEXN_TYPEERR, "'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them") -MSG_DEF(JSMSG_BAD_TOISOSTRING_PROP, 253, 0, JSEXN_TYPEERR, "toISOString property is not callable") -MSG_DEF(JSMSG_BAD_PARSE_NODE, 254, 0, JSEXN_INTERNALERR, "bad parse node") -MSG_DEF(JSMSG_NOT_EXPECTED_TYPE, 255, 3, JSEXN_TYPEERR, "{0}: expected {1}, got {2}") -MSG_DEF(JSMSG_CALLER_IS_STRICT, 256, 0, JSEXN_TYPEERR, "access to strict mode caller function is censored") -MSG_DEF(JSMSG_NEED_DEBUG_MODE, 257, 0, JSEXN_ERR, "function can be called only in debug mode") -MSG_DEF(JSMSG_STRICT_CODE_LET_EXPR_STMT, 258, 0, JSEXN_ERR, "strict mode code may not contain unparenthesized let expression statements") -MSG_DEF(JSMSG_CANT_CHANGE_EXTENSIBILITY, 259, 0, JSEXN_TYPEERR, "can't change object's extensibility") -MSG_DEF(JSMSG_SC_BAD_SERIALIZED_DATA, 260, 1, JSEXN_INTERNALERR, "bad serialized structured data ({0})") -MSG_DEF(JSMSG_SC_UNSUPPORTED_TYPE, 261, 0, JSEXN_TYPEERR, "unsupported type for structured data") -MSG_DEF(JSMSG_SC_RECURSION, 262, 0, JSEXN_INTERNALERR, "recursive object") -MSG_DEF(JSMSG_CANT_WRAP_XML_OBJECT, 263, 0, JSEXN_TYPEERR, "can't wrap XML objects") -MSG_DEF(JSMSG_BAD_CLONE_VERSION, 264, 0, JSEXN_ERR, "unsupported structured clone version") -MSG_DEF(JSMSG_CANT_CLONE_OBJECT, 265, 0, JSEXN_TYPEERR, "can't clone object") -MSG_DEF(JSMSG_NON_NATIVE_SCOPE, 266, 0, JSEXN_TYPEERR, "non-native scope object") -MSG_DEF(JSMSG_STRICT_FUNCTION_STATEMENT, 267, 0, JSEXN_SYNTAXERR, "in strict mode code, functions may be declared only at top level or immediately within another function") -MSG_DEF(JSMSG_INVALID_FOR_IN_INIT, 268, 0, JSEXN_SYNTAXERR, "for-in loop let declaration may not have an initializer") -MSG_DEF(JSMSG_CLEARED_SCOPE, 269, 0, JSEXN_TYPEERR, "attempt to run compile-and-go script on a cleared scope") diff --git a/x86/mozilla/include/jsanalyze.h b/x86/mozilla/include/jsanalyze.h deleted file mode 100644 index de74302..0000000 --- a/x86/mozilla/include/jsanalyze.h +++ /dev/null @@ -1,213 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 4; tab-width: 40; indent-tabs-mode: nil -*- */ -/* vim: set ts=40 sw=4 et tw=99: */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Mozilla SpiderMonkey bytecode analysis - * - * The Initial Developer of the Original Code is - * Mozilla Foundation - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* Definitions for javascript analysis. */ - -#ifndef jsanalyze_h___ -#define jsanalyze_h___ - -#include "jsarena.h" -#include "jscntxt.h" -#include "jsscript.h" - -struct JSScript; - -namespace js { -namespace analyze { - -class Script; - -/* Information about a bytecode instruction. */ -struct Bytecode -{ - friend class Script; - - /* Whether there are any incoming jumps to this instruction. */ - bool jumpTarget : 1; - - /* Whether this instruction has been analyzed to get its output defines and stack. */ - bool analyzed : 1; - - /* Whether this is a catch/finally entry point. */ - bool exceptionEntry : 1; - - /* Whether this is in a try block. */ - bool inTryBlock : 1; - - /* Whether this is a method JIT safe point. */ - bool safePoint : 1; - - /* Stack depth before this opcode. */ - uint32 stackDepth; - - /* - * The set of locals defined at this point. This does not include locals which - * were unconditionally defined at an earlier point in the script. - */ - uint32 defineCount; - uint32 *defineArray; - - Bytecode() - { - PodZero(this); - } - - private: - bool mergeDefines(JSContext *cx, - Script *script, bool initial, uint32 newDepth, - uint32 *newArray, uint32 newCount); - - /* Whether a local variable is in the define set at this bytecode. */ - bool isDefined(uint32 slot) - { - JS_ASSERT(analyzed); - for (size_t ind = 0; ind < defineCount; ind++) { - if (defineArray[ind] == slot) - return true; - } - return false; - } -}; - -/* Information about a script. */ -class Script -{ - friend struct Bytecode; - - JSScript *script; - Bytecode **code; - - /* Maximum number of locals to consider for a script. */ - static const unsigned LOCAL_LIMIT = 50; - - /* Offsets at which each local becomes unconditionally defined, or a value below. */ - uint32 *locals; - - static const uint32 LOCAL_USE_BEFORE_DEF = uint32(-1); - static const uint32 LOCAL_CONDITIONALLY_DEFINED = uint32(-2); - - bool outOfMemory; - bool hadFailure; - bool usesRval; - bool usesScope; - - public: - /* Pool for allocating analysis structures which will not outlive this script. */ - JSArenaPool pool; - - void analyze(JSContext *cx, JSScript *script); - void destroy(); - - /* - * For analysis scripts allocated on the stack. Scripts don't have constructors, - * and must be zeroed out before being used. - */ - ~Script() { destroy(); } - - /* Whether we ran out of memory during analysis. */ - bool OOM() { return outOfMemory; } - - /* Whether the script was analyzed successfully. */ - bool failed() { return hadFailure; } - - /* Whether there are POPV/SETRVAL bytecodes which can write to the frame's rval. */ - bool usesReturnValue() const { return usesRval; } - - /* Whether there are NAME bytecodes which can access the frame's scope chain. */ - bool usesScopeChain() const { return usesScope; } - - /* Accessors for bytecode information. */ - - Bytecode& getCode(uint32 offset) { - JS_ASSERT(offset < script->length); - JS_ASSERT(code[offset]); - return *code[offset]; - } - Bytecode& getCode(jsbytecode *pc) { return getCode(pc - script->code); } - - Bytecode* maybeCode(uint32 offset) { - JS_ASSERT(offset < script->length); - return code[offset]; - } - Bytecode* maybeCode(jsbytecode *pc) { return maybeCode(pc - script->code); } - - bool jumpTarget(uint32 offset) { - JS_ASSERT(offset < script->length); - return code[offset] && code[offset]->jumpTarget; - } - bool jumpTarget(jsbytecode *pc) { return jumpTarget(pc - script->code); } - - /* Accessors for local variable information. */ - - unsigned localCount() { - return (script->nfixed >= LOCAL_LIMIT) ? LOCAL_LIMIT : script->nfixed; - } - - bool localHasUseBeforeDef(uint32 local) { - JS_ASSERT(local < script->nfixed && !failed()); - return local >= localCount() || locals[local] == LOCAL_USE_BEFORE_DEF; - } - - /* These return true for variables that may have a use before def. */ - bool localDefined(uint32 local, uint32 offset) { - return localHasUseBeforeDef(local) || (locals[local] <= offset) || - getCode(offset).isDefined(local); - } - bool localDefined(uint32 local, jsbytecode *pc) { - return localDefined(local, pc - script->code); - } - - private: - void setOOM(JSContext *cx) { - if (!outOfMemory) - js_ReportOutOfMemory(cx); - outOfMemory = true; - hadFailure = true; - } - - inline bool addJump(JSContext *cx, unsigned offset, - unsigned *currentOffset, unsigned *forwardJump, - unsigned stackDepth, uint32 *defineArray, unsigned defineCount); - - inline void setLocal(uint32 local, uint32 offset); -}; - -} /* namespace analyze */ -} /* namespace js */ - -#endif // jsanalyze_h___ diff --git a/x86/mozilla/include/jsapi.h b/x86/mozilla/include/jsapi.h deleted file mode 100644 index 8e51d73..0000000 --- a/x86/mozilla/include/jsapi.h +++ /dev/null @@ -1,3899 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=78: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsapi_h___ -#define jsapi_h___ -/* - * JavaScript API. - */ -#include -#include -#include "js-config.h" -#include "jspubtd.h" -#include "jsutil.h" - -JS_BEGIN_EXTERN_C - -/* - * In release builds, jsval and jsid are defined to be integral types. This - * prevents many bugs from being caught at compile time. E.g.: - * - * jsval v = ... - * if (v == JS_TRUE) // error - * ... - * - * jsid id = v; // error - * - * To catch more errors, jsval and jsid are given struct types in debug builds. - * Struct assignment and (in C++) operator== allow correct code to be mostly - * oblivious to the change. This feature can be explicitly disabled in debug - * builds by defining JS_NO_JSVAL_JSID_STRUCT_TYPES. - */ -#ifdef JS_USE_JSVAL_JSID_STRUCT_TYPES - -/* Well-known JS values. N.B. These constants are initialized at startup. */ -extern JS_PUBLIC_DATA(jsval) JSVAL_NULL; -extern JS_PUBLIC_DATA(jsval) JSVAL_ZERO; -extern JS_PUBLIC_DATA(jsval) JSVAL_ONE; -extern JS_PUBLIC_DATA(jsval) JSVAL_FALSE; -extern JS_PUBLIC_DATA(jsval) JSVAL_TRUE; -extern JS_PUBLIC_DATA(jsval) JSVAL_VOID; - -#else - -/* Well-known JS values. */ -#define JSVAL_NULL BUILD_JSVAL(JSVAL_TAG_NULL, 0) -#define JSVAL_ZERO BUILD_JSVAL(JSVAL_TAG_INT32, 0) -#define JSVAL_ONE BUILD_JSVAL(JSVAL_TAG_INT32, 1) -#define JSVAL_FALSE BUILD_JSVAL(JSVAL_TAG_BOOLEAN, JS_FALSE) -#define JSVAL_TRUE BUILD_JSVAL(JSVAL_TAG_BOOLEAN, JS_TRUE) -#define JSVAL_VOID BUILD_JSVAL(JSVAL_TAG_UNDEFINED, 0) - -#endif - -/************************************************************************/ - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_NULL(jsval v) -{ - jsval_layout l; - l.asBits = JSVAL_BITS(v); - return JSVAL_IS_NULL_IMPL(l); -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_VOID(jsval v) -{ - jsval_layout l; - l.asBits = JSVAL_BITS(v); - return JSVAL_IS_UNDEFINED_IMPL(l); -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_INT(jsval v) -{ - jsval_layout l; - l.asBits = JSVAL_BITS(v); - return JSVAL_IS_INT32_IMPL(l); -} - -static JS_ALWAYS_INLINE jsint -JSVAL_TO_INT(jsval v) -{ - jsval_layout l; - JS_ASSERT(JSVAL_IS_INT(v)); - l.asBits = JSVAL_BITS(v); - return JSVAL_TO_INT32_IMPL(l); -} - -#define JSVAL_INT_BITS 32 -#define JSVAL_INT_MIN ((jsint)0x80000000) -#define JSVAL_INT_MAX ((jsint)0x7fffffff) - -static JS_ALWAYS_INLINE jsval -INT_TO_JSVAL(int32 i) -{ - return IMPL_TO_JSVAL(INT32_TO_JSVAL_IMPL(i)); -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_DOUBLE(jsval v) -{ - jsval_layout l; - l.asBits = JSVAL_BITS(v); - return JSVAL_IS_DOUBLE_IMPL(l); -} - -static JS_ALWAYS_INLINE jsdouble -JSVAL_TO_DOUBLE(jsval v) -{ - jsval_layout l; - JS_ASSERT(JSVAL_IS_DOUBLE(v)); - l.asBits = JSVAL_BITS(v); - return l.asDouble; -} - -static JS_ALWAYS_INLINE jsval -DOUBLE_TO_JSVAL(jsdouble d) -{ - d = JS_CANONICALIZE_NAN(d); - return IMPL_TO_JSVAL(DOUBLE_TO_JSVAL_IMPL(d)); -} - -static JS_ALWAYS_INLINE jsval -UINT_TO_JSVAL(uint32 i) -{ - if (i <= JSVAL_INT_MAX) - return INT_TO_JSVAL((int32)i); - return DOUBLE_TO_JSVAL((jsdouble)i); -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_NUMBER(jsval v) -{ - jsval_layout l; - l.asBits = JSVAL_BITS(v); - return JSVAL_IS_NUMBER_IMPL(l); -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_STRING(jsval v) -{ - jsval_layout l; - l.asBits = JSVAL_BITS(v); - return JSVAL_IS_STRING_IMPL(l); -} - -static JS_ALWAYS_INLINE JSString * -JSVAL_TO_STRING(jsval v) -{ - jsval_layout l; - JS_ASSERT(JSVAL_IS_STRING(v)); - l.asBits = JSVAL_BITS(v); - return JSVAL_TO_STRING_IMPL(l); -} - -static JS_ALWAYS_INLINE jsval -STRING_TO_JSVAL(JSString *str) -{ - return IMPL_TO_JSVAL(STRING_TO_JSVAL_IMPL(str)); -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_OBJECT(jsval v) -{ - jsval_layout l; - l.asBits = JSVAL_BITS(v); - return JSVAL_IS_OBJECT_OR_NULL_IMPL(l); -} - -static JS_ALWAYS_INLINE JSObject * -JSVAL_TO_OBJECT(jsval v) -{ - jsval_layout l; - JS_ASSERT(JSVAL_IS_OBJECT(v)); - l.asBits = JSVAL_BITS(v); - return JSVAL_TO_OBJECT_IMPL(l); -} - -static JS_ALWAYS_INLINE jsval -OBJECT_TO_JSVAL(JSObject *obj) -{ - if (obj) - return IMPL_TO_JSVAL(OBJECT_TO_JSVAL_IMPL(obj)); - return JSVAL_NULL; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_BOOLEAN(jsval v) -{ - jsval_layout l; - l.asBits = JSVAL_BITS(v); - return JSVAL_IS_BOOLEAN_IMPL(l); -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_TO_BOOLEAN(jsval v) -{ - jsval_layout l; - JS_ASSERT(JSVAL_IS_BOOLEAN(v)); - l.asBits = JSVAL_BITS(v); - return JSVAL_TO_BOOLEAN_IMPL(l); -} - -static JS_ALWAYS_INLINE jsval -BOOLEAN_TO_JSVAL(JSBool b) -{ - return IMPL_TO_JSVAL(BOOLEAN_TO_JSVAL_IMPL(b)); -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_PRIMITIVE(jsval v) -{ - jsval_layout l; - l.asBits = JSVAL_BITS(v); - return JSVAL_IS_PRIMITIVE_IMPL(l); -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_GCTHING(jsval v) -{ - jsval_layout l; - l.asBits = JSVAL_BITS(v); - return JSVAL_IS_GCTHING_IMPL(l); -} - -static JS_ALWAYS_INLINE void * -JSVAL_TO_GCTHING(jsval v) -{ - jsval_layout l; - JS_ASSERT(JSVAL_IS_GCTHING(v)); - l.asBits = JSVAL_BITS(v); - return JSVAL_TO_GCTHING_IMPL(l); -} - -/* To be GC-safe, privates are tagged as doubles. */ - -static JS_ALWAYS_INLINE jsval -PRIVATE_TO_JSVAL(void *ptr) -{ - return IMPL_TO_JSVAL(PRIVATE_PTR_TO_JSVAL_IMPL(ptr)); -} - -static JS_ALWAYS_INLINE void * -JSVAL_TO_PRIVATE(jsval v) -{ - jsval_layout l; - JS_ASSERT(JSVAL_IS_DOUBLE(v)); - l.asBits = JSVAL_BITS(v); - return JSVAL_TO_PRIVATE_PTR_IMPL(l); -} - -/************************************************************************/ - -/* - * A jsid is an identifier for a property or method of an object which is - * either a 31-bit signed integer, interned string or object. If XML is - * enabled, there is an additional singleton jsid value; see - * JS_DEFAULT_XML_NAMESPACE_ID below. Finally, there is an additional jsid - * value, JSID_VOID, which does not occur in JS scripts but may be used to - * indicate the absence of a valid jsid. - * - * A jsid is not implicitly convertible to or from a jsval; JS_ValueToId or - * JS_IdToValue must be used instead. - */ - -#define JSID_TYPE_STRING 0x0 -#define JSID_TYPE_INT 0x1 -#define JSID_TYPE_VOID 0x2 -#define JSID_TYPE_OBJECT 0x4 -#define JSID_TYPE_DEFAULT_XML_NAMESPACE 0x6 -#define JSID_TYPE_MASK 0x7 - -/* - * Avoid using canonical 'id' for jsid parameters since this is a magic word in - * Objective-C++ which, apparently, wants to be able to #include jsapi.h. - */ -#define id iden - -static JS_ALWAYS_INLINE JSBool -JSID_IS_STRING(jsid id) -{ - return (JSID_BITS(id) & JSID_TYPE_MASK) == 0; -} - -static JS_ALWAYS_INLINE JSString * -JSID_TO_STRING(jsid id) -{ - JS_ASSERT(JSID_IS_STRING(id)); - return (JSString *)(JSID_BITS(id)); -} - -static JS_ALWAYS_INLINE JSBool -JSID_IS_ZERO(jsid id) -{ - return JSID_BITS(id) == 0; -} - -JS_PUBLIC_API(JSBool) -JS_StringHasBeenInterned(JSString *str); - -/* A jsid may only hold an interned JSString. */ -static JS_ALWAYS_INLINE jsid -INTERNED_STRING_TO_JSID(JSString *str) -{ - jsid id; - JS_ASSERT(str); - JS_ASSERT(JS_StringHasBeenInterned(str)); - JS_ASSERT(((size_t)str & JSID_TYPE_MASK) == 0); - JSID_BITS(id) = (size_t)str; - return id; -} - -static JS_ALWAYS_INLINE JSBool -JSID_IS_INT(jsid id) -{ - return !!(JSID_BITS(id) & JSID_TYPE_INT); -} - -static JS_ALWAYS_INLINE int32 -JSID_TO_INT(jsid id) -{ - JS_ASSERT(JSID_IS_INT(id)); - return ((int32)JSID_BITS(id)) >> 1; -} - -/* - * Note: when changing these values, verify that their use in - * js_CheckForStringIndex is still valid. - */ -#define JSID_INT_MIN (-(1 << 30)) -#define JSID_INT_MAX ((1 << 30) - 1) - -static JS_ALWAYS_INLINE JSBool -INT_FITS_IN_JSID(int32 i) -{ - return ((jsuint)(i) - (jsuint)JSID_INT_MIN <= - (jsuint)(JSID_INT_MAX - JSID_INT_MIN)); -} - -static JS_ALWAYS_INLINE jsid -INT_TO_JSID(int32 i) -{ - jsid id; - JS_ASSERT(INT_FITS_IN_JSID(i)); - JSID_BITS(id) = ((i << 1) | JSID_TYPE_INT); - return id; -} - -static JS_ALWAYS_INLINE JSBool -JSID_IS_OBJECT(jsid id) -{ - return (JSID_BITS(id) & JSID_TYPE_MASK) == JSID_TYPE_OBJECT && - (size_t)JSID_BITS(id) != JSID_TYPE_OBJECT; -} - -static JS_ALWAYS_INLINE JSObject * -JSID_TO_OBJECT(jsid id) -{ - JS_ASSERT(JSID_IS_OBJECT(id)); - return (JSObject *)(JSID_BITS(id) & ~(size_t)JSID_TYPE_MASK); -} - -static JS_ALWAYS_INLINE jsid -OBJECT_TO_JSID(JSObject *obj) -{ - jsid id; - JS_ASSERT(obj != NULL); - JS_ASSERT(((size_t)obj & JSID_TYPE_MASK) == 0); - JSID_BITS(id) = ((size_t)obj | JSID_TYPE_OBJECT); - return id; -} - -static JS_ALWAYS_INLINE JSBool -JSID_IS_GCTHING(jsid id) -{ - return JSID_IS_STRING(id) || JSID_IS_OBJECT(id); -} - -static JS_ALWAYS_INLINE void * -JSID_TO_GCTHING(jsid id) -{ - return (void *)(JSID_BITS(id) & ~(size_t)JSID_TYPE_MASK); -} - -/* - * The magic XML namespace id is not a valid jsid. Global object classes in - * embeddings that enable JS_HAS_XML_SUPPORT (E4X) should handle this id. - */ - -static JS_ALWAYS_INLINE JSBool -JSID_IS_DEFAULT_XML_NAMESPACE(jsid id) -{ - JS_ASSERT_IF(((size_t)JSID_BITS(id) & JSID_TYPE_MASK) == JSID_TYPE_DEFAULT_XML_NAMESPACE, - JSID_BITS(id) == JSID_TYPE_DEFAULT_XML_NAMESPACE); - return ((size_t)JSID_BITS(id) == JSID_TYPE_DEFAULT_XML_NAMESPACE); -} - -#ifdef JS_USE_JSVAL_JSID_STRUCT_TYPES -extern JS_PUBLIC_DATA(jsid) JS_DEFAULT_XML_NAMESPACE_ID; -#else -#define JS_DEFAULT_XML_NAMESPACE_ID ((jsid)JSID_TYPE_DEFAULT_XML_NAMESPACE) -#endif - -/* - * A void jsid is not a valid id and only arises as an exceptional API return - * value, such as in JS_NextProperty. Embeddings must not pass JSID_VOID into - * JSAPI entry points expecting a jsid and do not need to handle JSID_VOID in - * hooks receiving a jsid except when explicitly noted in the API contract. - */ - -static JS_ALWAYS_INLINE JSBool -JSID_IS_VOID(jsid id) -{ - JS_ASSERT_IF(((size_t)JSID_BITS(id) & JSID_TYPE_MASK) == JSID_TYPE_VOID, - JSID_BITS(id) == JSID_TYPE_VOID); - return ((size_t)JSID_BITS(id) == JSID_TYPE_VOID); -} - -static JS_ALWAYS_INLINE JSBool -JSID_IS_EMPTY(jsid id) -{ - return ((size_t)JSID_BITS(id) == JSID_TYPE_OBJECT); -} - -#undef id - -#ifdef JS_USE_JSVAL_JSID_STRUCT_TYPES -extern JS_PUBLIC_DATA(jsid) JSID_VOID; -extern JS_PUBLIC_DATA(jsid) JSID_EMPTY; -#else -# define JSID_VOID ((jsid)JSID_TYPE_VOID) -# define JSID_EMPTY ((jsid)JSID_TYPE_OBJECT) -#endif - -/************************************************************************/ - -/* Lock and unlock the GC thing held by a jsval. */ -#define JSVAL_LOCK(cx,v) (JSVAL_IS_GCTHING(v) \ - ? JS_LockGCThing(cx, JSVAL_TO_GCTHING(v)) \ - : JS_TRUE) -#define JSVAL_UNLOCK(cx,v) (JSVAL_IS_GCTHING(v) \ - ? JS_UnlockGCThing(cx, JSVAL_TO_GCTHING(v)) \ - : JS_TRUE) - -/* Property attributes, set in JSPropertySpec and passed to API functions. */ -#define JSPROP_ENUMERATE 0x01 /* property is visible to for/in loop */ -#define JSPROP_READONLY 0x02 /* not settable: assignment is no-op */ -#define JSPROP_PERMANENT 0x04 /* property cannot be deleted */ -#define JSPROP_GETTER 0x10 /* property holds getter function */ -#define JSPROP_SETTER 0x20 /* property holds setter function */ -#define JSPROP_SHARED 0x40 /* don't allocate a value slot for this - property; don't copy the property on - set of the same-named property in an - object that delegates to a prototype - containing this property */ -#define JSPROP_INDEX 0x80 /* name is actually (jsint) index */ -#define JSPROP_SHORTID 0x100 /* set in JSPropertyDescriptor.attrs - if getters/setters use a shortid */ - -/* Function flags, set in JSFunctionSpec and passed to JS_NewFunction etc. */ -#define JSFUN_LAMBDA 0x08 /* expressed, not declared, function */ -#define JSFUN_HEAVYWEIGHT 0x80 /* activation requires a Call object */ - -#define JSFUN_HEAVYWEIGHT_TEST(f) ((f) & JSFUN_HEAVYWEIGHT) - -/* 0x0100 is unused */ -#define JSFUN_CONSTRUCTOR 0x0200 /* native that can be called as a ctor - without creating a this object */ - -#define JSFUN_FLAGS_MASK 0x07f8 /* overlay JSFUN_* attributes -- - bits 12-15 are used internally to - flag interpreted functions */ - -#define JSFUN_STUB_GSOPS 0x1000 /* use JS_PropertyStub getter/setter - instead of defaulting to class gsops - for property holding function */ - -/* - * Re-use JSFUN_LAMBDA, which applies only to scripted functions, for use in - * JSFunctionSpec arrays that specify generic native prototype methods, i.e., - * methods of a class prototype that are exposed as static methods taking an - * extra leading argument: the generic |this| parameter. - * - * If you set this flag in a JSFunctionSpec struct's flags initializer, then - * that struct must live at least as long as the native static method object - * created due to this flag by JS_DefineFunctions or JS_InitClass. Typically - * JSFunctionSpec structs are allocated in static arrays. - */ -#define JSFUN_GENERIC_NATIVE JSFUN_LAMBDA - -/* - * Microseconds since the epoch, midnight, January 1, 1970 UTC. See the - * comment in jstypes.h regarding safe int64 usage. - */ -extern JS_PUBLIC_API(int64) -JS_Now(void); - -/* Don't want to export data, so provide accessors for non-inline jsvals. */ -extern JS_PUBLIC_API(jsval) -JS_GetNaNValue(JSContext *cx); - -extern JS_PUBLIC_API(jsval) -JS_GetNegativeInfinityValue(JSContext *cx); - -extern JS_PUBLIC_API(jsval) -JS_GetPositiveInfinityValue(JSContext *cx); - -extern JS_PUBLIC_API(jsval) -JS_GetEmptyStringValue(JSContext *cx); - -extern JS_PUBLIC_API(JSString *) -JS_GetEmptyString(JSRuntime *rt); - -/* - * Format is a string of the following characters (spaces are insignificant), - * specifying the tabulated type conversions: - * - * b JSBool Boolean - * c uint16/jschar ECMA uint16, Unicode char - * i int32 ECMA int32 - * u uint32 ECMA uint32 - * j int32 Rounded int32 (coordinate) - * d jsdouble IEEE double - * I jsdouble Integral IEEE double - * S JSString * Unicode string, accessed by a JSString pointer - * W jschar * Unicode character vector, 0-terminated (W for wide) - * o JSObject * Object reference - * f JSFunction * Function private - * v jsval Argument value (no conversion) - * * N/A Skip this argument (no vararg) - * / N/A End of required arguments - * - * The variable argument list after format must consist of &b, &c, &s, e.g., - * where those variables have the types given above. For the pointer types - * char *, JSString *, and JSObject *, the pointed-at memory returned belongs - * to the JS runtime, not to the calling native code. The runtime promises - * to keep this memory valid so long as argv refers to allocated stack space - * (so long as the native function is active). - * - * Fewer arguments than format specifies may be passed only if there is a / - * in format after the last required argument specifier and argc is at least - * the number of required arguments. More arguments than format specifies - * may be passed without error; it is up to the caller to deal with trailing - * unconverted arguments. - */ -extern JS_PUBLIC_API(JSBool) -JS_ConvertArguments(JSContext *cx, uintN argc, jsval *argv, const char *format, - ...); - -#ifdef va_start -extern JS_PUBLIC_API(JSBool) -JS_ConvertArgumentsVA(JSContext *cx, uintN argc, jsval *argv, - const char *format, va_list ap); -#endif - -#ifdef JS_ARGUMENT_FORMATTER_DEFINED - -/* - * Add and remove a format string handler for JS_{Convert,Push}Arguments{,VA}. - * The handler function has this signature (see jspubtd.h): - * - * JSBool MyArgumentFormatter(JSContext *cx, const char *format, - * JSBool fromJS, jsval **vpp, va_list *app); - * - * It should return true on success, and return false after reporting an error - * or detecting an already-reported error. - * - * For a given format string, for example "AA", the formatter is called from - * JS_ConvertArgumentsVA like so: - * - * formatter(cx, "AA...", JS_TRUE, &sp, &ap); - * - * sp points into the arguments array on the JS stack, while ap points into - * the stdarg.h va_list on the C stack. The JS_TRUE passed for fromJS tells - * the formatter to convert zero or more jsvals at sp to zero or more C values - * accessed via pointers-to-values at ap, updating both sp (via *vpp) and ap - * (via *app) to point past the converted arguments and their result pointers - * on the C stack. - * - * When called from JS_PushArgumentsVA, the formatter is invoked thus: - * - * formatter(cx, "AA...", JS_FALSE, &sp, &ap); - * - * where JS_FALSE for fromJS means to wrap the C values at ap according to the - * format specifier and store them at sp, updating ap and sp appropriately. - * - * The "..." after "AA" is the rest of the format string that was passed into - * JS_{Convert,Push}Arguments{,VA}. The actual format trailing substring used - * in each Convert or PushArguments call is passed to the formatter, so that - * one such function may implement several formats, in order to share code. - * - * Remove just forgets about any handler associated with format. Add does not - * copy format, it points at the string storage allocated by the caller, which - * is typically a string constant. If format is in dynamic storage, it is up - * to the caller to keep the string alive until Remove is called. - */ -extern JS_PUBLIC_API(JSBool) -JS_AddArgumentFormatter(JSContext *cx, const char *format, - JSArgumentFormatter formatter); - -extern JS_PUBLIC_API(void) -JS_RemoveArgumentFormatter(JSContext *cx, const char *format); - -#endif /* JS_ARGUMENT_FORMATTER_DEFINED */ - -extern JS_PUBLIC_API(JSBool) -JS_ConvertValue(JSContext *cx, jsval v, JSType type, jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_ValueToObject(JSContext *cx, jsval v, JSObject **objp); - -extern JS_PUBLIC_API(JSFunction *) -JS_ValueToFunction(JSContext *cx, jsval v); - -extern JS_PUBLIC_API(JSFunction *) -JS_ValueToConstructor(JSContext *cx, jsval v); - -extern JS_PUBLIC_API(JSString *) -JS_ValueToString(JSContext *cx, jsval v); - -extern JS_PUBLIC_API(JSString *) -JS_ValueToSource(JSContext *cx, jsval v); - -extern JS_PUBLIC_API(JSBool) -JS_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp); - -extern JS_PUBLIC_API(JSBool) -JS_DoubleIsInt32(jsdouble d, jsint *ip); - -/* - * Convert a value to a number, then to an int32, according to the ECMA rules - * for ToInt32. - */ -extern JS_PUBLIC_API(JSBool) -JS_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip); - -/* - * Convert a value to a number, then to a uint32, according to the ECMA rules - * for ToUint32. - */ -extern JS_PUBLIC_API(JSBool) -JS_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip); - -/* - * Convert a value to a number, then to an int32 if it fits by rounding to - * nearest; but failing with an error report if the double is out of range - * or unordered. - */ -extern JS_PUBLIC_API(JSBool) -JS_ValueToInt32(JSContext *cx, jsval v, int32 *ip); - -/* - * ECMA ToUint16, for mapping a jsval to a Unicode point. - */ -extern JS_PUBLIC_API(JSBool) -JS_ValueToUint16(JSContext *cx, jsval v, uint16 *ip); - -extern JS_PUBLIC_API(JSBool) -JS_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp); - -extern JS_PUBLIC_API(JSType) -JS_TypeOfValue(JSContext *cx, jsval v); - -extern JS_PUBLIC_API(const char *) -JS_GetTypeName(JSContext *cx, JSType type); - -extern JS_PUBLIC_API(JSBool) -JS_StrictlyEqual(JSContext *cx, jsval v1, jsval v2, JSBool *equal); - -extern JS_PUBLIC_API(JSBool) -JS_SameValue(JSContext *cx, jsval v1, jsval v2, JSBool *same); - -/************************************************************************/ - -/* - * Initialization, locking, contexts, and memory allocation. - * - * It is important that the first runtime and first context be created in a - * single-threaded fashion, otherwise the behavior of the library is undefined. - * See: http://developer.mozilla.org/en/docs/Category:JSAPI_Reference - */ -#define JS_NewRuntime JS_Init -#define JS_DestroyRuntime JS_Finish -#define JS_LockRuntime JS_Lock -#define JS_UnlockRuntime JS_Unlock - -extern JS_PUBLIC_API(JSRuntime *) -JS_NewRuntime(uint32 maxbytes); - -/* Deprecated. */ -#define JS_CommenceRuntimeShutDown(rt) ((void) 0) - -extern JS_PUBLIC_API(void) -JS_DestroyRuntime(JSRuntime *rt); - -extern JS_PUBLIC_API(void) -JS_ShutDown(void); - -JS_PUBLIC_API(void *) -JS_GetRuntimePrivate(JSRuntime *rt); - -JS_PUBLIC_API(void) -JS_SetRuntimePrivate(JSRuntime *rt, void *data); - -extern JS_PUBLIC_API(void) -JS_BeginRequest(JSContext *cx); - -extern JS_PUBLIC_API(void) -JS_EndRequest(JSContext *cx); - -/* Yield to pending GC operations, regardless of request depth */ -extern JS_PUBLIC_API(void) -JS_YieldRequest(JSContext *cx); - -extern JS_PUBLIC_API(jsrefcount) -JS_SuspendRequest(JSContext *cx); - -extern JS_PUBLIC_API(void) -JS_ResumeRequest(JSContext *cx, jsrefcount saveDepth); - -extern JS_PUBLIC_API(JSBool) -JS_IsInRequest(JSContext *cx); - -#ifdef __cplusplus -JS_END_EXTERN_C - -class JSAutoRequest { - public: - JSAutoRequest(JSContext *cx JS_GUARD_OBJECT_NOTIFIER_PARAM) - : mContext(cx), mSaveDepth(0) { - JS_GUARD_OBJECT_NOTIFIER_INIT; - JS_BeginRequest(mContext); - } - ~JSAutoRequest() { - JS_EndRequest(mContext); - } - - void suspend() { - mSaveDepth = JS_SuspendRequest(mContext); - } - void resume() { - JS_ResumeRequest(mContext, mSaveDepth); - } - - protected: - JSContext *mContext; - jsrefcount mSaveDepth; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER - -#if 0 - private: - static void *operator new(size_t) CPP_THROW_NEW { return 0; }; - static void operator delete(void *, size_t) { }; -#endif -}; - -class JSAutoSuspendRequest { - public: - JSAutoSuspendRequest(JSContext *cx JS_GUARD_OBJECT_NOTIFIER_PARAM) - : mContext(cx), mSaveDepth(0) { - JS_GUARD_OBJECT_NOTIFIER_INIT; - if (mContext) { - mSaveDepth = JS_SuspendRequest(mContext); - } - } - ~JSAutoSuspendRequest() { - resume(); - } - - void resume() { - if (mContext) { - JS_ResumeRequest(mContext, mSaveDepth); - mContext = 0; - } - } - - protected: - JSContext *mContext; - jsrefcount mSaveDepth; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER - -#if 0 - private: - static void *operator new(size_t) CPP_THROW_NEW { return 0; }; - static void operator delete(void *, size_t) { }; -#endif -}; - -class JSAutoCheckRequest { - public: - JSAutoCheckRequest(JSContext *cx JS_GUARD_OBJECT_NOTIFIER_PARAM) { -#if defined JS_THREADSAFE && defined DEBUG - mContext = cx; - JS_ASSERT(JS_IsInRequest(cx)); -#endif - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - - ~JSAutoCheckRequest() { -#if defined JS_THREADSAFE && defined DEBUG - JS_ASSERT(JS_IsInRequest(mContext)); -#endif - } - - - private: -#if defined JS_THREADSAFE && defined DEBUG - JSContext *mContext; -#endif - JS_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -JS_BEGIN_EXTERN_C -#endif - -extern JS_PUBLIC_API(void) -JS_Lock(JSRuntime *rt); - -extern JS_PUBLIC_API(void) -JS_Unlock(JSRuntime *rt); - -extern JS_PUBLIC_API(JSContextCallback) -JS_SetContextCallback(JSRuntime *rt, JSContextCallback cxCallback); - -extern JS_PUBLIC_API(JSContext *) -JS_NewContext(JSRuntime *rt, size_t stackChunkSize); - -extern JS_PUBLIC_API(void) -JS_DestroyContext(JSContext *cx); - -extern JS_PUBLIC_API(void) -JS_DestroyContextNoGC(JSContext *cx); - -extern JS_PUBLIC_API(void) -JS_DestroyContextMaybeGC(JSContext *cx); - -extern JS_PUBLIC_API(void *) -JS_GetContextPrivate(JSContext *cx); - -extern JS_PUBLIC_API(void) -JS_SetContextPrivate(JSContext *cx, void *data); - -extern JS_PUBLIC_API(JSRuntime *) -JS_GetRuntime(JSContext *cx); - -extern JS_PUBLIC_API(JSContext *) -JS_ContextIterator(JSRuntime *rt, JSContext **iterp); - -extern JS_PUBLIC_API(JSVersion) -JS_GetVersion(JSContext *cx); - -extern JS_PUBLIC_API(JSVersion) -JS_SetVersion(JSContext *cx, JSVersion version); - -extern JS_PUBLIC_API(const char *) -JS_VersionToString(JSVersion version); - -extern JS_PUBLIC_API(JSVersion) -JS_StringToVersion(const char *string); - -/* - * JS options are orthogonal to version, and may be freely composed with one - * another as well as with version. - * - * JSOPTION_VAROBJFIX is recommended -- see the comments associated with the - * prototypes for JS_ExecuteScript, JS_EvaluateScript, etc. - */ -#define JSOPTION_STRICT JS_BIT(0) /* warn on dubious practice */ -#define JSOPTION_WERROR JS_BIT(1) /* convert warning to error */ -#define JSOPTION_VAROBJFIX JS_BIT(2) /* make JS_EvaluateScript use - the last object on its 'obj' - param's scope chain as the - ECMA 'variables object' */ -#define JSOPTION_PRIVATE_IS_NSISUPPORTS \ - JS_BIT(3) /* context private data points - to an nsISupports subclass */ -#define JSOPTION_COMPILE_N_GO JS_BIT(4) /* caller of JS_Compile*Script - promises to execute compiled - script once only; enables - compile-time scope chain - resolution of consts. */ -#define JSOPTION_ATLINE JS_BIT(5) /* //@line number ["filename"] - option supported for the - XUL preprocessor and kindred - beasts. */ -#define JSOPTION_XML JS_BIT(6) /* EMCAScript for XML support: - parse as a token, - not backward compatible with - the comment-hiding hack used - in HTML script tags. */ -#define JSOPTION_DONT_REPORT_UNCAUGHT \ - JS_BIT(8) /* When returning from the - outermost API call, prevent - uncaught exceptions from - being converted to error - reports */ - -#define JSOPTION_RELIMIT JS_BIT(9) /* Throw exception on any - regular expression which - backtracks more than n^3 - times, where n is length - of the input string */ -#define JSOPTION_ANONFUNFIX JS_BIT(10) /* Disallow function () {} in - statement context per - ECMA-262 Edition 3. */ - -#define JSOPTION_JIT JS_BIT(11) /* Enable JIT compilation. */ - -#define JSOPTION_NO_SCRIPT_RVAL JS_BIT(12) /* A promise to the compiler - that a null rval out-param - will be passed to each call - to JS_ExecuteScript. */ -#define JSOPTION_UNROOTED_GLOBAL JS_BIT(13) /* The GC will not root the - contexts' global objects - (see JS_GetGlobalObject), - leaving that up to the - embedding. */ - -#define JSOPTION_METHODJIT JS_BIT(14) /* Whole-method JIT. */ -#define JSOPTION_PROFILING JS_BIT(15) /* Profiler to make tracer/methodjit choices. */ -#define JSOPTION_METHODJIT_ALWAYS \ - JS_BIT(16) /* Always whole-method JIT, - don't tune at run-time. */ - -/* Options which reflect compile-time properties of scripts. */ -#define JSCOMPILEOPTION_MASK (JSOPTION_XML | JSOPTION_ANONFUNFIX) - -#define JSRUNOPTION_MASK (JS_BITMASK(17) & ~JSCOMPILEOPTION_MASK) -#define JSALLOPTION_MASK (JSCOMPILEOPTION_MASK | JSRUNOPTION_MASK) - -extern JS_PUBLIC_API(uint32) -JS_GetOptions(JSContext *cx); - -extern JS_PUBLIC_API(uint32) -JS_SetOptions(JSContext *cx, uint32 options); - -extern JS_PUBLIC_API(uint32) -JS_ToggleOptions(JSContext *cx, uint32 options); - -extern JS_PUBLIC_API(const char *) -JS_GetImplementationVersion(void); - -extern JS_PUBLIC_API(JSCompartmentCallback) -JS_SetCompartmentCallback(JSRuntime *rt, JSCompartmentCallback callback); - -extern JS_PUBLIC_API(JSWrapObjectCallback) -JS_SetWrapObjectCallbacks(JSRuntime *rt, - JSWrapObjectCallback callback, - JSPreWrapCallback precallback); - -extern JS_PUBLIC_API(JSCrossCompartmentCall *) -JS_EnterCrossCompartmentCall(JSContext *cx, JSObject *target); - -extern JS_PUBLIC_API(JSCrossCompartmentCall *) -JS_EnterCrossCompartmentCallScript(JSContext *cx, JSScript *target); - -extern JS_PUBLIC_API(void) -JS_LeaveCrossCompartmentCall(JSCrossCompartmentCall *call); - -extern JS_PUBLIC_API(void *) -JS_SetCompartmentPrivate(JSContext *cx, JSCompartment *compartment, void *data); - -extern JS_PUBLIC_API(void *) -JS_GetCompartmentPrivate(JSContext *cx, JSCompartment *compartment); - -extern JS_PUBLIC_API(JSBool) -JS_WrapObject(JSContext *cx, JSObject **objp); - -extern JS_PUBLIC_API(JSBool) -JS_WrapValue(JSContext *cx, jsval *vp); - -extern JS_PUBLIC_API(JSObject *) -JS_TransplantObject(JSContext *cx, JSObject *origobj, JSObject *target); - -extern JS_FRIEND_API(JSObject *) -js_TransplantObjectWithWrapper(JSContext *cx, - JSObject *origobj, - JSObject *origwrapper, - JSObject *targetobj, - JSObject *targetwrapper); - -extern JS_FRIEND_API(JSObject *) -js_TransplantObjectWithWrapper(JSContext *cx, - JSObject *origobj, - JSObject *origwrapper, - JSObject *targetobj, - JSObject *targetwrapper); - -#ifdef __cplusplus -JS_END_EXTERN_C - -class JS_PUBLIC_API(JSAutoEnterCompartment) -{ - JSCrossCompartmentCall *call; - - public: - JSAutoEnterCompartment() : call(NULL) {} - - bool enter(JSContext *cx, JSObject *target); - - bool enter(JSContext *cx, JSScript *target); - - void enterAndIgnoreErrors(JSContext *cx, JSObject *target); - - bool entered() const { return call != NULL; } - - ~JSAutoEnterCompartment() { - if (call && call != reinterpret_cast(1)) - JS_LeaveCrossCompartmentCall(call); - } - - void swap(JSAutoEnterCompartment &other) { - JSCrossCompartmentCall *tmp = call; - call = other.call; - other.call = tmp; - } -}; - -JS_BEGIN_EXTERN_C -#endif - -extern JS_PUBLIC_API(JSObject *) -JS_GetGlobalObject(JSContext *cx); - -extern JS_PUBLIC_API(void) -JS_SetGlobalObject(JSContext *cx, JSObject *obj); - -/* - * Initialize standard JS class constructors, prototypes, and any top-level - * functions and constants associated with the standard classes (e.g. isNaN - * for Number). - * - * NB: This sets cx's global object to obj if it was null. - */ -extern JS_PUBLIC_API(JSBool) -JS_InitStandardClasses(JSContext *cx, JSObject *obj); - -/* - * Resolve id, which must contain either a string or an int, to a standard - * class name in obj if possible, defining the class's constructor and/or - * prototype and storing true in *resolved. If id does not name a standard - * class or a top-level property induced by initializing a standard class, - * store false in *resolved and just return true. Return false on error, - * as usual for JSBool result-typed API entry points. - * - * This API can be called directly from a global object class's resolve op, - * to define standard classes lazily. The class's enumerate op should call - * JS_EnumerateStandardClasses(cx, obj), to define eagerly during for..in - * loops any classes not yet resolved lazily. - */ -extern JS_PUBLIC_API(JSBool) -JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsid id, - JSBool *resolved); - -extern JS_PUBLIC_API(JSBool) -JS_EnumerateStandardClasses(JSContext *cx, JSObject *obj); - -/* - * Enumerate any already-resolved standard class ids into ida, or into a new - * JSIdArray if ida is null. Return the augmented array on success, null on - * failure with ida (if it was non-null on entry) destroyed. - */ -extern JS_PUBLIC_API(JSIdArray *) -JS_EnumerateResolvedStandardClasses(JSContext *cx, JSObject *obj, - JSIdArray *ida); - -extern JS_PUBLIC_API(JSBool) -JS_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, - JSObject **objp); - -extern JS_PUBLIC_API(JSObject *) -JS_GetScopeChain(JSContext *cx); - -extern JS_PUBLIC_API(JSObject *) -JS_GetGlobalForObject(JSContext *cx, JSObject *obj); - -extern JS_PUBLIC_API(JSObject *) -JS_GetGlobalForScopeChain(JSContext *cx); - -#ifdef JS_HAS_CTYPES -/* - * Initialize the 'ctypes' object on a global variable 'obj'. The 'ctypes' - * object will be sealed. - */ -extern JS_PUBLIC_API(JSBool) -JS_InitCTypesClass(JSContext *cx, JSObject *global); - -/* - * Convert a unicode string 'source' of length 'slen' to the platform native - * charset, returning a null-terminated string allocated with JS_malloc. On - * failure, this function should report an error. - */ -typedef char * -(* JSCTypesUnicodeToNativeFun)(JSContext *cx, const jschar *source, size_t slen); - -/* - * Set of function pointers that ctypes can use for various internal functions. - * See JS_SetCTypesCallbacks below. Providing NULL for a function is safe, - * and will result in the applicable ctypes functionality not being available. - */ -struct JSCTypesCallbacks { - JSCTypesUnicodeToNativeFun unicodeToNative; -}; - -typedef struct JSCTypesCallbacks JSCTypesCallbacks; - -/* - * Set the callbacks on the provided 'ctypesObj' object. 'callbacks' should be a - * pointer to static data that exists for the lifetime of 'ctypesObj', but it - * may safely be altered after calling this function and without having - * to call this function again. - */ -extern JS_PUBLIC_API(JSBool) -JS_SetCTypesCallbacks(JSContext *cx, JSObject *ctypesObj, JSCTypesCallbacks *callbacks); -#endif - -/* - * Macros to hide interpreter stack layout details from a JSFastNative using - * its jsval *vp parameter. The stack layout underlying invocation can't change - * without breaking source and binary compatibility (argv[-2] is well-known to - * be the callee jsval, and argv[-1] is as well known to be |this|). - * - * Note well: However, argv[-1] may be JSVAL_NULL where with slow natives it - * is the global object, so embeddings implementing fast natives *must* call - * JS_THIS or JS_THIS_OBJECT and test for failure indicated by a null return, - * which should propagate as a false return from native functions and hooks. - * - * To reduce boilerplace checks, JS_InstanceOf and JS_GetInstancePrivate now - * handle a null obj parameter by returning false (throwing a TypeError if - * given non-null argv), so most native functions that type-check their |this| - * parameter need not add null checking. - * - * NB: there is an anti-dependency between JS_CALLEE and JS_SET_RVAL: native - * methods that may inspect their callee must defer setting their return value - * until after any such possible inspection. Otherwise the return value will be - * inspected instead of the callee function object. - * - * WARNING: These are not (yet) mandatory macros, but new code outside of the - * engine should use them. In the Mozilla 2.0 milestone their definitions may - * change incompatibly. - * - * N.B. constructors must not use JS_THIS, as no 'this' object has been created. - */ - -#define JS_CALLEE(cx,vp) ((vp)[0]) -#define JS_THIS(cx,vp) JS_ComputeThis(cx, vp) -#define JS_THIS_OBJECT(cx,vp) (JSVAL_TO_OBJECT(JS_THIS(cx,vp))) -#define JS_ARGV(cx,vp) ((vp) + 2) -#define JS_RVAL(cx,vp) (*(vp)) -#define JS_SET_RVAL(cx,vp,v) (*(vp) = (v)) - -extern JS_PUBLIC_API(jsval) -JS_ComputeThis(JSContext *cx, jsval *vp); - -#ifdef __cplusplus -#undef JS_THIS -static inline jsval -JS_THIS(JSContext *cx, jsval *vp) -{ - return JSVAL_IS_PRIMITIVE(vp[1]) ? JS_ComputeThis(cx, vp) : vp[1]; -} -#endif - -/* - * |this| is passed to functions in ES5 without change. Functions themselves - * do any post-processing they desire to box |this|, compute the global object, - * &c. Use this macro to retrieve a function's unboxed |this| value. - * - * This macro must not be used in conjunction with JS_THIS or JS_THIS_OBJECT, - * or vice versa. Either use the provided this value with this macro, or - * compute the boxed this value using those. - * - * N.B. constructors must not use JS_THIS_VALUE, as no 'this' object has been - * created. - */ -#define JS_THIS_VALUE(cx,vp) ((vp)[1]) - -extern JS_PUBLIC_API(void *) -JS_malloc(JSContext *cx, size_t nbytes); - -extern JS_PUBLIC_API(void *) -JS_realloc(JSContext *cx, void *p, size_t nbytes); - -extern JS_PUBLIC_API(void) -JS_free(JSContext *cx, void *p); - -extern JS_PUBLIC_API(void) -JS_updateMallocCounter(JSContext *cx, size_t nbytes); - -extern JS_PUBLIC_API(char *) -JS_strdup(JSContext *cx, const char *s); - -extern JS_PUBLIC_API(JSBool) -JS_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval); - -/* - * A GC root is a pointer to a jsval, JSObject * or JSString * that itself - * points into the GC heap. JS_AddValueRoot takes a pointer to a jsval and - * JS_AddGCThingRoot takes a pointer to a JSObject * or JString *. - * - * Note that, since JS_Add*Root stores the address of a variable (of type - * jsval, JSString *, or JSObject *), that variable must live until - * JS_Remove*Root is called to remove that variable. For example, after: - * - * void some_function() { - * jsval v; - * JS_AddNamedRootedValue(cx, &v, "name"); - * - * the caller must perform - * - * JS_RemoveRootedValue(cx, &v); - * - * before some_function() returns. - * - * Also, use JS_AddNamed*Root(cx, &structPtr->memberObj, "structPtr->memberObj") - * in preference to JS_Add*Root(cx, &structPtr->memberObj), in order to identify - * roots by their source callsites. This way, you can find the callsite while - * debugging if you should fail to do JS_Remove*Root(cx, &structPtr->memberObj) - * before freeing structPtr's memory. - */ -extern JS_PUBLIC_API(JSBool) -JS_AddValueRoot(JSContext *cx, jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_AddStringRoot(JSContext *cx, JSString **rp); - -extern JS_PUBLIC_API(JSBool) -JS_AddObjectRoot(JSContext *cx, JSObject **rp); - -extern JS_PUBLIC_API(JSBool) -JS_AddGCThingRoot(JSContext *cx, void **rp); - -#ifdef NAME_ALL_GC_ROOTS -#define JS_DEFINE_TO_TOKEN(def) #def -#define JS_DEFINE_TO_STRING(def) JS_DEFINE_TO_TOKEN(def) -#define JS_AddValueRoot(cx,vp) JS_AddNamedValueRoot((cx), (vp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__)) -#define JS_AddStringRoot(cx,rp) JS_AddNamedStringRoot((cx), (rp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__)) -#define JS_AddObjectRoot(cx,rp) JS_AddNamedObjectRoot((cx), (rp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__)) -#define JS_AddGCThingRoot(cx,rp) JS_AddNamedGCThingRoot((cx), (rp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__)) -#endif - -extern JS_PUBLIC_API(JSBool) -JS_AddNamedValueRoot(JSContext *cx, jsval *vp, const char *name); - -extern JS_PUBLIC_API(JSBool) -JS_AddNamedStringRoot(JSContext *cx, JSString **rp, const char *name); - -extern JS_PUBLIC_API(JSBool) -JS_AddNamedObjectRoot(JSContext *cx, JSObject **rp, const char *name); - -extern JS_PUBLIC_API(JSBool) -JS_AddNamedGCThingRoot(JSContext *cx, void **rp, const char *name); - -extern JS_PUBLIC_API(JSBool) -JS_RemoveValueRoot(JSContext *cx, jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_RemoveStringRoot(JSContext *cx, JSString **rp); - -extern JS_PUBLIC_API(JSBool) -JS_RemoveObjectRoot(JSContext *cx, JSObject **rp); - -extern JS_PUBLIC_API(JSBool) -JS_RemoveGCThingRoot(JSContext *cx, void **rp); - -/* TODO: remove these APIs */ - -extern JS_FRIEND_API(JSBool) -js_AddRootRT(JSRuntime *rt, jsval *vp, const char *name); - -extern JS_FRIEND_API(JSBool) -js_AddGCThingRootRT(JSRuntime *rt, void **rp, const char *name); - -extern JS_FRIEND_API(JSBool) -js_RemoveRoot(JSRuntime *rt, void *rp); - -#ifdef __cplusplus -JS_END_EXTERN_C - -namespace JS { - -/* - * Protecting non-jsval, non-JSObject *, non-JSString * values from collection - * - * Most of the time, the garbage collector's conservative stack scanner works - * behind the scenes, finding all live values and protecting them from being - * collected. However, when JSAPI client code obtains a pointer to data the - * scanner does not know about, owned by an object the scanner does know about, - * Care Must Be Taken. - * - * The scanner recognizes only a select set of types: pointers to JSObjects and - * similar things (JSFunctions, and so on), pointers to JSStrings, and jsvals. - * So while the scanner finds all live |JSString| pointers, it does not notice - * |jschar| pointers. - * - * So suppose we have: - * - * void f(JSString *str) { - * const jschar *ch = JS_GetStringCharsZ(str); - * ... do stuff with ch, but no uses of str ...; - * } - * - * After the call to |JS_GetStringCharsZ|, there are no further uses of - * |str|, which means that the compiler is within its rights to not store - * it anywhere. But because the stack scanner will not notice |ch|, there - * is no longer any live value in this frame that would keep the string - * alive. If |str| is the last reference to that |JSString|, and the - * collector runs while we are using |ch|, the string's array of |jschar|s - * may be freed out from under us. - * - * Note that there is only an issue when 1) we extract a thing X the scanner - * doesn't recognize from 2) a thing Y the scanner does recognize, and 3) if Y - * gets garbage-collected, then X gets freed. If we have code like this: - * - * void g(JSObject *obj) { - * jsval x; - * JS_GetProperty(obj, "x", &x); - * ... do stuff with x ... - * } - * - * there's no problem, because the value we've extracted, x, is a jsval, a - * type that the conservative scanner recognizes. - * - * Conservative GC frees us from the obligation to explicitly root the types it - * knows about, but when we work with derived values like |ch|, we must root - * their owners, as the derived value alone won't keep them alive. - * - * A JS::Anchor is a kind of GC root that allows us to keep the owners of - * derived values like |ch| alive throughout the Anchor's lifetime. We could - * fix the above code as follows: - * - * void f(JSString *str) { - * JS::Anchor a_str(str); - * const jschar *ch = JS_GetStringCharsZ(str); - * ... do stuff with ch, but no uses of str ...; - * } - * - * This simply ensures that |str| will be live until |a_str| goes out of scope. - * As long as we don't retain a pointer to the string's characters for longer - * than that, we have avoided all garbage collection hazards. - */ -template class AnchorPermitted; -template<> class AnchorPermitted { }; -template<> class AnchorPermitted { }; -template<> class AnchorPermitted { }; -template<> class AnchorPermitted { }; -template<> class AnchorPermitted { }; -template<> class AnchorPermitted { }; -template<> class AnchorPermitted { }; - -template -class Anchor: AnchorPermitted { - public: - Anchor() { } - explicit Anchor(T t) { hold = t; } - inline ~Anchor(); - T &get() { return hold; } - void set(const T &t) { hold = t; } - void clear() { hold = 0; } - private: - T hold; - /* Anchors should not be assigned or passed to functions. */ - Anchor(const Anchor &); - const Anchor &operator=(const Anchor &); -}; - -#ifdef __GNUC__ -template -inline Anchor::~Anchor() { - /* - * No code is generated for this. But because this is marked 'volatile', G++ will - * assume it has important side-effects, and won't delete it. (G++ never looks at - * the actual text and notices it's empty.) And because we have passed |hold| to - * it, GCC will keep |hold| alive until this point. - * - * The "memory" clobber operand ensures that G++ will not move prior memory - * accesses after the asm --- it's a barrier. Unfortunately, it also means that - * G++ will assume that all memory has changed after the asm, as it would for a - * call to an unknown function. I don't know of a way to avoid that consequence. - */ - asm volatile("":: "g" (hold) : "memory"); -} -#else -template -inline Anchor::~Anchor() { - /* - * An adequate portable substitute, for non-structure types. - * - * The compiler promises that, by the end of an expression statement, the - * last-stored value to a volatile object is the same as it would be in an - * unoptimized, direct implementation (the "abstract machine" whose behavior the - * language spec describes). However, the compiler is still free to reorder - * non-volatile accesses across this store --- which is what we must prevent. So - * assigning the held value to a volatile variable, as we do here, is not enough. - * - * In our case, however, garbage collection only occurs at function calls, so it - * is sufficient to ensure that the destructor's store isn't moved earlier across - * any function calls that could collect. It is hard to imagine the compiler - * analyzing the program so thoroughly that it could prove that such motion was - * safe. In practice, compilers treat calls to the collector as opaque operations - * --- in particular, as operations which could access volatile variables, across - * which this destructor must not be moved. - * - * ("Objection, your honor! *Alleged* killer whale!") - * - * The disadvantage of this approach is that it does generate code for the store. - * We do need to use Anchors in some cases where cycles are tight. - */ - volatile T sink; - sink = hold; -} - -#ifdef JS_USE_JSVAL_JSID_STRUCT_TYPES -/* - * The default assignment operator for |struct C| has the signature: - * - * C& C::operator=(const C&) - * - * And in particular requires implicit conversion of |this| to type |C| for the return - * value. But |volatile C| cannot thus be converted to |C|, so just doing |sink = hold| as - * in the non-specialized version would fail to compile. Do the assignment on asBits - * instead, since I don't think we want to give jsval_layout an assignment operator - * returning |volatile jsval_layout|. - */ -template<> -inline Anchor::~Anchor() { - volatile jsval sink; - sink.asBits = hold.asBits; -} -#endif -#endif - -} /* namespace JS */ - -JS_BEGIN_EXTERN_C -#endif - -/* - * This symbol may be used by embedders to detect the change from the old - * JS_AddRoot(JSContext *, void *) APIs to the new ones above. - */ -#define JS_TYPED_ROOTING_API - -/* Obsolete rooting APIs. */ -#define JS_ClearNewbornRoots(cx) ((void) 0) -#define JS_EnterLocalRootScope(cx) (JS_TRUE) -#define JS_LeaveLocalRootScope(cx) ((void) 0) -#define JS_LeaveLocalRootScopeWithResult(cx, rval) ((void) 0) -#define JS_ForgetLocalRoot(cx, thing) ((void) 0) - -typedef enum JSGCRootType { - JS_GC_ROOT_VALUE_PTR, - JS_GC_ROOT_GCTHING_PTR -} JSGCRootType; - -#ifdef DEBUG -extern JS_PUBLIC_API(void) -JS_DumpNamedRoots(JSRuntime *rt, - void (*dump)(const char *name, void *rp, JSGCRootType type, void *data), - void *data); -#endif - -/* - * Call JS_MapGCRoots to map the GC's roots table using map(rp, name, data). - * The root is pointed at by rp; if the root is unnamed, name is null; data is - * supplied from the third parameter to JS_MapGCRoots. - * - * The map function should return JS_MAP_GCROOT_REMOVE to cause the currently - * enumerated root to be removed. To stop enumeration, set JS_MAP_GCROOT_STOP - * in the return value. To keep on mapping, return JS_MAP_GCROOT_NEXT. These - * constants are flags; you can OR them together. - * - * This function acquires and releases rt's GC lock around the mapping of the - * roots table, so the map function should run to completion in as few cycles - * as possible. Of course, map cannot call JS_GC, JS_MaybeGC, JS_BeginRequest, - * or any JS API entry point that acquires locks, without double-tripping or - * deadlocking on the GC lock. - * - * The JSGCRootType parameter indicates whether rp is a pointer to a Value - * (which is obtained by '(Value *)rp') or a pointer to a GC-thing pointer - * (which is obtained by '(void **)rp'). - * - * JS_MapGCRoots returns the count of roots that were successfully mapped. - */ -#define JS_MAP_GCROOT_NEXT 0 /* continue mapping entries */ -#define JS_MAP_GCROOT_STOP 1 /* stop mapping entries */ -#define JS_MAP_GCROOT_REMOVE 2 /* remove and free the current entry */ - -typedef intN -(* JSGCRootMapFun)(void *rp, JSGCRootType type, const char *name, void *data); - -extern JS_PUBLIC_API(uint32) -JS_MapGCRoots(JSRuntime *rt, JSGCRootMapFun map, void *data); - -extern JS_PUBLIC_API(JSBool) -JS_LockGCThing(JSContext *cx, void *thing); - -extern JS_PUBLIC_API(JSBool) -JS_LockGCThingRT(JSRuntime *rt, void *thing); - -extern JS_PUBLIC_API(JSBool) -JS_UnlockGCThing(JSContext *cx, void *thing); - -extern JS_PUBLIC_API(JSBool) -JS_UnlockGCThingRT(JSRuntime *rt, void *thing); - -/* - * Register externally maintained GC roots. - * - * traceOp: the trace operation. For each root the implementation should call - * JS_CallTracer whenever the root contains a traceable thing. - * data: the data argument to pass to each invocation of traceOp. - */ -extern JS_PUBLIC_API(void) -JS_SetExtraGCRoots(JSRuntime *rt, JSTraceDataOp traceOp, void *data); - -/* - * For implementors of JSMarkOp. All new code should implement JSTraceOp - * instead. - */ -extern JS_PUBLIC_API(void) -JS_MarkGCThing(JSContext *cx, jsval v, const char *name, void *arg); - -/* - * JS_CallTracer API and related macros for implementors of JSTraceOp, to - * enumerate all references to traceable things reachable via a property or - * other strong ref identified for debugging purposes by name or index or - * a naming callback. - * - * By definition references to traceable things include non-null pointers - * to JSObject, JSString and jsdouble and corresponding jsvals. - * - * See the JSTraceOp typedef in jspubtd.h. - */ - -/* Trace kinds to pass to JS_Tracing. */ -#define JSTRACE_OBJECT 0 -#define JSTRACE_STRING 1 - -/* - * Use the following macros to check if a particular jsval is a traceable - * thing and to extract the thing and its kind to pass to JS_CallTracer. - */ -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_TRACEABLE(jsval v) -{ - jsval_layout l; - l.asBits = JSVAL_BITS(v); - return JSVAL_IS_TRACEABLE_IMPL(l); -} - -static JS_ALWAYS_INLINE void * -JSVAL_TO_TRACEABLE(jsval v) -{ - return JSVAL_TO_GCTHING(v); -} - -static JS_ALWAYS_INLINE uint32 -JSVAL_TRACE_KIND(jsval v) -{ - jsval_layout l; - JS_ASSERT(JSVAL_IS_GCTHING(v)); - l.asBits = JSVAL_BITS(v); - return JSVAL_TRACE_KIND_IMPL(l); -} - -struct JSTracer { - JSContext *context; - JSTraceCallback callback; - JSTraceNamePrinter debugPrinter; - const void *debugPrintArg; - size_t debugPrintIndex; -}; - -/* - * The method to call on each reference to a traceable thing stored in a - * particular JSObject or other runtime structure. With DEBUG defined the - * caller before calling JS_CallTracer must initialize JSTracer fields - * describing the reference using the macros below. - */ -extern JS_PUBLIC_API(void) -JS_CallTracer(JSTracer *trc, void *thing, uint32 kind); - -/* - * Set debugging information about a reference to a traceable thing to prepare - * for the following call to JS_CallTracer. - * - * When printer is null, arg must be const char * or char * C string naming - * the reference and index must be either (size_t)-1 indicating that the name - * alone describes the reference or it must be an index into some array vector - * that stores the reference. - * - * When printer callback is not null, the arg and index arguments are - * available to the callback as debugPrinterArg and debugPrintIndex fields - * of JSTracer. - * - * The storage for name or callback's arguments needs to live only until - * the following call to JS_CallTracer returns. - */ -#ifdef DEBUG -# define JS_SET_TRACING_DETAILS(trc, printer, arg, index) \ - JS_BEGIN_MACRO \ - (trc)->debugPrinter = (printer); \ - (trc)->debugPrintArg = (arg); \ - (trc)->debugPrintIndex = (index); \ - JS_END_MACRO -#else -# define JS_SET_TRACING_DETAILS(trc, printer, arg, index) \ - JS_BEGIN_MACRO \ - JS_END_MACRO -#endif - -/* - * Convenience macro to describe the argument of JS_CallTracer using C string - * and index. - */ -# define JS_SET_TRACING_INDEX(trc, name, index) \ - JS_SET_TRACING_DETAILS(trc, NULL, name, index) - -/* - * Convenience macro to describe the argument of JS_CallTracer using C string. - */ -# define JS_SET_TRACING_NAME(trc, name) \ - JS_SET_TRACING_DETAILS(trc, NULL, name, (size_t)-1) - -/* - * Convenience macro to invoke JS_CallTracer using C string as the name for - * the reference to a traceable thing. - */ -# define JS_CALL_TRACER(trc, thing, kind, name) \ - JS_BEGIN_MACRO \ - JS_SET_TRACING_NAME(trc, name); \ - JS_CallTracer((trc), (thing), (kind)); \ - JS_END_MACRO - -/* - * Convenience macros to invoke JS_CallTracer when jsval represents a - * reference to a traceable thing. - */ -#define JS_CALL_VALUE_TRACER(trc, val, name) \ - JS_BEGIN_MACRO \ - if (JSVAL_IS_TRACEABLE(val)) { \ - JS_CALL_TRACER((trc), JSVAL_TO_GCTHING(val), \ - JSVAL_TRACE_KIND(val), name); \ - } \ - JS_END_MACRO - -#define JS_CALL_OBJECT_TRACER(trc, object, name) \ - JS_BEGIN_MACRO \ - JSObject *obj_ = (object); \ - JS_ASSERT(obj_); \ - JS_CALL_TRACER((trc), obj_, JSTRACE_OBJECT, name); \ - JS_END_MACRO - -#define JS_CALL_STRING_TRACER(trc, string, name) \ - JS_BEGIN_MACRO \ - JSString *str_ = (string); \ - JS_ASSERT(str_); \ - JS_CALL_TRACER((trc), str_, JSTRACE_STRING, name); \ - JS_END_MACRO - -/* - * API for JSTraceCallback implementations. - */ -# define JS_TRACER_INIT(trc, cx_, callback_) \ - JS_BEGIN_MACRO \ - (trc)->context = (cx_); \ - (trc)->callback = (callback_); \ - (trc)->debugPrinter = NULL; \ - (trc)->debugPrintArg = NULL; \ - (trc)->debugPrintIndex = (size_t)-1; \ - JS_END_MACRO - -extern JS_PUBLIC_API(void) -JS_TraceChildren(JSTracer *trc, void *thing, uint32 kind); - -extern JS_PUBLIC_API(void) -JS_TraceRuntime(JSTracer *trc); - -#ifdef DEBUG - -extern JS_PUBLIC_API(void) -JS_PrintTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc, - void *thing, uint32 kind, JSBool includeDetails); - -/* - * DEBUG-only method to dump the object graph of heap-allocated things. - * - * fp: file for the dump output. - * start: when non-null, dump only things reachable from start - * thing. Otherwise dump all things reachable from the - * runtime roots. - * startKind: trace kind of start if start is not null. Must be 0 when - * start is null. - * thingToFind: dump only paths in the object graph leading to thingToFind - * when non-null. - * maxDepth: the upper bound on the number of edges to descend from the - * graph roots. - * thingToIgnore: thing to ignore during the graph traversal when non-null. - */ -extern JS_PUBLIC_API(JSBool) -JS_DumpHeap(JSContext *cx, FILE *fp, void* startThing, uint32 startKind, - void *thingToFind, size_t maxDepth, void *thingToIgnore); - -#endif - -/* - * Garbage collector API. - */ -extern JS_PUBLIC_API(void) -JS_GC(JSContext *cx); - -extern JS_PUBLIC_API(void) -JS_MaybeGC(JSContext *cx); - -extern JS_PUBLIC_API(JSGCCallback) -JS_SetGCCallback(JSContext *cx, JSGCCallback cb); - -extern JS_PUBLIC_API(JSGCCallback) -JS_SetGCCallbackRT(JSRuntime *rt, JSGCCallback cb); - -extern JS_PUBLIC_API(JSBool) -JS_IsGCMarkingTracer(JSTracer *trc); - -extern JS_PUBLIC_API(JSBool) -JS_IsAboutToBeFinalized(JSContext *cx, void *thing); - -typedef enum JSGCParamKey { - /* Maximum nominal heap before last ditch GC. */ - JSGC_MAX_BYTES = 0, - - /* Number of JS_malloc bytes before last ditch GC. */ - JSGC_MAX_MALLOC_BYTES = 1, - - /* Hoard stackPools for this long, in ms, default is 30 seconds. */ - JSGC_STACKPOOL_LIFESPAN = 2, - - /* - * The factor that defines when the GC is invoked. The factor is a - * percent of the memory allocated by the GC after the last run of - * the GC. When the current memory allocated by the GC is more than - * this percent then the GC is invoked. The factor cannot be less - * than 100 since the current memory allocated by the GC cannot be less - * than the memory allocated after the last run of the GC. - */ - JSGC_TRIGGER_FACTOR = 3, - - /* Amount of bytes allocated by the GC. */ - JSGC_BYTES = 4, - - /* Number of times when GC was invoked. */ - JSGC_NUMBER = 5, - - /* Max size of the code cache in bytes. */ - JSGC_MAX_CODE_CACHE_BYTES = 6, - - /* Select GC mode. */ - JSGC_MODE = 7, - - /* Number of GC chunks waiting to expire. */ - JSGC_UNUSED_CHUNKS = 8 -} JSGCParamKey; - -typedef enum JSGCMode { - /* Perform only global GCs. */ - JSGC_MODE_GLOBAL = 0, - - /* Perform per-compartment GCs until too much garbage has accumulated. */ - JSGC_MODE_COMPARTMENT = 1 -} JSGCMode; - -extern JS_PUBLIC_API(void) -JS_SetGCParameter(JSRuntime *rt, JSGCParamKey key, uint32 value); - -extern JS_PUBLIC_API(uint32) -JS_GetGCParameter(JSRuntime *rt, JSGCParamKey key); - -extern JS_PUBLIC_API(void) -JS_SetGCParameterForThread(JSContext *cx, JSGCParamKey key, uint32 value); - -extern JS_PUBLIC_API(uint32) -JS_GetGCParameterForThread(JSContext *cx, JSGCParamKey key); - -/* - * Flush the code cache for the current thread. The operation might be - * delayed if the cache cannot be flushed currently because native - * code is currently executing. - */ - -extern JS_PUBLIC_API(void) -JS_FlushCaches(JSContext *cx); - -/* - * Add a finalizer for external strings created by JS_NewExternalString (see - * below) using a type-code returned from this function, and that understands - * how to free or release the memory pointed at by JS_GetStringChars(str). - * - * Return a nonnegative type index if there is room for finalizer in the - * global GC finalizers table, else return -1. If the engine is compiled - * JS_THREADSAFE and used in a multi-threaded environment, this function must - * be invoked on the primordial thread only, at startup -- or else the entire - * program must single-thread itself while loading a module that calls this - * function. - */ -extern JS_PUBLIC_API(intN) -JS_AddExternalStringFinalizer(JSStringFinalizeOp finalizer); - -/* - * Remove finalizer from the global GC finalizers table, returning its type - * code if found, -1 if not found. - * - * As with JS_AddExternalStringFinalizer, there is a threading restriction - * if you compile the engine JS_THREADSAFE: this function may be called for a - * given finalizer pointer on only one thread; different threads may call to - * remove distinct finalizers safely. - * - * You must ensure that all strings with finalizer's type have been collected - * before calling this function. Otherwise, string data will be leaked by the - * GC, for want of a finalizer to call. - */ -extern JS_PUBLIC_API(intN) -JS_RemoveExternalStringFinalizer(JSStringFinalizeOp finalizer); - -/* - * Create a new JSString whose chars member refers to external memory, i.e., - * memory requiring spe, type-specific finalization. The type code must - * be a nonnegative return value from JS_AddExternalStringFinalizer. - */ -extern JS_PUBLIC_API(JSString *) -JS_NewExternalString(JSContext *cx, jschar *chars, size_t length, intN type); - -/* - * Returns the external-string finalizer index for this string, or -1 if it is - * an "internal" (native to JS engine) string. - */ -extern JS_PUBLIC_API(intN) -JS_GetExternalStringGCType(JSRuntime *rt, JSString *str); - -/* - * Deprecated. Use JS_SetNativeStackQuoata instead. - */ -extern JS_PUBLIC_API(void) -JS_SetThreadStackLimit(JSContext *cx, jsuword limitAddr); - -/* - * Set the size of the native stack that should not be exceed. To disable - * stack size checking pass 0. - */ -extern JS_PUBLIC_API(void) -JS_SetNativeStackQuota(JSContext *cx, size_t stackSize); - - -/* - * Set the quota on the number of bytes that stack-like data structures can - * use when the runtime compiles and executes scripts. These structures - * consume heap space, so JS_SetThreadStackLimit does not bound their size. - * The default quota is 128MB which is very generous. - * - * The function must be called before any script compilation or execution API - * calls, i.e. either immediately after JS_NewContext or from JSCONTEXT_NEW - * context callback. - */ -extern JS_PUBLIC_API(void) -JS_SetScriptStackQuota(JSContext *cx, size_t quota); - -#define JS_DEFAULT_SCRIPT_STACK_QUOTA ((size_t) 0x8000000) - -/************************************************************************/ - -/* - * Classes, objects, and properties. - */ -typedef void (*JSClassInternal)(); - -/* For detailed comments on the function pointer types, see jspubtd.h. */ -struct JSClass { - const char *name; - uint32 flags; - - /* Mandatory non-null function pointer members. */ - JSPropertyOp addProperty; - JSPropertyOp delProperty; - JSPropertyOp getProperty; - JSStrictPropertyOp setProperty; - JSEnumerateOp enumerate; - JSResolveOp resolve; - JSConvertOp convert; - JSFinalizeOp finalize; - - /* Optionally non-null members start here. */ - JSClassInternal reserved0; - JSCheckAccessOp checkAccess; - JSNative call; - JSNative construct; - JSXDRObjectOp xdrObject; - JSHasInstanceOp hasInstance; - JSMarkOp mark; - - JSClassInternal reserved1; - void *reserved[19]; -}; - -#define JSCLASS_HAS_PRIVATE (1<<0) /* objects have private slot */ -#define JSCLASS_NEW_ENUMERATE (1<<1) /* has JSNewEnumerateOp hook */ -#define JSCLASS_NEW_RESOLVE (1<<2) /* has JSNewResolveOp hook */ -#define JSCLASS_PRIVATE_IS_NSISUPPORTS (1<<3) /* private is (nsISupports *) */ -#define JSCLASS_NEW_RESOLVE_GETS_START (1<<5) /* JSNewResolveOp gets starting - object in prototype chain - passed in via *objp in/out - parameter */ -#define JSCLASS_CONSTRUCT_PROTOTYPE (1<<6) /* call constructor on class - prototype */ -#define JSCLASS_DOCUMENT_OBSERVER (1<<7) /* DOM document observer */ - -/* - * To reserve slots fetched and stored via JS_Get/SetReservedSlot, bitwise-or - * JSCLASS_HAS_RESERVED_SLOTS(n) into the initializer for JSClass.flags, where - * n is a constant in [1, 255]. Reserved slots are indexed from 0 to n-1. - */ -#define JSCLASS_RESERVED_SLOTS_SHIFT 8 /* room for 8 flags below */ -#define JSCLASS_RESERVED_SLOTS_WIDTH 8 /* and 16 above this field */ -#define JSCLASS_RESERVED_SLOTS_MASK JS_BITMASK(JSCLASS_RESERVED_SLOTS_WIDTH) -#define JSCLASS_HAS_RESERVED_SLOTS(n) (((n) & JSCLASS_RESERVED_SLOTS_MASK) \ - << JSCLASS_RESERVED_SLOTS_SHIFT) -#define JSCLASS_RESERVED_SLOTS(clasp) (((clasp)->flags \ - >> JSCLASS_RESERVED_SLOTS_SHIFT) \ - & JSCLASS_RESERVED_SLOTS_MASK) - -#define JSCLASS_HIGH_FLAGS_SHIFT (JSCLASS_RESERVED_SLOTS_SHIFT + \ - JSCLASS_RESERVED_SLOTS_WIDTH) - -#define JSCLASS_INTERNAL_FLAG1 (1<<(JSCLASS_HIGH_FLAGS_SHIFT+0)) -#define JSCLASS_IS_ANONYMOUS (1<<(JSCLASS_HIGH_FLAGS_SHIFT+1)) -#define JSCLASS_IS_GLOBAL (1<<(JSCLASS_HIGH_FLAGS_SHIFT+2)) - -/* Indicates that JSClass.mark is a tracer with JSTraceOp type. */ -#define JSCLASS_MARK_IS_TRACE (1<<(JSCLASS_HIGH_FLAGS_SHIFT+3)) -#define JSCLASS_INTERNAL_FLAG2 (1<<(JSCLASS_HIGH_FLAGS_SHIFT+4)) - -/* Indicate whether the proto or ctor should be frozen. */ -#define JSCLASS_FREEZE_PROTO (1<<(JSCLASS_HIGH_FLAGS_SHIFT+5)) -#define JSCLASS_FREEZE_CTOR (1<<(JSCLASS_HIGH_FLAGS_SHIFT+6)) - -/* Additional global reserved slots, beyond those for standard prototypes. */ -#define JSRESERVED_GLOBAL_SLOTS_COUNT 6 -#define JSRESERVED_GLOBAL_THIS (JSProto_LIMIT * 3) -#define JSRESERVED_GLOBAL_THROWTYPEERROR (JSRESERVED_GLOBAL_THIS + 1) -#define JSRESERVED_GLOBAL_REGEXP_STATICS (JSRESERVED_GLOBAL_THROWTYPEERROR + 1) -#define JSRESERVED_GLOBAL_FUNCTION_NS (JSRESERVED_GLOBAL_REGEXP_STATICS + 1) -#define JSRESERVED_GLOBAL_EVAL_ALLOWED (JSRESERVED_GLOBAL_FUNCTION_NS + 1) -#define JSRESERVED_GLOBAL_FLAGS (JSRESERVED_GLOBAL_EVAL_ALLOWED + 1) - -/* Global flags. */ -#define JSGLOBAL_FLAGS_CLEARED 0x1 - -/* - * ECMA-262 requires that most constructors used internally create objects - * with "the original Foo.prototype value" as their [[Prototype]] (__proto__) - * member initial value. The "original ... value" verbiage is there because - * in ECMA-262, global properties naming class objects are read/write and - * deleteable, for the most part. - * - * Implementing this efficiently requires that global objects have classes - * with the following flags. Failure to use JSCLASS_GLOBAL_FLAGS was - * prevously allowed, but is now an ES5 violation and thus unsupported. - */ -#define JSCLASS_GLOBAL_FLAGS \ - (JSCLASS_IS_GLOBAL | \ - JSCLASS_HAS_RESERVED_SLOTS(JSRESERVED_GLOBAL_THIS + JSRESERVED_GLOBAL_SLOTS_COUNT)) - -/* Fast access to the original value of each standard class's prototype. */ -#define JSCLASS_CACHED_PROTO_SHIFT (JSCLASS_HIGH_FLAGS_SHIFT + 8) -#define JSCLASS_CACHED_PROTO_WIDTH 8 -#define JSCLASS_CACHED_PROTO_MASK JS_BITMASK(JSCLASS_CACHED_PROTO_WIDTH) -#define JSCLASS_HAS_CACHED_PROTO(key) ((key) << JSCLASS_CACHED_PROTO_SHIFT) -#define JSCLASS_CACHED_PROTO_KEY(clasp) ((JSProtoKey) \ - (((clasp)->flags \ - >> JSCLASS_CACHED_PROTO_SHIFT) \ - & JSCLASS_CACHED_PROTO_MASK)) - -/* Initializer for unused members of statically initialized JSClass structs. */ -#define JSCLASS_NO_INTERNAL_MEMBERS 0,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} -#define JSCLASS_NO_OPTIONAL_MEMBERS 0,0,0,0,0,0,0,JSCLASS_NO_INTERNAL_MEMBERS - -struct JSIdArray { - jsint length; - jsid vector[1]; /* actually, length jsid words */ -}; - -extern JS_PUBLIC_API(void) -JS_DestroyIdArray(JSContext *cx, JSIdArray *ida); - -extern JS_PUBLIC_API(JSBool) -JS_ValueToId(JSContext *cx, jsval v, jsid *idp); - -extern JS_PUBLIC_API(JSBool) -JS_IdToValue(JSContext *cx, jsid id, jsval *vp); - -/* - * JSNewResolveOp flag bits. - */ -#define JSRESOLVE_QUALIFIED 0x01 /* resolve a qualified property id */ -#define JSRESOLVE_ASSIGNING 0x02 /* resolve on the left of assignment */ -#define JSRESOLVE_DETECTING 0x04 /* 'if (o.p)...' or '(o.p) ?...:...' */ -#define JSRESOLVE_DECLARING 0x08 /* var, const, or function prolog op */ -#define JSRESOLVE_CLASSNAME 0x10 /* class name used when constructing */ -#define JSRESOLVE_WITH 0x20 /* resolve inside a with statement */ - -extern JS_PUBLIC_API(JSBool) -JS_PropertyStub(JSContext *cx, JSObject *obj, jsid id, jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_StrictPropertyStub(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_EnumerateStub(JSContext *cx, JSObject *obj); - -extern JS_PUBLIC_API(JSBool) -JS_ResolveStub(JSContext *cx, JSObject *obj, jsid id); - -extern JS_PUBLIC_API(JSBool) -JS_ConvertStub(JSContext *cx, JSObject *obj, JSType type, jsval *vp); - -extern JS_PUBLIC_API(void) -JS_FinalizeStub(JSContext *cx, JSObject *obj); - -struct JSConstDoubleSpec { - jsdouble dval; - const char *name; - uint8 flags; - uint8 spare[3]; -}; - -/* - * To define an array element rather than a named property member, cast the - * element's index to (const char *) and initialize name with it, and set the - * JSPROP_INDEX bit in flags. - */ -struct JSPropertySpec { - const char *name; - int8 tinyid; - uint8 flags; - JSPropertyOp getter; - JSStrictPropertyOp setter; -}; - -struct JSFunctionSpec { - const char *name; - JSNative call; - uint16 nargs; - uint16 flags; -}; - -/* - * Terminating sentinel initializer to put at the end of a JSFunctionSpec array - * that's passed to JS_DefineFunctions or JS_InitClass. - */ -#define JS_FS_END JS_FS(NULL,NULL,0,0) - -/* - * Initializer macros for a JSFunctionSpec array element. JS_FN (whose name - * pays homage to the old JSNative/JSFastNative split) simply adds the flag - * JSFUN_STUB_GSOPS. - */ -#define JS_FS(name,call,nargs,flags) \ - {name, call, nargs, flags} -#define JS_FN(name,call,nargs,flags) \ - {name, call, nargs, (flags) | JSFUN_STUB_GSOPS} - -extern JS_PUBLIC_API(JSObject *) -JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, - JSClass *clasp, JSNative constructor, uintN nargs, - JSPropertySpec *ps, JSFunctionSpec *fs, - JSPropertySpec *static_ps, JSFunctionSpec *static_fs); - -#ifdef JS_THREADSAFE -extern JS_PUBLIC_API(JSClass *) -JS_GetClass(JSContext *cx, JSObject *obj); - -#define JS_GET_CLASS(cx,obj) JS_GetClass(cx, obj) -#else -extern JS_PUBLIC_API(JSClass *) -JS_GetClass(JSObject *obj); - -#define JS_GET_CLASS(cx,obj) JS_GetClass(obj) -#endif - -extern JS_PUBLIC_API(JSBool) -JS_InstanceOf(JSContext *cx, JSObject *obj, JSClass *clasp, jsval *argv); - -extern JS_PUBLIC_API(JSBool) -JS_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp); - -extern JS_PUBLIC_API(void *) -JS_GetPrivate(JSContext *cx, JSObject *obj); - -extern JS_PUBLIC_API(JSBool) -JS_SetPrivate(JSContext *cx, JSObject *obj, void *data); - -extern JS_PUBLIC_API(void *) -JS_GetInstancePrivate(JSContext *cx, JSObject *obj, JSClass *clasp, - jsval *argv); - -extern JS_PUBLIC_API(JSObject *) -JS_GetPrototype(JSContext *cx, JSObject *obj); - -extern JS_PUBLIC_API(JSBool) -JS_SetPrototype(JSContext *cx, JSObject *obj, JSObject *proto); - -extern JS_PUBLIC_API(JSObject *) -JS_GetParent(JSContext *cx, JSObject *obj); - -extern JS_PUBLIC_API(JSBool) -JS_SetParent(JSContext *cx, JSObject *obj, JSObject *parent); - -extern JS_PUBLIC_API(JSObject *) -JS_GetConstructor(JSContext *cx, JSObject *proto); - -/* - * Get a unique identifier for obj, good for the lifetime of obj (even if it - * is moved by a copying GC). Return false on failure (likely out of memory), - * and true with *idp containing the unique id on success. - */ -extern JS_PUBLIC_API(JSBool) -JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp); - -extern JS_PUBLIC_API(JSObject *) -JS_NewGlobalObject(JSContext *cx, JSClass *clasp); - -extern JS_PUBLIC_API(JSObject *) -JS_NewCompartmentAndGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals); - -extern JS_PUBLIC_API(JSObject *) -JS_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent); - -/* Queries the [[Extensible]] property of the object. */ -extern JS_PUBLIC_API(JSBool) -JS_IsExtensible(JSObject *obj); - -/* - * Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default - * proto if proto's actual parameter value is null. - */ -extern JS_PUBLIC_API(JSObject *) -JS_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto, - JSObject *parent); - -/* - * Freeze obj, and all objects it refers to, recursively. This will not recurse - * through non-extensible objects, on the assumption that those are already - * deep-frozen. - */ -extern JS_PUBLIC_API(JSBool) -JS_DeepFreezeObject(JSContext *cx, JSObject *obj); - -/* - * Freezes an object; see ES5's Object.freeze(obj) method. - */ -extern JS_PUBLIC_API(JSBool) -JS_FreezeObject(JSContext *cx, JSObject *obj); - -extern JS_PUBLIC_API(JSObject *) -JS_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto, - JSObject *parent); - -extern JS_PUBLIC_API(JSObject *) -JS_ConstructObjectWithArguments(JSContext *cx, JSClass *clasp, JSObject *proto, - JSObject *parent, uintN argc, jsval *argv); - -extern JS_PUBLIC_API(JSObject *) -JS_New(JSContext *cx, JSObject *ctor, uintN argc, jsval *argv); - -extern JS_PUBLIC_API(JSObject *) -JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, JSClass *clasp, - JSObject *proto, uintN attrs); - -extern JS_PUBLIC_API(JSBool) -JS_DefineConstDoubles(JSContext *cx, JSObject *obj, JSConstDoubleSpec *cds); - -extern JS_PUBLIC_API(JSBool) -JS_DefineProperties(JSContext *cx, JSObject *obj, JSPropertySpec *ps); - -extern JS_PUBLIC_API(JSBool) -JS_DefineProperty(JSContext *cx, JSObject *obj, const char *name, jsval value, - JSPropertyOp getter, JSStrictPropertyOp setter, uintN attrs); - -extern JS_PUBLIC_API(JSBool) -JS_DefinePropertyById(JSContext *cx, JSObject *obj, jsid id, jsval value, - JSPropertyOp getter, JSStrictPropertyOp setter, uintN attrs); - -extern JS_PUBLIC_API(JSBool) -JS_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id, jsval descriptor, JSBool *bp); - -/* - * Determine the attributes (JSPROP_* flags) of a property on a given object. - * - * If the object does not have a property by that name, *foundp will be - * JS_FALSE and the value of *attrsp is undefined. - */ -extern JS_PUBLIC_API(JSBool) -JS_GetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name, - uintN *attrsp, JSBool *foundp); - -/* - * The same, but if the property is native, return its getter and setter via - * *getterp and *setterp, respectively (and only if the out parameter pointer - * is not null). - */ -extern JS_PUBLIC_API(JSBool) -JS_GetPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj, - const char *name, - uintN *attrsp, JSBool *foundp, - JSPropertyOp *getterp, - JSStrictPropertyOp *setterp); - -extern JS_PUBLIC_API(JSBool) -JS_GetPropertyAttrsGetterAndSetterById(JSContext *cx, JSObject *obj, - jsid id, - uintN *attrsp, JSBool *foundp, - JSPropertyOp *getterp, - JSStrictPropertyOp *setterp); - -/* - * Set the attributes of a property on a given object. - * - * If the object does not have a property by that name, *foundp will be - * JS_FALSE and nothing will be altered. - */ -extern JS_PUBLIC_API(JSBool) -JS_SetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name, - uintN attrs, JSBool *foundp); - -extern JS_PUBLIC_API(JSBool) -JS_DefinePropertyWithTinyId(JSContext *cx, JSObject *obj, const char *name, - int8 tinyid, jsval value, - JSPropertyOp getter, JSStrictPropertyOp setter, - uintN attrs); - -extern JS_PUBLIC_API(JSBool) -JS_AliasProperty(JSContext *cx, JSObject *obj, const char *name, - const char *alias); - -extern JS_PUBLIC_API(JSBool) -JS_AlreadyHasOwnProperty(JSContext *cx, JSObject *obj, const char *name, - JSBool *foundp); - -extern JS_PUBLIC_API(JSBool) -JS_AlreadyHasOwnPropertyById(JSContext *cx, JSObject *obj, jsid id, - JSBool *foundp); - -extern JS_PUBLIC_API(JSBool) -JS_HasProperty(JSContext *cx, JSObject *obj, const char *name, JSBool *foundp); - -extern JS_PUBLIC_API(JSBool) -JS_HasPropertyById(JSContext *cx, JSObject *obj, jsid id, JSBool *foundp); - -extern JS_PUBLIC_API(JSBool) -JS_LookupProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_LookupPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, const char *name, - uintN flags, jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_LookupPropertyWithFlagsById(JSContext *cx, JSObject *obj, jsid id, - uintN flags, JSObject **objp, jsval *vp); - -struct JSPropertyDescriptor { - JSObject *obj; - uintN attrs; - JSPropertyOp getter; - JSStrictPropertyOp setter; - jsval value; - uintN shortid; -}; - -/* - * Like JS_GetPropertyAttrsGetterAndSetterById but will return a property on - * an object on the prototype chain (returned in objp). If data->obj is null, - * then this property was not found on the prototype chain. - */ -extern JS_PUBLIC_API(JSBool) -JS_GetPropertyDescriptorById(JSContext *cx, JSObject *obj, jsid id, uintN flags, - JSPropertyDescriptor *desc); - -extern JS_PUBLIC_API(JSBool) -JS_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_GetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_GetPropertyDefault(JSContext *cx, JSObject *obj, const char *name, jsval def, jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_GetPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_GetPropertyByIdDefault(JSContext *cx, JSObject *obj, jsid id, jsval def, jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_GetMethodById(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, - jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_GetMethod(JSContext *cx, JSObject *obj, const char *name, JSObject **objp, - jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_SetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_SetPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_DeleteProperty(JSContext *cx, JSObject *obj, const char *name); - -extern JS_PUBLIC_API(JSBool) -JS_DeleteProperty2(JSContext *cx, JSObject *obj, const char *name, - jsval *rval); - -extern JS_PUBLIC_API(JSBool) -JS_DeletePropertyById(JSContext *cx, JSObject *obj, jsid id); - -extern JS_PUBLIC_API(JSBool) -JS_DeletePropertyById2(JSContext *cx, JSObject *obj, jsid id, jsval *rval); - -extern JS_PUBLIC_API(JSBool) -JS_DefineUCProperty(JSContext *cx, JSObject *obj, - const jschar *name, size_t namelen, jsval value, - JSPropertyOp getter, JSStrictPropertyOp setter, - uintN attrs); - -/* - * Determine the attributes (JSPROP_* flags) of a property on a given object. - * - * If the object does not have a property by that name, *foundp will be - * JS_FALSE and the value of *attrsp is undefined. - */ -extern JS_PUBLIC_API(JSBool) -JS_GetUCPropertyAttributes(JSContext *cx, JSObject *obj, - const jschar *name, size_t namelen, - uintN *attrsp, JSBool *foundp); - -/* - * The same, but if the property is native, return its getter and setter via - * *getterp and *setterp, respectively (and only if the out parameter pointer - * is not null). - */ -extern JS_PUBLIC_API(JSBool) -JS_GetUCPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj, - const jschar *name, size_t namelen, - uintN *attrsp, JSBool *foundp, - JSPropertyOp *getterp, - JSStrictPropertyOp *setterp); - -/* - * Set the attributes of a property on a given object. - * - * If the object does not have a property by that name, *foundp will be - * JS_FALSE and nothing will be altered. - */ -extern JS_PUBLIC_API(JSBool) -JS_SetUCPropertyAttributes(JSContext *cx, JSObject *obj, - const jschar *name, size_t namelen, - uintN attrs, JSBool *foundp); - - -extern JS_PUBLIC_API(JSBool) -JS_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *obj, - const jschar *name, size_t namelen, - int8 tinyid, jsval value, - JSPropertyOp getter, JSStrictPropertyOp setter, - uintN attrs); - -extern JS_PUBLIC_API(JSBool) -JS_AlreadyHasOwnUCProperty(JSContext *cx, JSObject *obj, const jschar *name, - size_t namelen, JSBool *foundp); - -extern JS_PUBLIC_API(JSBool) -JS_HasUCProperty(JSContext *cx, JSObject *obj, - const jschar *name, size_t namelen, - JSBool *vp); - -extern JS_PUBLIC_API(JSBool) -JS_LookupUCProperty(JSContext *cx, JSObject *obj, - const jschar *name, size_t namelen, - jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_GetUCProperty(JSContext *cx, JSObject *obj, - const jschar *name, size_t namelen, - jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_SetUCProperty(JSContext *cx, JSObject *obj, - const jschar *name, size_t namelen, - jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_DeleteUCProperty2(JSContext *cx, JSObject *obj, - const jschar *name, size_t namelen, - jsval *rval); - -extern JS_PUBLIC_API(JSObject *) -JS_NewArrayObject(JSContext *cx, jsint length, jsval *vector); - -extern JS_PUBLIC_API(JSBool) -JS_IsArrayObject(JSContext *cx, JSObject *obj); - -extern JS_PUBLIC_API(JSBool) -JS_GetArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp); - -extern JS_PUBLIC_API(JSBool) -JS_SetArrayLength(JSContext *cx, JSObject *obj, jsuint length); - -extern JS_PUBLIC_API(JSBool) -JS_HasArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp); - -extern JS_PUBLIC_API(JSBool) -JS_DefineElement(JSContext *cx, JSObject *obj, jsint index, jsval value, - JSPropertyOp getter, JSStrictPropertyOp setter, uintN attrs); - -extern JS_PUBLIC_API(JSBool) -JS_AliasElement(JSContext *cx, JSObject *obj, const char *name, jsint alias); - -extern JS_PUBLIC_API(JSBool) -JS_AlreadyHasOwnElement(JSContext *cx, JSObject *obj, jsint index, - JSBool *foundp); - -extern JS_PUBLIC_API(JSBool) -JS_HasElement(JSContext *cx, JSObject *obj, jsint index, JSBool *foundp); - -extern JS_PUBLIC_API(JSBool) -JS_LookupElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_GetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_SetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_DeleteElement(JSContext *cx, JSObject *obj, jsint index); - -extern JS_PUBLIC_API(JSBool) -JS_DeleteElement2(JSContext *cx, JSObject *obj, jsint index, jsval *rval); - -extern JS_PUBLIC_API(void) -JS_ClearScope(JSContext *cx, JSObject *obj); - -extern JS_PUBLIC_API(JSIdArray *) -JS_Enumerate(JSContext *cx, JSObject *obj); - -/* - * Create an object to iterate over enumerable properties of obj, in arbitrary - * property definition order. NB: This differs from longstanding for..in loop - * order, which uses order of property definition in obj. - */ -extern JS_PUBLIC_API(JSObject *) -JS_NewPropertyIterator(JSContext *cx, JSObject *obj); - -/* - * Return true on success with *idp containing the id of the next enumerable - * property to visit using iterobj, or JSID_IS_VOID if there is no such property - * left to visit. Return false on error. - */ -extern JS_PUBLIC_API(JSBool) -JS_NextProperty(JSContext *cx, JSObject *iterobj, jsid *idp); - -extern JS_PUBLIC_API(JSBool) -JS_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, - jsval *vp, uintN *attrsp); - -extern JS_PUBLIC_API(JSBool) -JS_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval v); - -/************************************************************************/ - -/* - * Security protocol. - */ -struct JSPrincipals { - char *codebase; - - /* XXX unspecified and unused by Mozilla code -- can we remove these? */ - void * (* getPrincipalArray)(JSContext *cx, JSPrincipals *); - JSBool (* globalPrivilegesEnabled)(JSContext *cx, JSPrincipals *); - - /* Don't call "destroy"; use reference counting macros below. */ - jsrefcount refcount; - - void (* destroy)(JSContext *cx, JSPrincipals *); - JSBool (* subsume)(JSPrincipals *, JSPrincipals *); -}; - -#ifdef JS_THREADSAFE -#define JSPRINCIPALS_HOLD(cx, principals) JS_HoldPrincipals(cx,principals) -#define JSPRINCIPALS_DROP(cx, principals) JS_DropPrincipals(cx,principals) - -extern JS_PUBLIC_API(jsrefcount) -JS_HoldPrincipals(JSContext *cx, JSPrincipals *principals); - -extern JS_PUBLIC_API(jsrefcount) -JS_DropPrincipals(JSContext *cx, JSPrincipals *principals); - -#else -#define JSPRINCIPALS_HOLD(cx, principals) (++(principals)->refcount) -#define JSPRINCIPALS_DROP(cx, principals) \ - ((--(principals)->refcount == 0) \ - ? ((*(principals)->destroy)((cx), (principals)), 0) \ - : (principals)->refcount) -#endif - - -struct JSSecurityCallbacks { - JSCheckAccessOp checkObjectAccess; - JSPrincipalsTranscoder principalsTranscoder; - JSObjectPrincipalsFinder findObjectPrincipals; - JSCSPEvalChecker contentSecurityPolicyAllows; -}; - -extern JS_PUBLIC_API(JSSecurityCallbacks *) -JS_SetRuntimeSecurityCallbacks(JSRuntime *rt, JSSecurityCallbacks *callbacks); - -extern JS_PUBLIC_API(JSSecurityCallbacks *) -JS_GetRuntimeSecurityCallbacks(JSRuntime *rt); - -extern JS_PUBLIC_API(JSSecurityCallbacks *) -JS_SetContextSecurityCallbacks(JSContext *cx, JSSecurityCallbacks *callbacks); - -extern JS_PUBLIC_API(JSSecurityCallbacks *) -JS_GetSecurityCallbacks(JSContext *cx); - -/************************************************************************/ - -/* - * Functions and scripts. - */ -extern JS_PUBLIC_API(JSFunction *) -JS_NewFunction(JSContext *cx, JSNative call, uintN nargs, uintN flags, - JSObject *parent, const char *name); - -/* - * Create the function with the name given by the id. JSID_IS_STRING(id) must - * be true. - */ -extern JS_PUBLIC_API(JSFunction *) -JS_NewFunctionById(JSContext *cx, JSNative call, uintN nargs, uintN flags, - JSObject *parent, jsid id); - -extern JS_PUBLIC_API(JSObject *) -JS_GetFunctionObject(JSFunction *fun); - -/* - * Return the function's identifier as a JSString, or null if fun is unnamed. - * The returned string lives as long as fun, so you don't need to root a saved - * reference to it if fun is well-connected or rooted, and provided you bound - * the use of the saved reference by fun's lifetime. - */ -extern JS_PUBLIC_API(JSString *) -JS_GetFunctionId(JSFunction *fun); - -/* - * Return JSFUN_* flags for fun. - */ -extern JS_PUBLIC_API(uintN) -JS_GetFunctionFlags(JSFunction *fun); - -/* - * Return the arity (length) of fun. - */ -extern JS_PUBLIC_API(uint16) -JS_GetFunctionArity(JSFunction *fun); - -/* - * Infallible predicate to test whether obj is a function object (faster than - * comparing obj's class name to "Function", but equivalent unless someone has - * overwritten the "Function" identifier with a different constructor and then - * created instances using that constructor that might be passed in as obj). - */ -extern JS_PUBLIC_API(JSBool) -JS_ObjectIsFunction(JSContext *cx, JSObject *obj); - -extern JS_PUBLIC_API(JSBool) -JS_ObjectIsCallable(JSContext *cx, JSObject *obj); - -extern JS_PUBLIC_API(JSBool) -JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs); - -extern JS_PUBLIC_API(JSFunction *) -JS_DefineFunction(JSContext *cx, JSObject *obj, const char *name, JSNative call, - uintN nargs, uintN attrs); - -extern JS_PUBLIC_API(JSFunction *) -JS_DefineUCFunction(JSContext *cx, JSObject *obj, - const jschar *name, size_t namelen, JSNative call, - uintN nargs, uintN attrs); - -extern JS_PUBLIC_API(JSFunction *) -JS_DefineFunctionById(JSContext *cx, JSObject *obj, jsid id, JSNative call, - uintN nargs, uintN attrs); - -extern JS_PUBLIC_API(JSObject *) -JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent); - -/* - * Given a buffer, return JS_FALSE if the buffer might become a valid - * javascript statement with the addition of more lines. Otherwise return - * JS_TRUE. The intent is to support interactive compilation - accumulate - * lines in a buffer until JS_BufferIsCompilableUnit is true, then pass it to - * the compiler. - */ -extern JS_PUBLIC_API(JSBool) -JS_BufferIsCompilableUnit(JSContext *cx, JSObject *obj, - const char *bytes, size_t length); - -/* - * The JSScript objects returned by the following functions refer to string and - * other kinds of literals, including doubles and RegExp objects. These - * literals are vulnerable to garbage collection; to root script objects and - * prevent literals from being collected, create a rootable object using - * JS_NewScriptObject, and root the resulting object using JS_Add[Named]Root. - */ -extern JS_PUBLIC_API(JSScript *) -JS_CompileScript(JSContext *cx, JSObject *obj, - const char *bytes, size_t length, - const char *filename, uintN lineno); - -extern JS_PUBLIC_API(JSScript *) -JS_CompileScriptForPrincipals(JSContext *cx, JSObject *obj, - JSPrincipals *principals, - const char *bytes, size_t length, - const char *filename, uintN lineno); - -extern JS_PUBLIC_API(JSScript *) -JS_CompileScriptForPrincipalsVersion(JSContext *cx, JSObject *obj, - JSPrincipals *principals, - const char *bytes, size_t length, - const char *filename, uintN lineno, - JSVersion version); - -extern JS_PUBLIC_API(JSScript *) -JS_CompileUCScript(JSContext *cx, JSObject *obj, - const jschar *chars, size_t length, - const char *filename, uintN lineno); - -extern JS_PUBLIC_API(JSScript *) -JS_CompileUCScriptForPrincipals(JSContext *cx, JSObject *obj, - JSPrincipals *principals, - const jschar *chars, size_t length, - const char *filename, uintN lineno); - -extern JS_PUBLIC_API(JSScript *) -JS_CompileUCScriptForPrincipalsVersion(JSContext *cx, JSObject *obj, - JSPrincipals *principals, - const jschar *chars, size_t length, - const char *filename, uintN lineno, - JSVersion version); - -extern JS_PUBLIC_API(JSScript *) -JS_CompileFile(JSContext *cx, JSObject *obj, const char *filename); - -extern JS_PUBLIC_API(JSScript *) -JS_CompileFileHandle(JSContext *cx, JSObject *obj, const char *filename, - FILE *fh); - -extern JS_PUBLIC_API(JSScript *) -JS_CompileFileHandleForPrincipals(JSContext *cx, JSObject *obj, - const char *filename, FILE *fh, - JSPrincipals *principals); - -extern JS_PUBLIC_API(JSScript *) -JS_CompileFileHandleForPrincipalsVersion(JSContext *cx, JSObject *obj, - const char *filename, FILE *fh, - JSPrincipals *principals, - JSVersion version); - -/* - * NB: you must use JS_NewScriptObject and root a pointer to its return value - * in order to keep a JSScript and its atoms safe from garbage collection after - * creating the script via JS_Compile* and before a JS_ExecuteScript* call. - * E.g., and without error checks: - * - * JSScript *script = JS_CompileFile(cx, global, filename); - * JSObject *scrobj = JS_NewScriptObject(cx, script); - * JS_AddNamedObjectRoot(cx, &scrobj, "scrobj"); - * do { - * jsval result; - * JS_ExecuteScript(cx, global, script, &result); - * JS_GC(); - * } while (!JSVAL_IS_BOOLEAN(result) || JSVAL_TO_BOOLEAN(result)); - * JS_RemoveObjectRoot(cx, &scrobj); - */ -extern JS_PUBLIC_API(JSObject *) -JS_NewScriptObject(JSContext *cx, JSScript *script); - -/* - * Infallible getter for a script's object. If JS_NewScriptObject has not been - * called on script yet, the return value will be null. - */ -extern JS_PUBLIC_API(JSObject *) -JS_GetScriptObject(JSScript *script); - -extern JS_PUBLIC_API(void) -JS_DestroyScript(JSContext *cx, JSScript *script); - -extern JS_PUBLIC_API(JSFunction *) -JS_CompileFunction(JSContext *cx, JSObject *obj, const char *name, - uintN nargs, const char **argnames, - const char *bytes, size_t length, - const char *filename, uintN lineno); - -extern JS_PUBLIC_API(JSFunction *) -JS_CompileFunctionForPrincipals(JSContext *cx, JSObject *obj, - JSPrincipals *principals, const char *name, - uintN nargs, const char **argnames, - const char *bytes, size_t length, - const char *filename, uintN lineno); - -extern JS_PUBLIC_API(JSFunction *) -JS_CompileUCFunction(JSContext *cx, JSObject *obj, const char *name, - uintN nargs, const char **argnames, - const jschar *chars, size_t length, - const char *filename, uintN lineno); - -extern JS_PUBLIC_API(JSFunction *) -JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj, - JSPrincipals *principals, const char *name, - uintN nargs, const char **argnames, - const jschar *chars, size_t length, - const char *filename, uintN lineno); - -extern JS_PUBLIC_API(JSFunction *) -JS_CompileUCFunctionForPrincipalsVersion(JSContext *cx, JSObject *obj, - JSPrincipals *principals, const char *name, - uintN nargs, const char **argnames, - const jschar *chars, size_t length, - const char *filename, uintN lineno, - JSVersion version); - -extern JS_PUBLIC_API(JSString *) -JS_DecompileScript(JSContext *cx, JSScript *script, const char *name, - uintN indent); - -/* - * API extension: OR this into indent to avoid pretty-printing the decompiled - * source resulting from JS_DecompileFunction{,Body}. - */ -#define JS_DONT_PRETTY_PRINT ((uintN)0x8000) - -extern JS_PUBLIC_API(JSString *) -JS_DecompileFunction(JSContext *cx, JSFunction *fun, uintN indent); - -extern JS_PUBLIC_API(JSString *) -JS_DecompileFunctionBody(JSContext *cx, JSFunction *fun, uintN indent); - -/* - * NB: JS_ExecuteScript and the JS_Evaluate*Script* quadruplets use the obj - * parameter as the initial scope chain header, the 'this' keyword value, and - * the variables object (ECMA parlance for where 'var' and 'function' bind - * names) of the execution context for script. - * - * Using obj as the variables object is problematic if obj's parent (which is - * the scope chain link; see JS_SetParent and JS_NewObject) is not null: in - * this case, variables created by 'var x = 0', e.g., go in obj, but variables - * created by assignment to an unbound id, 'x = 0', go in the last object on - * the scope chain linked by parent. - * - * ECMA calls that last scoping object the "global object", but note that many - * embeddings have several such objects. ECMA requires that "global code" be - * executed with the variables object equal to this global object. But these - * JS API entry points provide freedom to execute code against a "sub-global", - * i.e., a parented or scoped object, in which case the variables object will - * differ from the last object on the scope chain, resulting in confusing and - * non-ECMA explicit vs. implicit variable creation. - * - * Caveat embedders: unless you already depend on this buggy variables object - * binding behavior, you should call JS_SetOptions(cx, JSOPTION_VAROBJFIX) or - * JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_VAROBJFIX) -- the latter if - * someone may have set other options on cx already -- for each context in the - * application, if you pass parented objects as the obj parameter, or may ever - * pass such objects in the future. - * - * Why a runtime option? The alternative is to add six or so new API entry - * points with signatures matching the following six, and that doesn't seem - * worth the code bloat cost. Such new entry points would probably have less - * obvious names, too, so would not tend to be used. The JS_SetOption call, - * OTOH, can be more easily hacked into existing code that does not depend on - * the bug; such code can continue to use the familiar JS_EvaluateScript, - * etc., entry points. - */ -extern JS_PUBLIC_API(JSBool) -JS_ExecuteScript(JSContext *cx, JSObject *obj, JSScript *script, jsval *rval); - -extern JS_PUBLIC_API(JSBool) -JS_ExecuteScriptVersion(JSContext *cx, JSObject *obj, JSScript *script, jsval *rval, - JSVersion version); - -/* - * Execute either the function-defining prolog of a script, or the script's - * main body, but not both. - */ -typedef enum JSExecPart { JSEXEC_PROLOG, JSEXEC_MAIN } JSExecPart; - -extern JS_PUBLIC_API(JSBool) -JS_EvaluateScript(JSContext *cx, JSObject *obj, - const char *bytes, uintN length, - const char *filename, uintN lineno, - jsval *rval); - -extern JS_PUBLIC_API(JSBool) -JS_EvaluateScriptForPrincipals(JSContext *cx, JSObject *obj, - JSPrincipals *principals, - const char *bytes, uintN length, - const char *filename, uintN lineno, - jsval *rval); - -extern JS_PUBLIC_API(JSBool) -JS_EvaluateScriptForPrincipalsVersion(JSContext *cx, JSObject *obj, - JSPrincipals *principals, - const char *bytes, uintN length, - const char *filename, uintN lineno, - jsval *rval, JSVersion version); - -extern JS_PUBLIC_API(JSBool) -JS_EvaluateUCScript(JSContext *cx, JSObject *obj, - const jschar *chars, uintN length, - const char *filename, uintN lineno, - jsval *rval); - -extern JS_PUBLIC_API(JSBool) -JS_EvaluateUCScriptForPrincipalsVersion(JSContext *cx, JSObject *obj, - JSPrincipals *principals, - const jschar *chars, uintN length, - const char *filename, uintN lineno, - jsval *rval, JSVersion version); - -extern JS_PUBLIC_API(JSBool) -JS_EvaluateUCScriptForPrincipals(JSContext *cx, JSObject *obj, - JSPrincipals *principals, - const jschar *chars, uintN length, - const char *filename, uintN lineno, - jsval *rval); - -extern JS_PUBLIC_API(JSBool) -JS_CallFunction(JSContext *cx, JSObject *obj, JSFunction *fun, uintN argc, - jsval *argv, jsval *rval); - -extern JS_PUBLIC_API(JSBool) -JS_CallFunctionName(JSContext *cx, JSObject *obj, const char *name, uintN argc, - jsval *argv, jsval *rval); - -extern JS_PUBLIC_API(JSBool) -JS_CallFunctionValue(JSContext *cx, JSObject *obj, jsval fval, uintN argc, - jsval *argv, jsval *rval); - -#ifdef __cplusplus -JS_END_EXTERN_C - -namespace JS { - -static inline bool -Call(JSContext *cx, JSObject *thisObj, JSFunction *fun, uintN argc, jsval *argv, jsval *rval) { - return !!JS_CallFunction(cx, thisObj, fun, argc, argv, rval); -} - -static inline bool -Call(JSContext *cx, JSObject *thisObj, const char *name, uintN argc, jsval *argv, jsval *rval) { - return !!JS_CallFunctionName(cx, thisObj, name, argc, argv, rval); -} - -static inline bool -Call(JSContext *cx, JSObject *thisObj, jsval fun, uintN argc, jsval *argv, jsval *rval) { - return !!JS_CallFunctionValue(cx, thisObj, fun, argc, argv, rval); -} - -extern JS_PUBLIC_API(bool) -Call(JSContext *cx, jsval thisv, jsval fun, uintN argc, jsval *argv, jsval *rval); - -static inline bool -Call(JSContext *cx, jsval thisv, JSObject *funObj, uintN argc, jsval *argv, jsval *rval) { - return Call(cx, thisv, OBJECT_TO_JSVAL(funObj), argc, argv, rval); -} - -} /* namespace js */ - -JS_BEGIN_EXTERN_C -#endif /* __cplusplus */ - -/* - * These functions allow setting an operation callback that will be called - * from the thread the context is associated with some time after any thread - * triggered the callback using JS_TriggerOperationCallback(cx). - * - * In a threadsafe build the engine internally triggers operation callbacks - * under certain circumstances (i.e. GC and title transfer) to force the - * context to yield its current request, which the engine always - * automatically does immediately prior to calling the callback function. - * The embedding should thus not rely on callbacks being triggered through - * the external API only. - * - * Important note: Additional callbacks can occur inside the callback handler - * if it re-enters the JS engine. The embedding must ensure that the callback - * is disconnected before attempting such re-entry. - */ - -extern JS_PUBLIC_API(JSOperationCallback) -JS_SetOperationCallback(JSContext *cx, JSOperationCallback callback); - -extern JS_PUBLIC_API(JSOperationCallback) -JS_GetOperationCallback(JSContext *cx); - -extern JS_PUBLIC_API(void) -JS_TriggerOperationCallback(JSContext *cx); - -extern JS_PUBLIC_API(void) -JS_TriggerAllOperationCallbacks(JSRuntime *rt); - -extern JS_PUBLIC_API(JSBool) -JS_IsRunning(JSContext *cx); - -/* - * Saving and restoring frame chains. - * - * These two functions are used to set aside cx's call stack while that stack - * is inactive. After a call to JS_SaveFrameChain, it looks as if there is no - * code running on cx. Before calling JS_RestoreFrameChain, cx's call stack - * must be balanced and all nested calls to JS_SaveFrameChain must have had - * matching JS_RestoreFrameChain calls. - * - * JS_SaveFrameChain deals with cx not having any code running on it. A null - * return does not signify an error, and JS_RestoreFrameChain handles a null - * frame pointer argument safely. - */ -extern JS_PUBLIC_API(JSStackFrame *) -JS_SaveFrameChain(JSContext *cx); - -extern JS_PUBLIC_API(void) -JS_RestoreFrameChain(JSContext *cx, JSStackFrame *fp); - -/************************************************************************/ - -/* - * Strings. - * - * NB: JS_NewUCString takes ownership of bytes on success, avoiding a copy; - * but on error (signified by null return), it leaves chars owned by the - * caller. So the caller must free bytes in the error case, if it has no use - * for them. In contrast, all the JS_New*StringCopy* functions do not take - * ownership of the character memory passed to them -- they copy it. - */ -extern JS_PUBLIC_API(JSString *) -JS_NewStringCopyN(JSContext *cx, const char *s, size_t n); - -extern JS_PUBLIC_API(JSString *) -JS_NewStringCopyZ(JSContext *cx, const char *s); - -extern JS_PUBLIC_API(JSString *) -JS_InternJSString(JSContext *cx, JSString *str); - -extern JS_PUBLIC_API(JSString *) -JS_InternString(JSContext *cx, const char *s); - -extern JS_PUBLIC_API(JSString *) -JS_NewUCString(JSContext *cx, jschar *chars, size_t length); - -extern JS_PUBLIC_API(JSString *) -JS_NewUCStringCopyN(JSContext *cx, const jschar *s, size_t n); - -extern JS_PUBLIC_API(JSString *) -JS_NewUCStringCopyZ(JSContext *cx, const jschar *s); - -extern JS_PUBLIC_API(JSString *) -JS_InternUCStringN(JSContext *cx, const jschar *s, size_t length); - -extern JS_PUBLIC_API(JSString *) -JS_InternUCString(JSContext *cx, const jschar *s); - -extern JS_PUBLIC_API(JSBool) -JS_CompareStrings(JSContext *cx, JSString *str1, JSString *str2, int32 *result); - -extern JS_PUBLIC_API(JSBool) -JS_StringEqualsAscii(JSContext *cx, JSString *str, const char *asciiBytes, JSBool *match); - -extern JS_PUBLIC_API(size_t) -JS_PutEscapedString(JSContext *cx, char *buffer, size_t size, JSString *str, char quote); - -extern JS_PUBLIC_API(JSBool) -JS_FileEscapedString(FILE *fp, JSString *str, char quote); - -/* - * Extracting string characters and length. - * - * While getting the length of a string is infallible, getting the chars can - * fail. As indicated by the lack of a JSContext parameter, there are two - * special cases where getting the chars is infallible: - * - * The first case is interned strings, i.e., strings from JS_InternString or - * JSID_TO_STRING(id), using JS_GetInternedStringChars*. - * - * The second case is "flat" strings that have been explicitly prepared in a - * fallible context by JS_FlattenString. To catch errors, a separate opaque - * JSFlatString type is returned by JS_FlattenString and expected by - * JS_GetFlatStringChars. Note, though, that this is purely a syntactic - * distinction: the input and output of JS_FlattenString are the same actual - * GC-thing so only one needs to be rooted. If a JSString is known to be flat, - * JS_ASSERT_STRING_IS_FLAT can be used to make a debug-checked cast. Example: - * - * // in a fallible context - * JSFlatString *fstr = JS_FlattenString(cx, str); - * if (!fstr) - * return JS_FALSE; - * JS_ASSERT(fstr == JS_ASSERT_STRING_IS_FLAT(str)); - * - * // in an infallible context, for the same 'str' - * const jschar *chars = JS_GetFlatStringChars(fstr) - * JS_ASSERT(chars); - * - * The CharsZ APIs guarantee that the returned array has a null character at - * chars[length]. This can require additional copying so clients should prefer - * APIs without CharsZ if possible. The infallible functions also return - * null-terminated arrays. (There is no additional cost or non-Z alternative - * for the infallible functions, so 'Z' is left out of the identifier.) - */ - -extern JS_PUBLIC_API(size_t) -JS_GetStringLength(JSString *str); - -extern JS_PUBLIC_API(const jschar *) -JS_GetStringCharsAndLength(JSContext *cx, JSString *str, size_t *length); - -extern JS_PUBLIC_API(const jschar *) -JS_GetInternedStringChars(JSString *str); - -extern JS_PUBLIC_API(const jschar *) -JS_GetInternedStringCharsAndLength(JSString *str, size_t *length); - -extern JS_PUBLIC_API(const jschar *) -JS_GetStringCharsZ(JSContext *cx, JSString *str); - -extern JS_PUBLIC_API(const jschar *) -JS_GetStringCharsZAndLength(JSContext *cx, JSString *str, size_t *length); - -extern JS_PUBLIC_API(JSFlatString *) -JS_FlattenString(JSContext *cx, JSString *str); - -extern JS_PUBLIC_API(const jschar *) -JS_GetFlatStringChars(JSFlatString *str); - -static JS_ALWAYS_INLINE JSFlatString * -JSID_TO_FLAT_STRING(jsid id) -{ - JS_ASSERT(JSID_IS_STRING(id)); - return (JSFlatString *)(JSID_BITS(id)); -} - -static JS_ALWAYS_INLINE JSFlatString * -JS_ASSERT_STRING_IS_FLAT(JSString *str) -{ - JS_ASSERT(JS_GetFlatStringChars((JSFlatString *)str)); - return (JSFlatString *)str; -} - -static JS_ALWAYS_INLINE JSString * -JS_FORGET_STRING_FLATNESS(JSFlatString *fstr) -{ - return (JSString *)fstr; -} - -/* - * Additional APIs that avoid fallibility when given a flat string. - */ - -extern JS_PUBLIC_API(JSBool) -JS_FlatStringEqualsAscii(JSFlatString *str, const char *asciiBytes); - -extern JS_PUBLIC_API(size_t) -JS_PutEscapedFlatString(char *buffer, size_t size, JSFlatString *str, char quote); - -/* - * This function is now obsolete and behaves the same as JS_NewUCString. Use - * JS_NewUCString instead. - */ -extern JS_PUBLIC_API(JSString *) -JS_NewGrowableString(JSContext *cx, jschar *chars, size_t length); - -/* - * Mutable string support. A string's characters are never mutable in this JS - * implementation, but a dependent string is a substring of another dependent - * or immutable string, and a rope is a lazily concatenated string that creates - * its underlying buffer the first time it is accessed. Even after a rope - * creates its underlying buffer, it still considered mutable. The direct data - * members of the (opaque to API clients) JSString struct may be changed in a - * single-threaded way for dependent strings and ropes. - * - * Therefore mutable strings (ropes and dependent strings) cannot be used by - * more than one thread at a time. You may call JS_MakeStringImmutable to - * convert the string from a mutable string to an immutable (and therefore - * thread-safe) string. The engine takes care of converting ropes and dependent - * strings to immutable for you if you store strings in multi-threaded objects - * using JS_SetProperty or kindred API entry points. - * - * If you store a JSString pointer in a native data structure that is (safely) - * accessible to multiple threads, you must call JS_MakeStringImmutable before - * retiring the store. - */ - -/* - * Create a dependent string, i.e., a string that owns no character storage, - * but that refers to a slice of another string's chars. Dependent strings - * are mutable by definition, so the thread safety comments above apply. - */ -extern JS_PUBLIC_API(JSString *) -JS_NewDependentString(JSContext *cx, JSString *str, size_t start, - size_t length); - -/* - * Concatenate two strings, possibly resulting in a rope. - * See above for thread safety comments. - */ -extern JS_PUBLIC_API(JSString *) -JS_ConcatStrings(JSContext *cx, JSString *left, JSString *right); - -/* - * Convert a dependent string into an independent one. This function does not - * change the string's mutability, so the thread safety comments above apply. - */ -extern JS_PUBLIC_API(const jschar *) -JS_UndependString(JSContext *cx, JSString *str); - -/* - * Convert a mutable string (either rope or dependent) into an immutable, - * thread-safe one. - */ -extern JS_PUBLIC_API(JSBool) -JS_MakeStringImmutable(JSContext *cx, JSString *str); - -/* - * Return JS_TRUE if C (char []) strings passed via the API and internally - * are UTF-8. - */ -JS_PUBLIC_API(JSBool) -JS_CStringsAreUTF8(void); - -/* - * Update the value to be returned by JS_CStringsAreUTF8(). Once set, it - * can never be changed. This API must be called before the first call to - * JS_NewRuntime. - */ -JS_PUBLIC_API(void) -JS_SetCStringsAreUTF8(void); - -/* - * Character encoding support. - * - * For both JS_EncodeCharacters and JS_DecodeBytes, set *dstlenp to the size - * of the destination buffer before the call; on return, *dstlenp contains the - * number of bytes (JS_EncodeCharacters) or jschars (JS_DecodeBytes) actually - * stored. To determine the necessary destination buffer size, make a sizing - * call that passes NULL for dst. - * - * On errors, the functions report the error. In that case, *dstlenp contains - * the number of characters or bytes transferred so far. If cx is NULL, no - * error is reported on failure, and the functions simply return JS_FALSE. - * - * NB: Neither function stores an additional zero byte or jschar after the - * transcoded string. - * - * If JS_CStringsAreUTF8() is true then JS_EncodeCharacters encodes to - * UTF-8, and JS_DecodeBytes decodes from UTF-8, which may create additional - * errors if the character sequence is malformed. If UTF-8 support is - * disabled, the functions deflate and inflate, respectively. - */ -JS_PUBLIC_API(JSBool) -JS_EncodeCharacters(JSContext *cx, const jschar *src, size_t srclen, char *dst, - size_t *dstlenp); - -JS_PUBLIC_API(JSBool) -JS_DecodeBytes(JSContext *cx, const char *src, size_t srclen, jschar *dst, - size_t *dstlenp); - -/* - * A variation on JS_EncodeCharacters where a null terminated string is - * returned that you are expected to call JS_free on when done. - */ -JS_PUBLIC_API(char *) -JS_EncodeString(JSContext *cx, JSString *str); - -/* - * Get number of bytes in the string encoding (without accounting for a - * terminating zero bytes. The function returns (size_t) -1 if the string - * can not be encoded into bytes and reports an error using cx accordingly. - */ -JS_PUBLIC_API(size_t) -JS_GetStringEncodingLength(JSContext *cx, JSString *str); - -/* - * Encode string into a buffer. The function does not stores an additional - * zero byte. The function returns (size_t) -1 if the string can not be - * encoded into bytes with no error reported. Otherwise it returns the number - * of bytes that are necessary to encode the string. If that exceeds the - * length parameter, the string will be cut and only length bytes will be - * written into the buffer. - * - * If JS_CStringsAreUTF8() is true, the string does not fit into the buffer - * and the the first length bytes ends in the middle of utf-8 encoding for - * some character, then such partial utf-8 encoding is replaced by zero bytes. - * This way the result always represents the valid UTF-8 sequence. - */ -JS_PUBLIC_API(size_t) -JS_EncodeStringToBuffer(JSString *str, char *buffer, size_t length); - -#ifdef __cplusplus - -class JSAutoByteString { - public: - JSAutoByteString(JSContext *cx, JSString *str JS_GUARD_OBJECT_NOTIFIER_PARAM) - : mBytes(JS_EncodeString(cx, str)) { - JS_ASSERT(cx); - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - - JSAutoByteString(JS_GUARD_OBJECT_NOTIFIER_PARAM0) - : mBytes(NULL) { - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - - ~JSAutoByteString() { - js_free(mBytes); - } - - /* Take ownership of the given byte array. */ - void initBytes(char *bytes) { - JS_ASSERT(!mBytes); - mBytes = bytes; - } - - char *encode(JSContext *cx, JSString *str) { - JS_ASSERT(!mBytes); - JS_ASSERT(cx); - mBytes = JS_EncodeString(cx, str); - return mBytes; - } - - void clear() { - js_free(mBytes); - mBytes = NULL; - } - - char *ptr() const { - return mBytes; - } - - bool operator!() const { - return !mBytes; - } - - private: - char *mBytes; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER - - /* Copy and assignment are not supported. */ - JSAutoByteString(const JSAutoByteString &another); - JSAutoByteString &operator=(const JSAutoByteString &another); -}; - -#endif - -/************************************************************************/ -/* - * JSON functions - */ -typedef JSBool (* JSONWriteCallback)(const jschar *buf, uint32 len, void *data); - -/* - * JSON.stringify as specified by ES3.1 (draft) - */ -JS_PUBLIC_API(JSBool) -JS_Stringify(JSContext *cx, jsval *vp, JSObject *replacer, jsval space, - JSONWriteCallback callback, void *data); - -/* - * Retrieve a toJSON function. If found, set vp to its result. - */ -JS_PUBLIC_API(JSBool) -JS_TryJSON(JSContext *cx, jsval *vp); - -/* - * JSON.parse as specified by ES3.1 (draft) - */ -JS_PUBLIC_API(JSONParser *) -JS_BeginJSONParse(JSContext *cx, jsval *vp); - -JS_PUBLIC_API(JSBool) -JS_ConsumeJSONText(JSContext *cx, JSONParser *jp, const jschar *data, uint32 len); - -JS_PUBLIC_API(JSBool) -JS_FinishJSONParse(JSContext *cx, JSONParser *jp, jsval reviver); - -/************************************************************************/ - -/* API for the HTML5 internal structured cloning algorithm. */ - -/* The maximum supported structured-clone serialization format version. */ -#define JS_STRUCTURED_CLONE_VERSION 1 - -struct JSStructuredCloneCallbacks { - ReadStructuredCloneOp read; - WriteStructuredCloneOp write; - StructuredCloneErrorOp reportError; -}; - -JS_PUBLIC_API(JSBool) -JS_ReadStructuredClone(JSContext *cx, const uint64 *data, size_t nbytes, - uint32 version, jsval *vp, - const JSStructuredCloneCallbacks *optionalCallbacks, - void *closure); - -/* Note: On success, the caller is responsible for calling js_free(*datap). */ -JS_PUBLIC_API(JSBool) -JS_WriteStructuredClone(JSContext *cx, jsval v, uint64 **datap, size_t *nbytesp, - const JSStructuredCloneCallbacks *optionalCallbacks, - void *closure); - -JS_PUBLIC_API(JSBool) -JS_StructuredClone(JSContext *cx, jsval v, jsval *vp, - const JSStructuredCloneCallbacks *optionalCallbacks, - void *closure); - -#ifdef __cplusplus -/* RAII sugar for JS_WriteStructuredClone. */ -class JSAutoStructuredCloneBuffer { - JSContext *cx_; - uint64 *data_; - size_t nbytes_; - uint32 version_; - - public: - JSAutoStructuredCloneBuffer() - : cx_(NULL), data_(NULL), nbytes_(0), version_(JS_STRUCTURED_CLONE_VERSION) {} - - ~JSAutoStructuredCloneBuffer() { clear(); } - - JSContext *cx() const { return cx_; } - uint64 *data() const { return data_; } - size_t nbytes() const { return nbytes_; } - - void clear(JSContext *cx=NULL) { - if (data_) { - if (!cx) - cx = cx_; - JS_ASSERT(cx); - JS_free(cx, data_); - cx_ = NULL; - data_ = NULL; - nbytes_ = 0; - version_ = 0; - } - } - - /* - * Adopt some memory. It will be automatically freed by the destructor. - * data must have been allocated using JS_malloc. - */ - void adopt(JSContext *cx, uint64 *data, size_t nbytes, - uint32 version=JS_STRUCTURED_CLONE_VERSION) { - clear(cx); - cx_ = cx; - data_ = data; - nbytes_ = nbytes; - version_ = version; - } - - /* - * Remove the buffer so that it will not be automatically freed. - * After this, the caller is responsible for calling JS_free(*datap). - */ - void steal(uint64 **datap, size_t *nbytesp, JSContext **cxp=NULL, - uint32 *versionp=NULL) { - *datap = data_; - *nbytesp = nbytes_; - if (cxp) - *cxp = cx_; - if (versionp) - *versionp = version_; - - cx_ = NULL; - data_ = NULL; - nbytes_ = 0; - version_ = 0; - } - - bool read(jsval *vp, JSContext *cx=NULL, - const JSStructuredCloneCallbacks *optionalCallbacks=NULL, - void *closure=NULL) const { - if (!cx) - cx = cx_; - JS_ASSERT(cx); - JS_ASSERT(data_); - return !!JS_ReadStructuredClone(cx, data_, nbytes_, version_, vp, - optionalCallbacks, closure); - } - - bool write(JSContext *cx, jsval v, - const JSStructuredCloneCallbacks *optionalCallbacks=NULL, - void *closure=NULL) { - clear(cx); - cx_ = cx; - bool ok = !!JS_WriteStructuredClone(cx, v, &data_, &nbytes_, - optionalCallbacks, closure); - if (!ok) { - data_ = NULL; - nbytes_ = 0; - version_ = JS_STRUCTURED_CLONE_VERSION; - } - return ok; - } - - /** - * Swap ownership with another JSAutoStructuredCloneBuffer. - */ - void swap(JSAutoStructuredCloneBuffer &other) { - JSContext *cx = other.cx_; - uint64 *data = other.data_; - size_t nbytes = other.nbytes_; - uint32 version = other.version_; - - other.cx_ = this->cx_; - other.data_ = this->data_; - other.nbytes_ = this->nbytes_; - other.version_ = this->version_; - - this->cx_ = cx; - this->data_ = data; - this->nbytes_ = nbytes; - this->version_ = version; - } - - private: - /* Copy and assignment are not supported. */ - JSAutoStructuredCloneBuffer(const JSAutoStructuredCloneBuffer &other); - JSAutoStructuredCloneBuffer &operator=(const JSAutoStructuredCloneBuffer &other); -}; -#endif - -/* API for implementing custom serialization behavior (for ImageData, File, etc.) */ - -/* The range of tag values the application may use for its own custom object types. */ -#define JS_SCTAG_USER_MIN ((uint32) 0xFFFF8000) -#define JS_SCTAG_USER_MAX ((uint32) 0xFFFFFFFF) - -#define JS_SCERR_RECURSION 0 - -JS_PUBLIC_API(void) -JS_SetStructuredCloneCallbacks(JSRuntime *rt, const JSStructuredCloneCallbacks *callbacks); - -JS_PUBLIC_API(JSBool) -JS_ReadUint32Pair(JSStructuredCloneReader *r, uint32 *p1, uint32 *p2); - -JS_PUBLIC_API(JSBool) -JS_ReadBytes(JSStructuredCloneReader *r, void *p, size_t len); - -JS_PUBLIC_API(JSBool) -JS_WriteUint32Pair(JSStructuredCloneWriter *w, uint32 tag, uint32 data); - -JS_PUBLIC_API(JSBool) -JS_WriteBytes(JSStructuredCloneWriter *w, const void *p, size_t len); - -/************************************************************************/ - -/* - * Locale specific string conversion and error message callbacks. - */ -struct JSLocaleCallbacks { - JSLocaleToUpperCase localeToUpperCase; - JSLocaleToLowerCase localeToLowerCase; - JSLocaleCompare localeCompare; - JSLocaleToUnicode localeToUnicode; - JSErrorCallback localeGetErrorMessage; -}; - -/* - * Establish locale callbacks. The pointer must persist as long as the - * JSContext. Passing NULL restores the default behaviour. - */ -extern JS_PUBLIC_API(void) -JS_SetLocaleCallbacks(JSContext *cx, JSLocaleCallbacks *callbacks); - -/* - * Return the address of the current locale callbacks struct, which may - * be NULL. - */ -extern JS_PUBLIC_API(JSLocaleCallbacks *) -JS_GetLocaleCallbacks(JSContext *cx); - -/************************************************************************/ - -/* - * Error reporting. - */ - -/* - * Report an exception represented by the sprintf-like conversion of format - * and its arguments. This exception message string is passed to a pre-set - * JSErrorReporter function (set by JS_SetErrorReporter; see jspubtd.h for - * the JSErrorReporter typedef). - */ -extern JS_PUBLIC_API(void) -JS_ReportError(JSContext *cx, const char *format, ...); - -/* - * Use an errorNumber to retrieve the format string, args are char * - */ -extern JS_PUBLIC_API(void) -JS_ReportErrorNumber(JSContext *cx, JSErrorCallback errorCallback, - void *userRef, const uintN errorNumber, ...); - -/* - * Use an errorNumber to retrieve the format string, args are jschar * - */ -extern JS_PUBLIC_API(void) -JS_ReportErrorNumberUC(JSContext *cx, JSErrorCallback errorCallback, - void *userRef, const uintN errorNumber, ...); - -/* - * As above, but report a warning instead (JSREPORT_IS_WARNING(report.flags)). - * Return true if there was no error trying to issue the warning, and if the - * warning was not converted into an error due to the JSOPTION_WERROR option - * being set, false otherwise. - */ -extern JS_PUBLIC_API(JSBool) -JS_ReportWarning(JSContext *cx, const char *format, ...); - -extern JS_PUBLIC_API(JSBool) -JS_ReportErrorFlagsAndNumber(JSContext *cx, uintN flags, - JSErrorCallback errorCallback, void *userRef, - const uintN errorNumber, ...); - -extern JS_PUBLIC_API(JSBool) -JS_ReportErrorFlagsAndNumberUC(JSContext *cx, uintN flags, - JSErrorCallback errorCallback, void *userRef, - const uintN errorNumber, ...); - -/* - * Complain when out of memory. - */ -extern JS_PUBLIC_API(void) -JS_ReportOutOfMemory(JSContext *cx); - -/* - * Complain when an allocation size overflows the maximum supported limit. - */ -extern JS_PUBLIC_API(void) -JS_ReportAllocationOverflow(JSContext *cx); - -struct JSErrorReport { - const char *filename; /* source file name, URL, etc., or null */ - uintN lineno; /* source line number */ - const char *linebuf; /* offending source line without final \n */ - const char *tokenptr; /* pointer to error token in linebuf */ - const jschar *uclinebuf; /* unicode (original) line buffer */ - const jschar *uctokenptr; /* unicode (original) token pointer */ - uintN flags; /* error/warning, etc. */ - uintN errorNumber; /* the error number, e.g. see js.msg */ - const jschar *ucmessage; /* the (default) error message */ - const jschar **messageArgs; /* arguments for the error message */ -}; - -/* - * JSErrorReport flag values. These may be freely composed. - */ -#define JSREPORT_ERROR 0x0 /* pseudo-flag for default case */ -#define JSREPORT_WARNING 0x1 /* reported via JS_ReportWarning */ -#define JSREPORT_EXCEPTION 0x2 /* exception was thrown */ -#define JSREPORT_STRICT 0x4 /* error or warning due to strict option */ - -/* - * This condition is an error in strict mode code, a warning if - * JS_HAS_STRICT_OPTION(cx), and otherwise should not be reported at - * all. We check the strictness of the context's top frame's script; - * where that isn't appropriate, the caller should do the right checks - * itself instead of using this flag. - */ -#define JSREPORT_STRICT_MODE_ERROR 0x8 - -/* - * If JSREPORT_EXCEPTION is set, then a JavaScript-catchable exception - * has been thrown for this runtime error, and the host should ignore it. - * Exception-aware hosts should also check for JS_IsExceptionPending if - * JS_ExecuteScript returns failure, and signal or propagate the exception, as - * appropriate. - */ -#define JSREPORT_IS_WARNING(flags) (((flags) & JSREPORT_WARNING) != 0) -#define JSREPORT_IS_EXCEPTION(flags) (((flags) & JSREPORT_EXCEPTION) != 0) -#define JSREPORT_IS_STRICT(flags) (((flags) & JSREPORT_STRICT) != 0) -#define JSREPORT_IS_STRICT_MODE_ERROR(flags) (((flags) & \ - JSREPORT_STRICT_MODE_ERROR) != 0) - -extern JS_PUBLIC_API(JSErrorReporter) -JS_SetErrorReporter(JSContext *cx, JSErrorReporter er); - -/************************************************************************/ - -/* - * Dates. - */ - -extern JS_PUBLIC_API(JSObject *) -JS_NewDateObject(JSContext *cx, int year, int mon, int mday, int hour, int min, int sec); - -extern JS_PUBLIC_API(JSObject *) -JS_NewDateObjectMsec(JSContext *cx, jsdouble msec); - -/* - * Infallible predicate to test whether obj is a date object. - */ -extern JS_PUBLIC_API(JSBool) -JS_ObjectIsDate(JSContext *cx, JSObject *obj); - -/************************************************************************/ - -/* - * Regular Expressions. - */ -#define JSREG_FOLD 0x01 /* fold uppercase to lowercase */ -#define JSREG_GLOB 0x02 /* global exec, creates array of matches */ -#define JSREG_MULTILINE 0x04 /* treat ^ and $ as begin and end of line */ -#define JSREG_STICKY 0x08 /* only match starting at lastIndex */ -#define JSREG_FLAT 0x10 /* parse as a flat regexp */ -#define JSREG_NOCOMPILE 0x20 /* do not try to compile to native code */ - -extern JS_PUBLIC_API(JSObject *) -JS_NewRegExpObject(JSContext *cx, JSObject *obj, char *bytes, size_t length, uintN flags); - -extern JS_PUBLIC_API(JSObject *) -JS_NewUCRegExpObject(JSContext *cx, JSObject *obj, jschar *chars, size_t length, uintN flags); - -extern JS_PUBLIC_API(void) -JS_SetRegExpInput(JSContext *cx, JSObject *obj, JSString *input, JSBool multiline); - -extern JS_PUBLIC_API(void) -JS_ClearRegExpStatics(JSContext *cx, JSObject *obj); - -extern JS_PUBLIC_API(JSBool) -JS_ExecuteRegExp(JSContext *cx, JSObject *obj, JSObject *reobj, jschar *chars, size_t length, - size_t *indexp, JSBool test, jsval *rval); - -/* RegExp interface for clients without a global object. */ - -extern JS_PUBLIC_API(JSObject *) -JS_NewRegExpObjectNoStatics(JSContext *cx, char *bytes, size_t length, uintN flags); - -extern JS_PUBLIC_API(JSObject *) -JS_NewUCRegExpObjectNoStatics(JSContext *cx, jschar *chars, size_t length, uintN flags); - -extern JS_PUBLIC_API(JSBool) -JS_ExecuteRegExpNoStatics(JSContext *cx, JSObject *reobj, jschar *chars, size_t length, - size_t *indexp, JSBool test, jsval *rval); - -/************************************************************************/ - -extern JS_PUBLIC_API(JSBool) -JS_IsExceptionPending(JSContext *cx); - -extern JS_PUBLIC_API(JSBool) -JS_GetPendingException(JSContext *cx, jsval *vp); - -extern JS_PUBLIC_API(void) -JS_SetPendingException(JSContext *cx, jsval v); - -extern JS_PUBLIC_API(void) -JS_ClearPendingException(JSContext *cx); - -extern JS_PUBLIC_API(JSBool) -JS_ReportPendingException(JSContext *cx); - -/* - * Save the current exception state. This takes a snapshot of cx's current - * exception state without making any change to that state. - * - * The returned state pointer MUST be passed later to JS_RestoreExceptionState - * (to restore that saved state, overriding any more recent state) or else to - * JS_DropExceptionState (to free the state struct in case it is not correct - * or desirable to restore it). Both Restore and Drop free the state struct, - * so callers must stop using the pointer returned from Save after calling the - * Release or Drop API. - */ -extern JS_PUBLIC_API(JSExceptionState *) -JS_SaveExceptionState(JSContext *cx); - -extern JS_PUBLIC_API(void) -JS_RestoreExceptionState(JSContext *cx, JSExceptionState *state); - -extern JS_PUBLIC_API(void) -JS_DropExceptionState(JSContext *cx, JSExceptionState *state); - -/* - * If the given value is an exception object that originated from an error, - * the exception will contain an error report struct, and this API will return - * the address of that struct. Otherwise, it returns NULL. The lifetime of - * the error report struct that might be returned is the same as the lifetime - * of the exception object. - */ -extern JS_PUBLIC_API(JSErrorReport *) -JS_ErrorFromException(JSContext *cx, jsval v); - -/* - * Given a reported error's message and JSErrorReport struct pointer, throw - * the corresponding exception on cx. - */ -extern JS_PUBLIC_API(JSBool) -JS_ThrowReportedError(JSContext *cx, const char *message, - JSErrorReport *reportp); - -/* - * Throws a StopIteration exception on cx. - */ -extern JS_PUBLIC_API(JSBool) -JS_ThrowStopIteration(JSContext *cx); - -/* - * Associate the current thread with the given context. This is done - * implicitly by JS_NewContext. - * - * Returns the old thread id for this context, which should be treated as - * an opaque value. This value is provided for comparison to 0, which - * indicates that ClearContextThread has been called on this context - * since the last SetContextThread, or non-0, which indicates the opposite. - */ -extern JS_PUBLIC_API(jsword) -JS_GetContextThread(JSContext *cx); - -extern JS_PUBLIC_API(jsword) -JS_SetContextThread(JSContext *cx); - -extern JS_PUBLIC_API(jsword) -JS_ClearContextThread(JSContext *cx); - -#ifdef MOZ_TRACE_JSCALLS -typedef void (*JSFunctionCallback)(const JSFunction *fun, - const JSScript *scr, - const JSContext *cx, - int entering); - -/* - * The callback is expected to be quick and noninvasive. It should not - * trigger interrupts, turn on debugging, or produce uncaught JS - * exceptions. The state of the stack and registers in the context - * cannot be relied upon, since this callback may be invoked directly - * from either JIT. The 'entering' field means we are entering a - * function if it is positive, leaving a function if it is zero or - * negative. - */ -extern JS_PUBLIC_API(void) -JS_SetFunctionCallback(JSContext *cx, JSFunctionCallback fcb); - -extern JS_PUBLIC_API(JSFunctionCallback) -JS_GetFunctionCallback(JSContext *cx); -#endif - -/************************************************************************/ - -/* - * JS_IsConstructing must be called from within a native given the - * native's original cx and vp arguments. If JS_IsConstructing is true, - * JS_THIS must not be used; the constructor should construct and return a - * new object. Otherwise, the native is called as an ordinary function and - * JS_THIS may be used. - */ -static JS_ALWAYS_INLINE JSBool -JS_IsConstructing(JSContext *cx, const jsval *vp) -{ - jsval_layout l; - -#ifdef DEBUG - JSObject *callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)); - if (JS_ObjectIsFunction(cx, callee)) { - JSFunction *fun = JS_ValueToFunction(cx, JS_CALLEE(cx, vp)); - JS_ASSERT((JS_GetFunctionFlags(fun) & JSFUN_CONSTRUCTOR) != 0); - } else { - JS_ASSERT(JS_GET_CLASS(cx, callee)->construct != NULL); - } -#endif - - l.asBits = JSVAL_BITS(vp[1]); - return JSVAL_IS_MAGIC_IMPL(l); -} - -/* - * In the case of a constructor called from JS_ConstructObject and - * JS_InitClass where the class has the JSCLASS_CONSTRUCT_PROTOTYPE flag set, - * the JS engine passes the constructor a non-standard 'this' object. In such - * cases, the following query provides the additional information of whether a - * special 'this' was supplied. E.g.: - * - * JSBool foo_native(JSContext *cx, uintN argc, jsval *vp) { - * JSObject *maybeThis; - * if (JS_IsConstructing_PossiblyWithGivenThisObject(cx, vp, &maybeThis)) { - * // native called as a constructor - * if (maybeThis) - * // native called as a constructor with maybeThis as 'this' - * } else { - * // native called as function, maybeThis is still uninitialized - * } - * } - * - * Note that embeddings do not need to use this query unless they use the - * aforementioned API/flags. - */ -static JS_ALWAYS_INLINE JSBool -JS_IsConstructing_PossiblyWithGivenThisObject(JSContext *cx, const jsval *vp, - JSObject **maybeThis) -{ - jsval_layout l; - JSBool isCtor; - -#ifdef DEBUG - JSObject *callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)); - if (JS_ObjectIsFunction(cx, callee)) { - JSFunction *fun = JS_ValueToFunction(cx, JS_CALLEE(cx, vp)); - JS_ASSERT((JS_GetFunctionFlags(fun) & JSFUN_CONSTRUCTOR) != 0); - } else { - JS_ASSERT(JS_GET_CLASS(cx, callee)->construct != NULL); - } -#endif - - l.asBits = JSVAL_BITS(vp[1]); - isCtor = JSVAL_IS_MAGIC_IMPL(l); - if (isCtor) - *maybeThis = MAGIC_JSVAL_TO_OBJECT_OR_NULL_IMPL(l); - return isCtor; -} - -/* - * If a constructor does not have any static knowledge about the type of - * object to create, it can request that the JS engine create a default new - * 'this' object, as is done for non-constructor natives when called with new. - */ -extern JS_PUBLIC_API(JSObject *) -JS_NewObjectForConstructor(JSContext *cx, const jsval *vp); - -/************************************************************************/ - -#ifdef DEBUG -#define JS_GC_ZEAL 1 -#endif - -#ifdef JS_GC_ZEAL -extern JS_PUBLIC_API(void) -JS_SetGCZeal(JSContext *cx, uint8 zeal); -#endif - -JS_END_EXTERN_C - -#endif /* jsapi_h___ */ diff --git a/x86/mozilla/include/jsarena.h b/x86/mozilla/include/jsarena.h deleted file mode 100644 index 6eeb04a..0000000 --- a/x86/mozilla/include/jsarena.h +++ /dev/null @@ -1,291 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsarena_h___ -#define jsarena_h___ -/* - * Lifetime-based fast allocation, inspired by much prior art, including - * "Fast Allocation and Deallocation of Memory Based on Object Lifetimes" - * David R. Hanson, Software -- Practice and Experience, Vol. 20(1). - * - * Also supports LIFO allocation (JS_ARENA_MARK/JS_ARENA_RELEASE). - */ -#include -#include "jstypes.h" -#include "jscompat.h" - -JS_BEGIN_EXTERN_C - -typedef struct JSArena JSArena; -typedef struct JSArenaPool JSArenaPool; - -struct JSArena { - JSArena *next; /* next arena for this lifetime */ - jsuword base; /* aligned base address, follows this header */ - jsuword limit; /* one beyond last byte in arena */ - jsuword avail; /* points to next available byte */ -}; - -#ifdef JS_ARENAMETER -typedef struct JSArenaStats JSArenaStats; - -struct JSArenaStats { - JSArenaStats *next; /* next in arenaStats list */ - char *name; /* name for debugging */ - uint32 narenas; /* number of arenas in pool */ - uint32 nallocs; /* number of JS_ARENA_ALLOCATE() calls */ - uint32 nmallocs; /* number of malloc() calls */ - uint32 ndeallocs; /* number of lifetime deallocations */ - uint32 ngrows; /* number of JS_ARENA_GROW() calls */ - uint32 ninplace; /* number of in-place growths */ - uint32 nreallocs; /* number of arena grow extending reallocs */ - uint32 nreleases; /* number of JS_ARENA_RELEASE() calls */ - uint32 nfastrels; /* number of "fast path" releases */ - size_t nbytes; /* total bytes allocated */ - size_t maxalloc; /* maximum allocation size in bytes */ - double variance; /* size variance accumulator */ -}; -#endif - -struct JSArenaPool { - JSArena first; /* first arena in pool list */ - JSArena *current; /* arena from which to allocate space */ - size_t arenasize; /* net exact size of a new arena */ - jsuword mask; /* alignment mask (power-of-2 - 1) */ - size_t *quotap; /* pointer to the quota on pool allocation - size or null if pool is unlimited */ -#ifdef JS_ARENAMETER - JSArenaStats stats; -#endif -}; - -#define JS_ARENA_ALIGN(pool, n) (((jsuword)(n) + (pool)->mask) & ~(pool)->mask) - -#define JS_ARENA_ALLOCATE(p, pool, nb) \ - JS_ARENA_ALLOCATE_CAST(p, void *, pool, nb) - -#define JS_ARENA_ALLOCATE_TYPE(p, type, pool) \ - JS_ARENA_ALLOCATE_COMMON(p, type *, pool, sizeof(type), 0) - -#define JS_ARENA_ALLOCATE_CAST(p, type, pool, nb) \ - JS_ARENA_ALLOCATE_COMMON(p, type, pool, nb, _nb > _a->limit) - -/* - * NB: In JS_ARENA_ALLOCATE_CAST and JS_ARENA_GROW_CAST, always subtract _nb - * from a->limit rather than adding _nb to _p, to avoid overflowing a 32-bit - * address space (possible when running a 32-bit program on a 64-bit system - * where the kernel maps the heap up against the top of the 32-bit address - * space). - * - * Thanks to Juergen Kreileder , who brought this up in - * https://bugzilla.mozilla.org/show_bug.cgi?id=279273. - */ -#define JS_ARENA_ALLOCATE_COMMON(p, type, pool, nb, guard) \ - JS_BEGIN_MACRO \ - JSArena *_a = (pool)->current; \ - size_t _nb = JS_ARENA_ALIGN(pool, nb); \ - jsuword _p = _a->avail; \ - if ((guard) || _p > _a->limit - _nb) \ - _p = (jsuword)JS_ArenaAllocate(pool, _nb); \ - else \ - _a->avail = _p + _nb; \ - p = (type) _p; \ - STATIC_ASSUME(!p || ubound((char *)p) >= nb) \ - JS_ArenaCountAllocation(pool, nb); \ - JS_END_MACRO - -#define JS_ARENA_GROW(p, pool, size, incr) \ - JS_ARENA_GROW_CAST(p, void *, pool, size, incr) - -#define JS_ARENA_GROW_CAST(p, type, pool, size, incr) \ - JS_BEGIN_MACRO \ - JSArena *_a = (pool)->current; \ - if (_a->avail == (jsuword)(p) + JS_ARENA_ALIGN(pool, size)) { \ - size_t _nb = (size) + (incr); \ - _nb = JS_ARENA_ALIGN(pool, _nb); \ - if (_a->limit >= _nb && (jsuword)(p) <= _a->limit - _nb) { \ - _a->avail = (jsuword)(p) + _nb; \ - JS_ArenaCountInplaceGrowth(pool, size, incr); \ - } else if ((jsuword)(p) == _a->base) { \ - p = (type) JS_ArenaRealloc(pool, p, size, incr); \ - } else { \ - p = (type) JS_ArenaGrow(pool, p, size, incr); \ - } \ - } else { \ - p = (type) JS_ArenaGrow(pool, p, size, incr); \ - } \ - STATIC_ASSUME(!p || ubound((char *)p) >= size + incr); \ - JS_ArenaCountGrowth(pool, size, incr); \ - JS_END_MACRO - -#define JS_ARENA_MARK(pool) ((void *) (pool)->current->avail) -#define JS_UPTRDIFF(p,q) ((jsuword)(p) - (jsuword)(q)) - -/* - * Check if the mark is inside arena's allocated area. - */ -#define JS_ARENA_MARK_MATCH(a, mark) \ - (JS_UPTRDIFF(mark, (a)->base) <= JS_UPTRDIFF((a)->avail, (a)->base)) - -#ifdef DEBUG -#define JS_FREE_PATTERN 0xDA -#define JS_CLEAR_UNUSED(a) (JS_ASSERT((a)->avail <= (a)->limit), \ - memset((void*)(a)->avail, JS_FREE_PATTERN, \ - (a)->limit - (a)->avail)) -#define JS_CLEAR_ARENA(a) memset((void*)(a), JS_FREE_PATTERN, \ - (a)->limit - (jsuword)(a)) -#else -#define JS_CLEAR_UNUSED(a) /* nothing */ -#define JS_CLEAR_ARENA(a) /* nothing */ -#endif - -#define JS_ARENA_RELEASE(pool, mark) \ - JS_BEGIN_MACRO \ - char *_m = (char *)(mark); \ - JSArena *_a = (pool)->current; \ - if (_a != &(pool)->first && JS_ARENA_MARK_MATCH(_a, _m)) { \ - _a->avail = (jsuword)JS_ARENA_ALIGN(pool, _m); \ - JS_ASSERT(_a->avail <= _a->limit); \ - JS_CLEAR_UNUSED(_a); \ - JS_ArenaCountRetract(pool, _m); \ - } else { \ - JS_ArenaRelease(pool, _m); \ - } \ - JS_ArenaCountRelease(pool, _m); \ - JS_END_MACRO - -#ifdef JS_ARENAMETER -#define JS_COUNT_ARENA(pool,op) ((pool)->stats.narenas op) -#else -#define JS_COUNT_ARENA(pool,op) -#endif - -#define JS_ARENA_DESTROY(pool, a, pnext) \ - JS_BEGIN_MACRO \ - JS_COUNT_ARENA(pool,--); \ - if ((pool)->current == (a)) (pool)->current = &(pool)->first; \ - *(pnext) = (a)->next; \ - JS_CLEAR_ARENA(a); \ - js_free(a); \ - (a) = NULL; \ - JS_END_MACRO - -/* - * Initialize an arena pool with a minimum size per arena of size bytes. - */ -extern JS_PUBLIC_API(void) -JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size, - size_t align, size_t *quotap); - -/* - * Free the arenas in pool. The user may continue to allocate from pool - * after calling this function. There is no need to call JS_InitArenaPool() - * again unless JS_FinishArenaPool(pool) has been called. - */ -extern JS_PUBLIC_API(void) -JS_FreeArenaPool(JSArenaPool *pool); - -/* - * Free the arenas in pool and finish using it altogether. - */ -extern JS_PUBLIC_API(void) -JS_FinishArenaPool(JSArenaPool *pool); - -/* - * Deprecated do-nothing function. - */ -extern JS_PUBLIC_API(void) -JS_ArenaFinish(void); - -/* - * Deprecated do-nothing function. - */ -extern JS_PUBLIC_API(void) -JS_ArenaShutDown(void); - -/* - * Friend functions used by the JS_ARENA_*() macros. - */ -extern JS_PUBLIC_API(void *) -JS_ArenaAllocate(JSArenaPool *pool, size_t nb); - -extern JS_PUBLIC_API(void *) -JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr); - -extern JS_PUBLIC_API(void *) -JS_ArenaGrow(JSArenaPool *pool, void *p, size_t size, size_t incr); - -extern JS_PUBLIC_API(void) -JS_ArenaRelease(JSArenaPool *pool, char *mark); - -#ifdef JS_ARENAMETER - -#include - -extern JS_PUBLIC_API(void) -JS_ArenaCountAllocation(JSArenaPool *pool, size_t nb); - -extern JS_PUBLIC_API(void) -JS_ArenaCountInplaceGrowth(JSArenaPool *pool, size_t size, size_t incr); - -extern JS_PUBLIC_API(void) -JS_ArenaCountGrowth(JSArenaPool *pool, size_t size, size_t incr); - -extern JS_PUBLIC_API(void) -JS_ArenaCountRelease(JSArenaPool *pool, char *mark); - -extern JS_PUBLIC_API(void) -JS_ArenaCountRetract(JSArenaPool *pool, char *mark); - -extern JS_PUBLIC_API(void) -JS_DumpArenaStats(FILE *fp); - -#else /* !JS_ARENAMETER */ - -#define JS_ArenaCountAllocation(ap, nb) /* nothing */ -#define JS_ArenaCountInplaceGrowth(ap, size, incr) /* nothing */ -#define JS_ArenaCountGrowth(ap, size, incr) /* nothing */ -#define JS_ArenaCountRelease(ap, mark) /* nothing */ -#define JS_ArenaCountRetract(ap, mark) /* nothing */ - -#endif /* !JS_ARENAMETER */ - -JS_END_EXTERN_C - -#endif /* jsarena_h___ */ diff --git a/x86/mozilla/include/jsarray.h b/x86/mozilla/include/jsarray.h deleted file mode 100644 index a230b50..0000000 --- a/x86/mozilla/include/jsarray.h +++ /dev/null @@ -1,342 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsarray_h___ -#define jsarray_h___ -/* - * JS Array interface. - */ -#include "jsprvtd.h" -#include "jspubtd.h" -#include "jsatom.h" -#include "jsobj.h" -#include "jsstr.h" - -/* Small arrays are dense, no matter what. */ -const uintN MIN_SPARSE_INDEX = 256; - -inline JSObject::EnsureDenseResult -JSObject::ensureDenseArrayElements(JSContext *cx, uintN index, uintN extra) -{ - JS_ASSERT(isDenseArray()); - uintN currentCapacity = numSlots(); - - uintN requiredCapacity; - if (extra == 1) { - /* Optimize for the common case. */ - if (index < currentCapacity) - return ED_OK; - requiredCapacity = index + 1; - if (requiredCapacity == 0) { - /* Overflow. */ - return ED_SPARSE; - } - } else { - requiredCapacity = index + extra; - if (requiredCapacity < index) { - /* Overflow. */ - return ED_SPARSE; - } - if (requiredCapacity <= currentCapacity) - return ED_OK; - } - - /* - * We use the extra argument also as a hint about number of non-hole - * elements to be inserted. - */ - if (requiredCapacity > MIN_SPARSE_INDEX && - willBeSparseDenseArray(requiredCapacity, extra)) { - return ED_SPARSE; - } - return growSlots(cx, requiredCapacity) ? ED_OK : ED_FAILED; -} - -extern bool -js_StringIsIndex(JSLinearString *str, jsuint *indexp); - -inline JSBool -js_IdIsIndex(jsid id, jsuint *indexp) -{ - if (JSID_IS_INT(id)) { - jsint i; - i = JSID_TO_INT(id); - if (i < 0) - return JS_FALSE; - *indexp = (jsuint)i; - return JS_TRUE; - } - - if (JS_UNLIKELY(!JSID_IS_STRING(id))) - return JS_FALSE; - - return js_StringIsIndex(JSID_TO_ATOM(id), indexp); -} - -/* XML really wants to pretend jsvals are jsids. */ -inline bool -js_IdValIsIndex(JSContext *cx, jsval id, jsuint *indexp, bool *isIndex) -{ - if (JSVAL_IS_INT(id)) { - jsint i; - i = JSVAL_TO_INT(id); - if (i < 0) { - *isIndex = false; - return true; - } - *indexp = (jsuint)i; - *isIndex = true; - return true; - } - - if (!JSVAL_IS_STRING(id)) { - *isIndex = false; - return true; - } - - JSLinearString *str = JSVAL_TO_STRING(id)->ensureLinear(cx); - if (!str) - return false; - - *isIndex = js_StringIsIndex(str, indexp); - return true; -} - -extern js::Class js_ArrayClass, js_SlowArrayClass; - -inline bool -JSObject::isDenseArray() const -{ - return getClass() == &js_ArrayClass; -} - -inline bool -JSObject::isSlowArray() const -{ - return getClass() == &js_SlowArrayClass; -} - -inline bool -JSObject::isArray() const -{ - return isDenseArray() || isSlowArray(); -} - -/* - * Dense arrays are not native -- aobj->isNative() for a dense array aobj - * results in false, meaning aobj->map does not point to a js::Shape. - * - * But Array methods are called via aobj.sort(), e.g., and the interpreter and - * the trace recorder must consult the property cache in order to perform well. - * The cache works only for native objects. - * - * Therefore the interpreter (js_Interpret in JSOP_GETPROP and JSOP_CALLPROP) - * and js_GetPropertyHelper use this inline function to skip up one link in the - * prototype chain when obj is a dense array, in order to find a native object - * (to wit, Array.prototype) in which to probe for cached methods. - * - * Note that setting aobj.__proto__ for a dense array aobj turns aobj into a - * slow array, avoiding the neede to skip. - * - * Callers of js_GetProtoIfDenseArray must take care to use the original object - * (obj) for the |this| value of a getter, setter, or method call (bug 476447). - */ -static JS_INLINE JSObject * -js_GetProtoIfDenseArray(JSObject *obj) -{ - return obj->isDenseArray() ? obj->getProto() : obj; -} - -extern JSObject * -js_InitArrayClass(JSContext *cx, JSObject *obj); - -extern bool -js_InitContextBusyArrayTable(JSContext *cx); - -namespace js -{ - -/* Create a dense array with no capacity allocated, length set to 0. */ -extern JSObject * JS_FASTCALL -NewDenseEmptyArray(JSContext *cx, JSObject *proto=NULL); - -/* Create a dense array with length and capacity == 'length'. */ -extern JSObject * JS_FASTCALL -NewDenseAllocatedArray(JSContext *cx, uint length, JSObject *proto=NULL); - -/* - * Create a dense array with a set length, but without allocating space for the - * contents. This is useful, e.g., when accepting length from the user. - */ -extern JSObject * JS_FASTCALL -NewDenseUnallocatedArray(JSContext *cx, uint length, JSObject *proto=NULL); - -/* Create a dense array with a copy of vp. */ -extern JSObject * -NewDenseCopiedArray(JSContext *cx, uint length, Value *vp, JSObject *proto=NULL); - -/* Create a sparse array. */ -extern JSObject * -NewSlowEmptyArray(JSContext *cx); - -} - -extern JSBool -js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp); - -extern JSBool -js_SetLengthProperty(JSContext *cx, JSObject *obj, jsdouble length); - -extern JSBool -js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp); - -extern JSBool JS_FASTCALL -js_IndexToId(JSContext *cx, jsuint index, jsid *idp); - -namespace js { - -/* - * This function assumes 'length' is effectively the result of calling - * js_GetLengthProperty on aobj. - */ -extern bool -GetElements(JSContext *cx, JSObject *aobj, jsuint length, js::Value *vp); - -} - -/* - * JS-specific merge sort function. - */ -typedef JSBool (*JSComparator)(void *arg, const void *a, const void *b, - int *result); - -enum JSMergeSortElemType { - JS_SORTING_VALUES, - JS_SORTING_GENERIC -}; - -/* - * NB: vec is the array to be sorted, tmp is temporary space at least as big - * as vec. Both should be GC-rooted if appropriate. - * - * isValue should true iff vec points to an array of js::Value - * - * The sorted result is in vec. vec may be in an inconsistent state if the - * comparator function cmp returns an error inside a comparison, so remember - * to check the return value of this function. - */ -extern bool -js_MergeSort(void *vec, size_t nel, size_t elsize, JSComparator cmp, - void *arg, void *tmp, JSMergeSortElemType elemType); - -/* - * The Array.prototype.sort fast-native entry point is exported for joined - * function optimization in js{interp,tracer}.cpp. - */ -namespace js { -extern JSBool -array_sort(JSContext *cx, uintN argc, js::Value *vp); -} - -#ifdef DEBUG -extern JSBool -js_ArrayInfo(JSContext *cx, uintN argc, jsval *vp); -#endif - -extern JSBool -js_ArrayCompPush(JSContext *cx, JSObject *obj, const js::Value &vp); - -/* - * Fast dense-array-to-buffer conversion for use by canvas. - * - * If the array is a dense array, fill [offset..offset+count] values into - * destination, assuming that types are consistent. Return JS_TRUE if - * successful, otherwise JS_FALSE -- note that the destination buffer may be - * modified even if JS_FALSE is returned (e.g. due to finding an inappropriate - * type later on in the array). If JS_FALSE is returned, no error conditions - * or exceptions are set on the context. - * - * This method succeeds if each element of the array is an integer or a double. - * Values outside the 0-255 range are clamped to that range. Double values are - * converted to integers in this range by clamping and then rounding to - * nearest, ties to even. - */ - -JS_FRIEND_API(JSBool) -js_CoerceArrayToCanvasImageData(JSObject *obj, jsuint offset, jsuint count, - JSUint8 *dest); - -JSBool -js_PrototypeHasIndexedProperties(JSContext *cx, JSObject *obj); - -/* - * Utility to access the value from the id returned by array_lookupProperty. - */ -JSBool -js_GetDenseArrayElementValue(JSContext *cx, JSObject *obj, jsid id, - js::Value *vp); - -/* Array constructor native. Exposed only so the JIT can know its address. */ -JSBool -js_Array(JSContext *cx, uintN argc, js::Value *vp); - -/* - * Makes a fast clone of a dense array as long as the array only contains - * primitive values. - * - * If the return value is JS_FALSE then clone will not be set. - * - * If the return value is JS_TRUE then clone will either be set to the address - * of a new JSObject or to NULL if the array was not dense or contained values - * that were not primitives. - */ -JS_FRIEND_API(JSBool) -js_CloneDensePrimitiveArray(JSContext *cx, JSObject *obj, JSObject **clone); - -/* - * Returns JS_TRUE if the given object is a dense array that contains only - * primitive values. - */ -JS_FRIEND_API(JSBool) -js_IsDensePrimitiveArray(JSObject *obj); - -extern JSBool JS_FASTCALL -js_EnsureDenseArrayCapacity(JSContext *cx, JSObject *obj, jsint i); - -#endif /* jsarray_h___ */ diff --git a/x86/mozilla/include/jsatom.h b/x86/mozilla/include/jsatom.h deleted file mode 100644 index ced0ebc..0000000 --- a/x86/mozilla/include/jsatom.h +++ /dev/null @@ -1,614 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsatom_h___ -#define jsatom_h___ -/* - * JS atom table. - */ -#include -#include "jsversion.h" -#include "jsapi.h" -#include "jsprvtd.h" -#include "jshash.h" -#include "jshashtable.h" -#include "jspubtd.h" -#include "jsstr.h" -#include "jslock.h" -#include "jsvalue.h" - -#define ATOM_PINNED 0x1 /* atom is pinned against GC */ -#define ATOM_INTERNED 0x2 /* pinned variant for JS_Intern* API */ -#define ATOM_NOCOPY 0x4 /* don't copy atom string bytes */ -#define ATOM_TMPSTR 0x8 /* internal, to avoid extra string */ - -#define STRING_TO_ATOM(str) (JS_ASSERT(str->isAtomized()), \ - (JSAtom *)str) -#define ATOM_TO_STRING(atom) (atom) -#define ATOM_TO_JSVAL(atom) STRING_TO_JSVAL(ATOM_TO_STRING(atom)) - -/* Engine-internal extensions of jsid */ - -static JS_ALWAYS_INLINE jsid -JSID_FROM_BITS(size_t bits) -{ - jsid id; - JSID_BITS(id) = bits; - return id; -} - -static JS_ALWAYS_INLINE jsid -ATOM_TO_JSID(JSAtom *atom) -{ - JS_ASSERT(((size_t)atom & 0x7) == 0); - return JSID_FROM_BITS((size_t)atom); -} - -/* All strings stored in jsids are atomized. */ -static JS_ALWAYS_INLINE JSBool -JSID_IS_ATOM(jsid id) -{ - return JSID_IS_STRING(id); -} - -static JS_ALWAYS_INLINE JSBool -JSID_IS_ATOM(jsid id, JSAtom *atom) -{ - return JSID_BITS(id) == JSID_BITS(ATOM_TO_JSID(atom)); -} - -static JS_ALWAYS_INLINE JSAtom * -JSID_TO_ATOM(jsid id) -{ - return (JSAtom *)JSID_TO_STRING(id); -} - -namespace js { - -static JS_ALWAYS_INLINE Value -IdToValue(jsid id) -{ - if (JSID_IS_STRING(id)) - return StringValue(JSID_TO_STRING(id)); - if (JS_LIKELY(JSID_IS_INT(id))) - return Int32Value(JSID_TO_INT(id)); - if (JS_LIKELY(JSID_IS_OBJECT(id))) - return ObjectValue(*JSID_TO_OBJECT(id)); - JS_ASSERT(JSID_IS_DEFAULT_XML_NAMESPACE(id) || JSID_IS_VOID(id)); - return UndefinedValue(); -} - -static JS_ALWAYS_INLINE jsval -IdToJsval(jsid id) -{ - return Jsvalify(IdToValue(id)); -} - -} - -#if JS_BYTES_PER_WORD == 4 -# define ATOM_HASH(atom) ((JSHashNumber)(atom) >> 2) -#elif JS_BYTES_PER_WORD == 8 -# define ATOM_HASH(atom) (((JSHashNumber)(jsuword)(atom) >> 3) ^ \ - (JSHashNumber)((jsuword)(atom) >> 32)) -#else -# error "Unsupported configuration" -#endif - -/* - * Return a printable, lossless char[] representation of a string-type atom. - * The lifetime of the result matches the lifetime of bytes. - */ -extern const char * -js_AtomToPrintableString(JSContext *cx, JSAtom *atom, JSAutoByteString *bytes); - -struct JSAtomListElement { - JSHashEntry entry; -}; - -#define ALE_ATOM(ale) ((JSAtom *) (ale)->entry.key) -#define ALE_INDEX(ale) (jsatomid(uintptr_t((ale)->entry.value))) -#define ALE_VALUE(ale) ((jsboxedword) (ale)->entry.value) -#define ALE_NEXT(ale) ((JSAtomListElement *) (ale)->entry.next) - -/* - * In an upvars list, ALE_DEFN(ale)->resolve() is the outermost definition the - * name may reference. If a with block or a function that calls eval encloses - * the use, the name may end up referring to something else at runtime. - */ -#define ALE_DEFN(ale) ((JSDefinition *) (ale)->entry.value) - -#define ALE_SET_ATOM(ale,atom) ((ale)->entry.key = (const void *)(atom)) -#define ALE_SET_INDEX(ale,index)((ale)->entry.value = (void *)(index)) -#define ALE_SET_DEFN(ale, dn) ((ale)->entry.value = (void *)(dn)) -#define ALE_SET_VALUE(ale, v) ((ale)->entry.value = (void *)(v)) -#define ALE_SET_NEXT(ale,nxt) ((ale)->entry.next = (JSHashEntry *)(nxt)) - -/* - * NB: JSAtomSet must be plain-old-data as it is embedded in the pn_u union in - * JSParseNode. JSAtomList encapsulates all operational uses of a JSAtomSet. - * - * The JSAtomList name is traditional, even though the implementation is a map - * (not to be confused with JSAtomMap). In particular the "ALE" and "ale" short - * names for JSAtomListElement variables roll off the fingers, compared to ASE - * or AME alternatives. - */ -struct JSAtomSet { - JSHashEntry *list; /* literals indexed for mapping */ - JSHashTable *table; /* hash table if list gets too long */ - jsuint count; /* count of indexed literals */ -}; - -struct JSAtomList : public JSAtomSet -{ -#ifdef DEBUG - const JSAtomSet* set; /* asserted null in mutating methods */ -#endif - - JSAtomList() { - list = NULL; table = NULL; count = 0; -#ifdef DEBUG - set = NULL; -#endif - } - - JSAtomList(const JSAtomSet& as) { - list = as.list; table = as.table; count = as.count; -#ifdef DEBUG - set = &as; -#endif - } - - void clear() { JS_ASSERT(!set); list = NULL; table = NULL; count = 0; } - - JSAtomListElement *lookup(JSAtom *atom) { - JSHashEntry **hep; - return rawLookup(atom, hep); - } - - JSAtomListElement *rawLookup(JSAtom *atom, JSHashEntry **&hep); - - enum AddHow { UNIQUE, SHADOW, HOIST }; - - JSAtomListElement *add(js::Parser *parser, JSAtom *atom, AddHow how = UNIQUE); - - void remove(js::Parser *parser, JSAtom *atom) { - JSHashEntry **hep; - JSAtomListElement *ale = rawLookup(atom, hep); - if (ale) - rawRemove(parser, ale, hep); - } - - void rawRemove(js::Parser *parser, JSAtomListElement *ale, JSHashEntry **hep); -}; - -/* - * A subclass of JSAtomList with a destructor. This atom list owns its - * hash table and its entries, but no keys or values. - */ -struct JSAutoAtomList: public JSAtomList -{ - JSAutoAtomList(js::Parser *p): parser(p) {} - ~JSAutoAtomList(); - private: - js::Parser *parser; /* For freeing list entries. */ -}; - -/* - * Iterate over an atom list. We define a call operator to minimize the syntax - * tax for users. We do not use a more standard pattern using ++ and * because - * (a) it's the wrong pattern for a non-scalar; (b) it's overkill -- one method - * is enough. (This comment is overkill!) - */ -class JSAtomListIterator { - JSAtomList* list; - JSAtomListElement* next; - uint32 index; - - public: - JSAtomListIterator(JSAtomList* al) : list(al) { reset(); } - - void reset() { - next = (JSAtomListElement *) list->list; - index = 0; - } - - JSAtomListElement* operator ()(); -}; - -struct JSAtomMap { - JSAtom **vector; /* array of ptrs to indexed atoms */ - jsatomid length; /* count of (to-be-)indexed atoms */ -}; - -namespace js { - -#define ATOM_ENTRY_FLAG_MASK ((size_t)(ATOM_PINNED | ATOM_INTERNED)) - -JS_STATIC_ASSERT(ATOM_ENTRY_FLAG_MASK < JS_GCTHING_ALIGN); - -typedef uintptr_t AtomEntryType; - -static JS_ALWAYS_INLINE JSAtom * -AtomEntryToKey(AtomEntryType entry) -{ - JS_ASSERT(entry != 0); - return (JSAtom *)(entry & ~ATOM_ENTRY_FLAG_MASK); -} - -struct AtomHasher -{ - typedef JSLinearString *Lookup; - - static HashNumber hash(JSLinearString *str) { - return js_HashString(str); - } - - static bool match(AtomEntryType entry, JSLinearString *lookup) { - return entry ? EqualStrings(AtomEntryToKey(entry), lookup) : false; - } -}; - -typedef HashSet AtomSet; - -} /* namespace js */ - -struct JSAtomState -{ - js::AtomSet atoms; - -#ifdef JS_THREADSAFE - JSThinLock lock; -#endif - - /* - * From this point until the end of struct definition the struct must - * contain only JSAtom fields. We use this to access the storage occupied - * by the common atoms in js_FinishCommonAtoms. - * - * js_common_atom_names defined in jsatom.c contains C strings for atoms - * in the order of atom fields here. Therefore you must update that array - * if you change member order here. - */ - - /* The rt->emptyString atom, see jsstr.c's js_InitRuntimeStringState. */ - JSAtom *emptyAtom; - - /* - * Literal value and type names. - * NB: booleanAtoms must come right before typeAtoms! - */ - JSAtom *booleanAtoms[2]; - JSAtom *typeAtoms[JSTYPE_LIMIT]; - JSAtom *nullAtom; - - /* Standard class constructor or prototype names. */ - JSAtom *classAtoms[JSProto_LIMIT]; - - /* Various built-in or commonly-used atoms, pinned on first context. */ - JSAtom *anonymousAtom; - JSAtom *applyAtom; - JSAtom *argumentsAtom; - JSAtom *arityAtom; - JSAtom *callAtom; - JSAtom *calleeAtom; - JSAtom *callerAtom; - JSAtom *classPrototypeAtom; - JSAtom *constructorAtom; - JSAtom *eachAtom; - JSAtom *evalAtom; - JSAtom *fileNameAtom; - JSAtom *getAtom; - JSAtom *globalAtom; - JSAtom *ignoreCaseAtom; - JSAtom *indexAtom; - JSAtom *inputAtom; - JSAtom *toISOStringAtom; - JSAtom *iteratorAtom; - JSAtom *joinAtom; - JSAtom *lastIndexAtom; - JSAtom *lengthAtom; - JSAtom *lineNumberAtom; - JSAtom *messageAtom; - JSAtom *multilineAtom; - JSAtom *nameAtom; - JSAtom *nextAtom; - JSAtom *noSuchMethodAtom; - JSAtom *objectNullAtom; - JSAtom *objectUndefinedAtom; - JSAtom *protoAtom; - JSAtom *setAtom; - JSAtom *sourceAtom; - JSAtom *stackAtom; - JSAtom *stickyAtom; - JSAtom *toGMTStringAtom; - JSAtom *toLocaleStringAtom; - JSAtom *toSourceAtom; - JSAtom *toStringAtom; - JSAtom *toUTCStringAtom; - JSAtom *valueOfAtom; - JSAtom *toJSONAtom; - JSAtom *void0Atom; - JSAtom *enumerableAtom; - JSAtom *configurableAtom; - JSAtom *writableAtom; - JSAtom *valueAtom; - JSAtom *testAtom; - JSAtom *useStrictAtom; - JSAtom *locAtom; - JSAtom *lineAtom; - JSAtom *InfinityAtom; - JSAtom *NaNAtom; - JSAtom *builderAtom; - -#if JS_HAS_XML_SUPPORT - JSAtom *etagoAtom; - JSAtom *namespaceAtom; - JSAtom *ptagcAtom; - JSAtom *qualifierAtom; - JSAtom *spaceAtom; - JSAtom *stagoAtom; - JSAtom *starAtom; - JSAtom *starQualifierAtom; - JSAtom *tagcAtom; - JSAtom *xmlAtom; - - /* Represents an invalid URI, for internal use only. */ - JSAtom *functionNamespaceURIAtom; -#endif - - JSAtom *ProxyAtom; - - JSAtom *getOwnPropertyDescriptorAtom; - JSAtom *getPropertyDescriptorAtom; - JSAtom *definePropertyAtom; - JSAtom *deleteAtom; - JSAtom *getOwnPropertyNamesAtom; - JSAtom *enumerateAtom; - JSAtom *fixAtom; - - JSAtom *hasAtom; - JSAtom *hasOwnAtom; - JSAtom *keysAtom; - JSAtom *iterateAtom; - - /* Less frequently used atoms, pinned lazily by JS_ResolveStandardClass. */ - struct { - JSAtom *XMLListAtom; - JSAtom *decodeURIAtom; - JSAtom *decodeURIComponentAtom; - JSAtom *defineGetterAtom; - JSAtom *defineSetterAtom; - JSAtom *encodeURIAtom; - JSAtom *encodeURIComponentAtom; - JSAtom *escapeAtom; - JSAtom *hasOwnPropertyAtom; - JSAtom *isFiniteAtom; - JSAtom *isNaNAtom; - JSAtom *isPrototypeOfAtom; - JSAtom *isXMLNameAtom; - JSAtom *lookupGetterAtom; - JSAtom *lookupSetterAtom; - JSAtom *parseFloatAtom; - JSAtom *parseIntAtom; - JSAtom *propertyIsEnumerableAtom; - JSAtom *unescapeAtom; - JSAtom *unevalAtom; - JSAtom *unwatchAtom; - JSAtom *watchAtom; - } lazy; -}; - -#define ATOM(name) cx->runtime->atomState.name##Atom - -#define ATOM_OFFSET_START offsetof(JSAtomState, emptyAtom) -#define LAZY_ATOM_OFFSET_START offsetof(JSAtomState, lazy) -#define ATOM_OFFSET_LIMIT (sizeof(JSAtomState)) - -#define COMMON_ATOMS_START(state) \ - ((JSAtom **)((uint8 *)(state) + ATOM_OFFSET_START)) -#define COMMON_ATOM_INDEX(name) \ - ((offsetof(JSAtomState, name##Atom) - ATOM_OFFSET_START) \ - / sizeof(JSAtom*)) -#define COMMON_TYPE_ATOM_INDEX(type) \ - ((offsetof(JSAtomState, typeAtoms[type]) - ATOM_OFFSET_START) \ - / sizeof(JSAtom*)) - -#define ATOM_OFFSET(name) offsetof(JSAtomState, name##Atom) -#define OFFSET_TO_ATOM(rt,off) (*(JSAtom **)((char*)&(rt)->atomState + (off))) -#define CLASS_ATOM_OFFSET(name) offsetof(JSAtomState,classAtoms[JSProto_##name]) - -#define CLASS_ATOM(cx,name) \ - ((cx)->runtime->atomState.classAtoms[JSProto_##name]) - -extern const char *const js_common_atom_names[]; -extern const size_t js_common_atom_count; - -/* - * Macros to access C strings for JSType and boolean literals. - */ -#define JS_BOOLEAN_STR(type) (js_common_atom_names[1 + (type)]) -#define JS_TYPE_STR(type) (js_common_atom_names[1 + 2 + (type)]) - -/* Well-known predefined C strings. */ -#define JS_PROTO(name,code,init) extern const char js_##name##_str[]; -#include "jsproto.tbl" -#undef JS_PROTO - -extern const char js_anonymous_str[]; -extern const char js_apply_str[]; -extern const char js_arguments_str[]; -extern const char js_arity_str[]; -extern const char js_call_str[]; -extern const char js_callee_str[]; -extern const char js_caller_str[]; -extern const char js_class_prototype_str[]; -extern const char js_close_str[]; -extern const char js_constructor_str[]; -extern const char js_count_str[]; -extern const char js_etago_str[]; -extern const char js_each_str[]; -extern const char js_eval_str[]; -extern const char js_fileName_str[]; -extern const char js_get_str[]; -extern const char js_getter_str[]; -extern const char js_global_str[]; -extern const char js_ignoreCase_str[]; -extern const char js_index_str[]; -extern const char js_input_str[]; -extern const char js_iterator_str[]; -extern const char js_join_str[]; -extern const char js_lastIndex_str[]; -extern const char js_length_str[]; -extern const char js_lineNumber_str[]; -extern const char js_message_str[]; -extern const char js_multiline_str[]; -extern const char js_name_str[]; -extern const char js_namespace_str[]; -extern const char js_next_str[]; -extern const char js_noSuchMethod_str[]; -extern const char js_object_str[]; -extern const char js_proto_str[]; -extern const char js_ptagc_str[]; -extern const char js_qualifier_str[]; -extern const char js_send_str[]; -extern const char js_setter_str[]; -extern const char js_set_str[]; -extern const char js_source_str[]; -extern const char js_space_str[]; -extern const char js_stack_str[]; -extern const char js_sticky_str[]; -extern const char js_stago_str[]; -extern const char js_star_str[]; -extern const char js_starQualifier_str[]; -extern const char js_tagc_str[]; -extern const char js_toGMTString_str[]; -extern const char js_toLocaleString_str[]; -extern const char js_toSource_str[]; -extern const char js_toString_str[]; -extern const char js_toUTCString_str[]; -extern const char js_undefined_str[]; -extern const char js_valueOf_str[]; -extern const char js_toJSON_str[]; -extern const char js_xml_str[]; -extern const char js_enumerable_str[]; -extern const char js_configurable_str[]; -extern const char js_writable_str[]; -extern const char js_value_str[]; -extern const char js_test_str[]; - -/* - * Initialize atom state. Return true on success, false on failure to allocate - * memory. The caller must zero rt->atomState before calling this function and - * only call it after js_InitGC successfully returns. - */ -extern JSBool -js_InitAtomState(JSRuntime *rt); - -/* - * Free and clear atom state including any interned string atoms. This - * function must be called before js_FinishGC. - */ -extern void -js_FinishAtomState(JSRuntime *rt); - -/* - * Atom tracing and garbage collection hooks. - */ - -extern void -js_TraceAtomState(JSTracer *trc); - -extern void -js_SweepAtomState(JSContext *cx); - -extern JSBool -js_InitCommonAtoms(JSContext *cx); - -extern void -js_FinishCommonAtoms(JSContext *cx); - -/* - * Find or create the atom for a string. Return null on failure to allocate - * memory. - */ -extern JSAtom * -js_AtomizeString(JSContext *cx, JSString *str, uintN flags); - -extern JSAtom * -js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags); - -extern JSAtom * -js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags); - -/* - * Return an existing atom for the given char array or null if the char - * sequence is currently not atomized. - */ -extern JSAtom * -js_GetExistingStringAtom(JSContext *cx, const jschar *chars, size_t length); - -#ifdef DEBUG - -extern JS_FRIEND_API(void) -js_DumpAtoms(JSContext *cx, FILE *fp); - -#endif - -inline bool -js_ValueToAtom(JSContext *cx, const js::Value &v, JSAtom **atomp); - -inline bool -js_ValueToStringId(JSContext *cx, const js::Value &v, jsid *idp); - -inline bool -js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval, - jsid *idp); -inline bool -js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval, - jsid *idp, js::Value *vp); -/* - * For all unmapped atoms recorded in al, add a mapping from the atom's index - * to its address. map->length must already be set to the number of atoms in - * the list and map->vector must point to pre-allocated memory. - */ -extern void -js_InitAtomMap(JSContext *cx, JSAtomMap *map, JSAtomList *al); - -#endif /* jsatom_h___ */ diff --git a/x86/mozilla/include/jsautocfg.h b/x86/mozilla/include/jsautocfg.h deleted file mode 100644 index f293029..0000000 --- a/x86/mozilla/include/jsautocfg.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef js_cpucfg___ -#define js_cpucfg___ - -/* AUTOMATICALLY GENERATED - DO NOT EDIT */ - -#define IS_LITTLE_ENDIAN 1 -#undef IS_BIG_ENDIAN - -#ifdef __hppa -# define JS_STACK_GROWTH_DIRECTION (1) -#else -# define JS_STACK_GROWTH_DIRECTION (-1) -#endif -#endif /* js_cpucfg___ */ diff --git a/x86/mozilla/include/jsautokw.h b/x86/mozilla/include/jsautokw.h deleted file mode 100644 index e9f103b..0000000 --- a/x86/mozilla/include/jsautokw.h +++ /dev/null @@ -1,296 +0,0 @@ - /* - * Generating switch for the list of 45 entries: - * false - * true - * null - * break - * case - * catch - * continue - * debugger - * default - * delete - * do - * else - * finally - * for - * function - * if - * in - * instanceof - * new - * return - * switch - * this - * throw - * try - * typeof - * var - * void - * while - * with - * class - * enum - * export - * extends - * import - * super - * const - * let - * yield - * implements - * interface - * package - * private - * protected - * public - * static - */ - switch (JSKW_LENGTH()) { - case 2: - if (JSKW_AT(0) == 'd') { - if (JSKW_AT(1)=='o') { - JSKW_GOT_MATCH(10) /* do */ - } - JSKW_NO_MATCH() - } - if (JSKW_AT(0) == 'i') { - if (JSKW_AT(1) == 'f') { - JSKW_GOT_MATCH(15) /* if */ - } - if (JSKW_AT(1) == 'n') { - JSKW_GOT_MATCH(16) /* in */ - } - JSKW_NO_MATCH() - } - JSKW_NO_MATCH() - case 3: - switch (JSKW_AT(2)) { - case 'r': - if (JSKW_AT(0) == 'f') { - if (JSKW_AT(1)=='o') { - JSKW_GOT_MATCH(13) /* for */ - } - JSKW_NO_MATCH() - } - if (JSKW_AT(0) == 'v') { - if (JSKW_AT(1)=='a') { - JSKW_GOT_MATCH(25) /* var */ - } - JSKW_NO_MATCH() - } - JSKW_NO_MATCH() - case 't': - if (JSKW_AT(0)=='l' && JSKW_AT(1)=='e') { - JSKW_GOT_MATCH(36) /* let */ - } - JSKW_NO_MATCH() - case 'w': - if (JSKW_AT(0)=='n' && JSKW_AT(1)=='e') { - JSKW_GOT_MATCH(18) /* new */ - } - JSKW_NO_MATCH() - case 'y': - if (JSKW_AT(0)=='t' && JSKW_AT(1)=='r') { - JSKW_GOT_MATCH(23) /* try */ - } - JSKW_NO_MATCH() - } - JSKW_NO_MATCH() - case 4: - switch (JSKW_AT(2)) { - case 'i': - if (JSKW_AT(0) == 't') { - if (JSKW_AT(3)=='s' && JSKW_AT(1)=='h') { - JSKW_GOT_MATCH(21) /* this */ - } - JSKW_NO_MATCH() - } - if (JSKW_AT(0) == 'v') { - if (JSKW_AT(3)=='d' && JSKW_AT(1)=='o') { - JSKW_GOT_MATCH(26) /* void */ - } - JSKW_NO_MATCH() - } - JSKW_NO_MATCH() - case 'l': - if (JSKW_AT(0)=='n' && JSKW_AT(1)=='u' && JSKW_AT(3)=='l') { - JSKW_GOT_MATCH(2) /* null */ - } - JSKW_NO_MATCH() - case 's': - if (JSKW_AT(1) == 'a') { - if (JSKW_AT(0)=='c' && JSKW_AT(3)=='e') { - JSKW_GOT_MATCH(4) /* case */ - } - JSKW_NO_MATCH() - } - if (JSKW_AT(1) == 'l') { - if (JSKW_AT(0)=='e' && JSKW_AT(3)=='e') { - JSKW_GOT_MATCH(11) /* else */ - } - JSKW_NO_MATCH() - } - JSKW_NO_MATCH() - case 't': - if (JSKW_AT(0)=='w' && JSKW_AT(1)=='i' && JSKW_AT(3)=='h') { - JSKW_GOT_MATCH(28) /* with */ - } - JSKW_NO_MATCH() - case 'u': - if (JSKW_AT(0) == 'e') { - if (JSKW_AT(3)=='m' && JSKW_AT(1)=='n') { - JSKW_GOT_MATCH(30) /* enum */ - } - JSKW_NO_MATCH() - } - if (JSKW_AT(0) == 't') { - if (JSKW_AT(3)=='e' && JSKW_AT(1)=='r') { - JSKW_GOT_MATCH(1) /* true */ - } - JSKW_NO_MATCH() - } - JSKW_NO_MATCH() - } - JSKW_NO_MATCH() - case 5: - switch (JSKW_AT(3)) { - case 'a': - if (JSKW_AT(0)=='b' && JSKW_AT(1)=='r' && JSKW_AT(2)=='e' && JSKW_AT(4)=='k') { - JSKW_GOT_MATCH(3) /* break */ - } - JSKW_NO_MATCH() - case 'c': - if (JSKW_AT(0)=='c' && JSKW_AT(1)=='a' && JSKW_AT(2)=='t' && JSKW_AT(4)=='h') { - JSKW_GOT_MATCH(5) /* catch */ - } - JSKW_NO_MATCH() - case 'e': - if (JSKW_AT(0)=='s' && JSKW_AT(1)=='u' && JSKW_AT(2)=='p' && JSKW_AT(4)=='r') { - JSKW_GOT_MATCH(34) /* super */ - } - JSKW_NO_MATCH() - case 'l': - if (JSKW_AT(0) == 'w') { - if (JSKW_AT(4)=='e' && JSKW_AT(1)=='h' && JSKW_AT(2)=='i') { - JSKW_GOT_MATCH(27) /* while */ - } - JSKW_NO_MATCH() - } - if (JSKW_AT(0) == 'y') { - if (JSKW_AT(4)=='d' && JSKW_AT(1)=='i' && JSKW_AT(2)=='e') { - JSKW_GOT_MATCH(37) /* yield */ - } - JSKW_NO_MATCH() - } - JSKW_NO_MATCH() - case 'o': - if (JSKW_AT(0)=='t' && JSKW_AT(1)=='h' && JSKW_AT(2)=='r' && JSKW_AT(4)=='w') { - JSKW_GOT_MATCH(22) /* throw */ - } - JSKW_NO_MATCH() - case 's': - if (JSKW_AT(0) == 'c') { - if (JSKW_AT(4) == 's') { - if (JSKW_AT(2)=='a' && JSKW_AT(1)=='l') { - JSKW_GOT_MATCH(29) /* class */ - } - JSKW_NO_MATCH() - } - if (JSKW_AT(4) == 't') { - if (JSKW_AT(2)=='n' && JSKW_AT(1)=='o') { - JSKW_GOT_MATCH(35) /* const */ - } - JSKW_NO_MATCH() - } - JSKW_NO_MATCH() - } - if (JSKW_AT(0) == 'f') { - if (JSKW_AT(4)=='e' && JSKW_AT(1)=='a' && JSKW_AT(2)=='l') { - JSKW_GOT_MATCH(0) /* false */ - } - JSKW_NO_MATCH() - } - JSKW_NO_MATCH() - } - JSKW_NO_MATCH() - case 6: - switch (JSKW_AT(0)) { - case 'd': - JSKW_TEST_GUESS(9) /* delete */ - case 'e': - JSKW_TEST_GUESS(31) /* export */ - case 'i': - JSKW_TEST_GUESS(33) /* import */ - case 'p': - JSKW_TEST_GUESS(43) /* public */ - case 'r': - JSKW_TEST_GUESS(19) /* return */ - case 's': - if (JSKW_AT(1) == 't') { - if (JSKW_AT(5)=='c' && JSKW_AT(4)=='i' && JSKW_AT(2)=='a' && JSKW_AT(3)=='t') { - JSKW_GOT_MATCH(44) /* static */ - } - JSKW_NO_MATCH() - } - if (JSKW_AT(1) == 'w') { - if (JSKW_AT(5)=='h' && JSKW_AT(4)=='c' && JSKW_AT(2)=='i' && JSKW_AT(3)=='t') { - JSKW_GOT_MATCH(20) /* switch */ - } - JSKW_NO_MATCH() - } - JSKW_NO_MATCH() - case 't': - JSKW_TEST_GUESS(24) /* typeof */ - } - JSKW_NO_MATCH() - case 7: - switch (JSKW_AT(0)) { - case 'd': - JSKW_TEST_GUESS(8) /* default */ - case 'e': - JSKW_TEST_GUESS(32) /* extends */ - case 'f': - JSKW_TEST_GUESS(12) /* finally */ - case 'p': - if (JSKW_AT(1) == 'a') { - JSKW_TEST_GUESS(40) /* package */ - } - if (JSKW_AT(1) == 'r') { - JSKW_TEST_GUESS(41) /* private */ - } - JSKW_NO_MATCH() - } - JSKW_NO_MATCH() - case 8: - if (JSKW_AT(2) == 'b') { - JSKW_TEST_GUESS(7) /* debugger */ - } - if (JSKW_AT(2) == 'n') { - if (JSKW_AT(0) == 'c') { - JSKW_TEST_GUESS(6) /* continue */ - } - if (JSKW_AT(0) == 'f') { - JSKW_TEST_GUESS(14) /* function */ - } - JSKW_NO_MATCH() - } - JSKW_NO_MATCH() - case 9: - if (JSKW_AT(0) == 'i') { - JSKW_TEST_GUESS(39) /* interface */ - } - if (JSKW_AT(0) == 'p') { - JSKW_TEST_GUESS(42) /* protected */ - } - JSKW_NO_MATCH() - case 10: - if (JSKW_AT(1) == 'n') { - JSKW_TEST_GUESS(17) /* instanceof */ - } - if (JSKW_AT(1) == 'm') { - JSKW_TEST_GUESS(38) /* implements */ - } - JSKW_NO_MATCH() - } - JSKW_NO_MATCH() diff --git a/x86/mozilla/include/jsbit.h b/x86/mozilla/include/jsbit.h deleted file mode 100644 index de1e291..0000000 --- a/x86/mozilla/include/jsbit.h +++ /dev/null @@ -1,305 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsbit_h___ -#define jsbit_h___ - -#include "jstypes.h" -#include "jscompat.h" -#include "jsutil.h" - -JS_BEGIN_EXTERN_C - -/* -** A jsbitmap_t is a long integer that can be used for bitmaps -*/ -typedef jsuword jsbitmap_t; /* NSPR name, a la Unix system types */ -typedef jsbitmap_t jsbitmap; /* JS-style scalar typedef name */ - -#define JS_BITMAP_SIZE(bits) (JS_HOWMANY(bits, JS_BITS_PER_WORD) * \ - sizeof(jsbitmap)) - -#define JS_TEST_BIT(_map,_bit) ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] & \ - ((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1)))) -#define JS_SET_BIT(_map,_bit) ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] |= \ - ((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1)))) -#define JS_CLEAR_BIT(_map,_bit) ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] &= \ - ~((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1)))) - -/* -** Compute the log of the least power of 2 greater than or equal to n -*/ -extern JS_PUBLIC_API(JSIntn) JS_CeilingLog2(JSUint32 i); - -/* -** Compute the log of the greatest power of 2 less than or equal to n -*/ -extern JS_PUBLIC_API(JSIntn) JS_FloorLog2(JSUint32 i); - -/* - * Replace bit-scanning code sequences with CPU-specific instructions to - * speedup calculations of ceiling/floor log2. - * - * With GCC 3.4 or later we can use __builtin_clz for that, see bug 327129. - * - * SWS: Added MSVC intrinsic bitscan support. See bugs 349364 and 356856. - */ -#if defined(_WIN32) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) - -unsigned char _BitScanForward(unsigned long * Index, unsigned long Mask); -unsigned char _BitScanReverse(unsigned long * Index, unsigned long Mask); -# pragma intrinsic(_BitScanForward,_BitScanReverse) - -__forceinline static int -__BitScanForward32(unsigned int val) -{ - unsigned long idx; - - _BitScanForward(&idx, (unsigned long)val); - return (int)idx; -} -__forceinline static int -__BitScanReverse32(unsigned int val) -{ - unsigned long idx; - - _BitScanReverse(&idx, (unsigned long)val); - return (int)(31-idx); -} -# define js_bitscan_ctz32(val) __BitScanForward32(val) -# define js_bitscan_clz32(val) __BitScanReverse32(val) -# define JS_HAS_BUILTIN_BITSCAN32 - -#if defined(_M_AMD64) || defined(_M_X64) -unsigned char _BitScanForward64(unsigned long * Index, unsigned __int64 Mask); -unsigned char _BitScanReverse64(unsigned long * Index, unsigned __int64 Mask); -# pragma intrinsic(_BitScanForward64,_BitScanReverse64) - -__forceinline static int -__BitScanForward64(unsigned __int64 val) -{ - unsigned long idx; - - _BitScanForward64(&idx, val); - return (int)idx; -} -__forceinline static int -__BitScanReverse64(unsigned __int64 val) -{ - unsigned long idx; - - _BitScanReverse64(&idx, val); - return (int)(63-idx); -} -# define js_bitscan_ctz64(val) __BitScanForward64(val) -# define js_bitscan_clz64(val) __BitScanReverse64(val) -# define JS_HAS_BUILTIN_BITSCAN64 -#endif -#elif (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) - -# define js_bitscan_ctz32(val) __builtin_ctz(val) -# define js_bitscan_clz32(val) __builtin_clz(val) -# define JS_HAS_BUILTIN_BITSCAN32 -# if (JS_BYTES_PER_WORD == 8) -# define js_bitscan_ctz64(val) __builtin_ctzll(val) -# define js_bitscan_clz64(val) __builtin_clzll(val) -# define JS_HAS_BUILTIN_BITSCAN64 -# endif - -#endif - -/* -** Macro version of JS_CeilingLog2: Compute the log of the least power of -** 2 greater than or equal to _n. The result is returned in _log2. -*/ -#ifdef JS_HAS_BUILTIN_BITSCAN32 -/* - * Use intrinsic function or count-leading-zeros to calculate ceil(log2(_n)). - * The macro checks for "n <= 1" and not "n != 0" as js_bitscan_clz32(0) is - * undefined. - */ -# define JS_CEILING_LOG2(_log2,_n) \ - JS_BEGIN_MACRO \ - unsigned int j_ = (unsigned int)(_n); \ - (_log2) = (j_ <= 1 ? 0 : 32 - js_bitscan_clz32(j_ - 1)); \ - JS_END_MACRO -#else -# define JS_CEILING_LOG2(_log2,_n) \ - JS_BEGIN_MACRO \ - JSUint32 j_ = (JSUint32)(_n); \ - (_log2) = 0; \ - if ((j_) & ((j_)-1)) \ - (_log2) += 1; \ - if ((j_) >> 16) \ - (_log2) += 16, (j_) >>= 16; \ - if ((j_) >> 8) \ - (_log2) += 8, (j_) >>= 8; \ - if ((j_) >> 4) \ - (_log2) += 4, (j_) >>= 4; \ - if ((j_) >> 2) \ - (_log2) += 2, (j_) >>= 2; \ - if ((j_) >> 1) \ - (_log2) += 1; \ - JS_END_MACRO -#endif - -/* -** Macro version of JS_FloorLog2: Compute the log of the greatest power of -** 2 less than or equal to _n. The result is returned in _log2. -** -** This is equivalent to finding the highest set bit in the word. -*/ -#ifdef JS_HAS_BUILTIN_BITSCAN32 -/* - * Use js_bitscan_clz32 or count-leading-zeros to calculate floor(log2(_n)). - * Since js_bitscan_clz32(0) is undefined, the macro set the loweset bit to 1 - * to ensure 0 result when _n == 0. - */ -# define JS_FLOOR_LOG2(_log2,_n) \ - JS_BEGIN_MACRO \ - (_log2) = 31 - js_bitscan_clz32(((unsigned int)(_n)) | 1); \ - JS_END_MACRO -#else -# define JS_FLOOR_LOG2(_log2,_n) \ - JS_BEGIN_MACRO \ - JSUint32 j_ = (JSUint32)(_n); \ - (_log2) = 0; \ - if ((j_) >> 16) \ - (_log2) += 16, (j_) >>= 16; \ - if ((j_) >> 8) \ - (_log2) += 8, (j_) >>= 8; \ - if ((j_) >> 4) \ - (_log2) += 4, (j_) >>= 4; \ - if ((j_) >> 2) \ - (_log2) += 2, (j_) >>= 2; \ - if ((j_) >> 1) \ - (_log2) += 1; \ - JS_END_MACRO -#endif - -/* - * Internal function. - * Compute the log of the least power of 2 greater than or equal to n. This is - * a version of JS_CeilingLog2 that operates on unsigned integers with - * CPU-dependant size. - */ -#define JS_CEILING_LOG2W(n) ((n) <= 1 ? 0 : 1 + JS_FLOOR_LOG2W((n) - 1)) - -/* - * Internal function. - * Compute the log of the greatest power of 2 less than or equal to n. - * This is a version of JS_FloorLog2 that operates on unsigned integers with - * CPU-dependant size and requires that n != 0. - */ -#define JS_FLOOR_LOG2W(n) (JS_ASSERT((n) != 0), js_FloorLog2wImpl(n)) - -#if JS_BYTES_PER_WORD == 4 - -# ifdef JS_HAS_BUILTIN_BITSCAN32 -# define js_FloorLog2wImpl(n) \ - ((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz32(n))) -# else -# define js_FloorLog2wImpl(n) ((size_t)JS_FloorLog2(n)) -#endif - -#elif JS_BYTES_PER_WORD == 8 - -# ifdef JS_HAS_BUILTIN_BITSCAN64 -# define js_FloorLog2wImpl(n) \ - ((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz64(n))) -# else -extern size_t js_FloorLog2wImpl(size_t n); -# endif - -#else - -# error "NOT SUPPORTED" - -#endif - -namespace js { - -inline size_t -CountTrailingZeros(size_t n) -{ - JS_ASSERT(n != 0); -#if JS_BYTES_PER_WORD != 4 && JS_BYTES_PER_WORD != 8 -# error "NOT SUPPORTED" -#endif - -#if JS_BYTES_PER_WORD == 4 && defined JS_HAS_BUILTIN_BITSCAN32 - return js_bitscan_ctz32(n); -#elif JS_BYTES_PER_WORD == 8 && defined JS_HAS_BUILTIN_BITSCAN64 - return js_bitscan_ctz64(n); -#else - size_t count = 0; -# if JS_BYTES_PER_WORD == 8 - if (!(n & size_t(0xFFFFFFFFU))) { count += 32; n >>= 32; } -# endif - if (!(n & 0xFFFF)) { count += 16; n >>= 16; } - if (!(n & 0xFF)) { count += 8; n >>= 8; } - if (!(n & 0xF)) { count += 4; n >>= 4; } - if (!(n & 0x3)) { count += 2; n >>= 2; } - if (!(n & 0x1)) { count += 1; n >>= 1; } - return count + 1 - (n & 0x1); -#endif -} - -} - -/* - * Macros for rotate left. There is no rotate operation in the C Language so - * the construct (a << 4) | (a >> 28) is used instead. Most compilers convert - * this to a rotate instruction but some versions of MSVC don't without a - * little help. To get MSVC to generate a rotate instruction, we have to use - * the _rotl intrinsic and use a pragma to make _rotl inline. - * - * MSVC in VS2005 will do an inline rotate instruction on the above construct. - */ - -#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || \ - defined(_M_X64)) -#include -#pragma intrinsic(_rotl) -#define JS_ROTATE_LEFT32(a, bits) _rotl(a, bits) -#else -#define JS_ROTATE_LEFT32(a, bits) (((a) << (bits)) | ((a) >> (32 - (bits)))) -#endif - -JS_END_EXTERN_C -#endif /* jsbit_h___ */ diff --git a/x86/mozilla/include/jsbool.h b/x86/mozilla/include/jsbool.h deleted file mode 100644 index 477b409..0000000 --- a/x86/mozilla/include/jsbool.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsbool_h___ -#define jsbool_h___ -/* - * JS boolean interface. - */ - -#include "jsapi.h" -#include "jsobj.h" -#include "jsstr.h" - -extern js::Class js_BooleanClass; - -inline bool -JSObject::isBoolean() const -{ - return getClass() == &js_BooleanClass; -} - -extern JSObject * -js_InitBooleanClass(JSContext *cx, JSObject *obj); - -extern JSString * -js_BooleanToString(JSContext *cx, JSBool b); - -namespace js { - -extern bool -BooleanToStringBuffer(JSContext *cx, JSBool b, StringBuffer &sb); - -} /* namespace js */ - -extern JSBool -js_ValueToBoolean(const js::Value &v); - -#endif /* jsbool_h___ */ diff --git a/x86/mozilla/include/jsbuiltins.h b/x86/mozilla/include/jsbuiltins.h deleted file mode 100644 index 5381814..0000000 --- a/x86/mozilla/include/jsbuiltins.h +++ /dev/null @@ -1,635 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released - * May 28, 2008. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * - * Contributor(s): - * Jason Orendorff - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsbuiltins_h___ -#define jsbuiltins_h___ - -#ifdef JS_TRACER - -#include "nanojit/nanojit.h" -#include "jsvalue.h" - -#ifdef THIS -#undef THIS -#endif - -enum JSTNErrType { INFALLIBLE, FAIL_STATUS, FAIL_NULL, FAIL_NEG, FAIL_NEITHER }; -enum { - JSTN_ERRTYPE_MASK = 0x07, - JSTN_UNBOX_AFTER = 0x08, - JSTN_MORE = 0x10, - JSTN_CONSTRUCTOR = 0x20, - JSTN_RETURN_NULLABLE_STR = 0x40, - JSTN_RETURN_NULLABLE_OBJ = 0x80 -}; - -#define JSTN_ERRTYPE(jstn) ((jstn)->flags & JSTN_ERRTYPE_MASK) - -/* - * Type describing a type specialization of a js::Native. - * - * |prefix| and |argtypes| declare what arguments should be passed to the - * native function. |prefix| can contain the following characters: - * - * 'C': a JSContext* argument - * 'T': |this| as a JSObject* argument (bails if |this| is not an object) - * 'S': |this| as a JSString* argument (bails if |this| is not a string) - * 'R': a JSRuntime* argument - * 'P': the pc as a jsbytecode* - * 'D': |this| as a number (jsdouble) - * 'f': the function being called, as a JSObject* - * 'p': the .prototype of the function, as a JSObject* - * - * The corresponding things will get passed as arguments to the builtin in - * reverse order (so TC means JSContext* as the first arg, and the - * JSObject* for |this| as the second arg). - * - * |argtypes| can contain the following characters: - * 'd': a number (double) argument - * 'i': an integer argument - * 's': a JSString* argument - * 'o': a JSObject* argument - * 'r': a JSObject* argument that is of class js_RegExpClass - * 'f': a JSObject* argument that is of class js_FunctionClass - * 'v': a value argument: on 32-bit, a Value*, on 64-bit, a jsval - */ -struct JSSpecializedNative { - const nanojit::CallInfo *builtin; - const char *prefix; - const char *argtypes; - uintN flags; /* JSTNErrType | JSTN_UNBOX_AFTER | JSTN_MORE | - JSTN_CONSTRUCTOR */ -}; - -/* - * Type holding extra trace-specific information about a fast native. - * - * 'specializations' points to a static array of available specializations - * terminated by the lack of having the JSTN_MORE flag set. - */ -struct JSNativeTraceInfo { - js::Native native; - JSSpecializedNative *specializations; -}; - -/* Macros used by JS_DEFINE_CALLINFOn. */ -#ifdef DEBUG -#define _JS_CI_NAME(op) ,#op -#else -#define _JS_CI_NAME(op) -#endif - -#define _JS_I32_ARGTYPE nanojit::ARGTYPE_I -#define _JS_I32_RETTYPE nanojit::ARGTYPE_I -#define _JS_U64_ARGTYPE nanojit::ARGTYPE_Q -#define _JS_U64_RETTYPE nanojit::ARGTYPE_Q -#define _JS_F64_ARGTYPE nanojit::ARGTYPE_D -#define _JS_F64_RETTYPE nanojit::ARGTYPE_D -#define _JS_PTR_ARGTYPE nanojit::ARGTYPE_P -#define _JS_PTR_RETTYPE nanojit::ARGTYPE_P - -struct ClosureVarInfo; - -/* - * Supported types for builtin functions. - * - * Types with -- for the two string fields are not permitted as argument types - * in JS_DEFINE_TRCINFO. - * - * There are three kinds of traceable-native error handling. - * - * - If a traceable native's return type ends with _FAIL, it always runs to - * completion. It can either succeed or fail with an error or exception; - * on success, it may or may not stay on trace. There may be side effects - * in any case. If the call succeeds but bails off trace, we resume in the - * interpreter at the next opcode. - * - * _FAIL builtins indicate failure or bailing off trace by setting bits in - * cx->interpState->builtinStatus. - * - * - If a traceable native's return type contains _RETRY, it can either - * succeed, fail with a JS exception, or tell the caller to bail off trace - * and retry the call from the interpreter. The last case happens if the - * builtin discovers that it can't do its job without examining the JS - * stack, reentering the interpreter, accessing properties of the global - * object, etc. - * - * The builtin must detect the need to retry before committing any side - * effects. If a builtin can't do this, it must use a _FAIL return type - * instead of _RETRY. - * - * _RETRY builtins indicate failure with a special return value that - * depends on the return type: - * - * BOOL_RETRY: JS_NEITHER - * INT32_RETRY: any negative value - * STRING_RETRY: NULL - * OBJECT_RETRY_NULL: NULL - * - * _RETRY function calls are faster than _FAIL calls. Each _RETRY call - * saves two writes to tm->bailExit and a read from state->builtinStatus. - * - * - All other traceable natives are infallible (e.g. Date.now, Math.log). - * - * Special builtins known to the tracer can have their own idiosyncratic - * error codes. - * - * When a traceable native returns a value indicating failure, we fall off - * trace. If an exception is pending, it is thrown; otherwise, we assume the - * builtin had no side effects and retry the current bytecode in the - * interpreter. - * - * So a builtin must not return a value indicating failure after causing side - * effects (such as reporting an error), without setting an exception pending. - * The operation would be retried, despite the first attempt's observable - * effects. - */ -#define _JS_CTYPE(ctype, size, pch, ach, flags) (ctype, size, pch, ach, flags) - -#define _JS_CTYPE_CONTEXT _JS_CTYPE(JSContext *, _JS_PTR,"C", "", INFALLIBLE) -#define _JS_CTYPE_RUNTIME _JS_CTYPE(JSRuntime *, _JS_PTR,"R", "", INFALLIBLE) -#define _JS_CTYPE_MATHCACHE _JS_CTYPE(js::MathCache *, _JS_PTR,"M", "", INFALLIBLE) -#define _JS_CTYPE_THIS _JS_CTYPE(JSObject *, _JS_PTR,"T", "", INFALLIBLE) -#define _JS_CTYPE_THIS_DOUBLE _JS_CTYPE(jsdouble, _JS_F64,"D", "", INFALLIBLE) -#define _JS_CTYPE_THIS_STRING _JS_CTYPE(JSString *, _JS_PTR,"S", "", INFALLIBLE) -#define _JS_CTYPE_CALLEE _JS_CTYPE(JSObject *, _JS_PTR,"f", "", INFALLIBLE) -#define _JS_CTYPE_CALLEE_PROTOTYPE _JS_CTYPE(JSObject *, _JS_PTR,"p", "", INFALLIBLE) -#define _JS_CTYPE_FUNCTION _JS_CTYPE(JSFunction *, _JS_PTR, --, --, INFALLIBLE) -#define _JS_CTYPE_PC _JS_CTYPE(jsbytecode *, _JS_PTR,"P", "", INFALLIBLE) -#define _JS_CTYPE_VALUEPTR _JS_CTYPE(js::Value *, _JS_PTR, --, --, INFALLIBLE) -#define _JS_CTYPE_CVALUEPTR _JS_CTYPE(const js::Value *, _JS_PTR, --, --, INFALLIBLE) -#define _JS_CTYPE_JSID _JS_CTYPE(jsid, _JS_PTR, --, --, INFALLIBLE) -#define _JS_CTYPE_JSVAL _JS_CTYPE(js::Value, _JS_U64, --, --, INFALLIBLE) -#define _JS_CTYPE_BOOL _JS_CTYPE(JSBool, _JS_I32, "","i", INFALLIBLE) -#define _JS_CTYPE_BOOL_RETRY _JS_CTYPE(JSBool, _JS_I32, --, --, FAIL_NEITHER) -#define _JS_CTYPE_BOOL_FAIL _JS_CTYPE(JSBool, _JS_I32, --, --, FAIL_STATUS) -#define _JS_CTYPE_BOOLPTR _JS_CTYPE(JSBool *, _JS_PTR, --, --, INFALLIBLE) -#define _JS_CTYPE_INT32 _JS_CTYPE(int32, _JS_I32, "","i", INFALLIBLE) -#define _JS_CTYPE_INT32_RETRY _JS_CTYPE(int32, _JS_I32, --, --, FAIL_NEG) -#define _JS_CTYPE_INT32_FAIL _JS_CTYPE(int32, _JS_I32, --, --, FAIL_STATUS) -#define _JS_CTYPE_INT32PTR _JS_CTYPE(int32 *, _JS_PTR, --, --, INFALLIBLE) -#define _JS_CTYPE_UINT32 _JS_CTYPE(uint32, _JS_I32, "","i", INFALLIBLE) -#define _JS_CTYPE_UINT32_RETRY _JS_CTYPE(uint32, _JS_I32, --, --, FAIL_NEG) -#define _JS_CTYPE_UINT32_FAIL _JS_CTYPE(uint32, _JS_I32, --, --, FAIL_STATUS) -#define _JS_CTYPE_DOUBLE _JS_CTYPE(jsdouble, _JS_F64, "","d", INFALLIBLE) -#define _JS_CTYPE_DOUBLE_FAIL _JS_CTYPE(jsdouble, _JS_F64, --, --, FAIL_STATUS) -#define _JS_CTYPE_STRING _JS_CTYPE(JSString *, _JS_PTR, "","s", INFALLIBLE) -#define _JS_CTYPE_STRING_RETRY _JS_CTYPE(JSString *, _JS_PTR, --, --, FAIL_NULL) -#define _JS_CTYPE_STRING_FAIL _JS_CTYPE(JSString *, _JS_PTR, --, --, FAIL_STATUS) -#define _JS_CTYPE_STRING_OR_NULL_FAIL _JS_CTYPE(JSString *, _JS_PTR, --, --, FAIL_STATUS | \ - JSTN_RETURN_NULLABLE_STR) -#define _JS_CTYPE_STRINGPTR _JS_CTYPE(JSString **, _JS_PTR, --, --, INFALLIBLE) -#define _JS_CTYPE_OBJECT _JS_CTYPE(JSObject *, _JS_PTR, "","o", INFALLIBLE) -#define _JS_CTYPE_OBJECT_RETRY _JS_CTYPE(JSObject *, _JS_PTR, --, --, FAIL_NULL) -#define _JS_CTYPE_OBJECT_FAIL _JS_CTYPE(JSObject *, _JS_PTR, --, --, FAIL_STATUS) -#define _JS_CTYPE_OBJECT_OR_NULL_FAIL _JS_CTYPE(JSObject *, _JS_PTR, --, --, FAIL_STATUS | \ - JSTN_RETURN_NULLABLE_OBJ) -#define _JS_CTYPE_OBJECTPTR _JS_CTYPE(JSObject **, _JS_PTR, --, --, INFALLIBLE) -#define _JS_CTYPE_CONSTRUCTOR_RETRY _JS_CTYPE(JSObject *, _JS_PTR, --, --, FAIL_NULL | \ - JSTN_CONSTRUCTOR) -#define _JS_CTYPE_REGEXP _JS_CTYPE(JSObject *, _JS_PTR, "","r", INFALLIBLE) -#define _JS_CTYPE_SHAPE _JS_CTYPE(js::Shape *, _JS_PTR, --, --, INFALLIBLE) -#define _JS_CTYPE_TRACERSTATE _JS_CTYPE(TracerState *, _JS_PTR, --, --, INFALLIBLE) -#define _JS_CTYPE_FRAGMENT _JS_CTYPE(nanojit::Fragment *, _JS_PTR, --, --, INFALLIBLE) -#define _JS_CTYPE_CLASS _JS_CTYPE(js::Class *, _JS_PTR, --, --, INFALLIBLE) -#define _JS_CTYPE_DOUBLEPTR _JS_CTYPE(double *, _JS_PTR, --, --, INFALLIBLE) -#define _JS_CTYPE_CHARPTR _JS_CTYPE(char *, _JS_PTR, --, --, INFALLIBLE) -#define _JS_CTYPE_CVIPTR _JS_CTYPE(const ClosureVarInfo *, _JS_PTR, --, --, INFALLIBLE) -#define _JS_CTYPE_FRAMEINFO _JS_CTYPE(FrameInfo *, _JS_PTR, --, --, INFALLIBLE) -#define _JS_CTYPE_PICTABLE _JS_CTYPE(PICTable *, _JS_PTR, --, --, INFALLIBLE) -#define _JS_CTYPE_UINTN _JS_CTYPE(uintN, _JS_PTR, --, --, INFALLIBLE) - -/* - * The "VALUE" type is used to indicate that a native takes a js::Value - * parameter by value. Unfortunately, for technical reasons, we can't simply - * have the parameter type be js::Value. Furthermore, the right thing to pass - * differs based on word size. Thus, a native that declares a parameter of type - * VALUE should have the corresponding argument type be: - * - on 32-bit: const Value* - * - on 64-bit: jsval (which is a uint64) - * - * To write code that just does the right thing, use the pattern: - * void foo(js::ValueArgType arg) { - * const js::Value &v = js::ValueArgToConstRef(arg); - */ -#if JS_BITS_PER_WORD == 32 -# define _JS_CTYPE_VALUE _JS_CTYPE(js::ValueArgType, _JS_PTR, "","v", INFALLIBLE) -#elif JS_BITS_PER_WORD == 64 -# define _JS_CTYPE_VALUE _JS_CTYPE(js::ValueArgType, _JS_U64, "","v", INFALLIBLE) -#endif - -#define _JS_EXPAND(tokens) tokens - -#define _JS_CTYPE_TYPE2(t,s,p,a,f) t -#define _JS_CTYPE_TYPE(tyname) _JS_EXPAND(_JS_CTYPE_TYPE2 _JS_CTYPE_##tyname) -#define _JS_CTYPE_RETTYPE2(t,s,p,a,f) s##_RETTYPE -#define _JS_CTYPE_RETTYPE(tyname) _JS_EXPAND(_JS_CTYPE_RETTYPE2 _JS_CTYPE_##tyname) -#define _JS_CTYPE_ARGTYPE2(t,s,p,a,f) s##_ARGTYPE -#define _JS_CTYPE_ARGTYPE(tyname) _JS_EXPAND(_JS_CTYPE_ARGTYPE2 _JS_CTYPE_##tyname) -#define _JS_CTYPE_PCH2(t,s,p,a,f) p -#define _JS_CTYPE_PCH(tyname) _JS_EXPAND(_JS_CTYPE_PCH2 _JS_CTYPE_##tyname) -#define _JS_CTYPE_ACH2(t,s,p,a,f) a -#define _JS_CTYPE_ACH(tyname) _JS_EXPAND(_JS_CTYPE_ACH2 _JS_CTYPE_##tyname) -#define _JS_CTYPE_FLAGS2(t,s,p,a,f) f -#define _JS_CTYPE_FLAGS(tyname) _JS_EXPAND(_JS_CTYPE_FLAGS2 _JS_CTYPE_##tyname) - -#define _JS_static_TN(t) static t -#define _JS_static_CI static -#define _JS_extern_TN(t) extern t -#define _JS_extern_CI -#define _JS_FRIEND_TN(t) extern JS_FRIEND_API(t) -#define _JS_FRIEND_CI -#define _JS_TN_LINKAGE(linkage, t) _JS_##linkage##_TN(t) -#define _JS_CI_LINKAGE(linkage) _JS_##linkage##_CI - -#define _JS_CALLINFO(name) name##_ci - -#if defined(JS_NO_FASTCALL) && defined(NANOJIT_IA32) -#define _JS_DEFINE_CALLINFO(linkage, name, crtype, cargtypes, argtypes, isPure, storeAccSet) \ - _JS_TN_LINKAGE(linkage, crtype) name cargtypes; \ - _JS_CI_LINKAGE(linkage) const nanojit::CallInfo _JS_CALLINFO(name) = \ - { (intptr_t) &name, argtypes, nanojit::ABI_CDECL, isPure, storeAccSet _JS_CI_NAME(name) };\ - JS_STATIC_ASSERT_IF(isPure, (storeAccSet) == nanojit::ACCSET_NONE); - -#else -#define _JS_DEFINE_CALLINFO(linkage, name, crtype, cargtypes, argtypes, isPure, storeAccSet) \ - _JS_TN_LINKAGE(linkage, crtype) FASTCALL name cargtypes; \ - _JS_CI_LINKAGE(linkage) const nanojit::CallInfo _JS_CALLINFO(name) = \ - { (intptr_t) &name, argtypes, nanojit::ABI_FASTCALL, isPure, storeAccSet _JS_CI_NAME(name) }; \ - JS_STATIC_ASSERT_IF(isPure, (storeAccSet) == nanojit::ACCSET_NONE); -#endif - -/* - * This macro is used for builtin functions that can be called from JITted - * code. It declares a C function named and a CallInfo struct named - * _ci so the tracer can call it. The in JS_DEFINE_CALLINFO_ is - * the number of arguments the builtin takes. Builtins with no arguments - * are not supported. Using a macro is clunky but ensures that the types - * for each C function matches those for the corresponding CallInfo struct; - * mismatched types can cause subtle problems. - * - * The macro arguments are: - * - * - The linkage for the function and the associated CallInfo global. It - * can be extern, static, or FRIEND, which specifies JS_FRIEND_API linkage - * for the function. - * - * - The return type. This identifier must name one of the _JS_TYPEINFO_* - * macros defined in jsbuiltins.h. - * - * - The builtin name. - * - * - The parameter types. - * - * - The isPure flag. Set to 1 if: - * (a) the function's return value is determined solely by its arguments - * (ie. no hidden state, no implicit inputs used such as global - * variables or the result of an I/O operation); and - * (b) the function causes no observable side-effects (ie. no writes to - * global variables, no I/O output). - * Multiple calls to a pure function can be merged during CSE. - * - * - The storeAccSet. This indicates which memory access regions the function - * accesses. It must be ACCSET_NONE if the function is pure; use - * ACCSET_STORE_ANY if you're not sure. Used to determine if each call site - * of the function aliases any loads. - */ -#define JS_DEFINE_CALLINFO_1(linkage, rt, op, at0, isPure, storeAccSet) \ - _JS_DEFINE_CALLINFO(linkage, op, \ - _JS_CTYPE_TYPE(rt), \ - (_JS_CTYPE_TYPE(at0)), \ - nanojit::CallInfo::typeSig1(_JS_CTYPE_RETTYPE(rt), \ - _JS_CTYPE_ARGTYPE(at0)), \ - isPure, storeAccSet) -#define JS_DEFINE_CALLINFO_2(linkage, rt, op, at0, at1, isPure, storeAccSet) \ - _JS_DEFINE_CALLINFO(linkage, op, \ - _JS_CTYPE_TYPE(rt), \ - (_JS_CTYPE_TYPE(at0), \ - _JS_CTYPE_TYPE(at1)), \ - nanojit::CallInfo::typeSig2(_JS_CTYPE_RETTYPE(rt), \ - _JS_CTYPE_ARGTYPE(at0), \ - _JS_CTYPE_ARGTYPE(at1)), \ - isPure, storeAccSet) -#define JS_DEFINE_CALLINFO_3(linkage, rt, op, at0, at1, at2, isPure, storeAccSet) \ - _JS_DEFINE_CALLINFO(linkage, op, \ - _JS_CTYPE_TYPE(rt), \ - (_JS_CTYPE_TYPE(at0), \ - _JS_CTYPE_TYPE(at1), \ - _JS_CTYPE_TYPE(at2)), \ - nanojit::CallInfo::typeSig3(_JS_CTYPE_RETTYPE(rt), \ - _JS_CTYPE_ARGTYPE(at0), \ - _JS_CTYPE_ARGTYPE(at1), \ - _JS_CTYPE_ARGTYPE(at2)), \ - isPure, storeAccSet) -#define JS_DEFINE_CALLINFO_4(linkage, rt, op, at0, at1, at2, at3, isPure, storeAccSet) \ - _JS_DEFINE_CALLINFO(linkage, op, \ - _JS_CTYPE_TYPE(rt), \ - (_JS_CTYPE_TYPE(at0), \ - _JS_CTYPE_TYPE(at1), \ - _JS_CTYPE_TYPE(at2), \ - _JS_CTYPE_TYPE(at3)), \ - nanojit::CallInfo::typeSig4(_JS_CTYPE_RETTYPE(rt), \ - _JS_CTYPE_ARGTYPE(at0), \ - _JS_CTYPE_ARGTYPE(at1), \ - _JS_CTYPE_ARGTYPE(at2), \ - _JS_CTYPE_ARGTYPE(at3)), \ - isPure, storeAccSet) -#define JS_DEFINE_CALLINFO_5(linkage, rt, op, at0, at1, at2, at3, at4, isPure, storeAccSet) \ - _JS_DEFINE_CALLINFO(linkage, op, \ - _JS_CTYPE_TYPE(rt), \ - (_JS_CTYPE_TYPE(at0), \ - _JS_CTYPE_TYPE(at1), \ - _JS_CTYPE_TYPE(at2), \ - _JS_CTYPE_TYPE(at3), \ - _JS_CTYPE_TYPE(at4)), \ - nanojit::CallInfo::typeSig5(_JS_CTYPE_RETTYPE(rt), \ - _JS_CTYPE_ARGTYPE(at0), \ - _JS_CTYPE_ARGTYPE(at1), \ - _JS_CTYPE_ARGTYPE(at2), \ - _JS_CTYPE_ARGTYPE(at3), \ - _JS_CTYPE_ARGTYPE(at4)), \ - isPure, storeAccSet) -#define JS_DEFINE_CALLINFO_6(linkage, rt, op, at0, at1, at2, at3, at4, at5, isPure, storeAccSet) \ - _JS_DEFINE_CALLINFO(linkage, op, \ - _JS_CTYPE_TYPE(rt), \ - (_JS_CTYPE_TYPE(at0), \ - _JS_CTYPE_TYPE(at1), \ - _JS_CTYPE_TYPE(at2), \ - _JS_CTYPE_TYPE(at3), \ - _JS_CTYPE_TYPE(at4), \ - _JS_CTYPE_TYPE(at5)), \ - nanojit::CallInfo::typeSig6(_JS_CTYPE_RETTYPE(rt), \ - _JS_CTYPE_ARGTYPE(at0), \ - _JS_CTYPE_ARGTYPE(at1), \ - _JS_CTYPE_ARGTYPE(at2), \ - _JS_CTYPE_ARGTYPE(at3), \ - _JS_CTYPE_ARGTYPE(at4), \ - _JS_CTYPE_ARGTYPE(at5)), \ - isPure, storeAccSet) -#define JS_DEFINE_CALLINFO_7(linkage, rt, op, at0, at1, at2, at3, at4, at5, at6, isPure, \ - storeAccSet) \ - _JS_DEFINE_CALLINFO(linkage, op, \ - _JS_CTYPE_TYPE(rt), \ - (_JS_CTYPE_TYPE(at0), \ - _JS_CTYPE_TYPE(at1), \ - _JS_CTYPE_TYPE(at2), \ - _JS_CTYPE_TYPE(at3), \ - _JS_CTYPE_TYPE(at4), \ - _JS_CTYPE_TYPE(at5), \ - _JS_CTYPE_TYPE(at6)), \ - nanojit::CallInfo::typeSig7(_JS_CTYPE_RETTYPE(rt), \ - _JS_CTYPE_ARGTYPE(at0), \ - _JS_CTYPE_ARGTYPE(at1), \ - _JS_CTYPE_ARGTYPE(at2), \ - _JS_CTYPE_ARGTYPE(at3), \ - _JS_CTYPE_ARGTYPE(at4), \ - _JS_CTYPE_ARGTYPE(at5), \ - _JS_CTYPE_ARGTYPE(at6)), \ - isPure, storeAccSet) -#define JS_DEFINE_CALLINFO_8(linkage, rt, op, at0, at1, at2, at3, at4, at5, at6, at7, isPure, \ - storeAccSet) \ - _JS_DEFINE_CALLINFO(linkage, op, \ - _JS_CTYPE_TYPE(rt), \ - (_JS_CTYPE_TYPE(at0), \ - _JS_CTYPE_TYPE(at1), \ - _JS_CTYPE_TYPE(at2), \ - _JS_CTYPE_TYPE(at3), \ - _JS_CTYPE_TYPE(at4), \ - _JS_CTYPE_TYPE(at5), \ - _JS_CTYPE_TYPE(at6), \ - _JS_CTYPE_TYPE(at7)), \ - nanojit::CallInfo::typeSig8(_JS_CTYPE_RETTYPE(rt), \ - _JS_CTYPE_ARGTYPE(at0), \ - _JS_CTYPE_ARGTYPE(at1), \ - _JS_CTYPE_ARGTYPE(at2), \ - _JS_CTYPE_ARGTYPE(at3), \ - _JS_CTYPE_ARGTYPE(at4), \ - _JS_CTYPE_ARGTYPE(at5), \ - _JS_CTYPE_ARGTYPE(at6), \ - _JS_CTYPE_ARGTYPE(at7)), \ - isPure, storeAccSet) - -#define JS_DECLARE_CALLINFO(name) extern const nanojit::CallInfo _JS_CALLINFO(name); - -#define _JS_TN_INIT_HELPER_n(n, args) _JS_TN_INIT_HELPER_##n args - -#define _JS_TN_INIT_HELPER_1(linkage, rt, op, at0, isPure, storeAccSet) \ - &_JS_CALLINFO(op), \ - _JS_CTYPE_PCH(at0), \ - _JS_CTYPE_ACH(at0), \ - _JS_CTYPE_FLAGS(rt) - -#define _JS_TN_INIT_HELPER_2(linkage, rt, op, at0, at1, isPure, storeAccSet) \ - &_JS_CALLINFO(op), \ - _JS_CTYPE_PCH(at1) _JS_CTYPE_PCH(at0), \ - _JS_CTYPE_ACH(at1) _JS_CTYPE_ACH(at0), \ - _JS_CTYPE_FLAGS(rt) - -#define _JS_TN_INIT_HELPER_3(linkage, rt, op, at0, at1, at2, isPure, storeAccSet) \ - &_JS_CALLINFO(op), \ - _JS_CTYPE_PCH(at2) _JS_CTYPE_PCH(at1) _JS_CTYPE_PCH(at0), \ - _JS_CTYPE_ACH(at2) _JS_CTYPE_ACH(at1) _JS_CTYPE_ACH(at0), \ - _JS_CTYPE_FLAGS(rt) - -#define _JS_TN_INIT_HELPER_4(linkage, rt, op, at0, at1, at2, at3, isPure, storeAccSet) \ - &_JS_CALLINFO(op), \ - _JS_CTYPE_PCH(at3) _JS_CTYPE_PCH(at2) _JS_CTYPE_PCH(at1) _JS_CTYPE_PCH(at0), \ - _JS_CTYPE_ACH(at3) _JS_CTYPE_ACH(at2) _JS_CTYPE_ACH(at1) _JS_CTYPE_ACH(at0), \ - _JS_CTYPE_FLAGS(rt) - -#define _JS_TN_INIT_HELPER_5(linkage, rt, op, at0, at1, at2, at3, at4, isPure, storeAccSet) \ - &_JS_CALLINFO(op), \ - _JS_CTYPE_PCH(at4) _JS_CTYPE_PCH(at3) _JS_CTYPE_PCH(at2) _JS_CTYPE_PCH(at1) \ - _JS_CTYPE_PCH(at0), \ - _JS_CTYPE_ACH(at4) _JS_CTYPE_ACH(at3) _JS_CTYPE_ACH(at2) _JS_CTYPE_ACH(at1) \ - _JS_CTYPE_ACH(at0), \ - _JS_CTYPE_FLAGS(rt) - -#define _JS_TN_INIT_HELPER_6(linkage, rt, op, at0, at1, at2, at3, at4, at5, isPure, storeAccSet) \ - &_JS_CALLINFO(op), \ - _JS_CTYPE_PCH(at5) _JS_CTYPE_PCH(at4) _JS_CTYPE_PCH(at3) _JS_CTYPE_PCH(at2) \ - _JS_CTYPE_PCH(at1) _JS_CTYPE_PCH(at0), \ - _JS_CTYPE_ACH(at5) _JS_CTYPE_ACH(at4) _JS_CTYPE_ACH(at3) _JS_CTYPE_ACH(at2) \ - _JS_CTYPE_ACH(at1) _JS_CTYPE_ACH(at0), \ - _JS_CTYPE_FLAGS(rt) - -#define _JS_TN_INIT_HELPER_7(linkage, rt, op, at0, at1, at2, at3, at4, at5, at6, isPure, storeAccSet) \ - &_JS_CALLINFO(op), \ - _JS_CTYPE_PCH(at6) _JS_CTYPE_PCH(at5) _JS_CTYPE_PCH(at4) _JS_CTYPE_PCH(at3) \ - _JS_CTYPE_PCH(at2) _JS_CTYPE_PCH(at1) _JS_CTYPE_PCH(at0), \ - _JS_CTYPE_ACH(at6) _JS_CTYPE_ACH(at5) _JS_CTYPE_ACH(at4) _JS_CTYPE_ACH(at3) \ - _JS_CTYPE_ACH(at2) _JS_CTYPE_ACH(at1) _JS_CTYPE_ACH(at0), \ - _JS_CTYPE_FLAGS(rt) - -#define _JS_TN_INIT_HELPER_8(linkage, rt, op, at0, at1, at2, at3, at4, at5, at6, at7, isPure, storeAccSet) \ - &_JS_CALLINFO(op), \ - _JS_CTYPE_PCH(at7) _JS_CTYPE_PCH(at6) _JS_CTYPE_PCH(at5) _JS_CTYPE_PCH(at4) \ - _JS_CTYPE_PCH(at3) _JS_CTYPE_PCH(at2) _JS_CTYPE_PCH(at1) _JS_CTYPE_PCH(at0), \ - _JS_CTYPE_ACH(at7) _JS_CTYPE_ACH(at6) _JS_CTYPE_ACH(at5) _JS_CTYPE_ACH(at4) \ - _JS_CTYPE_ACH(at3) _JS_CTYPE_ACH(at2) _JS_CTYPE_ACH(at1) _JS_CTYPE_ACH(at0), \ - _JS_CTYPE_FLAGS(rt) - -#define JS_DEFINE_TRCINFO_1(name, tn0) \ - _JS_DEFINE_CALLINFO_n tn0 \ - JSSpecializedNative name##_sns[] = { \ - { _JS_TN_INIT_HELPER_n tn0 } \ - }; \ - JSNativeTraceInfo name##_trcinfo = { JS_VALUEIFY_NATIVE(name), name##_sns }; - -#define JS_DEFINE_TRCINFO_2(name, tn0, tn1) \ - _JS_DEFINE_CALLINFO_n tn0 \ - _JS_DEFINE_CALLINFO_n tn1 \ - JSSpecializedNative name##_sns[] = { \ - { _JS_TN_INIT_HELPER_n tn0 | JSTN_MORE }, \ - { _JS_TN_INIT_HELPER_n tn1 } \ - }; \ - JSNativeTraceInfo name##_trcinfo = { JS_VALUEIFY_NATIVE(name), name##_sns }; - -#define JS_DEFINE_TRCINFO_3(name, tn0, tn1, tn2) \ - _JS_DEFINE_CALLINFO_n tn0 \ - _JS_DEFINE_CALLINFO_n tn1 \ - _JS_DEFINE_CALLINFO_n tn2 \ - JSSpecializedNative name##_sns[] = { \ - { _JS_TN_INIT_HELPER_n tn0 | JSTN_MORE }, \ - { _JS_TN_INIT_HELPER_n tn1 | JSTN_MORE }, \ - { _JS_TN_INIT_HELPER_n tn2 } \ - }; \ - JSNativeTraceInfo name##_trcinfo = { JS_VALUEIFY_NATIVE(name), name##_sns }; - -#define JS_DEFINE_TRCINFO_4(name, tn0, tn1, tn2, tn3) \ - _JS_DEFINE_CALLINFO_n tn0 \ - _JS_DEFINE_CALLINFO_n tn1 \ - _JS_DEFINE_CALLINFO_n tn2 \ - _JS_DEFINE_CALLINFO_n tn3 \ - JSSpecializedNative name##_sns[] = { \ - { _JS_TN_INIT_HELPER_n tn0 | JSTN_MORE }, \ - { _JS_TN_INIT_HELPER_n tn1 | JSTN_MORE }, \ - { _JS_TN_INIT_HELPER_n tn2 | JSTN_MORE }, \ - { _JS_TN_INIT_HELPER_n tn3 } \ - }; \ - JSNativeTraceInfo name##_trcinfo = { JS_VALUEIFY_NATIVE(name), name##_sns }; - -#define _JS_DEFINE_CALLINFO_n(n, args) JS_DEFINE_CALLINFO_##n args - -jsdouble FASTCALL -js_StringToNumber(JSContext* cx, JSString* str, JSBool *ok); - -/* Extern version of SetBuiltinError. */ -extern JS_FRIEND_API(void) -js_SetTraceableNativeFailed(JSContext *cx); - -extern jsdouble FASTCALL -js_dmod(jsdouble a, jsdouble b); - -#else - -#define JS_DEFINE_CALLINFO_1(linkage, rt, op, at0, isPure, storeAccSet) -#define JS_DEFINE_CALLINFO_2(linkage, rt, op, at0, at1, isPure, storeAccSet) -#define JS_DEFINE_CALLINFO_3(linkage, rt, op, at0, at1, at2, isPure, storeAccSet) -#define JS_DEFINE_CALLINFO_4(linkage, rt, op, at0, at1, at2, at3, isPure, storeAccSet) -#define JS_DEFINE_CALLINFO_5(linkage, rt, op, at0, at1, at2, at3, at4, isPure, storeAccSet) -#define JS_DEFINE_CALLINFO_6(linkage, rt, op, at0, at1, at2, at3, at4, at5, isPure, storeAccSet) -#define JS_DEFINE_CALLINFO_7(linkage, rt, op, at0, at1, at2, at3, at4, at5, at6, isPure, storeAccSet) -#define JS_DEFINE_CALLINFO_8(linkage, rt, op, at0, at1, at2, at3, at4, at5, at6, at7, isPure, storeAccSet) -#define JS_DECLARE_CALLINFO(name) -#define JS_DEFINE_TRCINFO_1(name, tn0) -#define JS_DEFINE_TRCINFO_2(name, tn0, tn1) -#define JS_DEFINE_TRCINFO_3(name, tn0, tn1, tn2) -#define JS_DEFINE_TRCINFO_4(name, tn0, tn1, tn2, tn3) - -#endif /* !JS_TRACER */ - -/* Defined in jsarray.cpp. */ -namespace js { -JS_DECLARE_CALLINFO(NewDenseEmptyArray) -JS_DECLARE_CALLINFO(NewDenseAllocatedArray) -JS_DECLARE_CALLINFO(NewDenseUnallocatedArray) -} -JS_DECLARE_CALLINFO(js_ArrayCompPush_tn) -JS_DECLARE_CALLINFO(js_EnsureDenseArrayCapacity) - -/* Defined in jsbuiltins.cpp. */ -JS_DECLARE_CALLINFO(js_UnboxDouble) -JS_DECLARE_CALLINFO(js_UnboxInt32) -JS_DECLARE_CALLINFO(js_dmod) -JS_DECLARE_CALLINFO(js_imod) -JS_DECLARE_CALLINFO(js_DoubleToInt32) -JS_DECLARE_CALLINFO(js_DoubleToUint32) -JS_DECLARE_CALLINFO(js_StringToNumber) -JS_DECLARE_CALLINFO(js_StringToInt32) -JS_DECLARE_CALLINFO(js_AddProperty) -JS_DECLARE_CALLINFO(js_AddAtomProperty) -JS_DECLARE_CALLINFO(js_HasNamedProperty) -JS_DECLARE_CALLINFO(js_HasNamedPropertyInt32) -JS_DECLARE_CALLINFO(js_TypeOfObject) -JS_DECLARE_CALLINFO(js_BooleanIntToString) -JS_DECLARE_CALLINFO(js_NewNullClosure) - -/* Defined in jsfun.cpp. */ -JS_DECLARE_CALLINFO(js_AllocFlatClosure) -JS_DECLARE_CALLINFO(js_PutArgumentsOnTrace) -JS_DECLARE_CALLINFO(js_PutCallObjectOnTrace) -JS_DECLARE_CALLINFO(js_SetCallVar) -JS_DECLARE_CALLINFO(js_SetCallArg) -JS_DECLARE_CALLINFO(js_CloneFunctionObject) -JS_DECLARE_CALLINFO(js_CreateCallObjectOnTrace) -JS_DECLARE_CALLINFO(js_NewArgumentsOnTrace) - -/* Defined in jsnum.cpp. */ -JS_DECLARE_CALLINFO(js_NumberToString) - -/* Defined in jsobj.cpp. */ -JS_DECLARE_CALLINFO(js_Object_tn) -JS_DECLARE_CALLINFO(js_CreateThisFromTrace) -JS_DECLARE_CALLINFO(js_InitializerObject) - -/* Defined in jsregexp.cpp. */ -JS_DECLARE_CALLINFO(js_CloneRegExpObject) - -/* Defined in jsstr.cpp. */ -JS_DECLARE_CALLINFO(js_String_tn) -JS_DECLARE_CALLINFO(js_CompareStringsOnTrace) -JS_DECLARE_CALLINFO(js_ConcatStrings) -JS_DECLARE_CALLINFO(js_EqualStringsOnTrace) -JS_DECLARE_CALLINFO(js_Flatten) - -/* Defined in jstypedarray.cpp. */ -JS_DECLARE_CALLINFO(js_TypedArray_uint8_clamp_double) - -#endif /* jsbuiltins_h___ */ diff --git a/x86/mozilla/include/jscell.h b/x86/mozilla/include/jscell.h deleted file mode 100644 index aadfe8d..0000000 --- a/x86/mozilla/include/jscell.h +++ /dev/null @@ -1,99 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is SpiderMonkey code. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Gregor Wagner - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jscell_h___ -#define jscell_h___ - -struct JSCompartment; - -namespace js { -namespace gc { - -template struct Arena; -struct ArenaBitmap; -struct MarkingDelay; -struct Chunk; -struct FreeCell; - -/* - * A GC cell is the base class for GC Things like JSObject, JSShortString, - * JSFunction, JSXML and for an empty cell called FreeCell. It helps avoiding - * casts from an Object to a Cell whenever we call GC related mark functions. - * Cell is not the base Class for JSString because static initialization - * (used for unitStringTables) does not work with inheritance. - */ - -struct Cell { - static const size_t CellShift = 3; - static const size_t CellSize = size_t(1) << CellShift; - static const size_t CellMask = CellSize - 1; - - inline Arena *arena() const; - inline Chunk *chunk() const; - inline ArenaBitmap *bitmap() const; - JS_ALWAYS_INLINE size_t cellIndex() const; - - JS_ALWAYS_INLINE bool isMarked(uint32 color) const; - JS_ALWAYS_INLINE bool markIfUnmarked(uint32 color) const; - JS_ALWAYS_INLINE void unmark(uint32 color) const; - - inline JSCompartment *compartment() const; - - /* Needed for compatibility reasons because Cell can't be a base class of JSString */ - JS_ALWAYS_INLINE js::gc::Cell *asCell() { return this; } - - JS_ALWAYS_INLINE js::gc::FreeCell *asFreeCell() { - return reinterpret_cast(this); - } -}; - -/* FreeCell has always size 8 */ -struct FreeCell : Cell { - union { - FreeCell *link; - double data; - }; -}; - -JS_STATIC_ASSERT(sizeof(FreeCell) == 8); - -} /* namespace gc */ -} /* namespace js */ - -#endif /* jscell_h___ */ diff --git a/x86/mozilla/include/jsclist.h b/x86/mozilla/include/jsclist.h deleted file mode 100644 index 604ec0e..0000000 --- a/x86/mozilla/include/jsclist.h +++ /dev/null @@ -1,139 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsclist_h___ -#define jsclist_h___ - -#include "jstypes.h" - -/* -** Circular linked list -*/ -typedef struct JSCListStr { - struct JSCListStr *next; - struct JSCListStr *prev; -} JSCList; - -/* -** Insert element "_e" into the list, before "_l". -*/ -#define JS_INSERT_BEFORE(_e,_l) \ - JS_BEGIN_MACRO \ - (_e)->next = (_l); \ - (_e)->prev = (_l)->prev; \ - (_l)->prev->next = (_e); \ - (_l)->prev = (_e); \ - JS_END_MACRO - -/* -** Insert element "_e" into the list, after "_l". -*/ -#define JS_INSERT_AFTER(_e,_l) \ - JS_BEGIN_MACRO \ - (_e)->next = (_l)->next; \ - (_e)->prev = (_l); \ - (_l)->next->prev = (_e); \ - (_l)->next = (_e); \ - JS_END_MACRO - -/* -** Return the element following element "_e" -*/ -#define JS_NEXT_LINK(_e) \ - ((_e)->next) -/* -** Return the element preceding element "_e" -*/ -#define JS_PREV_LINK(_e) \ - ((_e)->prev) - -/* -** Append an element "_e" to the end of the list "_l" -*/ -#define JS_APPEND_LINK(_e,_l) JS_INSERT_BEFORE(_e,_l) - -/* -** Insert an element "_e" at the head of the list "_l" -*/ -#define JS_INSERT_LINK(_e,_l) JS_INSERT_AFTER(_e,_l) - -/* Return the head/tail of the list */ -#define JS_LIST_HEAD(_l) (_l)->next -#define JS_LIST_TAIL(_l) (_l)->prev - -/* -** Remove the element "_e" from it's circular list. -*/ -#define JS_REMOVE_LINK(_e) \ - JS_BEGIN_MACRO \ - (_e)->prev->next = (_e)->next; \ - (_e)->next->prev = (_e)->prev; \ - JS_END_MACRO - -/* -** Remove the element "_e" from it's circular list. Also initializes the -** linkage. -*/ -#define JS_REMOVE_AND_INIT_LINK(_e) \ - JS_BEGIN_MACRO \ - (_e)->prev->next = (_e)->next; \ - (_e)->next->prev = (_e)->prev; \ - (_e)->next = (_e); \ - (_e)->prev = (_e); \ - JS_END_MACRO - -/* -** Return non-zero if the given circular list "_l" is empty, zero if the -** circular list is not empty -*/ -#define JS_CLIST_IS_EMPTY(_l) \ - ((_l)->next == (_l)) - -/* -** Initialize a circular list -*/ -#define JS_INIT_CLIST(_l) \ - JS_BEGIN_MACRO \ - (_l)->next = (_l); \ - (_l)->prev = (_l); \ - JS_END_MACRO - -#define JS_INIT_STATIC_CLIST(_l) \ - {(_l), (_l)} - -#endif /* jsclist_h___ */ diff --git a/x86/mozilla/include/jsclone.h b/x86/mozilla/include/jsclone.h deleted file mode 100644 index dbead17..0000000 --- a/x86/mozilla/include/jsclone.h +++ /dev/null @@ -1,191 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is JavaScript structured data serialization. - * - * The Initial Developer of the Original Code is - * the Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Jason Orendorff - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsclone_h___ -#define jsclone_h___ - -#include "jsapi.h" -#include "jscntxt.h" -#include "jshashtable.h" -#include "jsstdint.h" -#include "jsvector.h" -#include "jsvalue.h" - -namespace js { - -bool -WriteStructuredClone(JSContext *cx, const Value &v, uint64_t **bufp, size_t *nbytesp, - const JSStructuredCloneCallbacks *cb, void *cbClosure); - -bool -ReadStructuredClone(JSContext *cx, const uint64_t *data, size_t nbytes, Value *vp, - const JSStructuredCloneCallbacks *cb, void *cbClosure); - -struct SCOutput { - public: - explicit SCOutput(JSContext *cx); - - JSContext *context() const { return cx; } - - bool write(uint64_t u); - bool writePair(uint32_t tag, uint32_t data); - bool writeDouble(jsdouble d); - bool writeBytes(const void *p, size_t nbytes); - bool writeChars(const jschar *p, size_t nchars); - - template - bool writeArray(const T *p, size_t nbytes); - - bool extractBuffer(uint64_t **datap, size_t *sizep); - - private: - JSContext *cx; - js::Vector buf; -}; - -struct SCInput { - public: - SCInput(JSContext *cx, const uint64_t *data, size_t nbytes); - - JSContext *context() const { return cx; } - - bool read(uint64_t *p); - bool readPair(uint32_t *tagp, uint32_t *datap); - bool readDouble(jsdouble *p); - bool readBytes(void *p, size_t nbytes); - bool readChars(jschar *p, size_t nchars); - - template - bool readArray(T *p, size_t nelems); - - private: - bool eof(); - - void staticAssertions() { - JS_STATIC_ASSERT(sizeof(jschar) == 2); - JS_STATIC_ASSERT(sizeof(uint32_t) == 4); - JS_STATIC_ASSERT(sizeof(jsdouble) == 8); - } - - JSContext *cx; - const uint64_t *point; - const uint64_t *end; -}; - -} - -struct JSStructuredCloneReader { - public: - explicit JSStructuredCloneReader(js::SCInput &in, const JSStructuredCloneCallbacks *cb, - void *cbClosure) - : in(in), objs(in.context()), callbacks(cb), closure(cbClosure) { } - - js::SCInput &input() { return in; } - bool read(js::Value *vp); - - private: - JSContext *context() { return in.context(); } - - bool checkDouble(jsdouble d); - JSString *readString(uint32_t nchars); - bool readTypedArray(uint32_t tag, uint32_t nelems, js::Value *vp); - bool readArrayBuffer(uint32_t nbytes, js::Value *vp); - bool readId(jsid *idp); - bool startRead(js::Value *vp); - - js::SCInput ∈ - - // Stack of objects with properties remaining to be read. - js::AutoValueVector objs; - - // The user defined callbacks that will be used for cloning. - const JSStructuredCloneCallbacks *callbacks; - - // Any value passed to JS_ReadStructuredClone. - void *closure; -}; - -struct JSStructuredCloneWriter { - public: - explicit JSStructuredCloneWriter(js::SCOutput &out, const JSStructuredCloneCallbacks *cb, - void *cbClosure) - : out(out), objs(out.context()), counts(out.context()), ids(out.context()), - memory(out.context()), callbacks(cb), closure(cbClosure) { } - - bool init() { return memory.init(); } - - bool write(const js::Value &v); - - js::SCOutput &output() { return out; } - - private: - JSContext *context() { return out.context(); } - - bool writeString(uint32_t tag, JSString *str); - bool writeId(jsid id); - bool writeArrayBuffer(JSObject *obj); - bool writeTypedArray(JSObject *obj); - bool startObject(JSObject *obj); - bool startWrite(const js::Value &v); - - inline void checkStack(); - - js::SCOutput &out; - - // Stack of objects with properties remaining to be written. - js::AutoValueVector objs; - - // counts[i] is the number of properties of objs[i] remaining to be written. - // counts.length() == objs.length() and sum(counts) == ids.length(). - js::Vector counts; - - // Ids of properties remaining to be written. - js::AutoIdVector ids; - - // The "memory" list described in the HTML5 internal structured cloning algorithm. - // memory has the same elements as objs. - js::HashSet memory; - - // The user defined callbacks that will be used for cloning. - const JSStructuredCloneCallbacks *callbacks; - - // Any value passed to JS_WriteStructuredClone. - void *closure; -}; - -#endif /* jsclone_h___ */ diff --git a/x86/mozilla/include/jscntxt.h b/x86/mozilla/include/jscntxt.h deleted file mode 100644 index 4c9a2cc..0000000 --- a/x86/mozilla/include/jscntxt.h +++ /dev/null @@ -1,3348 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=78: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jscntxt_h___ -#define jscntxt_h___ -/* - * JS execution context. - */ -#include - -/* Gross special case for Gecko, which defines malloc/calloc/free. */ -#ifdef mozilla_mozalloc_macro_wrappers_h -# define JS_CNTXT_UNDEFD_MOZALLOC_WRAPPERS -/* The "anti-header" */ -# include "mozilla/mozalloc_undef_macro_wrappers.h" -#endif - -#include "jsprvtd.h" -#include "jsarena.h" -#include "jsclist.h" -#include "jslong.h" -#include "jsatom.h" -#include "jsdhash.h" -#include "jsdtoa.h" -#include "jsfun.h" -#include "jsgc.h" -#include "jsgcchunk.h" -#include "jshashtable.h" -#include "jsinterp.h" -#include "jsmath.h" -#include "jsobj.h" -#include "jspropertycache.h" -#include "jspropertytree.h" -#include "jsstaticcheck.h" -#include "jsutil.h" -#include "jsarray.h" -#include "jsvector.h" -#include "prmjtime.h" - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4100) /* Silence unreferenced formal parameter warnings */ -#pragma warning(push) -#pragma warning(disable:4355) /* Silence warning about "this" used in base member initializer list */ -#endif - -/* - * js_GetSrcNote cache to avoid O(n^2) growth in finding a source note for a - * given pc in a script. We use the script->code pointer to tag the cache, - * instead of the script address itself, so that source notes are always found - * by offset from the bytecode with which they were generated. - */ -typedef struct JSGSNCache { - jsbytecode *code; - JSDHashTable table; -#ifdef JS_GSNMETER - uint32 hits; - uint32 misses; - uint32 fills; - uint32 purges; -# define GSN_CACHE_METER(cache,cnt) (++(cache)->cnt) -#else -# define GSN_CACHE_METER(cache,cnt) /* nothing */ -#endif -} JSGSNCache; - -#define js_FinishGSNCache(cache) js_PurgeGSNCache(cache) - -extern void -js_PurgeGSNCache(JSGSNCache *cache); - -/* These helper macros take a cx as parameter and operate on its GSN cache. */ -#define JS_PURGE_GSN_CACHE(cx) js_PurgeGSNCache(&JS_GSN_CACHE(cx)) -#define JS_METER_GSN_CACHE(cx,cnt) GSN_CACHE_METER(&JS_GSN_CACHE(cx), cnt) - -/* Forward declarations of nanojit types. */ -namespace nanojit { - -class Assembler; -class CodeAlloc; -class Fragment; -template struct DefaultHash; -template class HashMap; -template class Seq; - -} /* namespace nanojit */ - -namespace js { - -/* Tracer constants. */ -static const size_t MONITOR_N_GLOBAL_STATES = 4; -static const size_t FRAGMENT_TABLE_SIZE = 512; -static const size_t MAX_NATIVE_STACK_SLOTS = 4096; -static const size_t MAX_CALL_STACK_ENTRIES = 500; -static const size_t MAX_GLOBAL_SLOTS = 4096; -static const size_t GLOBAL_SLOTS_BUFFER_SIZE = MAX_GLOBAL_SLOTS + 1; -static const size_t MAX_SLOW_NATIVE_EXTRA_SLOTS = 16; - -/* Forward declarations of tracer types. */ -class VMAllocator; -class FrameInfoCache; -struct FrameInfo; -struct VMSideExit; -struct TreeFragment; -struct TracerState; -template class Queue; -typedef Queue SlotList; -class TypeMap; -class LoopProfile; - -#if defined(JS_JIT_SPEW) || defined(DEBUG) -struct FragPI; -typedef nanojit::HashMap > FragStatsMap; -#endif - -namespace mjit { -class JaegerCompartment; -} - -/* - * Allocation policy that calls JSContext memory functions and reports errors - * to the context. Since the JSContext given on construction is stored for - * the lifetime of the container, this policy may only be used for containers - * whose lifetime is a shorter than the given JSContext. - */ -class ContextAllocPolicy -{ - JSContext *cx; - - public: - ContextAllocPolicy(JSContext *cx) : cx(cx) {} - JSContext *context() const { return cx; } - - /* Inline definitions below. */ - void *malloc(size_t bytes); - void free(void *p); - void *realloc(void *p, size_t bytes); - void reportAllocOverflow() const; -}; - -/* - * A StackSegment (referred to as just a 'segment') contains a prev-linked set - * of stack frames and the slots associated with each frame. A segment and its - * contained frames/slots also have a precise memory layout that is described - * in the js::StackSpace comment. A key layout invariant for segments is that - * prev-linked frames are adjacent in memory, separated only by the values that - * constitute the locals and expression stack of the prev-frame. - * - * The set of stack frames in a non-empty segment start at the segment's - * "current frame", which is the most recently pushed frame, and ends at the - * segment's "initial frame". Note that, while all stack frames in a segment - * are prev-linked, not all prev-linked frames are in the same segment. Hence, - * for a segment |ss|, |ss->getInitialFrame()->prev| may be non-null and in a - * different segment. This occurs when the VM reenters itself (via Invoke or - * Execute). In full generality, a single context may contain a forest of trees - * of stack frames. With respect to this forest, a segment contains a linear - * path along a single tree, not necessarily to the root. - * - * The frames of a non-empty segment must all be in the same context and thus - * each non-empty segment is referred to as being "in" a context. Segments in a - * context have an additional state of being either "active" or "suspended". A - * suspended segment |ss| has a "suspended frame" which is snapshot of |cx->regs| - * when the segment was suspended and serves as the current frame of |ss|. - * There is at most one active segment in a given context. Segments in a - * context execute LIFO and are maintained in a stack. The top of this stack - * is the context's "current segment". If a context |cx| has an active segment - * |ss|, then: - * 1. |ss| is |cx|'s current segment, - * 2. |cx->regs != NULL|, and - * 3. |ss|'s current frame is |cx->regs->fp|. - * Moreover, |cx->regs != NULL| iff |cx| has an active segment. - * - * An empty segment is not associated with any context. Empty segments are - * created when there is not an active segment for a context at the top of the - * stack and claim space for the arguments of an Invoke before the Invoke's - * stack frame is pushed. During the intervals when the arguments have been - * pushed, but not the stack frame, the segment cannot be pushed onto the - * context, since that would require some hack to deal with cx->fp not being - * the current frame of cx->currentSegment. - * - * Finally, (to support JS_SaveFrameChain/JS_RestoreFrameChain) a suspended - * segment may or may not be "saved". Normally, when the active segment is - * popped, the previous segment (which is necessarily suspended) becomes - * active. If the previous segment was saved, however, then it stays suspended - * until it is made active by a call to JS_RestoreFrameChain. This is why a - * context may have a current segment, but not an active segment. - */ -class StackSegment -{ - /* The context to which this segment belongs. */ - JSContext *cx; - - /* Link for JSContext segment stack mentioned in big comment above. */ - StackSegment *previousInContext; - - /* Link for StackSpace segment stack mentioned in StackSpace comment. */ - StackSegment *previousInMemory; - - /* The first frame executed in this segment. null iff cx is null */ - JSStackFrame *initialFrame; - - /* If this segment is suspended, |cx->regs| when it was suspended. */ - JSFrameRegs *suspendedRegs; - - /* The varobj on entry to initialFrame. */ - JSObject *initialVarObj; - - /* Whether this segment was suspended by JS_SaveFrameChain. */ - bool saved; - - /* Align at 8 bytes on all platforms. */ -#if JS_BITS_PER_WORD == 32 - void *padding; -#endif - - /* - * To make isActive a single null-ness check, this non-null constant is - * assigned to suspendedRegs when !inContext. - */ -#define NON_NULL_SUSPENDED_REGS ((JSFrameRegs *)0x1) - - public: - StackSegment() - : cx(NULL), previousInContext(NULL), previousInMemory(NULL), - initialFrame(NULL), suspendedRegs(NON_NULL_SUSPENDED_REGS), - initialVarObj(NULL), saved(false) - { - JS_ASSERT(!inContext()); - } - - /* Safe casts guaranteed by the contiguous-stack layout. */ - - Value *valueRangeBegin() const { - return (Value *)(this + 1); - } - - /* - * As described in the comment at the beginning of the class, a segment - * is in one of three states: - * - * !inContext: the segment has been created to root arguments for a - * future call to Invoke. - * isActive: the segment describes a set of stack frames in a context, - * where the top frame currently executing. - * isSuspended: like isActive, but the top frame has been suspended. - */ - - bool inContext() const { - JS_ASSERT(!!cx == !!initialFrame); - JS_ASSERT_IF(!cx, suspendedRegs == NON_NULL_SUSPENDED_REGS && !saved); - return cx; - } - - bool isActive() const { - JS_ASSERT_IF(!suspendedRegs, cx && !saved); - JS_ASSERT_IF(!cx, suspendedRegs == NON_NULL_SUSPENDED_REGS); - return !suspendedRegs; - } - - bool isSuspended() const { - JS_ASSERT_IF(!cx || !suspendedRegs, !saved); - JS_ASSERT_IF(!cx, suspendedRegs == NON_NULL_SUSPENDED_REGS); - return cx && suspendedRegs; - } - - /* Substate of suspended, queryable in any state. */ - - bool isSaved() const { - JS_ASSERT_IF(saved, isSuspended()); - return saved; - } - - /* Transitioning between inContext <--> isActive */ - - void joinContext(JSContext *cx, JSStackFrame *f) { - JS_ASSERT(!inContext()); - this->cx = cx; - initialFrame = f; - suspendedRegs = NULL; - JS_ASSERT(isActive()); - } - - void leaveContext() { - JS_ASSERT(isActive()); - this->cx = NULL; - initialFrame = NULL; - suspendedRegs = NON_NULL_SUSPENDED_REGS; - JS_ASSERT(!inContext()); - } - - JSContext *maybeContext() const { - return cx; - } - -#undef NON_NULL_SUSPENDED_REGS - - /* Transitioning between isActive <--> isSuspended */ - - void suspend(JSFrameRegs *regs) { - JS_ASSERT(isActive()); - JS_ASSERT(regs && regs->fp && contains(regs->fp)); - suspendedRegs = regs; - JS_ASSERT(isSuspended()); - } - - void resume() { - JS_ASSERT(isSuspended()); - suspendedRegs = NULL; - JS_ASSERT(isActive()); - } - - /* When isSuspended, transitioning isSaved <--> !isSaved */ - - void save(JSFrameRegs *regs) { - JS_ASSERT(!isSuspended()); - suspend(regs); - saved = true; - JS_ASSERT(isSaved()); - } - - void restore() { - JS_ASSERT(isSaved()); - saved = false; - resume(); - JS_ASSERT(!isSuspended()); - } - - /* Data available when inContext */ - - JSStackFrame *getInitialFrame() const { - JS_ASSERT(inContext()); - return initialFrame; - } - - inline JSFrameRegs *getCurrentRegs() const; - inline JSStackFrame *getCurrentFrame() const; - - /* Data available when isSuspended. */ - - JSFrameRegs *getSuspendedRegs() const { - JS_ASSERT(isSuspended()); - return suspendedRegs; - } - - JSStackFrame *getSuspendedFrame() const { - return suspendedRegs->fp; - } - - /* JSContext / js::StackSpace bookkeeping. */ - - void setPreviousInContext(StackSegment *seg) { - previousInContext = seg; - } - - StackSegment *getPreviousInContext() const { - return previousInContext; - } - - void setPreviousInMemory(StackSegment *seg) { - previousInMemory = seg; - } - - StackSegment *getPreviousInMemory() const { - return previousInMemory; - } - - void setInitialVarObj(JSObject *obj) { - JS_ASSERT(inContext()); - initialVarObj = obj; - } - - bool hasInitialVarObj() { - JS_ASSERT(inContext()); - return initialVarObj != NULL; - } - - JSObject &getInitialVarObj() const { - JS_ASSERT(inContext() && initialVarObj); - return *initialVarObj; - } - -#ifdef DEBUG - JS_REQUIRES_STACK bool contains(const JSStackFrame *fp) const; -#endif -}; - -static const size_t VALUES_PER_STACK_SEGMENT = sizeof(StackSegment) / sizeof(Value); -JS_STATIC_ASSERT(sizeof(StackSegment) % sizeof(Value) == 0); - -/* See StackSpace::pushInvokeArgs. */ -class InvokeArgsGuard : public CallArgs -{ - friend class StackSpace; - JSContext *cx; /* null implies nothing pushed */ - StackSegment *seg; - Value *prevInvokeArgEnd; -#ifdef DEBUG - StackSegment *prevInvokeSegment; - JSStackFrame *prevInvokeFrame; -#endif - public: - InvokeArgsGuard() : cx(NULL), seg(NULL) {} - ~InvokeArgsGuard(); - bool pushed() const { return cx != NULL; } -}; - -/* - * This type can be used to call Invoke when the arguments have already been - * pushed onto the stack as part of normal execution. - */ -struct InvokeArgsAlreadyOnTheStack : CallArgs -{ - InvokeArgsAlreadyOnTheStack(Value *vp, uintN argc) : CallArgs(vp + 2, argc) {} -}; - -/* See StackSpace::pushInvokeFrame. */ -class InvokeFrameGuard -{ - friend class StackSpace; - JSContext *cx_; /* null implies nothing pushed */ - JSFrameRegs regs_; - JSFrameRegs *prevRegs_; - public: - InvokeFrameGuard() : cx_(NULL) {} - ~InvokeFrameGuard() { if (pushed()) pop(); } - bool pushed() const { return cx_ != NULL; } - JSContext *pushedFrameContext() const { JS_ASSERT(pushed()); return cx_; } - void pop(); - JSStackFrame *fp() const { return regs_.fp; } -}; - -/* Reusable base; not for direct use. */ -class FrameGuard -{ - friend class StackSpace; - JSContext *cx_; /* null implies nothing pushed */ - StackSegment *seg_; - Value *vp_; - JSStackFrame *fp_; - public: - FrameGuard() : cx_(NULL), vp_(NULL), fp_(NULL) {} - JS_REQUIRES_STACK ~FrameGuard(); - bool pushed() const { return cx_ != NULL; } - StackSegment *segment() const { return seg_; } - Value *vp() const { return vp_; } - JSStackFrame *fp() const { return fp_; } -}; - -/* See StackSpace::pushExecuteFrame. */ -class ExecuteFrameGuard : public FrameGuard -{ - friend class StackSpace; - JSFrameRegs regs_; -}; - -/* See StackSpace::pushDummyFrame. */ -class DummyFrameGuard : public FrameGuard -{ - friend class StackSpace; - JSFrameRegs regs_; -}; - -/* See StackSpace::pushGeneratorFrame. */ -class GeneratorFrameGuard : public FrameGuard -{}; - -/* - * Stack layout - * - * Each JSThreadData has one associated StackSpace object which allocates all - * segments for the thread. StackSpace performs all such allocations in a - * single, fixed-size buffer using a specific layout scheme that allows some - * associations between segments, frames, and slots to be implicit, rather - * than explicitly stored as pointers. To maintain useful invariants, stack - * space is not given out arbitrarily, but rather allocated/deallocated for - * specific purposes. The use cases currently supported are: calling a function - * with arguments (e.g. Invoke), executing a script (e.g. Execute), inline - * interpreter calls, and pushing "dummy" frames for bookkeeping purposes. See - * associated member functions below. - * - * First, we consider the layout of individual segments. (See the - * js::StackSegment comment for terminology.) A non-empty segment (i.e., a - * segment in a context) has the following layout: - * - * initial frame current frame ------. if regs, - * .------------. | | regs->sp - * | V V V - * |segment| slots |frame| slots |frame| slots |frame| slots | - * | ^ | ^ | - * ? <----------' `----------' `----------' - * prev prev prev - * - * Moreover, the bytes in the following ranges form a contiguous array of - * Values that are marked during GC: - * 1. between a segment and its first frame - * 2. between two adjacent frames in a segment - * 3. between a segment's current frame and (if fp->regs) fp->regs->sp - * Thus, the VM must ensure that all such Values are safe to be marked. - * - * An empty segment is followed by arguments that are rooted by the - * StackSpace::invokeArgEnd pointer: - * - * invokeArgEnd - * | - * V - * |segment| slots | - * - * Above the level of segments, a StackSpace is simply a contiguous sequence - * of segments kept in a linked list: - * - * base currentSegment firstUnused end - * | | | | - * V V V V - * |segment| --- |segment| --- |segment| ------- | | - * | ^ | ^ | - * 0 <---' `-----------' `-----------' - * previous previous previous - * - * Both js::StackSpace and JSContext maintain a stack of segments, the top of - * which is the "current segment" for that thread or context, respectively. - * Since different contexts can arbitrarily interleave execution in a single - * thread, these stacks are different enough that a segment needs both - * "previousInMemory" and "previousInContext". - * - * For example, in a single thread, a function in segment S1 in a context CX1 - * may call out into C++ code that reenters the VM in a context CX2, which - * creates a new segment S2 in CX2, and CX1 may or may not equal CX2. - * - * Note that there is some structure to this interleaving of segments: - * 1. the inclusion from segments in a context to segments in a thread - * preserves order (in terms of previousInContext and previousInMemory, - * respectively). - * 2. the mapping from stack frames to their containing segment preserves - * order (in terms of prev and previousInContext, respectively). - */ -class StackSpace -{ - Value *base; -#ifdef XP_WIN - mutable Value *commitEnd; -#endif - Value *end; - StackSegment *currentSegment; -#ifdef DEBUG - /* - * Keep track of which segment/frame bumped invokeArgEnd so that - * firstUnused() can assert that, when invokeArgEnd is used as the top of - * the stack, it is being used appropriately. - */ - StackSegment *invokeSegment; - JSStackFrame *invokeFrame; -#endif - Value *invokeArgEnd; - - friend class InvokeArgsGuard; - friend class InvokeFrameGuard; - friend class FrameGuard; - - bool pushSegmentForInvoke(JSContext *cx, uintN argc, InvokeArgsGuard *ag); - void popSegmentForInvoke(const InvokeArgsGuard &ag); - - bool pushInvokeFrameSlow(JSContext *cx, const InvokeArgsGuard &ag, - InvokeFrameGuard *fg); - void popInvokeFrameSlow(const CallArgs &args); - - bool getSegmentAndFrame(JSContext *cx, uintN vplen, uintN nslots, - FrameGuard *fg) const; - void pushSegmentAndFrame(JSContext *cx, JSFrameRegs *regs, FrameGuard *fg); - void popSegmentAndFrame(JSContext *cx); - - struct EnsureSpaceCheck { - inline bool operator()(const StackSpace &, JSContext *, Value *, uintN); - }; - - struct LimitCheck { - JSStackFrame *base; - Value **limit; - LimitCheck(JSStackFrame *base, Value **limit) : base(base), limit(limit) {} - inline bool operator()(const StackSpace &, JSContext *, Value *, uintN); - }; - - template - inline JSStackFrame *getCallFrame(JSContext *cx, Value *sp, uintN nactual, - JSFunction *fun, JSScript *script, - uint32 *pflags, Check check) const; - - inline void popInvokeArgs(const InvokeArgsGuard &args); - inline void popInvokeFrame(const InvokeFrameGuard &ag); - - inline Value *firstUnused() const; - - inline bool isCurrentAndActive(JSContext *cx) const; - friend class AllFramesIter; - StackSegment *getCurrentSegment() const { return currentSegment; } - -#ifdef XP_WIN - /* Commit more memory from the reserved stack space. */ - JS_FRIEND_API(bool) bumpCommit(Value *from, ptrdiff_t nvals) const; -#endif - - public: - static const size_t CAPACITY_VALS = 512 * 1024; - static const size_t CAPACITY_BYTES = CAPACITY_VALS * sizeof(Value); - static const size_t COMMIT_VALS = 16 * 1024; - static const size_t COMMIT_BYTES = COMMIT_VALS * sizeof(Value); - - /* - * SunSpider and v8bench have roughly an average of 9 slots per script. - * Our heuristic for a quick over-recursion check uses a generous slot - * count based on this estimate. We take this frame size and multiply it - * by the old recursion limit from the interpreter. - * - * Worst case, if an average size script (<=9 slots) over recurses, it'll - * effectively be the same as having increased the old inline call count - * to <= 5,000. - */ - static const size_t STACK_QUOTA = (VALUES_PER_STACK_FRAME + 18) * - JS_MAX_INLINE_CALL_COUNT; - - /* Kept as a member of JSThreadData; cannot use constructor/destructor. */ - bool init(); - void finish(); - -#ifdef DEBUG - template - bool contains(T *t) const { - char *v = (char *)t; - JS_ASSERT(size_t(-1) - uintptr_t(t) >= sizeof(T)); - return v >= (char *)base && v + sizeof(T) <= (char *)end; - } -#endif - - /* - * When we LeaveTree, we need to rebuild the stack, which requires stack - * allocation. There is no good way to handle an OOM for these allocations, - * so this function checks that they cannot occur using the size of the - * TraceNativeStorage as a conservative upper bound. - */ - inline bool ensureEnoughSpaceToEnterTrace(); - - /* +1 for slow native's stack frame. */ - static const ptrdiff_t MAX_TRACE_SPACE_VALS = - MAX_NATIVE_STACK_SLOTS + MAX_CALL_STACK_ENTRIES * VALUES_PER_STACK_FRAME + - (VALUES_PER_STACK_SEGMENT + VALUES_PER_STACK_FRAME /* synthesized slow native */); - - /* Mark all segments, frames, and slots on the stack. */ - JS_REQUIRES_STACK void mark(JSTracer *trc); - - /* - * For all five use cases below: - * - The boolean-valued functions call js_ReportOutOfScriptQuota on OOM. - * - The "get*Frame" functions do not change any global state, they just - * check OOM and return pointers to an uninitialized frame with the - * requested missing arguments/slots. Only once the "push*Frame" - * function has been called is global state updated. Thus, between - * "get*Frame" and "push*Frame", the frame and slots are unrooted. - * - The "push*Frame" functions will set fp->prev; the caller needn't. - * - Functions taking "*Guard" arguments will use the guard's destructor - * to pop the allocation. The caller must ensure the guard has the - * appropriate lifetime. - * - The get*Frame functions put the 'nmissing' slots contiguously after - * the arguments. - */ - - /* - * pushInvokeArgs allocates |argc + 2| rooted values that will be passed as - * the arguments to Invoke. A single allocation can be used for multiple - * Invoke calls. The InvokeArgumentsGuard passed to Invoke must come from - * an immediately-enclosing (stack-wise) call to pushInvokeArgs. - */ - bool pushInvokeArgs(JSContext *cx, uintN argc, InvokeArgsGuard *ag); - - /* These functions are called inside Invoke, not Invoke clients. */ - bool getInvokeFrame(JSContext *cx, const CallArgs &args, JSFunction *fun, - JSScript *script, uint32 *flags, InvokeFrameGuard *fg) const; - - void pushInvokeFrame(JSContext *cx, const CallArgs &args, InvokeFrameGuard *fg); - - /* These functions are called inside Execute, not Execute clients. */ - bool getExecuteFrame(JSContext *cx, JSScript *script, ExecuteFrameGuard *fg) const; - void pushExecuteFrame(JSContext *cx, JSObject *initialVarObj, ExecuteFrameGuard *fg); - - /* - * Since RAII cannot be used for inline frames, callers must manually - * call pushInlineFrame/popInlineFrame. - */ - inline JSStackFrame *getInlineFrame(JSContext *cx, Value *sp, uintN nactual, - JSFunction *fun, JSScript *script, - uint32 *flags) const; - inline void pushInlineFrame(JSContext *cx, JSScript *script, JSStackFrame *fp, - JSFrameRegs *regs); - inline void popInlineFrame(JSContext *cx, JSStackFrame *prev, js::Value *newsp); - - /* These functions are called inside SendToGenerator. */ - bool getGeneratorFrame(JSContext *cx, uintN vplen, uintN nslots, - GeneratorFrameGuard *fg); - void pushGeneratorFrame(JSContext *cx, JSFrameRegs *regs, GeneratorFrameGuard *fg); - - /* Pushes a JSStackFrame::isDummyFrame. */ - bool pushDummyFrame(JSContext *cx, JSObject &scopeChain, DummyFrameGuard *fg); - - /* Check and bump the given stack limit. */ - inline JSStackFrame *getInlineFrameWithinLimit(JSContext *cx, Value *sp, uintN nactual, - JSFunction *fun, JSScript *script, uint32 *flags, - JSStackFrame *base, Value **limit) const; - - /* - * Compute a stack limit for entering method jit code which allows the - * method jit to check for end-of-stack and over-recursion with a single - * comparison. See STACK_QUOTA above. - */ - inline Value *getStackLimit(JSContext *cx); - - /* - * Try to bump the given 'limit' by bumping the commit limit. Return false - * if fully committed or if 'limit' exceeds 'base' + STACK_QUOTA. - */ - bool bumpCommitAndLimit(JSStackFrame *base, Value *from, uintN nvals, Value **limit) const; - - /* - * Allocate nvals on the top of the stack, report error on failure. - * N.B. the caller must ensure |from >= firstUnused()|. - */ - inline bool ensureSpace(JSContext *maybecx, Value *from, ptrdiff_t nvals) const; -}; - -JS_STATIC_ASSERT(StackSpace::CAPACITY_VALS % StackSpace::COMMIT_VALS == 0); - -/* - * While |cx->fp|'s pc/sp are available in |cx->regs|, to compute the saved - * value of pc/sp for any other frame, it is necessary to know about that - * frame's next-frame. This iterator maintains this information when walking - * a chain of stack frames starting at |cx->fp|. - * - * Usage: - * for (FrameRegsIter i(cx); !i.done(); ++i) - * ... i.fp() ... i.sp() ... i.pc() - */ -class FrameRegsIter -{ - JSContext *cx; - StackSegment *curseg; - JSStackFrame *curfp; - Value *cursp; - jsbytecode *curpc; - - void initSlow(); - void incSlow(JSStackFrame *fp, JSStackFrame *prev); - - public: - JS_REQUIRES_STACK inline FrameRegsIter(JSContext *cx); - - bool done() const { return curfp == NULL; } - inline FrameRegsIter &operator++(); - - JSStackFrame *fp() const { return curfp; } - Value *sp() const { return cursp; } - jsbytecode *pc() const { return curpc; } -}; - -/* - * Utility class for iteration over all active stack frames. - */ -class AllFramesIter -{ -public: - AllFramesIter(JSContext *cx); - - bool done() const { return curfp == NULL; } - AllFramesIter& operator++(); - - JSStackFrame *fp() const { return curfp; } - -private: - StackSegment *curcs; - JSStackFrame *curfp; -}; - -} /* namespace js */ - -#ifdef DEBUG -# define FUNCTION_KIND_METER_LIST(_) \ - _(allfun), _(heavy), _(nofreeupvar), _(onlyfreevar), \ - _(flat), _(badfunarg), \ - _(joinedsetmethod), _(joinedinitmethod), \ - _(joinedreplace), _(joinedsort), _(joinedmodulepat), \ - _(mreadbarrier), _(mwritebarrier), _(mwslotbarrier), \ - _(unjoined), _(indynamicscope) -# define identity(x) x - -struct JSFunctionMeter { - int32 FUNCTION_KIND_METER_LIST(identity); -}; - -# undef identity - -# define JS_FUNCTION_METER(cx,x) JS_RUNTIME_METER((cx)->runtime, functionMeter.x) -#else -# define JS_FUNCTION_METER(cx,x) ((void)0) -#endif - - -struct JSPendingProxyOperation { - JSPendingProxyOperation *next; - JSObject *object; -}; - -struct JSThreadData { -#ifdef JS_THREADSAFE - /* The request depth for this thread. */ - unsigned requestDepth; -#endif - -#ifdef JS_TRACER - /* - * During trace execution (or during trace recording or - * profiling), these fields point to the compartment doing the - * execution on this thread. At other times, they are NULL. If a - * thread tries to execute/record/profile one trace while another - * is still running, the initial one will abort. Therefore, we - * only need to track one at a time. - */ - JSCompartment *onTraceCompartment; - JSCompartment *recordingCompartment; - JSCompartment *profilingCompartment; - #endif - - /* - * If non-zero, we were been asked to call the operation callback as soon - * as possible. If the thread has an active request, this contributes - * towards rt->interruptCounter. - */ - volatile int32 interruptFlags; - - /* Keeper of the contiguous stack used by all contexts in this thread. */ - js::StackSpace stackSpace; - - /* - * Flag indicating that we are waiving any soft limits on the GC heap - * because we want allocations to be infallible (except when we hit OOM). - */ - bool waiveGCQuota; - - /* - * The GSN cache is per thread since even multi-cx-per-thread embeddings - * do not interleave js_GetSrcNote calls. - */ - JSGSNCache gsnCache; - - /* Property cache for faster call/get/set invocation. */ - js::PropertyCache propertyCache; - -#ifdef JS_TRACER - /* Maximum size of the tracer's code cache before we start flushing. */ - uint32 maxCodeCacheBytes; -#endif - - /* State used by dtoa.c. */ - DtoaState *dtoaState; - - /* Base address of the native stack for the current thread. */ - jsuword *nativeStackBase; - - /* List of currently pending operations on proxies. */ - JSPendingProxyOperation *pendingProxyOperation; - - js::ConservativeGCThreadData conservativeGC; - - bool init(); - void finish(); - void mark(JSTracer *trc); - void purge(JSContext *cx); - - /* This must be called with the GC lock held. */ - inline void triggerOperationCallback(JSRuntime *rt); -}; - -#ifdef JS_THREADSAFE - -/* - * Structure uniquely representing a thread. It holds thread-private data - * that can be accessed without a global lock. - */ -struct JSThread { - typedef js::HashMap, - js::SystemAllocPolicy> Map; - - /* Linked list of all contexts in use on this thread. */ - JSCList contextList; - - /* Opaque thread-id, from NSPR's PR_GetCurrentThread(). */ - void *id; - - /* Number of JS_SuspendRequest calls withot JS_ResumeRequest. */ - unsigned suspendCount; - -# ifdef DEBUG - unsigned checkRequestDepth; -# endif - - /* Factored out of JSThread for !JS_THREADSAFE embedding in JSRuntime. */ - JSThreadData data; -}; - -#define JS_THREAD_DATA(cx) (&(cx)->thread->data) - -extern JSThread * -js_CurrentThread(JSRuntime *rt); - -/* - * The function takes the GC lock and does not release in successful return. - * On error (out of memory) the function releases the lock but delegates - * the error reporting to the caller. - */ -extern JSBool -js_InitContextThread(JSContext *cx); - -/* - * On entrance the GC lock must be held and it will be held on exit. - */ -extern void -js_ClearContextThread(JSContext *cx); - -#endif /* JS_THREADSAFE */ - -typedef enum JSDestroyContextMode { - JSDCM_NO_GC, - JSDCM_MAYBE_GC, - JSDCM_FORCE_GC, - JSDCM_NEW_FAILED -} JSDestroyContextMode; - -typedef enum JSRuntimeState { - JSRTS_DOWN, - JSRTS_LAUNCHING, - JSRTS_UP, - JSRTS_LANDING -} JSRuntimeState; - -typedef struct JSPropertyTreeEntry { - JSDHashEntryHdr hdr; - js::Shape *child; -} JSPropertyTreeEntry; - -typedef void -(* JSActivityCallback)(void *arg, JSBool active); - -namespace js { - -typedef js::Vector WrapperVector; - -} - -struct JSRuntime { - /* Default compartment. */ - JSCompartment *atomsCompartment; -#ifdef JS_THREADSAFE - bool atomsCompartmentIsLocked; -#endif - - /* List of compartments (protected by the GC lock). */ - js::WrapperVector compartments; - - /* Runtime state, synchronized by the stateChange/gcLock condvar/lock. */ - JSRuntimeState state; - - /* Context create/destroy callback. */ - JSContextCallback cxCallback; - - /* Compartment create/destroy callback. */ - JSCompartmentCallback compartmentCallback; - - /* - * Sets a callback that is run whenever the runtime goes idle - the - * last active request ceases - and begins activity - when it was - * idle and a request begins. Note: The callback is called under the - * GC lock. - */ - void setActivityCallback(JSActivityCallback cb, void *arg) { - activityCallback = cb; - activityCallbackArg = arg; - } - - JSActivityCallback activityCallback; - void *activityCallbackArg; - - /* - * Shape regenerated whenever a prototype implicated by an "add property" - * property cache fill and induced trace guard has a readonly property or a - * setter defined on it. This number proxies for the shapes of all objects - * along the prototype chain of all objects in the runtime on which such an - * add-property result has been cached/traced. - * - * See bug 492355 for more details. - * - * This comes early in JSRuntime to minimize the immediate format used by - * trace-JITted code that reads it. - */ - uint32 protoHazardShape; - - /* Garbage collector state, used by jsgc.c. */ - js::GCChunkSet gcChunkSet; - - js::RootedValueMap gcRootsHash; - js::GCLocks gcLocksHash; - jsrefcount gcKeepAtoms; - size_t gcBytes; - size_t gcTriggerBytes; - size_t gcLastBytes; - size_t gcMaxBytes; - size_t gcMaxMallocBytes; - size_t gcChunksWaitingToExpire; - uint32 gcEmptyArenaPoolLifespan; - uint32 gcNumber; - js::GCMarker *gcMarkingTracer; - uint32 gcTriggerFactor; - int64 gcJitReleaseTime; - JSGCMode gcMode; - volatile bool gcIsNeeded; - - /* - * Compartment that triggered GC. If more than one Compatment need GC, - * gcTriggerCompartment is reset to NULL and a global GC is performed. - */ - JSCompartment *gcTriggerCompartment; - - /* Compartment that is currently involved in per-compartment GC */ - JSCompartment *gcCurrentCompartment; - - /* - * We can pack these flags as only the GC thread writes to them. Atomic - * updates to packed bytes are not guaranteed, so stores issued by one - * thread may be lost due to unsynchronized read-modify-write cycles on - * other threads. - */ - bool gcPoke; - bool gcMarkAndSweep; - bool gcRunning; - bool gcRegenShapes; - -#ifdef JS_GC_ZEAL - jsrefcount gcZeal; -#endif - - JSGCCallback gcCallback; - - private: - /* - * Malloc counter to measure memory pressure for GC scheduling. It runs - * from gcMaxMallocBytes down to zero. - */ - volatile ptrdiff_t gcMallocBytes; - - public: - js::GCChunkAllocator *gcChunkAllocator; - - void setCustomGCChunkAllocator(js::GCChunkAllocator *allocator) { - JS_ASSERT(allocator); - JS_ASSERT(state == JSRTS_DOWN); - gcChunkAllocator = allocator; - } - - /* - * The trace operation and its data argument to trace embedding-specific - * GC roots. - */ - JSTraceDataOp gcExtraRootsTraceOp; - void *gcExtraRootsData; - - /* Well-known numbers held for use by this runtime's contexts. */ - js::Value NaNValue; - js::Value negativeInfinityValue; - js::Value positiveInfinityValue; - - JSFlatString *emptyString; - - /* List of active contexts sharing this runtime; protected by gcLock. */ - JSCList contextList; - - /* Per runtime debug hooks -- see jsprvtd.h and jsdbgapi.h. */ - JSDebugHooks globalDebugHooks; - - /* - * Right now, we only support runtime-wide debugging. - */ - JSBool debugMode; - -#ifdef JS_TRACER - /* True if any debug hooks not supported by the JIT are enabled. */ - bool debuggerInhibitsJIT() const { - return (globalDebugHooks.interruptHook || - globalDebugHooks.callHook); - } -#endif - - /* More debugging state, see jsdbgapi.c. */ - JSCList trapList; - JSCList watchPointList; - - /* Client opaque pointers */ - void *data; - -#ifdef JS_THREADSAFE - /* These combine to interlock the GC and new requests. */ - PRLock *gcLock; - PRCondVar *gcDone; - PRCondVar *requestDone; - uint32 requestCount; - JSThread *gcThread; - - js::GCHelperThread gcHelperThread; - - /* Lock and owning thread pointer for JS_LOCK_RUNTIME. */ - PRLock *rtLock; -#ifdef DEBUG - void * rtLockOwner; -#endif - - /* Used to synchronize down/up state change; protected by gcLock. */ - PRCondVar *stateChange; - - /* - * Lock serializing trapList and watchPointList accesses, and count of all - * mutations to trapList and watchPointList made by debugger threads. To - * keep the code simple, we define debuggerMutations for the thread-unsafe - * case too. - */ - PRLock *debuggerLock; - - JSThread::Map threads; -#endif /* JS_THREADSAFE */ - uint32 debuggerMutations; - - /* - * Security callbacks set on the runtime are used by each context unless - * an override is set on the context. - */ - JSSecurityCallbacks *securityCallbacks; - - /* Structured data callbacks are runtime-wide. */ - const JSStructuredCloneCallbacks *structuredCloneCallbacks; - - /* - * The propertyRemovals counter is incremented for every JSObject::clear, - * and for each JSObject::remove method call that frees a slot in the given - * object. See js_NativeGet and js_NativeSet in jsobj.cpp. - */ - int32 propertyRemovals; - - /* Script filename table. */ - struct JSHashTable *scriptFilenameTable; - JSCList scriptFilenamePrefixes; -#ifdef JS_THREADSAFE - PRLock *scriptFilenameTableLock; -#endif - - /* Number localization, used by jsnum.c */ - const char *thousandsSeparator; - const char *decimalSeparator; - const char *numGrouping; - - /* - * Weak references to lazily-created, well-known XML singletons. - * - * NB: Singleton objects must be carefully disconnected from the rest of - * the object graph usually associated with a JSContext's global object, - * including the set of standard class objects. See jsxml.c for details. - */ - JSObject *anynameObject; - JSObject *functionNamespaceObject; - -#ifdef JS_THREADSAFE - /* Number of threads with active requests and unhandled interrupts. */ - volatile int32 interruptCounter; -#else - JSThreadData threadData; - -#define JS_THREAD_DATA(cx) (&(cx)->runtime->threadData) -#endif - - /* - * Object shape (property cache structural type) identifier generator. - * - * Type 0 stands for the empty scope, and must not be regenerated due to - * uint32 wrap-around. Since js_GenerateShape (in jsinterp.cpp) uses - * atomic pre-increment, the initial value for the first typed non-empty - * scope will be 1. - * - * If this counter overflows into SHAPE_OVERFLOW_BIT (in jsinterp.h), the - * cache is disabled, to avoid aliasing two different types. It stays - * disabled until a triggered GC at some later moment compresses live - * types, minimizing rt->shapeGen in the process. - */ - volatile uint32 shapeGen; - - /* Literal table maintained by jsatom.c functions. */ - JSAtomState atomState; - - /* - * Various metering fields are defined at the end of JSRuntime. In this - * way there is no need to recompile all the code that refers to other - * fields of JSRuntime after enabling the corresponding metering macro. - */ -#ifdef JS_DUMP_ENUM_CACHE_STATS - int32 nativeEnumProbes; - int32 nativeEnumMisses; -# define ENUM_CACHE_METER(name) JS_ATOMIC_INCREMENT(&cx->runtime->name) -#else -# define ENUM_CACHE_METER(name) ((void) 0) -#endif - -#ifdef JS_DUMP_LOOP_STATS - /* Loop statistics, to trigger trace recording and compiling. */ - JSBasicStats loopStats; -#endif - -#ifdef DEBUG - /* Function invocation metering. */ - jsrefcount inlineCalls; - jsrefcount nativeCalls; - jsrefcount nonInlineCalls; - jsrefcount constructs; - - jsrefcount liveObjectProps; - jsrefcount liveObjectPropsPreSweep; - - /* - * NB: emptyShapes (in JSCompartment) is init'ed iff at least one - * of these envars is set: - * - * JS_PROPTREE_STATFILE statistics on the property tree forest - * JS_PROPTREE_DUMPFILE all paths in the property tree forest - */ - const char *propTreeStatFilename; - const char *propTreeDumpFilename; - - bool meterEmptyShapes() const { return propTreeStatFilename || propTreeDumpFilename; } - - /* String instrumentation. */ - jsrefcount liveStrings; - jsrefcount totalStrings; - jsrefcount liveDependentStrings; - jsrefcount totalDependentStrings; - jsrefcount badUndependStrings; - double lengthSum; - double lengthSquaredSum; - double strdepLengthSum; - double strdepLengthSquaredSum; - - /* Script instrumentation. */ - jsrefcount liveScripts; - jsrefcount totalScripts; - jsrefcount liveEmptyScripts; - jsrefcount totalEmptyScripts; - jsrefcount highWaterLiveScripts; -#endif /* DEBUG */ - -#ifdef JS_SCOPE_DEPTH_METER - /* - * Stats on runtime prototype chain lookups and scope chain depths, i.e., - * counts of objects traversed on a chain until the wanted id is found. - */ - JSBasicStats protoLookupDepthStats; - JSBasicStats scopeSearchDepthStats; - - /* - * Stats on compile-time host environment and lexical scope chain lengths - * (maximum depths). - */ - JSBasicStats hostenvScopeDepthStats; - JSBasicStats lexicalScopeDepthStats; -#endif - -#ifdef JS_GCMETER - js::gc::JSGCStats gcStats; - js::gc::JSGCArenaStats globalArenaStats[js::gc::FINALIZE_LIMIT]; -#endif - -#ifdef DEBUG - /* - * If functionMeterFilename, set from an envariable in JSRuntime's ctor, is - * null, the remaining members in this ifdef'ed group are not initialized. - */ - const char *functionMeterFilename; - JSFunctionMeter functionMeter; - char lastScriptFilename[1024]; - - typedef js::HashMap, - js::SystemAllocPolicy> FunctionCountMap; - - FunctionCountMap methodReadBarrierCountMap; - FunctionCountMap unjoinedFunctionCountMap; -#endif - - JSWrapObjectCallback wrapObjectCallback; - JSPreWrapCallback preWrapObjectCallback; - -#ifdef JS_METHODJIT - uint32 mjitMemoryUsed; -#endif - uint32 stringMemoryUsed; - - JSRuntime(); - ~JSRuntime(); - - bool init(uint32 maxbytes); - - void setGCTriggerFactor(uint32 factor); - void setGCLastBytes(size_t lastBytes); - - /* - * Call the system malloc while checking for GC memory pressure and - * reporting OOM error when cx is not null. - */ - void* malloc(size_t bytes, JSContext *cx = NULL) { - updateMallocCounter(bytes); - void *p = ::js_malloc(bytes); - return JS_LIKELY(!!p) ? p : onOutOfMemory(NULL, bytes, cx); - } - - /* - * Call the system calloc while checking for GC memory pressure and - * reporting OOM error when cx is not null. - */ - void* calloc(size_t bytes, JSContext *cx = NULL) { - updateMallocCounter(bytes); - void *p = ::js_calloc(bytes); - return JS_LIKELY(!!p) ? p : onOutOfMemory(reinterpret_cast(1), bytes, cx); - } - - void* realloc(void* p, size_t oldBytes, size_t newBytes, JSContext *cx = NULL) { - JS_ASSERT(oldBytes < newBytes); - updateMallocCounter(newBytes - oldBytes); - void *p2 = ::js_realloc(p, newBytes); - return JS_LIKELY(!!p2) ? p2 : onOutOfMemory(p, newBytes, cx); - } - - void* realloc(void* p, size_t bytes, JSContext *cx = NULL) { - /* - * For compatibility we do not account for realloc that increases - * previously allocated memory. - */ - if (!p) - updateMallocCounter(bytes); - void *p2 = ::js_realloc(p, bytes); - return JS_LIKELY(!!p2) ? p2 : onOutOfMemory(p, bytes, cx); - } - - void free(void* p) { ::js_free(p); } - - bool isGCMallocLimitReached() const { return gcMallocBytes <= 0; } - - void resetGCMallocBytes() { gcMallocBytes = ptrdiff_t(gcMaxMallocBytes); } - - void setGCMaxMallocBytes(size_t value) { - /* - * For compatibility treat any value that exceeds PTRDIFF_T_MAX to - * mean that value. - */ - gcMaxMallocBytes = (ptrdiff_t(value) >= 0) ? value : size_t(-1) >> 1; - resetGCMallocBytes(); - } - - /* - * Call this after allocating memory held by GC things, to update memory - * pressure counters or report the OOM error if necessary. If oomError and - * cx is not null the function also reports OOM error. - * - * The function must be called outside the GC lock and in case of OOM error - * the caller must ensure that no deadlock possible during OOM reporting. - */ - void updateMallocCounter(size_t nbytes) { - /* We tolerate any thread races when updating gcMallocBytes. */ - ptrdiff_t newCount = gcMallocBytes - ptrdiff_t(nbytes); - gcMallocBytes = newCount; - if (JS_UNLIKELY(newCount <= 0)) - onTooMuchMalloc(); - } - - private: - /* - * The function must be called outside the GC lock. - */ - JS_FRIEND_API(void) onTooMuchMalloc(); - - /* - * This should be called after system malloc/realloc returns NULL to try - * to recove some memory or to report an error. Failures in malloc and - * calloc are signaled by p == null and p == reinterpret_cast(1). - * Other values of p mean a realloc failure. - * - * The function must be called outside the GC lock. - */ - JS_FRIEND_API(void *) onOutOfMemory(void *p, size_t nbytes, JSContext *cx); -}; - -/* Common macros to access thread-local caches in JSThread or JSRuntime. */ -#define JS_GSN_CACHE(cx) (JS_THREAD_DATA(cx)->gsnCache) -#define JS_PROPERTY_CACHE(cx) (JS_THREAD_DATA(cx)->propertyCache) - -#ifdef DEBUG -# define JS_RUNTIME_METER(rt, which) JS_ATOMIC_INCREMENT(&(rt)->which) -# define JS_RUNTIME_UNMETER(rt, which) JS_ATOMIC_DECREMENT(&(rt)->which) -#else -# define JS_RUNTIME_METER(rt, which) /* nothing */ -# define JS_RUNTIME_UNMETER(rt, which) /* nothing */ -#endif - -#define JS_KEEP_ATOMS(rt) JS_ATOMIC_INCREMENT(&(rt)->gcKeepAtoms); -#define JS_UNKEEP_ATOMS(rt) JS_ATOMIC_DECREMENT(&(rt)->gcKeepAtoms); - -#ifdef JS_ARGUMENT_FORMATTER_DEFINED -/* - * Linked list mapping format strings for JS_{Convert,Push}Arguments{,VA} to - * formatter functions. Elements are sorted in non-increasing format string - * length order. - */ -struct JSArgumentFormatMap { - const char *format; - size_t length; - JSArgumentFormatter formatter; - JSArgumentFormatMap *next; -}; -#endif - -/* - * Key and entry types for the JSContext.resolvingTable hash table, typedef'd - * here because all consumers need to see these declarations (and not just the - * typedef names, as would be the case for an opaque pointer-to-typedef'd-type - * declaration), along with cx->resolvingTable. - */ -typedef struct JSResolvingKey { - JSObject *obj; - jsid id; -} JSResolvingKey; - -typedef struct JSResolvingEntry { - JSDHashEntryHdr hdr; - JSResolvingKey key; - uint32 flags; -} JSResolvingEntry; - -#define JSRESFLAG_LOOKUP 0x1 /* resolving id from lookup */ -#define JSRESFLAG_WATCH 0x2 /* resolving id from watch */ -#define JSRESOLVE_INFER 0xffff /* infer bits from current bytecode */ - -extern const JSDebugHooks js_NullDebugHooks; /* defined in jsdbgapi.cpp */ - -namespace js { - -class AutoGCRooter; - -static inline bool -OptionsHasXML(uint32 options) -{ - return !!(options & JSOPTION_XML); -} - -static inline bool -OptionsHasAnonFunFix(uint32 options) -{ - return !!(options & JSOPTION_ANONFUNFIX); -} - -static inline bool -OptionsSameVersionFlags(uint32 self, uint32 other) -{ - static const uint32 mask = JSOPTION_XML | JSOPTION_ANONFUNFIX; - return !((self & mask) ^ (other & mask)); -} - -/* - * Flags accompany script version data so that a) dynamically created scripts - * can inherit their caller's compile-time properties and b) scripts can be - * appropriately compared in the eval cache across global option changes. An - * example of the latter is enabling the top-level-anonymous-function-is-error - * option: subsequent evals of the same, previously-valid script text may have - * become invalid. - */ -namespace VersionFlags { -static const uintN MASK = 0x0FFF; /* see JSVersion in jspubtd.h */ -static const uintN HAS_XML = 0x1000; /* flag induced by XML option */ -static const uintN ANONFUNFIX = 0x2000; /* see jsapi.h comment on JSOPTION_ANONFUNFIX */ -static const uintN FULL_MASK = 0x3FFF; -} - -static inline JSVersion -VersionNumber(JSVersion version) -{ - return JSVersion(uint32(version) & VersionFlags::MASK); -} - -static inline bool -VersionHasXML(JSVersion version) -{ - return !!(version & VersionFlags::HAS_XML); -} - -/* @warning This is a distinct condition from having the XML flag set. */ -static inline bool -VersionShouldParseXML(JSVersion version) -{ - return VersionHasXML(version) || VersionNumber(version) >= JSVERSION_1_6; -} - -static inline bool -VersionHasAnonFunFix(JSVersion version) -{ - return !!(version & VersionFlags::ANONFUNFIX); -} - -static inline void -VersionSetXML(JSVersion *version, bool enable) -{ - if (enable) - *version = JSVersion(uint32(*version) | VersionFlags::HAS_XML); - else - *version = JSVersion(uint32(*version) & ~VersionFlags::HAS_XML); -} - -static inline void -VersionSetAnonFunFix(JSVersion *version, bool enable) -{ - if (enable) - *version = JSVersion(uint32(*version) | VersionFlags::ANONFUNFIX); - else - *version = JSVersion(uint32(*version) & ~VersionFlags::ANONFUNFIX); -} - -static inline JSVersion -VersionExtractFlags(JSVersion version) -{ - return JSVersion(uint32(version) & ~VersionFlags::MASK); -} - -static inline void -VersionCopyFlags(JSVersion *version, JSVersion from) -{ - *version = JSVersion(VersionNumber(*version) | VersionExtractFlags(from)); -} - -static inline bool -VersionHasFlags(JSVersion version) -{ - return !!VersionExtractFlags(version); -} - -static inline uintN -VersionFlagsToOptions(JSVersion version) -{ - uintN copts = (VersionHasXML(version) ? JSOPTION_XML : 0) | - (VersionHasAnonFunFix(version) ? JSOPTION_ANONFUNFIX : 0); - JS_ASSERT((copts & JSCOMPILEOPTION_MASK) == copts); - return copts; -} - -static inline JSVersion -OptionFlagsToVersion(uintN options, JSVersion version) -{ - VersionSetXML(&version, OptionsHasXML(options)); - VersionSetAnonFunFix(&version, OptionsHasAnonFunFix(options)); - return version; -} - -static inline bool -VersionIsKnown(JSVersion version) -{ - return VersionNumber(version) != JSVERSION_UNKNOWN; -} - -typedef js::HashSet, - js::SystemAllocPolicy> BusyArraysMap; - -} /* namespace js */ - -struct JSContext -{ - explicit JSContext(JSRuntime *rt); - - /* JSRuntime contextList linkage. */ - JSCList link; - - private: - /* See JSContext::findVersion. */ - JSVersion defaultVersion; /* script compilation version */ - JSVersion versionOverride; /* supercedes defaultVersion when valid */ - bool hasVersionOverride; - - /* Exception state -- the exception member is a GC root by definition. */ - JSBool throwing; /* is there a pending exception? */ - js::Value exception; /* most-recently-thrown exception */ - - /* Per-context run options. */ - uintN runOptions; /* see jsapi.h for JSOPTION_* */ - - public: - /* Locale specific callbacks for string conversion. */ - JSLocaleCallbacks *localeCallbacks; - - /* - * cx->resolvingTable is non-null and non-empty if we are initializing - * standard classes lazily, or if we are otherwise recursing indirectly - * from js_LookupProperty through a Class.resolve hook. It is used to - * limit runaway recursion (see jsapi.c and jsobj.c). - */ - JSDHashTable *resolvingTable; - - /* - * True if generating an error, to prevent runaway recursion. - * NB: generatingError packs with throwing below. - */ - JSPackedBool generatingError; - - /* Limit pointer for checking native stack consumption during recursion. */ - jsuword stackLimit; - - /* Quota on the size of arenas used to compile and execute scripts. */ - size_t scriptStackQuota; - - /* Data shared by threads in an address space. */ - JSRuntime *const runtime; - - /* GC heap compartment. */ - JSCompartment *compartment; - - /* Currently executing frame and regs, set by stack operations. */ - JS_REQUIRES_STACK - JSFrameRegs *regs; - - /* Current frame accessors. */ - - JSStackFrame* fp() { - JS_ASSERT(regs && regs->fp); - return regs->fp; - } - - JSStackFrame* maybefp() { - JS_ASSERT_IF(regs, regs->fp); - return regs ? regs->fp : NULL; - } - - bool hasfp() { - JS_ASSERT_IF(regs, regs->fp); - return !!regs; - } - - public: - friend class js::StackSpace; - friend bool js::Interpret(JSContext *, JSStackFrame *, uintN, JSInterpMode); - - void resetCompartment(); - void wrapPendingException(); - - /* For grep-ability, changes to 'regs' should call this function. */ - void setCurrentRegs(JSFrameRegs *regs) { - JS_ASSERT_IF(regs, regs->fp); - this->regs = regs; - } - - /* Temporary arena pool used while compiling and decompiling. */ - JSArenaPool tempPool; - - /* Temporary arena pool used while evaluate regular expressions. */ - JSArenaPool regExpPool; - - /* Top-level object and pointer to top stack frame's scope chain. */ - JSObject *globalObject; - - /* State for object and array toSource conversion. */ - JSSharpObjectMap sharpObjectMap; - js::BusyArraysMap busyArrays; - - /* Argument formatter support for JS_{Convert,Push}Arguments{,VA}. */ - JSArgumentFormatMap *argumentFormatMap; - - /* Last message string and log file for debugging. */ - char *lastMessage; -#ifdef DEBUG - void *logfp; - jsbytecode *logPrevPc; -#endif - - /* Per-context optional error reporter. */ - JSErrorReporter errorReporter; - - /* Branch callback. */ - JSOperationCallback operationCallback; - - /* Interpreter activation count. */ - uintN interpLevel; - - /* Client opaque pointers. */ - void *data; - void *data2; - - private: - /* Linked list of segments. See StackSegment. */ - js::StackSegment *currentSegment; - - public: - void assertSegmentsInSync() const { -#ifdef DEBUG - if (regs) { - JS_ASSERT(currentSegment->isActive()); - if (js::StackSegment *prev = currentSegment->getPreviousInContext()) - JS_ASSERT(!prev->isActive()); - } else { - JS_ASSERT_IF(currentSegment, !currentSegment->isActive()); - } -#endif - } - - /* Return whether this context has an active segment. */ - bool hasActiveSegment() const { - assertSegmentsInSync(); - return !!regs; - } - - /* Assuming there is an active segment, return it. */ - js::StackSegment *activeSegment() const { - JS_ASSERT(hasActiveSegment()); - return currentSegment; - } - - /* Return the current segment, which may or may not be active. */ - js::StackSegment *getCurrentSegment() const { - assertSegmentsInSync(); - return currentSegment; - } - - inline js::RegExpStatics *regExpStatics(); - - /* Add the given segment to the list as the new active segment. */ - void pushSegmentAndFrame(js::StackSegment *newseg, JSFrameRegs ®s); - - /* Remove the active segment and make the next segment active. */ - void popSegmentAndFrame(); - - /* Mark the top segment as suspended, without pushing a new one. */ - void saveActiveSegment(); - - /* Undoes calls to suspendActiveSegment. */ - void restoreSegment(); - - /* Get the frame whose prev() is fp, which may be in any segment. */ - inline JSStackFrame *computeNextFrame(JSStackFrame *fp); - - /* - * Perform a linear search of all frames in all segments in the given context - * for the given frame, returning the segment, if found, and null otherwise. - */ - js::StackSegment *containingSegment(const JSStackFrame *target); - - /* Search the call stack for the nearest frame with static level targetLevel. */ - JSStackFrame *findFrameAtLevel(uintN targetLevel) const { - JSStackFrame *fp = regs->fp; - while (true) { - JS_ASSERT(fp && fp->isScriptFrame()); - if (fp->script()->staticLevel == targetLevel) - break; - fp = fp->prev(); - } - return fp; - } - - public: - /* - * The default script compilation version can be set iff there is no code running. - * This typically occurs via the JSAPI right after a context is constructed. - */ - bool canSetDefaultVersion() const { - return !regs && !hasVersionOverride; - } - - /* Force a version for future script compilation. */ - void overrideVersion(JSVersion newVersion) { - JS_ASSERT(!canSetDefaultVersion()); - versionOverride = newVersion; - hasVersionOverride = true; - } - - /* Set the default script compilation version. */ - void setDefaultVersion(JSVersion version) { - defaultVersion = version; - } - - void clearVersionOverride() { hasVersionOverride = false; } - JSVersion getDefaultVersion() const { return defaultVersion; } - bool isVersionOverridden() const { return hasVersionOverride; } - - JSVersion getVersionOverride() const { - JS_ASSERT(isVersionOverridden()); - return versionOverride; - } - - /* - * Set the default version if possible; otherwise, force the version. - * Return whether an override occurred. - */ - bool maybeOverrideVersion(JSVersion newVersion) { - if (canSetDefaultVersion()) { - setDefaultVersion(newVersion); - return false; - } - overrideVersion(newVersion); - return true; - } - - private: - /* - * If there is no code currently executing, turn the override version into - * the default version. - * - * NB: the only time the version is potentially capable of migrating is - * on return from the Execute or ExternalInvoke paths as they call through - * JSContext::popSegmentAndFrame. - */ - void maybeMigrateVersionOverride() { - if (JS_LIKELY(!isVersionOverridden() || currentSegment)) - return; - defaultVersion = versionOverride; - clearVersionOverride(); - } - - public: - /* - * Return: - * - The override version, if there is an override version. - * - The newest scripted frame's version, if there is such a frame. - * - The default verion. - * - * Note: if this ever shows up in a profile, just add caching! - */ - JSVersion findVersion() const { - if (hasVersionOverride) - return versionOverride; - - if (regs) { - /* There may be a scripted function somewhere on the stack! */ - JSStackFrame *fp = regs->fp; - while (fp && !fp->isScriptFrame()) - fp = fp->prev(); - if (fp) - return fp->script()->getVersion(); - } - - return defaultVersion; - } - - void setRunOptions(uintN ropts) { - JS_ASSERT((ropts & JSRUNOPTION_MASK) == ropts); - runOptions = ropts; - } - - /* Note: may override the version. */ - void setCompileOptions(uintN newcopts) { - JS_ASSERT((newcopts & JSCOMPILEOPTION_MASK) == newcopts); - if (JS_LIKELY(getCompileOptions() == newcopts)) - return; - JSVersion version = findVersion(); - JSVersion newVersion = js::OptionFlagsToVersion(newcopts, version); - maybeOverrideVersion(newVersion); - } - - uintN getRunOptions() const { return runOptions; } - uintN getCompileOptions() const { return js::VersionFlagsToOptions(findVersion()); } - uintN allOptions() const { return getRunOptions() | getCompileOptions(); } - - bool hasRunOption(uintN ropt) const { - JS_ASSERT((ropt & JSRUNOPTION_MASK) == ropt); - return !!(runOptions & ropt); - } - - bool hasStrictOption() const { return hasRunOption(JSOPTION_STRICT); } - bool hasWErrorOption() const { return hasRunOption(JSOPTION_WERROR); } - bool hasAtLineOption() const { return hasRunOption(JSOPTION_ATLINE); } - -#ifdef JS_THREADSAFE - JSThread *thread; - unsigned outstandingRequests;/* number of JS_BeginRequest calls - without the corresponding - JS_EndRequest. */ - JSCList threadLinks; /* JSThread contextList linkage */ - -#define CX_FROM_THREAD_LINKS(tl) \ - ((JSContext *)((char *)(tl) - offsetof(JSContext, threadLinks))) -#endif - - /* Stack of thread-stack-allocated GC roots. */ - js::AutoGCRooter *autoGCRooters; - - /* Debug hooks associated with the current context. */ - const JSDebugHooks *debugHooks; - - /* Security callbacks that override any defined on the runtime. */ - JSSecurityCallbacks *securityCallbacks; - - /* Stored here to avoid passing it around as a parameter. */ - uintN resolveFlags; - - /* Random number generator state, used by jsmath.cpp. */ - int64 rngSeed; - - /* Location to stash the iteration value between JSOP_MOREITER and JSOP_FOR*. */ - js::Value iterValue; - -#ifdef JS_TRACER - /* - * True if traces may be executed. Invariant: The value of traceJitenabled - * is always equal to the expression in updateJITEnabled below. - * - * This flag and the fields accessed by updateJITEnabled are written only - * in runtime->gcLock, to avoid race conditions that would leave the wrong - * value in traceJitEnabled. (But the interpreter reads this without - * locking. That can race against another thread setting debug hooks, but - * we always read cx->debugHooks without locking anyway.) - */ - bool traceJitEnabled; -#endif - -#ifdef JS_METHODJIT - bool methodJitEnabled; - bool profilingEnabled; -#endif - - /* Caller must be holding runtime->gcLock. */ - void updateJITEnabled(); - -#ifdef MOZ_TRACE_JSCALLS - /* Function entry/exit debugging callback. */ - JSFunctionCallback functionCallback; - - void doFunctionCallback(const JSFunction *fun, - const JSScript *scr, - int entering) const - { - if (functionCallback) - functionCallback(fun, scr, this, entering); - } -#endif - - DSTOffsetCache dstOffsetCache; - - /* List of currently active non-escaping enumerators (for-in). */ - JSObject *enumerators; - - private: - /* - * To go from a live generator frame (on the stack) to its generator object - * (see comment js_FloatingFrameIfGenerator), we maintain a stack of active - * generators, pushing and popping when entering and leaving generator - * frames, respectively. - */ - js::Vector genStack; - - public: -#ifdef JS_METHODJIT - inline js::mjit::JaegerCompartment *jaegerCompartment(); -#endif - - /* Return the generator object for the given generator frame. */ - JSGenerator *generatorFor(JSStackFrame *fp) const; - - /* Early OOM-check. */ - inline bool ensureGeneratorStackSpace(); - - bool enterGenerator(JSGenerator *gen) { - return genStack.append(gen); - } - - void leaveGenerator(JSGenerator *gen) { - JS_ASSERT(genStack.back() == gen); - genStack.popBack(); - } - -#ifdef JS_THREADSAFE - /* - * When non-null JSContext::free delegates the job to the background - * thread. - */ - js::GCHelperThread *gcBackgroundFree; -#endif - - inline void* malloc(size_t bytes) { - return runtime->malloc(bytes, this); - } - - inline void* mallocNoReport(size_t bytes) { - JS_ASSERT(bytes != 0); - return runtime->malloc(bytes, NULL); - } - - inline void* calloc(size_t bytes) { - JS_ASSERT(bytes != 0); - return runtime->calloc(bytes, this); - } - - inline void* realloc(void* p, size_t bytes) { - return runtime->realloc(p, bytes, this); - } - - inline void* realloc(void* p, size_t oldBytes, size_t newBytes) { - return runtime->realloc(p, oldBytes, newBytes, this); - } - - inline void free(void* p) { -#ifdef JS_THREADSAFE - if (gcBackgroundFree) { - gcBackgroundFree->freeLater(p); - return; - } -#endif - runtime->free(p); - } - - /* - * In the common case that we'd like to allocate the memory for an object - * with cx->malloc/free, we cannot use overloaded C++ operators (no - * placement delete). Factor the common workaround into one place. - */ -#define CREATE_BODY(parms) \ - void *memory = this->malloc(sizeof(T)); \ - if (!memory) \ - return NULL; \ - return new(memory) T parms; - - template - JS_ALWAYS_INLINE T *create() { - CREATE_BODY(()) - } - - template - JS_ALWAYS_INLINE T *create(const P1 &p1) { - CREATE_BODY((p1)) - } - - template - JS_ALWAYS_INLINE T *create(const P1 &p1, const P2 &p2) { - CREATE_BODY((p1, p2)) - } - - template - JS_ALWAYS_INLINE T *create(const P1 &p1, const P2 &p2, const P3 &p3) { - CREATE_BODY((p1, p2, p3)) - } -#undef CREATE_BODY - - template - JS_ALWAYS_INLINE void destroy(T *p) { - p->~T(); - this->free(p); - } - - void purge(); - - js::StackSpace &stack() const { - return JS_THREAD_DATA(this)->stackSpace; - } - -#ifdef DEBUG - void assertValidStackDepth(uintN depth) { - JS_ASSERT(0 <= regs->sp - regs->fp->base()); - JS_ASSERT(depth <= uintptr_t(regs->sp - regs->fp->base())); - } -#else - void assertValidStackDepth(uintN /*depth*/) {} -#endif - - bool isExceptionPending() { - return throwing; - } - - js::Value getPendingException() { - JS_ASSERT(throwing); - return exception; - } - - void setPendingException(js::Value v); - - void clearPendingException() { - this->throwing = false; - this->exception.setUndefined(); - } - - private: - /* - * The allocation code calls the function to indicate either OOM failure - * when p is null or that a memory pressure counter has reached some - * threshold when p is not null. The function takes the pointer and not - * a boolean flag to minimize the amount of code in its inlined callers. - */ - JS_FRIEND_API(void) checkMallocGCPressure(void *p); -}; /* struct JSContext */ - -#ifdef JS_THREADSAFE -# define JS_THREAD_ID(cx) ((cx)->thread ? (cx)->thread->id : 0) -#endif - -#if defined JS_THREADSAFE && defined DEBUG - -namespace js { - -class AutoCheckRequestDepth { - JSContext *cx; - public: - AutoCheckRequestDepth(JSContext *cx) : cx(cx) { cx->thread->checkRequestDepth++; } - - ~AutoCheckRequestDepth() { - JS_ASSERT(cx->thread->checkRequestDepth != 0); - cx->thread->checkRequestDepth--; - } -}; - -} - -# define CHECK_REQUEST(cx) \ - JS_ASSERT((cx)->thread); \ - JS_ASSERT((cx)->thread->data.requestDepth || (cx)->thread == (cx)->runtime->gcThread); \ - AutoCheckRequestDepth _autoCheckRequestDepth(cx); - -#else -# define CHECK_REQUEST(cx) ((void) 0) -# define CHECK_REQUEST_THREAD(cx) ((void) 0) -#endif - -static inline uintN -FramePCOffset(JSContext *cx, JSStackFrame* fp) -{ - jsbytecode *pc = fp->hasImacropc() ? fp->imacropc() : fp->pc(cx); - return uintN(pc - fp->script()->code); -} - -static inline JSAtom ** -FrameAtomBase(JSContext *cx, JSStackFrame *fp) -{ - return fp->hasImacropc() - ? COMMON_ATOMS_START(&cx->runtime->atomState) - : fp->script()->atomMap.vector; -} - -namespace js { - -class AutoGCRooter { - public: - AutoGCRooter(JSContext *cx, ptrdiff_t tag) - : down(cx->autoGCRooters), tag(tag), context(cx) - { - JS_ASSERT(this != cx->autoGCRooters); - CHECK_REQUEST(cx); - cx->autoGCRooters = this; - } - - ~AutoGCRooter() { - JS_ASSERT(this == context->autoGCRooters); - CHECK_REQUEST(context); - context->autoGCRooters = down; - } - - /* Implemented in jsgc.cpp. */ - inline void trace(JSTracer *trc); - -#ifdef __GNUC__ -# pragma GCC visibility push(default) -#endif - friend JS_FRIEND_API(void) MarkContext(JSTracer *trc, JSContext *acx); - friend void MarkRuntime(JSTracer *trc); -#ifdef __GNUC__ -# pragma GCC visibility pop -#endif - - protected: - AutoGCRooter * const down; - - /* - * Discriminates actual subclass of this being used. If non-negative, the - * subclass roots an array of values of the length stored in this field. - * If negative, meaning is indicated by the corresponding value in the enum - * below. Any other negative value indicates some deeper problem such as - * memory corruption. - */ - ptrdiff_t tag; - - JSContext * const context; - - enum { - JSVAL = -1, /* js::AutoValueRooter */ - SHAPE = -2, /* js::AutoShapeRooter */ - PARSER = -3, /* js::Parser */ - SCRIPT = -4, /* js::AutoScriptRooter */ - ENUMERATOR = -5, /* js::AutoEnumStateRooter */ - IDARRAY = -6, /* js::AutoIdArray */ - DESCRIPTORS = -7, /* js::AutoPropDescArrayRooter */ - NAMESPACES = -8, /* js::AutoNamespaceArray */ - XML = -9, /* js::AutoXMLRooter */ - OBJECT = -10, /* js::AutoObjectRooter */ - ID = -11, /* js::AutoIdRooter */ - VALVECTOR = -12, /* js::AutoValueVector */ - DESCRIPTOR = -13, /* js::AutoPropertyDescriptorRooter */ - STRING = -14, /* js::AutoStringRooter */ - IDVECTOR = -15, /* js::AutoIdVector */ - BINDINGS = -16, /* js::Bindings */ - SHAPEVECTOR = -17 /* js::AutoShapeVector */ - }; - - private: - /* No copy or assignment semantics. */ - AutoGCRooter(AutoGCRooter &ida); - void operator=(AutoGCRooter &ida); -}; - -/* FIXME(bug 332648): Move this into a public header. */ -class AutoValueRooter : private AutoGCRooter -{ - public: - explicit AutoValueRooter(JSContext *cx - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, JSVAL), val(js::NullValue()) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - - AutoValueRooter(JSContext *cx, const Value &v - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, JSVAL), val(v) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - - AutoValueRooter(JSContext *cx, jsval v - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, JSVAL), val(js::Valueify(v)) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - - /* - * If you are looking for Object* overloads, use AutoObjectRooter instead; - * rooting Object*s as a js::Value requires discerning whether or not it is - * a function object. Also, AutoObjectRooter is smaller. - */ - - void set(Value v) { - JS_ASSERT(tag == JSVAL); - val = v; - } - - void set(jsval v) { - JS_ASSERT(tag == JSVAL); - val = js::Valueify(v); - } - - const Value &value() const { - JS_ASSERT(tag == JSVAL); - return val; - } - - Value *addr() { - JS_ASSERT(tag == JSVAL); - return &val; - } - - const jsval &jsval_value() const { - JS_ASSERT(tag == JSVAL); - return Jsvalify(val); - } - - jsval *jsval_addr() { - JS_ASSERT(tag == JSVAL); - return Jsvalify(&val); - } - - friend void AutoGCRooter::trace(JSTracer *trc); - friend void MarkRuntime(JSTracer *trc); - - private: - Value val; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -class AutoObjectRooter : private AutoGCRooter { - public: - AutoObjectRooter(JSContext *cx, JSObject *obj = NULL - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, OBJECT), obj(obj) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - - void setObject(JSObject *obj) { - this->obj = obj; - } - - JSObject * object() const { - return obj; - } - - JSObject ** addr() { - return &obj; - } - - friend void AutoGCRooter::trace(JSTracer *trc); - friend void MarkRuntime(JSTracer *trc); - - private: - JSObject *obj; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -class AutoStringRooter : private AutoGCRooter { - public: - AutoStringRooter(JSContext *cx, JSString *str = NULL - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, STRING), str(str) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - - void setString(JSString *str) { - this->str = str; - } - - JSString * string() const { - return str; - } - - JSString ** addr() { - return &str; - } - - friend void AutoGCRooter::trace(JSTracer *trc); - - private: - JSString *str; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -class AutoArrayRooter : private AutoGCRooter { - public: - AutoArrayRooter(JSContext *cx, size_t len, Value *vec - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, len), array(vec) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - JS_ASSERT(tag >= 0); - } - - AutoArrayRooter(JSContext *cx, size_t len, jsval *vec - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, len), array(Valueify(vec)) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - JS_ASSERT(tag >= 0); - } - - void changeLength(size_t newLength) { - tag = ptrdiff_t(newLength); - JS_ASSERT(tag >= 0); - } - - void changeArray(Value *newArray, size_t newLength) { - changeLength(newLength); - array = newArray; - } - - Value *array; - - friend void AutoGCRooter::trace(JSTracer *trc); - - private: - JS_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -class AutoShapeRooter : private AutoGCRooter { - public: - AutoShapeRooter(JSContext *cx, const js::Shape *shape - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, SHAPE), shape(shape) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - - friend void AutoGCRooter::trace(JSTracer *trc); - friend void MarkRuntime(JSTracer *trc); - - private: - const js::Shape * const shape; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -class AutoScriptRooter : private AutoGCRooter { - public: - AutoScriptRooter(JSContext *cx, JSScript *script - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, SCRIPT), script(script) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - - void setScript(JSScript *script) { - this->script = script; - } - - friend void AutoGCRooter::trace(JSTracer *trc); - - private: - JSScript *script; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -class AutoIdRooter : private AutoGCRooter -{ - public: - explicit AutoIdRooter(JSContext *cx, jsid id = INT_TO_JSID(0) - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, ID), id_(id) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - - jsid id() { - return id_; - } - - jsid * addr() { - return &id_; - } - - friend void AutoGCRooter::trace(JSTracer *trc); - friend void MarkRuntime(JSTracer *trc); - - private: - jsid id_; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -class AutoIdArray : private AutoGCRooter { - public: - AutoIdArray(JSContext *cx, JSIdArray *ida JS_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, IDARRAY), idArray(ida) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - ~AutoIdArray() { - if (idArray) - JS_DestroyIdArray(context, idArray); - } - bool operator!() { - return idArray == NULL; - } - jsid operator[](size_t i) const { - JS_ASSERT(idArray); - JS_ASSERT(i < size_t(idArray->length)); - return idArray->vector[i]; - } - size_t length() const { - return idArray->length; - } - - friend void AutoGCRooter::trace(JSTracer *trc); - - JSIdArray *steal() { - JSIdArray *copy = idArray; - idArray = NULL; - return copy; - } - - protected: - inline void trace(JSTracer *trc); - - private: - JSIdArray * idArray; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER - - /* No copy or assignment semantics. */ - AutoIdArray(AutoIdArray &ida); - void operator=(AutoIdArray &ida); -}; - -/* The auto-root for enumeration object and its state. */ -class AutoEnumStateRooter : private AutoGCRooter -{ - public: - AutoEnumStateRooter(JSContext *cx, JSObject *obj - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, ENUMERATOR), obj(obj), stateValue() - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - JS_ASSERT(obj); - } - - ~AutoEnumStateRooter() { - if (!stateValue.isNull()) { -#ifdef DEBUG - JSBool ok = -#endif - obj->enumerate(context, JSENUMERATE_DESTROY, &stateValue, 0); - JS_ASSERT(ok); - } - } - - friend void AutoGCRooter::trace(JSTracer *trc); - - const Value &state() const { return stateValue; } - Value *addr() { return &stateValue; } - - protected: - void trace(JSTracer *trc); - - JSObject * const obj; - - private: - Value stateValue; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -#ifdef JS_HAS_XML_SUPPORT -class AutoXMLRooter : private AutoGCRooter { - public: - AutoXMLRooter(JSContext *cx, JSXML *xml - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, XML), xml(xml) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - JS_ASSERT(xml); - } - - friend void AutoGCRooter::trace(JSTracer *trc); - friend void MarkRuntime(JSTracer *trc); - - private: - JSXML * const xml; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER -}; -#endif /* JS_HAS_XML_SUPPORT */ - -class AutoBindingsRooter : private AutoGCRooter { - public: - AutoBindingsRooter(JSContext *cx, Bindings &bindings - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, BINDINGS), bindings(bindings) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - - friend void AutoGCRooter::trace(JSTracer *trc); - - private: - Bindings &bindings; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -class AutoLockGC { - public: - explicit AutoLockGC(JSRuntime *rt - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : rt(rt) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - JS_LOCK_GC(rt); - } - ~AutoLockGC() { JS_UNLOCK_GC(rt); } - - private: - JSRuntime *rt; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -class AutoUnlockGC { - private: - JSRuntime *rt; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER - - public: - explicit AutoUnlockGC(JSRuntime *rt - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : rt(rt) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - JS_UNLOCK_GC(rt); - } - ~AutoUnlockGC() { JS_LOCK_GC(rt); } -}; - -class AutoLockAtomsCompartment { - private: - JSContext *cx; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER - - public: - AutoLockAtomsCompartment(JSContext *cx - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : cx(cx) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - JS_LOCK(cx, &cx->runtime->atomState.lock); -#ifdef JS_THREADSAFE - cx->runtime->atomsCompartmentIsLocked = true; -#endif - } - ~AutoLockAtomsCompartment() { -#ifdef JS_THREADSAFE - cx->runtime->atomsCompartmentIsLocked = false; -#endif - JS_UNLOCK(cx, &cx->runtime->atomState.lock); - } -}; - -class AutoUnlockAtomsCompartment { - JSContext *cx; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER - - public: - AutoUnlockAtomsCompartment(JSContext *cx - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : cx(cx) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; -#ifdef JS_THREADSAFE - cx->runtime->atomsCompartmentIsLocked = false; -#endif - JS_UNLOCK(cx, &cx->runtime->atomState.lock); - } - ~AutoUnlockAtomsCompartment() { - JS_LOCK(cx, &cx->runtime->atomState.lock); -#ifdef JS_THREADSAFE - cx->runtime->atomsCompartmentIsLocked = true; -#endif - } -}; - -class AutoKeepAtoms { - JSRuntime *rt; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER - - public: - explicit AutoKeepAtoms(JSRuntime *rt - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : rt(rt) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - JS_KEEP_ATOMS(rt); - } - ~AutoKeepAtoms() { JS_UNKEEP_ATOMS(rt); } -}; - -class AutoArenaAllocator { - JSArenaPool *pool; - void *mark; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER - - public: - explicit AutoArenaAllocator(JSArenaPool *pool - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : pool(pool), mark(JS_ARENA_MARK(pool)) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - ~AutoArenaAllocator() { JS_ARENA_RELEASE(pool, mark); } - - template - T *alloc(size_t elems) { - void *ptr; - JS_ARENA_ALLOCATE(ptr, pool, elems * sizeof(T)); - return static_cast(ptr); - } -}; - -class AutoReleasePtr { - JSContext *cx; - void *ptr; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER - - AutoReleasePtr operator=(const AutoReleasePtr &other); - - public: - explicit AutoReleasePtr(JSContext *cx, void *ptr - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : cx(cx), ptr(ptr) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - ~AutoReleasePtr() { cx->free(ptr); } -}; - -/* - * FIXME: bug 602774: cleaner API for AutoReleaseNullablePtr - */ -class AutoReleaseNullablePtr { - JSContext *cx; - void *ptr; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER - - AutoReleaseNullablePtr operator=(const AutoReleaseNullablePtr &other); - - public: - explicit AutoReleaseNullablePtr(JSContext *cx, void *ptr - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : cx(cx), ptr(ptr) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - void reset(void *ptr2) { - if (ptr) - cx->free(ptr); - ptr = ptr2; - } - ~AutoReleaseNullablePtr() { if (ptr) cx->free(ptr); } -}; - -class AutoLocalNameArray { - public: - explicit AutoLocalNameArray(JSContext *cx, JSFunction *fun - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : context(cx), - mark(JS_ARENA_MARK(&cx->tempPool)), - names(fun->script()->bindings.getLocalNameArray(cx, &cx->tempPool)), - count(fun->script()->bindings.countLocalNames()) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - - ~AutoLocalNameArray() { - JS_ARENA_RELEASE(&context->tempPool, mark); - } - - operator bool() const { return !!names; } - - uint32 length() const { return count; } - - const jsuword &operator [](unsigned i) const { return names[i]; } - - private: - JSContext *context; - void *mark; - jsuword *names; - uint32 count; - - JS_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -template -class AlreadyIncRefed -{ - typedef RefCountable *****ConvertibleToBool; - - RefCountable *obj; - - public: - explicit AlreadyIncRefed(RefCountable *obj) : obj(obj) {} - - bool null() const { return obj == NULL; } - operator ConvertibleToBool() const { return (ConvertibleToBool)obj; } - - RefCountable *operator->() const { JS_ASSERT(!null()); return obj; } - RefCountable &operator*() const { JS_ASSERT(!null()); return *obj; } - RefCountable *get() const { return obj; } -}; - -template -class NeedsIncRef -{ - typedef RefCountable *****ConvertibleToBool; - - RefCountable *obj; - - public: - explicit NeedsIncRef(RefCountable *obj) : obj(obj) {} - - bool null() const { return obj == NULL; } - operator ConvertibleToBool() const { return (ConvertibleToBool)obj; } - - RefCountable *operator->() const { JS_ASSERT(!null()); return obj; } - RefCountable &operator*() const { JS_ASSERT(!null()); return *obj; } - RefCountable *get() const { return obj; } -}; - -template -class AutoRefCount -{ - typedef RefCountable *****ConvertibleToBool; - - JSContext *const cx; - RefCountable *obj; - - AutoRefCount(const AutoRefCount &); - void operator=(const AutoRefCount &); - - public: - explicit AutoRefCount(JSContext *cx) - : cx(cx), obj(NULL) - {} - - AutoRefCount(JSContext *cx, NeedsIncRef aobj) - : cx(cx), obj(aobj.get()) - { - if (obj) - obj->incref(cx); - } - - AutoRefCount(JSContext *cx, AlreadyIncRefed aobj) - : cx(cx), obj(aobj.get()) - {} - - ~AutoRefCount() { - if (obj) - obj->decref(cx); - } - - void reset(NeedsIncRef aobj) { - if (obj) - obj->decref(cx); - obj = aobj.get(); - if (obj) - obj->incref(cx); - } - - void reset(AlreadyIncRefed aobj) { - if (obj) - obj->decref(cx); - obj = aobj.get(); - } - - bool null() const { return obj == NULL; } - operator ConvertibleToBool() const { return (ConvertibleToBool)obj; } - - RefCountable *operator->() const { JS_ASSERT(!null()); return obj; } - RefCountable &operator*() const { JS_ASSERT(!null()); return *obj; } - RefCountable *get() const { return obj; } -}; - -} /* namespace js */ - -class JSAutoResolveFlags -{ - public: - JSAutoResolveFlags(JSContext *cx, uintN flags - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : mContext(cx), mSaved(cx->resolveFlags) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - cx->resolveFlags = flags; - } - - ~JSAutoResolveFlags() { mContext->resolveFlags = mSaved; } - - private: - JSContext *mContext; - uintN mSaved; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -extern JSThreadData * -js_CurrentThreadData(JSRuntime *rt); - -extern JSBool -js_InitThreads(JSRuntime *rt); - -extern void -js_FinishThreads(JSRuntime *rt); - -extern void -js_PurgeThreads(JSContext *cx); - -namespace js { - -#ifdef JS_THREADSAFE - -/* Iterator over JSThreadData from all JSThread instances. */ -class ThreadDataIter : public JSThread::Map::Range -{ - public: - ThreadDataIter(JSRuntime *rt) : JSThread::Map::Range(rt->threads.all()) {} - - JSThreadData *threadData() const { - return &front().value->data; - } -}; - -#else /* !JS_THREADSAFE */ - -class ThreadDataIter -{ - JSRuntime *runtime; - bool done; - public: - ThreadDataIter(JSRuntime *rt) : runtime(rt), done(false) {} - - bool empty() const { - return done; - } - - void popFront() { - JS_ASSERT(!done); - done = true; - } - - JSThreadData *threadData() const { - JS_ASSERT(!done); - return &runtime->threadData; - } -}; - -#endif /* !JS_THREADSAFE */ - -} /* namespace js */ - -/* - * Create and destroy functions for JSContext, which is manually allocated - * and exclusively owned. - */ -extern JSContext * -js_NewContext(JSRuntime *rt, size_t stackChunkSize); - -extern void -js_DestroyContext(JSContext *cx, JSDestroyContextMode mode); - -static JS_INLINE JSContext * -js_ContextFromLinkField(JSCList *link) -{ - JS_ASSERT(link); - return (JSContext *) ((uint8 *) link - offsetof(JSContext, link)); -} - -/* - * If unlocked, acquire and release rt->gcLock around *iterp update; otherwise - * the caller must be holding rt->gcLock. - */ -extern JSContext * -js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp); - -/* - * Iterate through contexts with active requests. The caller must be holding - * rt->gcLock in case of a thread-safe build, or otherwise guarantee that the - * context list is not alternated asynchroniously. - */ -extern JS_FRIEND_API(JSContext *) -js_NextActiveContext(JSRuntime *, JSContext *); - -/* - * Class.resolve and watchpoint recursion damping machinery. - */ -extern JSBool -js_StartResolving(JSContext *cx, JSResolvingKey *key, uint32 flag, - JSResolvingEntry **entryp); - -extern void -js_StopResolving(JSContext *cx, JSResolvingKey *key, uint32 flag, - JSResolvingEntry *entry, uint32 generation); - -/* - * Report an exception, which is currently realized as a printf-style format - * string and its arguments. - */ -typedef enum JSErrNum { -#define MSG_DEF(name, number, count, exception, format) \ - name = number, -#include "js.msg" -#undef MSG_DEF - JSErr_Limit -} JSErrNum; - -extern JS_FRIEND_API(const JSErrorFormatString *) -js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber); - -#ifdef va_start -extern JSBool -js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap); - -extern JSBool -js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback, - void *userRef, const uintN errorNumber, - JSBool charArgs, va_list ap); - -extern JSBool -js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback, - void *userRef, const uintN errorNumber, - char **message, JSErrorReport *reportp, - bool charArgs, va_list ap); -#endif - -extern void -js_ReportOutOfMemory(JSContext *cx); - -/* - * Report that cx->scriptStackQuota is exhausted. - */ -void -js_ReportOutOfScriptQuota(JSContext *cx); - -extern JS_FRIEND_API(void) -js_ReportOverRecursed(JSContext *cx); - -extern JS_FRIEND_API(void) -js_ReportAllocationOverflow(JSContext *cx); - -#define JS_CHECK_RECURSION(cx, onerror) \ - JS_BEGIN_MACRO \ - int stackDummy_; \ - \ - if (!JS_CHECK_STACK_SIZE(cx->stackLimit, &stackDummy_)) { \ - js_ReportOverRecursed(cx); \ - onerror; \ - } \ - JS_END_MACRO - -/* - * Report an exception using a previously composed JSErrorReport. - * XXXbe remove from "friend" API - */ -extern JS_FRIEND_API(void) -js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *report); - -extern void -js_ReportIsNotDefined(JSContext *cx, const char *name); - -/* - * Report an attempt to access the property of a null or undefined value (v). - */ -extern JSBool -js_ReportIsNullOrUndefined(JSContext *cx, intN spindex, const js::Value &v, - JSString *fallback); - -extern void -js_ReportMissingArg(JSContext *cx, const js::Value &v, uintN arg); - -/* - * Report error using js_DecompileValueGenerator(cx, spindex, v, fallback) as - * the first argument for the error message. If the error message has less - * then 3 arguments, use null for arg1 or arg2. - */ -extern JSBool -js_ReportValueErrorFlags(JSContext *cx, uintN flags, const uintN errorNumber, - intN spindex, const js::Value &v, JSString *fallback, - const char *arg1, const char *arg2); - -#define js_ReportValueError(cx,errorNumber,spindex,v,fallback) \ - ((void)js_ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber, \ - spindex, v, fallback, NULL, NULL)) - -#define js_ReportValueError2(cx,errorNumber,spindex,v,fallback,arg1) \ - ((void)js_ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber, \ - spindex, v, fallback, arg1, NULL)) - -#define js_ReportValueError3(cx,errorNumber,spindex,v,fallback,arg1,arg2) \ - ((void)js_ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber, \ - spindex, v, fallback, arg1, arg2)) - -extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit]; - -#ifdef JS_THREADSAFE -# define JS_ASSERT_REQUEST_DEPTH(cx) (JS_ASSERT((cx)->thread), \ - JS_ASSERT((cx)->thread->data.requestDepth >= 1)) -#else -# define JS_ASSERT_REQUEST_DEPTH(cx) ((void) 0) -#endif - -/* - * If the operation callback flag was set, call the operation callback. - * This macro can run the full GC. Return true if it is OK to continue and - * false otherwise. - */ -#define JS_CHECK_OPERATION_LIMIT(cx) \ - (JS_ASSERT_REQUEST_DEPTH(cx), \ - (!JS_THREAD_DATA(cx)->interruptFlags || js_InvokeOperationCallback(cx))) - -JS_ALWAYS_INLINE void -JSThreadData::triggerOperationCallback(JSRuntime *rt) -{ - /* - * Use JS_ATOMIC_SET and JS_ATOMIC_INCREMENT in the hope that it ensures - * the write will become immediately visible to other processors polling - * the flag. Note that we only care about visibility here, not read/write - * ordering: this field can only be written with the GC lock held. - */ - if (interruptFlags) - return; - JS_ATOMIC_SET(&interruptFlags, 1); - -#ifdef JS_THREADSAFE - /* rt->interruptCounter does not reflect suspended threads. */ - if (requestDepth != 0) - JS_ATOMIC_INCREMENT(&rt->interruptCounter); -#endif -} - -/* - * Invoke the operation callback and return false if the current execution - * is to be terminated. - */ -extern JSBool -js_InvokeOperationCallback(JSContext *cx); - -extern JSBool -js_HandleExecutionInterrupt(JSContext *cx); - -namespace js { - -/* These must be called with GC lock taken. */ - -JS_FRIEND_API(void) -TriggerOperationCallback(JSContext *cx); - -void -TriggerAllOperationCallbacks(JSRuntime *rt); - -} /* namespace js */ - -extern JSStackFrame * -js_GetScriptedCaller(JSContext *cx, JSStackFrame *fp); - -extern jsbytecode* -js_GetCurrentBytecodePC(JSContext* cx); - -extern bool -js_CurrentPCIsInImacro(JSContext *cx); - -namespace js { - -class RegExpStatics; - -extern JS_FORCES_STACK JS_FRIEND_API(void) -LeaveTrace(JSContext *cx); - -} /* namespace js */ - -/* - * Get the current frame, first lazily instantiating stack frames if needed. - * (Do not access cx->fp() directly except in JS_REQUIRES_STACK code.) - * - * Defined in jstracer.cpp if JS_TRACER is defined. - */ -static JS_FORCES_STACK JS_INLINE JSStackFrame * -js_GetTopStackFrame(JSContext *cx) -{ - js::LeaveTrace(cx); - return cx->maybefp(); -} - -static JS_INLINE JSBool -js_IsPropertyCacheDisabled(JSContext *cx) -{ - return cx->runtime->shapeGen >= js::SHAPE_OVERFLOW_BIT; -} - -static JS_INLINE uint32 -js_RegenerateShapeForGC(JSRuntime *rt) -{ - JS_ASSERT(rt->gcRunning); - JS_ASSERT(rt->gcRegenShapes); - - /* - * Under the GC, compared with js_GenerateShape, we don't need to use - * atomic increments but we still must make sure that after an overflow - * the shape stays such. - */ - uint32 shape = rt->shapeGen; - shape = (shape + 1) | (shape & js::SHAPE_OVERFLOW_BIT); - rt->shapeGen = shape; - return shape; -} - -namespace js { - -inline void * -ContextAllocPolicy::malloc(size_t bytes) -{ - return cx->malloc(bytes); -} - -inline void -ContextAllocPolicy::free(void *p) -{ - cx->free(p); -} - -inline void * -ContextAllocPolicy::realloc(void *p, size_t bytes) -{ - return cx->realloc(p, bytes); -} - -inline void -ContextAllocPolicy::reportAllocOverflow() const -{ - js_ReportAllocationOverflow(cx); -} - -template -class AutoVectorRooter : protected AutoGCRooter -{ - public: - explicit AutoVectorRooter(JSContext *cx, ptrdiff_t tag - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, tag), vector(cx) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - - size_t length() const { return vector.length(); } - - bool append(const T &v) { return vector.append(v); } - - void popBack() { vector.popBack(); } - - bool growBy(size_t inc) { - size_t oldLength = vector.length(); - if (!vector.growByUninitialized(inc)) - return false; - MakeRangeGCSafe(vector.begin() + oldLength, vector.end()); - return true; - } - - bool resize(size_t newLength) { - size_t oldLength = vector.length(); - if (newLength <= oldLength) { - vector.shrinkBy(oldLength - newLength); - return true; - } - if (!vector.growByUninitialized(newLength - oldLength)) - return false; - MakeRangeGCSafe(vector.begin() + oldLength, vector.end()); - return true; - } - - bool reserve(size_t newLength) { - return vector.reserve(newLength); - } - - T &operator[](size_t i) { return vector[i]; } - const T &operator[](size_t i) const { return vector[i]; } - - const T *begin() const { return vector.begin(); } - T *begin() { return vector.begin(); } - - const T *end() const { return vector.end(); } - T *end() { return vector.end(); } - - const T &back() const { return vector.back(); } - - friend void AutoGCRooter::trace(JSTracer *trc); - - private: - Vector vector; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -class AutoValueVector : public AutoVectorRooter -{ - public: - explicit AutoValueVector(JSContext *cx - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoVectorRooter(cx, VALVECTOR) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - - const jsval *jsval_begin() const { return Jsvalify(begin()); } - jsval *jsval_begin() { return Jsvalify(begin()); } - - const jsval *jsval_end() const { return Jsvalify(end()); } - jsval *jsval_end() { return Jsvalify(end()); } - - JS_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -class AutoIdVector : public AutoVectorRooter -{ - public: - explicit AutoIdVector(JSContext *cx - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoVectorRooter(cx, IDVECTOR) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - - JS_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -class AutoShapeVector : public AutoVectorRooter -{ - public: - explicit AutoShapeVector(JSContext *cx - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoVectorRooter(cx, SHAPEVECTOR) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - - JS_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -JSIdArray * -NewIdArray(JSContext *cx, jsint length); - -} /* namespace js */ - -#ifdef _MSC_VER -#pragma warning(pop) -#pragma warning(pop) -#endif - -#ifdef JS_CNTXT_UNDEFD_MOZALLOC_WRAPPERS -# include "mozilla/mozalloc_macro_wrappers.h" -#endif - -#endif /* jscntxt_h___ */ diff --git a/x86/mozilla/include/jscompartment.h b/x86/mozilla/include/jscompartment.h deleted file mode 100644 index 8630801..0000000 --- a/x86/mozilla/include/jscompartment.h +++ /dev/null @@ -1,635 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is SpiderMonkey code. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jscompartment_h___ -#define jscompartment_h___ - -#include "jscntxt.h" -#include "jsgc.h" -#include "jsmath.h" -#include "jsobj.h" -#include "jsfun.h" -#include "jsgcstats.h" -#include "jsclist.h" -#include "jsxml.h" - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4251) /* Silence warning about JS_FRIEND_API and data members. */ -#endif - -namespace JSC { - -class ExecutableAllocator; - -} - -namespace js { - -/* Holds the number of recording attemps for an address. */ -typedef HashMap, - SystemAllocPolicy> RecordAttemptMap; - -/* Holds the profile data for loops. */ -typedef HashMap, - SystemAllocPolicy> LoopProfileMap; - -class Oracle; - -typedef HashSet, - SystemAllocPolicy> TracedScriptSet; - -typedef HashMap, - SystemAllocPolicy> ToSourceCache; - -struct TraceMonitor; - -/* Holds the execution state during trace execution. */ -struct TracerState -{ - JSContext* cx; // current VM context handle - TraceMonitor* traceMonitor; // current TM - double* stackBase; // native stack base - double* sp; // native stack pointer, stack[0] is spbase[0] - double* eos; // first unusable word after the native stack / begin of globals - FrameInfo** callstackBase; // call stack base - void* sor; // start of rp stack - FrameInfo** rp; // call stack pointer - void* eor; // first unusable word after the call stack - VMSideExit* lastTreeExitGuard; // guard we exited on during a tree call - VMSideExit* lastTreeCallGuard; // guard we want to grow from if the tree - // call exit guard mismatched - void* rpAtLastTreeCall; // value of rp at innermost tree call guard - VMSideExit* outermostTreeExitGuard; // the last side exit returned by js_CallTree - TreeFragment* outermostTree; // the outermost tree we initially invoked - uintN* inlineCallCountp; // inline call count counter - VMSideExit** innermostNestedGuardp; - VMSideExit* innermost; - uint64 startTime; - TracerState* prev; - - // Used by _FAIL builtins; see jsbuiltins.h. The builtin sets the - // JSBUILTIN_BAILED bit if it bails off trace and the JSBUILTIN_ERROR bit - // if an error or exception occurred. - uint32 builtinStatus; - - // Used to communicate the location of the return value in case of a deep bail. - double* deepBailSp; - - // Used when calling natives from trace to root the vp vector. - uintN nativeVpLen; - js::Value* nativeVp; - - TracerState(JSContext *cx, TraceMonitor *tm, TreeFragment *ti, - uintN &inlineCallCountp, VMSideExit** innermostNestedGuardp); - ~TracerState(); -}; - -/* - * Storage for the execution state and store during trace execution. Generated - * code depends on the fact that the globals begin |MAX_NATIVE_STACK_SLOTS| - * doubles after the stack begins. Thus, on trace, |TracerState::eos| holds a - * pointer to the first global. - */ -struct TraceNativeStorage -{ - double stack_global_buf[MAX_NATIVE_STACK_SLOTS + GLOBAL_SLOTS_BUFFER_SIZE]; - FrameInfo *callstack_buf[MAX_CALL_STACK_ENTRIES]; - - double *stack() { return stack_global_buf; } - double *global() { return stack_global_buf + MAX_NATIVE_STACK_SLOTS; } - FrameInfo **callstack() { return callstack_buf; } -}; - -/* Holds data to track a single globa. */ -struct GlobalState { - JSObject* globalObj; - uint32 globalShape; - SlotList* globalSlots; -}; - -/* - * Trace monitor. Every JSCompartment has an associated trace monitor - * that keeps track of loop frequencies for all JavaScript code loaded - * into that runtime. - */ -struct TraceMonitor { - /* - * The context currently executing JIT-compiled code in this compartment, or - * NULL if none. Among other things, this can in certain cases prevent - * last-ditch GC and suppress calls to JS_ReportOutOfMemory. - * - * !tracecx && !recorder: not on trace - * !tracecx && recorder: recording - * tracecx && !recorder: executing a trace - * tracecx && recorder: executing inner loop, recording outer loop - */ - JSContext *tracecx; - - /* - * State for the current tree execution. bailExit is valid if the tree has - * called back into native code via a _FAIL builtin and has not yet bailed, - * else garbage (NULL in debug builds). - */ - js::TracerState *tracerState; - js::VMSideExit *bailExit; - - /* Counts the number of iterations run by the currently executing trace. */ - unsigned iterationCounter; - - /* - * Cached storage to use when executing on trace. While we may enter nested - * traces, we always reuse the outer trace's storage, so never need more - * than of these. - */ - TraceNativeStorage *storage; - - /* - * There are 4 allocators here. This might seem like overkill, but they - * have different lifecycles, and by keeping them separate we keep the - * amount of retained memory down significantly. They are flushed (ie. - * all the allocated memory is freed) periodically. - * - * - dataAlloc has the lifecycle of the monitor. It's flushed only when - * the monitor is flushed. It's used for fragments. - * - * - traceAlloc has the same flush lifecycle as the dataAlloc, but it is - * also *marked* when a recording starts and rewinds to the mark point - * if recording aborts. So you can put things in it that are only - * reachable on a successful record/compile cycle like GuardRecords and - * SideExits. - * - * - tempAlloc is flushed after each recording, successful or not. It's - * used to store LIR code and for all other elements in the LIR - * pipeline. - * - * - codeAlloc has the same lifetime as dataAlloc, but its API is - * different (CodeAlloc vs. VMAllocator). It's used for native code. - * It's also a good idea to keep code and data separate to avoid I-cache - * vs. D-cache issues. - */ - VMAllocator* dataAlloc; - VMAllocator* traceAlloc; - VMAllocator* tempAlloc; - nanojit::CodeAlloc* codeAlloc; - nanojit::Assembler* assembler; - FrameInfoCache* frameCache; - - /* This gets incremented every time the monitor is flushed. */ - uintN flushEpoch; - - Oracle* oracle; - TraceRecorder* recorder; - - /* If we are profiling a loop, this tracks the current profile. Otherwise NULL. */ - LoopProfile* profile; - - GlobalState globalStates[MONITOR_N_GLOBAL_STATES]; - TreeFragment *vmfragments[FRAGMENT_TABLE_SIZE]; - RecordAttemptMap* recordAttempts; - - /* A hashtable mapping PC values to loop profiles for those loops. */ - LoopProfileMap* loopProfiles; - - /* - * Maximum size of the code cache before we start flushing. 1/16 of this - * size is used as threshold for the regular expression code cache. - */ - uint32 maxCodeCacheBytes; - - /* - * If nonzero, do not flush the JIT cache after a deep bail. That would - * free JITted code pages that we will later return to. Instead, set the - * needFlush flag so that it can be flushed later. - */ - JSBool needFlush; - - // Cached temporary typemap to avoid realloc'ing every time we create one. - // This must be used in only one place at a given time. It must be cleared - // before use. - TypeMap* cachedTempTypeMap; - - /* Scripts with recorded fragments. */ - TracedScriptSet tracedScripts; - -#ifdef DEBUG - /* Fields needed for fragment/guard profiling. */ - nanojit::Seq* branches; - uint32 lastFragID; - /* - * profAlloc has a lifetime which spans exactly from InitJIT to - * FinishJIT. - */ - VMAllocator* profAlloc; - FragStatsMap* profTab; -#endif - - bool ontrace() const { - return !!tracecx; - } - - /* Flush the JIT cache. */ - void flush(); - - /* Sweep any cache entry pointing to dead GC things. */ - void sweep(JSContext *cx); - - /* Mark any tracer stacks that are active. */ - void mark(JSTracer *trc); - - bool outOfMemory() const; -}; - -namespace mjit { -class JaegerCompartment; -} -} - -/* Number of potentially reusable scriptsToGC to search for the eval cache. */ -#ifndef JS_EVAL_CACHE_SHIFT -# define JS_EVAL_CACHE_SHIFT 6 -#endif -#define JS_EVAL_CACHE_SIZE JS_BIT(JS_EVAL_CACHE_SHIFT) - -#ifdef DEBUG -# define EVAL_CACHE_METER_LIST(_) _(probe), _(hit), _(step), _(noscope) -# define identity(x) x - -struct JSEvalCacheMeter { - uint64 EVAL_CACHE_METER_LIST(identity); -}; - -# undef identity -#endif - -namespace js { - -class NativeIterCache { - static const size_t SIZE = size_t(1) << 8; - - /* Cached native iterators. */ - JSObject *data[SIZE]; - - static size_t getIndex(uint32 key) { - return size_t(key) % SIZE; - } - - public: - /* Native iterator most recently started. */ - JSObject *last; - - NativeIterCache() - : last(NULL) { - PodArrayZero(data); - } - - void purge() { - PodArrayZero(data); - last = NULL; - } - - JSObject *get(uint32 key) const { - return data[getIndex(key)]; - } - - void set(uint32 key, JSObject *iterobj) { - data[getIndex(key)] = iterobj; - } -}; - -/* - * A single-entry cache for some base-10 double-to-string conversions. This - * helps date-format-xparb.js. It also avoids skewing the results for - * v8-splay.js when measured by the SunSpider harness, where the splay tree - * initialization (which includes many repeated double-to-string conversions) - * is erroneously included in the measurement; see bug 562553. - */ -class DtoaCache { - double d; - jsint base; - JSString *s; // if s==NULL, d and base are not valid - public: - DtoaCache() : s(NULL) {} - void purge() { s = NULL; } - - JSString *lookup(jsint base, double d) { - return this->s && base == this->base && d == this->d ? this->s : NULL; - } - - void cache(jsint base, double d, JSString *s) { - this->base = base; - this->d = d; - this->s = s; - } - -}; - -} /* namespace js */ - -struct JS_FRIEND_API(JSCompartment) { - JSRuntime *rt; - JSPrincipals *principals; - js::gc::Chunk *chunk; - - js::gc::ArenaList arenas[js::gc::FINALIZE_LIMIT]; - js::gc::FreeLists freeLists; - - size_t gcBytes; - size_t gcTriggerBytes; - size_t gcLastBytes; - -#ifdef JS_GCMETER - js::gc::JSGCArenaStats compartmentStats[js::gc::FINALIZE_LIMIT]; -#endif - -#ifdef JS_TRACER - /* Trace-tree JIT recorder/interpreter state. */ - js::TraceMonitor traceMonitor; -#endif - - /* Hashed lists of scripts created by eval to garbage-collect. */ - JSScript *scriptsToGC[JS_EVAL_CACHE_SIZE]; - -#ifdef DEBUG - JSEvalCacheMeter evalCacheMeter; -#endif - - void *data; - bool active; // GC flag, whether there are active frames - js::WrapperMap crossCompartmentWrappers; - -#ifdef JS_METHODJIT - js::mjit::JaegerCompartment *jaegerCompartment; -#endif - - /* - * Shared scope property tree, and arena-pool for allocating its nodes. - */ - js::PropertyTree propertyTree; - -#ifdef DEBUG - /* Property metering. */ - jsrefcount livePropTreeNodes; - jsrefcount totalPropTreeNodes; - jsrefcount propTreeKidsChunks; - jsrefcount liveDictModeNodes; -#endif - - /* - * Runtime-shared empty scopes for well-known built-in objects that lack - * class prototypes (the usual locus of an emptyShape). Mnemonic: ABCDEW - */ - js::EmptyShape *emptyArgumentsShape; - js::EmptyShape *emptyBlockShape; - js::EmptyShape *emptyCallShape; - js::EmptyShape *emptyDeclEnvShape; - js::EmptyShape *emptyEnumeratorShape; - js::EmptyShape *emptyWithShape; - - typedef js::HashSet, - js::SystemAllocPolicy> EmptyShapeSet; - - EmptyShapeSet emptyShapes; - - bool debugMode; // true iff debug mode on - JSCList scripts; // scripts in this compartment - - JSC::ExecutableAllocator *regExpAllocator; - - js::NativeIterCache nativeIterCache; - - js::ToSourceCache toSourceCache; - - JSCompartment(JSRuntime *rt); - ~JSCompartment(); - - bool init(); - - /* Mark cross-compartment wrappers. */ - void markCrossCompartment(JSTracer *trc); - - /* Mark this compartment's local roots. */ - void mark(JSTracer *trc); - - bool wrap(JSContext *cx, js::Value *vp); - bool wrap(JSContext *cx, JSString **strp); - bool wrap(JSContext *cx, JSObject **objp); - bool wrapId(JSContext *cx, jsid *idp); - bool wrap(JSContext *cx, js::PropertyOp *op); - bool wrap(JSContext *cx, js::StrictPropertyOp *op); - bool wrap(JSContext *cx, js::PropertyDescriptor *desc); - bool wrap(JSContext *cx, js::AutoIdVector &props); - - void sweep(JSContext *cx, uint32 releaseInterval); - void purge(JSContext *cx); - void finishArenaLists(); - void finalizeObjectArenaLists(JSContext *cx); - void finalizeStringArenaLists(JSContext *cx); - bool arenaListsAreEmpty(); - - void setGCLastBytes(size_t lastBytes); - - js::DtoaCache dtoaCache; - - private: - js::MathCache *mathCache; - - js::MathCache *allocMathCache(JSContext *cx); - - bool marked; - - typedef js::HashMap, - js::SystemAllocPolicy> BackEdgeMap; - - BackEdgeMap backEdgeTable; - - JSCompartment *thisForCtor() { return this; } - public: - js::MathCache *getMathCache(JSContext *cx) { - return mathCache ? mathCache : allocMathCache(cx); - } - - bool isMarked() { return marked; } - void clearMark() { marked = false; } - - size_t backEdgeCount(jsbytecode *pc) const; - size_t incBackEdgeCount(jsbytecode *pc); -}; - -#define JS_SCRIPTS_TO_GC(cx) ((cx)->compartment->scriptsToGC) -#define JS_PROPERTY_TREE(cx) ((cx)->compartment->propertyTree) - -#ifdef DEBUG -#define JS_COMPARTMENT_METER(x) x -#else -#define JS_COMPARTMENT_METER(x) -#endif - -/* - * N.B. JS_ON_TRACE(cx) is true if JIT code is on the stack in the current - * thread, regardless of whether cx is the context in which that trace is - * executing. cx must be a context on the current thread. - */ -static inline bool -JS_ON_TRACE(JSContext *cx) -{ -#ifdef JS_TRACER - if (JS_THREAD_DATA(cx)->onTraceCompartment) - return JS_THREAD_DATA(cx)->onTraceCompartment->traceMonitor.ontrace(); -#endif - return false; -} - -#ifdef JS_TRACER -static inline js::TraceMonitor * -JS_TRACE_MONITOR_ON_TRACE(JSContext *cx) -{ - JS_ASSERT(JS_ON_TRACE(cx)); - return &JS_THREAD_DATA(cx)->onTraceCompartment->traceMonitor; -} - -/* - * Only call this directly from the interpreter loop or the method jit. - * Otherwise, we may get the wrong compartment, and thus the wrong - * TraceMonitor. - */ -static inline js::TraceMonitor * -JS_TRACE_MONITOR_FROM_CONTEXT(JSContext *cx) -{ - return &cx->compartment->traceMonitor; -} -#endif - -static inline js::TraceRecorder * -TRACE_RECORDER(JSContext *cx) -{ -#ifdef JS_TRACER - if (JS_THREAD_DATA(cx)->recordingCompartment) - return JS_THREAD_DATA(cx)->recordingCompartment->traceMonitor.recorder; -#endif - return NULL; -} - -static inline js::LoopProfile * -TRACE_PROFILER(JSContext *cx) -{ -#ifdef JS_TRACER - if (JS_THREAD_DATA(cx)->profilingCompartment) - return JS_THREAD_DATA(cx)->profilingCompartment->traceMonitor.profile; -#endif - return NULL; -} - -namespace js { -static inline MathCache * -GetMathCache(JSContext *cx) -{ - return cx->compartment->getMathCache(cx); -} -} - -#ifdef DEBUG -# define EVAL_CACHE_METER(x) (cx->compartment->evalCacheMeter.x++) -#else -# define EVAL_CACHE_METER(x) ((void) 0) -#endif - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -namespace js { - -class PreserveCompartment { - protected: - JSContext *cx; - private: - JSCompartment *oldCompartment; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER - public: - PreserveCompartment(JSContext *cx JS_GUARD_OBJECT_NOTIFIER_PARAM) : cx(cx) { - JS_GUARD_OBJECT_NOTIFIER_INIT; - oldCompartment = cx->compartment; - } - - ~PreserveCompartment() { - cx->compartment = oldCompartment; - } -}; - -class SwitchToCompartment : public PreserveCompartment { - public: - SwitchToCompartment(JSContext *cx, JSCompartment *newCompartment) : PreserveCompartment(cx) { - cx->compartment = newCompartment; - } - - SwitchToCompartment(JSContext *cx, JSObject *target) : PreserveCompartment(cx) { - cx->compartment = target->getCompartment(); - } -}; - -class AssertCompartmentUnchanged { - protected: - JSContext * const cx; - JSCompartment * const oldCompartment; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER - public: - AssertCompartmentUnchanged(JSContext *cx JS_GUARD_OBJECT_NOTIFIER_PARAM) - : cx(cx), oldCompartment(cx->compartment) { - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - - ~AssertCompartmentUnchanged() { - JS_ASSERT(cx->compartment == oldCompartment); - } -}; - -} - -#endif /* jscompartment_h___ */ diff --git a/x86/mozilla/include/jscompat.h b/x86/mozilla/include/jscompat.h deleted file mode 100644 index 5ecda6e..0000000 --- a/x86/mozilla/include/jscompat.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998-1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jscompat_h___ -#define jscompat_h___ -/* - * Compatibility glue for various NSPR versions. We must always define int8, - * int16, jsword, and so on to minimize differences with js/ref, no matter what - * the NSPR typedef names may be. - */ -#include "jstypes.h" -#include "jslong.h" - -typedef JSIntn intN; -typedef JSUintn uintN; -typedef JSUword jsuword; -typedef JSWord jsword; -typedef float float32; -#endif /* jscompat_h___ */ diff --git a/x86/mozilla/include/jsdate.h b/x86/mozilla/include/jsdate.h deleted file mode 100644 index ba97ddd..0000000 --- a/x86/mozilla/include/jsdate.h +++ /dev/null @@ -1,125 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * JS Date class interface. - */ - -#ifndef jsdate_h___ -#define jsdate_h___ - -#include "jsobj.h" - -extern js::Class js_DateClass; - -inline bool -JSObject::isDate() const -{ - return getClass() == &js_DateClass; -} - -#define HalfTimeDomain 8.64e15 - -#define TIMECLIP(d) ((JSDOUBLE_IS_FINITE(d) \ - && !((d < 0 ? -d : d) > HalfTimeDomain)) \ - ? js_DoubleToInteger(d + (+0.)) : js_NaN) - -extern JSObject * -js_InitDateClass(JSContext *cx, JSObject *obj); - -/* - * These functions provide a C interface to the date/time object - */ - -/* - * Construct a new Date Object from a time value given in milliseconds UTC - * since the epoch. - */ -extern JS_FRIEND_API(JSObject*) -js_NewDateObjectMsec(JSContext* cx, jsdouble msec_time); - -/* - * Construct a new Date Object from an exploded local time value. - * - * Assert that mon < 12 to help catch off-by-one user errors, which are common - * due to the 0-based month numbering copied into JS from Java (java.util.Date - * in 1995). - */ -extern JS_FRIEND_API(JSObject*) -js_NewDateObject(JSContext* cx, int year, int mon, int mday, - int hour, int min, int sec); - -/* - * Detect whether the internal date value is NaN. (Because failure is - * out-of-band for js_DateGet*) - */ -extern JS_FRIEND_API(JSBool) -js_DateIsValid(JSContext *cx, JSObject* obj); - -extern JS_FRIEND_API(int) -js_DateGetYear(JSContext *cx, JSObject* obj); - -extern JS_FRIEND_API(int) -js_DateGetMonth(JSContext *cx, JSObject* obj); - -extern JS_FRIEND_API(int) -js_DateGetDate(JSContext *cx, JSObject* obj); - -extern JS_FRIEND_API(int) -js_DateGetHours(JSContext *cx, JSObject* obj); - -extern JS_FRIEND_API(int) -js_DateGetMinutes(JSContext *cx, JSObject* obj); - -extern JS_FRIEND_API(int) -js_DateGetSeconds(JSContext *cx, JSObject* obj); - -extern JS_FRIEND_API(jsdouble) -js_DateGetMsecSinceEpoch(JSContext *cx, JSObject *obj); - -typedef uint32 JSIntervalTime; - -extern JS_FRIEND_API(JSIntervalTime) -js_IntervalNow(); - -/* Date constructor native. Exposed only so the JIT can know its address. */ -JSBool -js_Date(JSContext *cx, uintN argc, js::Value *vp); - -#endif /* jsdate_h___ */ diff --git a/x86/mozilla/include/jsdbgapi.h b/x86/mozilla/include/jsdbgapi.h deleted file mode 100644 index 992e166..0000000 --- a/x86/mozilla/include/jsdbgapi.h +++ /dev/null @@ -1,568 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsdbgapi_h___ -#define jsdbgapi_h___ -/* - * JS debugger API. - */ -#include "jsapi.h" -#include "jsopcode.h" -#include "jsprvtd.h" - -JS_BEGIN_EXTERN_C - -/* - * Currently, we only support runtime-wide debugging. In the future, we should - * be able to support compartment-wide debugging. - */ -extern JS_PUBLIC_API(void) -JS_SetRuntimeDebugMode(JSRuntime *rt, JSBool debug); - -/* - * Debug mode is a compartment-wide mode that enables a debugger to attach - * to and interact with running methodjit-ed frames. In particular, it causes - * every function to be compiled as if an eval was present (so eval-in-frame) - * can work, and it ensures that functions can be re-JITed for other debug - * features. In general, it is not safe to interact with frames that were live - * before debug mode was enabled. For this reason, it is also not safe to - * enable debug mode while frames are live. - */ - -/* Get current state of debugging mode. */ -extern JS_PUBLIC_API(JSBool) -JS_GetDebugMode(JSContext *cx); - -/* - * Turn on/off debugging mode for a single compartment. This must be - * called from the main thread and the compartment must be associated - * with the main thread. - */ -JS_FRIEND_API(JSBool) -JS_SetDebugModeForCompartment(JSContext *cx, JSCompartment *comp, JSBool debug); - -/* - * Turn on/off debugging mode for a context's compartment. - */ -JS_FRIEND_API(JSBool) -JS_SetDebugMode(JSContext *cx, JSBool debug); - -/* Turn on single step mode. Requires debug mode. */ -extern JS_FRIEND_API(JSBool) -js_SetSingleStepMode(JSContext *cx, JSScript *script, JSBool singleStep); - -/* Turn on single step mode. */ -extern JS_PUBLIC_API(JSBool) -JS_SetSingleStepMode(JSContext *cx, JSScript *script, JSBool singleStep); - -/* - * Unexported library-private helper used to unpatch all traps in a script. - * Returns script->code if script has no traps, else a JS_malloc'ed copy of - * script->code which the caller must JS_free, or null on JS_malloc OOM. - */ -extern jsbytecode * -js_UntrapScriptCode(JSContext *cx, JSScript *script); - -/* The closure argument will be marked. */ -extern JS_PUBLIC_API(JSBool) -JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc, - JSTrapHandler handler, jsval closure); - -extern JS_PUBLIC_API(JSOp) -JS_GetTrapOpcode(JSContext *cx, JSScript *script, jsbytecode *pc); - -extern JS_PUBLIC_API(void) -JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc, - JSTrapHandler *handlerp, jsval *closurep); - -extern JS_PUBLIC_API(void) -JS_ClearScriptTraps(JSContext *cx, JSScript *script); - -extern JS_PUBLIC_API(void) -JS_ClearAllTraps(JSContext *cx); - -extern JS_PUBLIC_API(JSTrapStatus) -JS_HandleTrap(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval); - -extern JS_PUBLIC_API(JSBool) -JS_SetInterrupt(JSRuntime *rt, JSInterruptHook handler, void *closure); - -extern JS_PUBLIC_API(JSBool) -JS_ClearInterrupt(JSRuntime *rt, JSInterruptHook *handlerp, void **closurep); - -/************************************************************************/ - -extern JS_PUBLIC_API(JSBool) -JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsid id, - JSWatchPointHandler handler, JSObject *closure); - -extern JS_PUBLIC_API(JSBool) -JS_ClearWatchPoint(JSContext *cx, JSObject *obj, jsid id, - JSWatchPointHandler *handlerp, JSObject **closurep); - -extern JS_PUBLIC_API(JSBool) -JS_ClearWatchPointsForObject(JSContext *cx, JSObject *obj); - -extern JS_PUBLIC_API(JSBool) -JS_ClearAllWatchPoints(JSContext *cx); - -#ifdef JS_HAS_OBJ_WATCHPOINT -/* - * Hide these non-API function prototypes by testing whether the internal - * header file "jsversion.h" has been included. - */ -extern void -js_TraceWatchPoints(JSTracer *trc, JSObject *obj); - -extern void -js_SweepWatchPoints(JSContext *cx); - -#ifdef __cplusplus - -extern JSBool -js_watch_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict, js::Value *vp); - -namespace js { - -bool -IsWatchedProperty(JSContext *cx, const Shape *shape); - -} - -#endif - -#endif /* JS_HAS_OBJ_WATCHPOINT */ - -/************************************************************************/ - -extern JS_PUBLIC_API(uintN) -JS_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc); - -extern JS_PUBLIC_API(jsbytecode *) -JS_LineNumberToPC(JSContext *cx, JSScript *script, uintN lineno); - -extern JS_PUBLIC_API(jsbytecode *) -JS_EndPC(JSContext *cx, JSScript *script); - -extern JS_PUBLIC_API(uintN) -JS_GetFunctionArgumentCount(JSContext *cx, JSFunction *fun); - -extern JS_PUBLIC_API(JSBool) -JS_FunctionHasLocalNames(JSContext *cx, JSFunction *fun); - -/* - * N.B. The mark is in the context temp pool and thus the caller must take care - * to call JS_ReleaseFunctionLocalNameArray in a LIFO manner (wrt to any other - * call that may use the temp pool. - */ -extern JS_PUBLIC_API(jsuword *) -JS_GetFunctionLocalNameArray(JSContext *cx, JSFunction *fun, void **markp); - -extern JS_PUBLIC_API(JSAtom *) -JS_LocalNameToAtom(jsuword w); - -extern JS_PUBLIC_API(JSString *) -JS_AtomKey(JSAtom *atom); - -extern JS_PUBLIC_API(void) -JS_ReleaseFunctionLocalNameArray(JSContext *cx, void *mark); - -extern JS_PUBLIC_API(JSScript *) -JS_GetFunctionScript(JSContext *cx, JSFunction *fun); - -extern JS_PUBLIC_API(JSNative) -JS_GetFunctionNative(JSContext *cx, JSFunction *fun); - -extern JS_PUBLIC_API(JSPrincipals *) -JS_GetScriptPrincipals(JSContext *cx, JSScript *script); - -/* - * Stack Frame Iterator - * - * Used to iterate through the JS stack frames to extract - * information from the frames. - */ - -extern JS_PUBLIC_API(JSStackFrame *) -JS_FrameIterator(JSContext *cx, JSStackFrame **iteratorp); - -extern JS_PUBLIC_API(JSScript *) -JS_GetFrameScript(JSContext *cx, JSStackFrame *fp); - -extern JS_PUBLIC_API(jsbytecode *) -JS_GetFramePC(JSContext *cx, JSStackFrame *fp); - -/* - * Get the closest scripted frame below fp. If fp is null, start from cx->fp. - */ -extern JS_PUBLIC_API(JSStackFrame *) -JS_GetScriptedCaller(JSContext *cx, JSStackFrame *fp); - -/* - * Return a weak reference to fp's principals. A null return does not denote - * an error, it means there are no principals. - */ -extern JSPrincipals * -js_StackFramePrincipals(JSContext *cx, JSStackFrame *fp); - -JSPrincipals * -js_EvalFramePrincipals(JSContext *cx, JSObject *callee, JSStackFrame *caller); - -extern JS_PUBLIC_API(void *) -JS_GetFrameAnnotation(JSContext *cx, JSStackFrame *fp); - -extern JS_PUBLIC_API(void) -JS_SetFrameAnnotation(JSContext *cx, JSStackFrame *fp, void *annotation); - -extern JS_PUBLIC_API(void *) -JS_GetFramePrincipalArray(JSContext *cx, JSStackFrame *fp); - -extern JS_PUBLIC_API(JSBool) -JS_IsScriptFrame(JSContext *cx, JSStackFrame *fp); - -/* this is deprecated, use JS_GetFrameScopeChain instead */ -extern JS_PUBLIC_API(JSObject *) -JS_GetFrameObject(JSContext *cx, JSStackFrame *fp); - -extern JS_PUBLIC_API(JSObject *) -JS_GetFrameScopeChain(JSContext *cx, JSStackFrame *fp); - -extern JS_PUBLIC_API(JSObject *) -JS_GetFrameCallObject(JSContext *cx, JSStackFrame *fp); - -extern JS_PUBLIC_API(JSBool) -JS_GetFrameThis(JSContext *cx, JSStackFrame *fp, jsval *thisv); - -extern JS_PUBLIC_API(JSFunction *) -JS_GetFrameFunction(JSContext *cx, JSStackFrame *fp); - -extern JS_PUBLIC_API(JSObject *) -JS_GetFrameFunctionObject(JSContext *cx, JSStackFrame *fp); - -/* XXXrginda Initially published with typo */ -#define JS_IsContructorFrame JS_IsConstructorFrame -extern JS_PUBLIC_API(JSBool) -JS_IsConstructorFrame(JSContext *cx, JSStackFrame *fp); - -extern JS_PUBLIC_API(JSBool) -JS_IsDebuggerFrame(JSContext *cx, JSStackFrame *fp); - -extern JS_PUBLIC_API(jsval) -JS_GetFrameReturnValue(JSContext *cx, JSStackFrame *fp); - -extern JS_PUBLIC_API(void) -JS_SetFrameReturnValue(JSContext *cx, JSStackFrame *fp, jsval rval); - -/** - * Return fp's callee function object (fp->callee) if it has one. Note that - * this API cannot fail. A null return means "no callee": fp is a global or - * eval-from-global frame, not a call frame. - * - * This API began life as an infallible getter, but now it can return either: - * - * 1. An optimized closure that was compiled assuming the function could not - * escape and be called from sites the compiler could not see. - * - * 2. A "joined function object", an optimization whereby SpiderMonkey avoids - * creating fresh function objects for every evaluation of a function - * expression that is used only once by a consumer that either promises to - * clone later when asked for the value or that cannot leak the value. - * - * Because Mozilla's Gecko embedding of SpiderMonkey (and no doubt other - * embeddings) calls this API in potentially performance-sensitive ways (e.g. - * in nsContentUtils::GetDocumentFromCaller), we are leaving this API alone. It - * may now return an unwrapped non-escaping optimized closure, or a joined - * function object. Such optimized objects may work well if called from the - * correct context, never mutated or compared for identity, etc. - * - * However, if you really need to get the same callee object that JS code would - * see, which means undoing the optimizations, where an undo attempt can fail, - * then use JS_GetValidFrameCalleeObject. - */ -extern JS_PUBLIC_API(JSObject *) -JS_GetFrameCalleeObject(JSContext *cx, JSStackFrame *fp); - -/** - * Return fp's callee function object after running the deferred closure - * cloning "method read barrier". This API can fail! If the frame has no - * callee, this API returns true with JSVAL_IS_VOID(*vp). - */ -extern JS_PUBLIC_API(JSBool) -JS_GetValidFrameCalleeObject(JSContext *cx, JSStackFrame *fp, jsval *vp); - -/************************************************************************/ - -extern JS_PUBLIC_API(const char *) -JS_GetScriptFilename(JSContext *cx, JSScript *script); - -extern JS_PUBLIC_API(uintN) -JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script); - -extern JS_PUBLIC_API(uintN) -JS_GetScriptLineExtent(JSContext *cx, JSScript *script); - -extern JS_PUBLIC_API(JSVersion) -JS_GetScriptVersion(JSContext *cx, JSScript *script); - -/************************************************************************/ - -/* - * Hook setters for script creation and destruction, see jsprvtd.h for the - * typedefs. These macros provide binary compatibility and newer, shorter - * synonyms. - */ -#define JS_SetNewScriptHook JS_SetNewScriptHookProc -#define JS_SetDestroyScriptHook JS_SetDestroyScriptHookProc - -extern JS_PUBLIC_API(void) -JS_SetNewScriptHook(JSRuntime *rt, JSNewScriptHook hook, void *callerdata); - -extern JS_PUBLIC_API(void) -JS_SetDestroyScriptHook(JSRuntime *rt, JSDestroyScriptHook hook, - void *callerdata); - -/************************************************************************/ - -extern JS_PUBLIC_API(JSBool) -JS_EvaluateUCInStackFrame(JSContext *cx, JSStackFrame *fp, - const jschar *chars, uintN length, - const char *filename, uintN lineno, - jsval *rval); - -extern JS_PUBLIC_API(JSBool) -JS_EvaluateInStackFrame(JSContext *cx, JSStackFrame *fp, - const char *bytes, uintN length, - const char *filename, uintN lineno, - jsval *rval); - -/************************************************************************/ - -typedef struct JSPropertyDesc { - jsval id; /* primary id, atomized string, or int */ - jsval value; /* property value */ - uint8 flags; /* flags, see below */ - uint8 spare; /* unused */ - uint16 slot; /* argument/variable slot */ - jsval alias; /* alias id if JSPD_ALIAS flag */ -} JSPropertyDesc; - -#define JSPD_ENUMERATE 0x01 /* visible to for/in loop */ -#define JSPD_READONLY 0x02 /* assignment is error */ -#define JSPD_PERMANENT 0x04 /* property cannot be deleted */ -#define JSPD_ALIAS 0x08 /* property has an alias id */ -#define JSPD_ARGUMENT 0x10 /* argument to function */ -#define JSPD_VARIABLE 0x20 /* local variable in function */ -#define JSPD_EXCEPTION 0x40 /* exception occurred fetching the property, */ - /* value is exception */ -#define JSPD_ERROR 0x80 /* native getter returned JS_FALSE without */ - /* throwing an exception */ - -typedef struct JSPropertyDescArray { - uint32 length; /* number of elements in array */ - JSPropertyDesc *array; /* alloc'd by Get, freed by Put */ -} JSPropertyDescArray; - -typedef struct JSScopeProperty JSScopeProperty; - -extern JS_PUBLIC_API(JSScopeProperty *) -JS_PropertyIterator(JSObject *obj, JSScopeProperty **iteratorp); - -extern JS_PUBLIC_API(JSBool) -JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *shape, - JSPropertyDesc *pd); - -extern JS_PUBLIC_API(JSBool) -JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda); - -extern JS_PUBLIC_API(void) -JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda); - -/************************************************************************/ - -extern JS_PUBLIC_API(JSBool) -JS_SetDebuggerHandler(JSRuntime *rt, JSDebuggerHandler hook, void *closure); - -extern JS_PUBLIC_API(JSBool) -JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure); - -extern JS_PUBLIC_API(JSBool) -JS_SetExecuteHook(JSRuntime *rt, JSInterpreterHook hook, void *closure); - -extern JS_PUBLIC_API(JSBool) -JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure); - -extern JS_PUBLIC_API(JSBool) -JS_SetThrowHook(JSRuntime *rt, JSThrowHook hook, void *closure); - -extern JS_PUBLIC_API(JSBool) -JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure); - -/************************************************************************/ - -extern JS_PUBLIC_API(size_t) -JS_GetObjectTotalSize(JSContext *cx, JSObject *obj); - -extern JS_PUBLIC_API(size_t) -JS_GetFunctionTotalSize(JSContext *cx, JSFunction *fun); - -extern JS_PUBLIC_API(size_t) -JS_GetScriptTotalSize(JSContext *cx, JSScript *script); - -/* - * Get the top-most running script on cx starting from fp, or from the top of - * cx's frame stack if fp is null, and return its script filename flags. If - * the script has a null filename member, return JSFILENAME_NULL. - */ -extern JS_PUBLIC_API(uint32) -JS_GetTopScriptFilenameFlags(JSContext *cx, JSStackFrame *fp); - -/* - * Get the script filename flags for the script. If the script doesn't have a - * filename, return JSFILENAME_NULL. - */ -extern JS_PUBLIC_API(uint32) -JS_GetScriptFilenameFlags(JSScript *script); - -/* - * Associate flags with a script filename prefix in rt, so that any subsequent - * script compilation will inherit those flags if the script's filename is the - * same as prefix, or if prefix is a substring of the script's filename. - * - * The API defines only one flag bit, JSFILENAME_SYSTEM, leaving the remaining - * 31 bits up to the API client to define. The union of all 32 bits must not - * be a legal combination, however, in order to preserve JSFILENAME_NULL as a - * unique value. API clients may depend on JSFILENAME_SYSTEM being a set bit - * in JSFILENAME_NULL -- a script with a null filename member is presumed to - * be a "system" script. - */ -extern JS_PUBLIC_API(JSBool) -JS_FlagScriptFilenamePrefix(JSRuntime *rt, const char *prefix, uint32 flags); - -#define JSFILENAME_NULL 0xffffffff /* null script filename */ -#define JSFILENAME_SYSTEM 0x00000001 /* "system" script, see below */ -#define JSFILENAME_PROTECTED 0x00000002 /* scripts need protection */ - -/* - * Return true if obj is a "system" object, that is, one created by - * JS_NewSystemObject with the system flag set and not JS_NewObject. - * - * What "system" means is up to the API client, but it can be used to implement - * access control policies based on script filenames and their prefixes, using - * JS_FlagScriptFilenamePrefix and JS_GetTopScriptFilenameFlags. - */ -extern JS_PUBLIC_API(JSBool) -JS_IsSystemObject(JSContext *cx, JSObject *obj); - -/* - * Mark an object as being a system object. This should be called immediately - * after allocating the object. A system object is an object for which - * JS_IsSystemObject returns true. - */ -extern JS_PUBLIC_API(JSBool) -JS_MakeSystemObject(JSContext *cx, JSObject *obj); - -/************************************************************************/ - -extern JS_PUBLIC_API(JSObject *) -JS_UnwrapObject(JSContext *cx, JSObject *obj); - -/************************************************************************/ - -extern JS_FRIEND_API(void) -js_RevertVersion(JSContext *cx); - -extern JS_PUBLIC_API(const JSDebugHooks *) -JS_GetGlobalDebugHooks(JSRuntime *rt); - -extern JS_PUBLIC_API(JSDebugHooks *) -JS_SetContextDebugHooks(JSContext *cx, const JSDebugHooks *hooks); - -/* Disable debug hooks for this context. */ -extern JS_PUBLIC_API(JSDebugHooks *) -JS_ClearContextDebugHooks(JSContext *cx); - -extern JS_PUBLIC_API(JSBool) -JS_StartProfiling(); - -extern JS_PUBLIC_API(void) -JS_StopProfiling(); - -extern JS_PUBLIC_API(JSBool) -JS_DefineProfilingFunctions(JSContext *cx, JSObject *obj); - -#ifdef MOZ_CALLGRIND - -extern JS_FRIEND_API(JSBool) -js_StopCallgrind(JSContext *cx, uintN argc, jsval *vp); - -extern JS_FRIEND_API(JSBool) -js_StartCallgrind(JSContext *cx, uintN argc, jsval *vp); - -extern JS_FRIEND_API(JSBool) -js_DumpCallgrind(JSContext *cx, uintN argc, jsval *vp); - -#endif /* MOZ_CALLGRIND */ - -#ifdef MOZ_VTUNE - -extern JS_FRIEND_API(JSBool) -js_StartVtune(JSContext *cx, uintN argc, jsval *vp); - -extern JS_FRIEND_API(JSBool) -js_StopVtune(JSContext *cx, uintN argc, jsval *vp); - -extern JS_FRIEND_API(JSBool) -js_PauseVtune(JSContext *cx, uintN argc, jsval *vp); - -extern JS_FRIEND_API(JSBool) -js_ResumeVtune(JSContext *cx, uintN argc, jsval *vp); - -#endif /* MOZ_VTUNE */ - -#ifdef MOZ_TRACEVIS -extern JS_FRIEND_API(JSBool) -js_InitEthogram(JSContext *cx, uintN argc, jsval *vp); -extern JS_FRIEND_API(JSBool) -js_ShutdownEthogram(JSContext *cx, uintN argc, jsval *vp); -#endif /* MOZ_TRACEVIS */ - -JS_END_EXTERN_C - -#endif /* jsdbgapi_h___ */ diff --git a/x86/mozilla/include/jsdhash.h b/x86/mozilla/include/jsdhash.h deleted file mode 100644 index 13ab221..0000000 --- a/x86/mozilla/include/jsdhash.h +++ /dev/null @@ -1,607 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla JavaScript code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1999-2001 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brendan Eich (Original Author) - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsdhash_h___ -#define jsdhash_h___ -/* - * Double hashing, a la Knuth 6. - */ -#include "jstypes.h" - -JS_BEGIN_EXTERN_C - -#if defined(__GNUC__) && defined(__i386__) && (__GNUC__ >= 3) && !defined(XP_OS2) -#define JS_DHASH_FASTCALL __attribute__ ((regparm (3),stdcall)) -#elif defined(XP_WIN) -#define JS_DHASH_FASTCALL __fastcall -#else -#define JS_DHASH_FASTCALL -#endif - -#ifdef DEBUG_XXXbrendan -#define JS_DHASHMETER 1 -#endif - -/* Table size limit, do not equal or exceed (see min&maxAlphaFrac, below). */ -#undef JS_DHASH_SIZE_LIMIT -#define JS_DHASH_SIZE_LIMIT JS_BIT(24) - -/* Minimum table size, or gross entry count (net is at most .75 loaded). */ -#ifndef JS_DHASH_MIN_SIZE -#define JS_DHASH_MIN_SIZE 16 -#elif (JS_DHASH_MIN_SIZE & (JS_DHASH_MIN_SIZE - 1)) != 0 -#error "JS_DHASH_MIN_SIZE must be a power of two!" -#endif - -/* - * Multiplicative hash uses an unsigned 32 bit integer and the golden ratio, - * expressed as a fixed-point 32-bit fraction. - */ -#define JS_DHASH_BITS 32 -#define JS_DHASH_GOLDEN_RATIO 0x9E3779B9U - -/* Primitive and forward-struct typedefs. */ -typedef uint32 JSDHashNumber; -typedef struct JSDHashEntryHdr JSDHashEntryHdr; -typedef struct JSDHashEntryStub JSDHashEntryStub; -typedef struct JSDHashTable JSDHashTable; -typedef struct JSDHashTableOps JSDHashTableOps; - -/* - * Table entry header structure. - * - * In order to allow in-line allocation of key and value, we do not declare - * either here. Instead, the API uses const void *key as a formal parameter. - * The key need not be stored in the entry; it may be part of the value, but - * need not be stored at all. - * - * Callback types are defined below and grouped into the JSDHashTableOps - * structure, for single static initialization per hash table sub-type. - * - * Each hash table sub-type should nest the JSDHashEntryHdr structure at the - * front of its particular entry type. The keyHash member contains the result - * of multiplying the hash code returned from the hashKey callback (see below) - * by JS_DHASH_GOLDEN_RATIO, then constraining the result to avoid the magic 0 - * and 1 values. The stored keyHash value is table size invariant, and it is - * maintained automatically by JS_DHashTableOperate -- users should never set - * it, and its only uses should be via the entry macros below. - * - * The JS_DHASH_ENTRY_IS_LIVE macro tests whether entry is neither free nor - * removed. An entry may be either busy or free; if busy, it may be live or - * removed. Consumers of this API should not access members of entries that - * are not live. - * - * However, use JS_DHASH_ENTRY_IS_BUSY for faster liveness testing of entries - * returned by JS_DHashTableOperate, as JS_DHashTableOperate never returns a - * non-live, busy (i.e., removed) entry pointer to its caller. See below for - * more details on JS_DHashTableOperate's calling rules. - */ -struct JSDHashEntryHdr { - JSDHashNumber keyHash; /* every entry must begin like this */ -}; - -#define JS_DHASH_ENTRY_IS_FREE(entry) ((entry)->keyHash == 0) -#define JS_DHASH_ENTRY_IS_BUSY(entry) (!JS_DHASH_ENTRY_IS_FREE(entry)) -#define JS_DHASH_ENTRY_IS_LIVE(entry) ((entry)->keyHash >= 2) - -/* - * A JSDHashTable is currently 8 words (without the JS_DHASHMETER overhead) - * on most architectures, and may be allocated on the stack or within another - * structure or class (see below for the Init and Finish functions to use). - * - * To decide whether to use double hashing vs. chaining, we need to develop a - * trade-off relation, as follows: - * - * Let alpha be the load factor, esize the entry size in words, count the - * entry count, and pow2 the power-of-two table size in entries. - * - * (JSDHashTable overhead) > (JSHashTable overhead) - * (unused table entry space) > (malloc and .next overhead per entry) + - * (buckets overhead) - * (1 - alpha) * esize * pow2 > 2 * count + pow2 - * - * Notice that alpha is by definition (count / pow2): - * - * (1 - alpha) * esize * pow2 > 2 * alpha * pow2 + pow2 - * (1 - alpha) * esize > 2 * alpha + 1 - * - * esize > (1 + 2 * alpha) / (1 - alpha) - * - * This assumes both tables must keep keyHash, key, and value for each entry, - * where key and value point to separately allocated strings or structures. - * If key and value can be combined into one pointer, then the trade-off is: - * - * esize > (1 + 3 * alpha) / (1 - alpha) - * - * If the entry value can be a subtype of JSDHashEntryHdr, rather than a type - * that must be allocated separately and referenced by an entry.value pointer - * member, and provided key's allocation can be fused with its entry's, then - * k (the words wasted per entry with chaining) is 4. - * - * To see these curves, feed gnuplot input like so: - * - * gnuplot> f(x,k) = (1 + k * x) / (1 - x) - * gnuplot> plot [0:.75] f(x,2), f(x,3), f(x,4) - * - * For k of 2 and a well-loaded table (alpha > .5), esize must be more than 4 - * words for chaining to be more space-efficient than double hashing. - * - * Solving for alpha helps us decide when to shrink an underloaded table: - * - * esize > (1 + k * alpha) / (1 - alpha) - * esize - alpha * esize > 1 + k * alpha - * esize - 1 > (k + esize) * alpha - * (esize - 1) / (k + esize) > alpha - * - * alpha < (esize - 1) / (esize + k) - * - * Therefore double hashing should keep alpha >= (esize - 1) / (esize + k), - * assuming esize is not too large (in which case, chaining should probably be - * used for any alpha). For esize=2 and k=3, we want alpha >= .2; for esize=3 - * and k=2, we want alpha >= .4. For k=4, esize could be 6, and alpha >= .5 - * would still obtain. See the JS_DHASH_MIN_ALPHA macro further below. - * - * The current implementation uses a configurable lower bound on alpha, which - * defaults to .25, when deciding to shrink the table (while still respecting - * JS_DHASH_MIN_SIZE). - * - * Note a qualitative difference between chaining and double hashing: under - * chaining, entry addresses are stable across table shrinks and grows. With - * double hashing, you can't safely hold an entry pointer and use it after an - * ADD or REMOVE operation, unless you sample table->generation before adding - * or removing, and compare the sample after, dereferencing the entry pointer - * only if table->generation has not changed. - * - * The moral of this story: there is no one-size-fits-all hash table scheme, - * but for small table entry size, and assuming entry address stability is not - * required, double hashing wins. - */ -struct JSDHashTable { - const JSDHashTableOps *ops; /* virtual operations, see below */ - void *data; /* ops- and instance-specific data */ - int16 hashShift; /* multiplicative hash shift */ - uint8 maxAlphaFrac; /* 8-bit fixed point max alpha */ - uint8 minAlphaFrac; /* 8-bit fixed point min alpha */ - uint32 entrySize; /* number of bytes in an entry */ - uint32 entryCount; /* number of entries in table */ - uint32 removedCount; /* removed entry sentinels in table */ - uint32 generation; /* entry storage generation number */ - char *entryStore; /* entry storage */ -#ifdef JS_DHASHMETER - struct JSDHashStats { - uint32 searches; /* total number of table searches */ - uint32 steps; /* hash chain links traversed */ - uint32 hits; /* searches that found key */ - uint32 misses; /* searches that didn't find key */ - uint32 lookups; /* number of JS_DHASH_LOOKUPs */ - uint32 addMisses; /* adds that miss, and do work */ - uint32 addOverRemoved; /* adds that recycled a removed entry */ - uint32 addHits; /* adds that hit an existing entry */ - uint32 addFailures; /* out-of-memory during add growth */ - uint32 removeHits; /* removes that hit, and do work */ - uint32 removeMisses; /* useless removes that miss */ - uint32 removeFrees; /* removes that freed entry directly */ - uint32 removeEnums; /* removes done by Enumerate */ - uint32 grows; /* table expansions */ - uint32 shrinks; /* table contractions */ - uint32 compresses; /* table compressions */ - uint32 enumShrinks; /* contractions after Enumerate */ - } stats; -#endif -}; - -/* - * Size in entries (gross, not net of free and removed sentinels) for table. - * We store hashShift rather than sizeLog2 to optimize the collision-free case - * in SearchTable. - */ -#define JS_DHASH_TABLE_SIZE(table) JS_BIT(JS_DHASH_BITS - (table)->hashShift) - -/* - * Table space at entryStore is allocated and freed using these callbacks. - * The allocator should return null on error only (not if called with nbytes - * equal to 0; but note that jsdhash.c code will never call with 0 nbytes). - */ -typedef void * -(* JSDHashAllocTable)(JSDHashTable *table, uint32 nbytes); - -typedef void -(* JSDHashFreeTable) (JSDHashTable *table, void *ptr); - -/* - * Compute the hash code for a given key to be looked up, added, or removed - * from table. A hash code may have any JSDHashNumber value. - */ -typedef JSDHashNumber -(* JSDHashHashKey) (JSDHashTable *table, const void *key); - -/* - * Compare the key identifying entry in table with the provided key parameter. - * Return JS_TRUE if keys match, JS_FALSE otherwise. - */ -typedef JSBool -(* JSDHashMatchEntry)(JSDHashTable *table, const JSDHashEntryHdr *entry, - const void *key); - -/* - * Copy the data starting at from to the new entry storage at to. Do not add - * reference counts for any strong references in the entry, however, as this - * is a "move" operation: the old entry storage at from will be freed without - * any reference-decrementing callback shortly. - */ -typedef void -(* JSDHashMoveEntry)(JSDHashTable *table, const JSDHashEntryHdr *from, - JSDHashEntryHdr *to); - -/* - * Clear the entry and drop any strong references it holds. This callback is - * invoked during a JS_DHASH_REMOVE operation (see below for operation codes), - * but only if the given key is found in the table. - */ -typedef void -(* JSDHashClearEntry)(JSDHashTable *table, JSDHashEntryHdr *entry); - -/* - * Called when a table (whether allocated dynamically by itself, or nested in - * a larger structure, or allocated on the stack) is finished. This callback - * allows table->ops-specific code to finalize table->data. - */ -typedef void -(* JSDHashFinalize) (JSDHashTable *table); - -/* - * Initialize a new entry, apart from keyHash. This function is called when - * JS_DHashTableOperate's JS_DHASH_ADD case finds no existing entry for the - * given key, and must add a new one. At that point, entry->keyHash is not - * set yet, to avoid claiming the last free entry in a severely overloaded - * table. - */ -typedef JSBool -(* JSDHashInitEntry)(JSDHashTable *table, JSDHashEntryHdr *entry, - const void *key); - -/* - * Finally, the "vtable" structure for JSDHashTable. The first eight hooks - * must be provided by implementations; they're called unconditionally by the - * generic jsdhash.c code. Hooks after these may be null. - * - * Summary of allocation-related hook usage with C++ placement new emphasis: - * allocTable Allocate raw bytes with malloc, no ctors run. - * freeTable Free raw bytes with free, no dtors run. - * initEntry Call placement new using default key-based ctor. - * Return JS_TRUE on success, JS_FALSE on error. - * moveEntry Call placement new using copy ctor, run dtor on old - * entry storage. - * clearEntry Run dtor on entry. - * finalize Stub unless table->data was initialized and needs to - * be finalized. - * - * Note the reason why initEntry is optional: the default hooks (stubs) clear - * entry storage: On successful JS_DHashTableOperate(tbl, key, JS_DHASH_ADD), - * the returned entry pointer addresses an entry struct whose keyHash member - * has been set non-zero, but all other entry members are still clear (null). - * JS_DHASH_ADD callers can test such members to see whether the entry was - * newly created by the JS_DHASH_ADD call that just succeeded. If placement - * new or similar initialization is required, define an initEntry hook. Of - * course, the clearEntry hook must zero or null appropriately. - * - * XXX assumes 0 is null for pointer types. - */ -struct JSDHashTableOps { - /* Mandatory hooks. All implementations must provide these. */ - JSDHashAllocTable allocTable; - JSDHashFreeTable freeTable; - JSDHashHashKey hashKey; - JSDHashMatchEntry matchEntry; - JSDHashMoveEntry moveEntry; - JSDHashClearEntry clearEntry; - JSDHashFinalize finalize; - - /* Optional hooks start here. If null, these are not called. */ - JSDHashInitEntry initEntry; -}; - -/* - * Default implementations for the above ops. - */ -extern JS_PUBLIC_API(void *) -JS_DHashAllocTable(JSDHashTable *table, uint32 nbytes); - -extern JS_PUBLIC_API(void) -JS_DHashFreeTable(JSDHashTable *table, void *ptr); - -extern JS_PUBLIC_API(JSDHashNumber) -JS_DHashStringKey(JSDHashTable *table, const void *key); - -/* A minimal entry contains a keyHash header and a void key pointer. */ -struct JSDHashEntryStub { - JSDHashEntryHdr hdr; - const void *key; -}; - -extern JS_PUBLIC_API(JSDHashNumber) -JS_DHashVoidPtrKeyStub(JSDHashTable *table, const void *key); - -extern JS_PUBLIC_API(JSBool) -JS_DHashMatchEntryStub(JSDHashTable *table, - const JSDHashEntryHdr *entry, - const void *key); - -extern JS_PUBLIC_API(JSBool) -JS_DHashMatchStringKey(JSDHashTable *table, - const JSDHashEntryHdr *entry, - const void *key); - -extern JS_PUBLIC_API(void) -JS_DHashMoveEntryStub(JSDHashTable *table, - const JSDHashEntryHdr *from, - JSDHashEntryHdr *to); - -extern JS_PUBLIC_API(void) -JS_DHashClearEntryStub(JSDHashTable *table, JSDHashEntryHdr *entry); - -extern JS_PUBLIC_API(void) -JS_DHashFreeStringKey(JSDHashTable *table, JSDHashEntryHdr *entry); - -extern JS_PUBLIC_API(void) -JS_DHashFinalizeStub(JSDHashTable *table); - -/* - * If you use JSDHashEntryStub or a subclass of it as your entry struct, and - * if your entries move via memcpy and clear via memset(0), you can use these - * stub operations. - */ -extern JS_PUBLIC_API(const JSDHashTableOps *) -JS_DHashGetStubOps(void); - -/* - * Dynamically allocate a new JSDHashTable using malloc, initialize it using - * JS_DHashTableInit, and return its address. Return null on malloc failure. - * Note that the entry storage at table->entryStore will be allocated using - * the ops->allocTable callback. - */ -extern JS_PUBLIC_API(JSDHashTable *) -JS_NewDHashTable(const JSDHashTableOps *ops, void *data, uint32 entrySize, - uint32 capacity); - -/* - * Finalize table's data, free its entry storage (via table->ops->freeTable), - * and return the memory starting at table to the malloc heap. - */ -extern JS_PUBLIC_API(void) -JS_DHashTableDestroy(JSDHashTable *table); - -/* - * Initialize table with ops, data, entrySize, and capacity. Capacity is a - * guess for the smallest table size at which the table will usually be less - * than 75% loaded (the table will grow or shrink as needed; capacity serves - * only to avoid inevitable early growth from JS_DHASH_MIN_SIZE). - */ -extern JS_PUBLIC_API(JSBool) -JS_DHashTableInit(JSDHashTable *table, const JSDHashTableOps *ops, void *data, - uint32 entrySize, uint32 capacity); - -/* - * Set maximum and minimum alpha for table. The defaults are 0.75 and .25. - * maxAlpha must be in [0.5, 0.9375] for the default JS_DHASH_MIN_SIZE; or if - * MinSize=JS_DHASH_MIN_SIZE <= 256, in [0.5, (float)(MinSize-1)/MinSize]; or - * else in [0.5, 255.0/256]. minAlpha must be in [0, maxAlpha / 2), so that - * we don't shrink on the very next remove after growing a table upon adding - * an entry that brings entryCount past maxAlpha * tableSize. - */ -extern JS_PUBLIC_API(void) -JS_DHashTableSetAlphaBounds(JSDHashTable *table, - float maxAlpha, - float minAlpha); - -/* - * Call this macro with k, the number of pointer-sized words wasted per entry - * under chaining, to compute the minimum alpha at which double hashing still - * beats chaining. - */ -#define JS_DHASH_MIN_ALPHA(table, k) \ - ((float)((table)->entrySize / sizeof(void *) - 1) \ - / ((table)->entrySize / sizeof(void *) + (k))) - -/* - * Default max/min alpha, and macros to compute the value for the |capacity| - * parameter to JS_NewDHashTable and JS_DHashTableInit, given default or any - * max alpha, such that adding entryCount entries right after initializing the - * table will not require a reallocation (so JS_DHASH_ADD can't fail for those - * JS_DHashTableOperate calls). - * - * NB: JS_DHASH_CAP is a helper macro meant for use only in JS_DHASH_CAPACITY. - * Don't use it directly! - */ -#define JS_DHASH_DEFAULT_MAX_ALPHA 0.75 -#define JS_DHASH_DEFAULT_MIN_ALPHA 0.25 - -#define JS_DHASH_CAP(entryCount, maxAlpha) \ - ((uint32)((double)(entryCount) / (maxAlpha))) - -#define JS_DHASH_CAPACITY(entryCount, maxAlpha) \ - (JS_DHASH_CAP(entryCount, maxAlpha) + \ - (((JS_DHASH_CAP(entryCount, maxAlpha) * (uint8)(0x100 * (maxAlpha))) \ - >> 8) < (entryCount))) - -#define JS_DHASH_DEFAULT_CAPACITY(entryCount) \ - JS_DHASH_CAPACITY(entryCount, JS_DHASH_DEFAULT_MAX_ALPHA) - -/* - * Finalize table's data, free its entry storage using table->ops->freeTable, - * and leave its members unchanged from their last live values (which leaves - * pointers dangling). If you want to burn cycles clearing table, it's up to - * your code to call memset. - */ -extern JS_PUBLIC_API(void) -JS_DHashTableFinish(JSDHashTable *table); - -/* - * To consolidate keyHash computation and table grow/shrink code, we use a - * single entry point for lookup, add, and remove operations. The operation - * codes are declared here, along with codes returned by JSDHashEnumerator - * functions, which control JS_DHashTableEnumerate's behavior. - */ -typedef enum JSDHashOperator { - JS_DHASH_LOOKUP = 0, /* lookup entry */ - JS_DHASH_ADD = 1, /* add entry */ - JS_DHASH_REMOVE = 2, /* remove entry, or enumerator says remove */ - JS_DHASH_NEXT = 0, /* enumerator says continue */ - JS_DHASH_STOP = 1 /* enumerator says stop */ -} JSDHashOperator; - -/* - * To lookup a key in table, call: - * - * entry = JS_DHashTableOperate(table, key, JS_DHASH_LOOKUP); - * - * If JS_DHASH_ENTRY_IS_BUSY(entry) is true, key was found and it identifies - * entry. If JS_DHASH_ENTRY_IS_FREE(entry) is true, key was not found. - * - * To add an entry identified by key to table, call: - * - * entry = JS_DHashTableOperate(table, key, JS_DHASH_ADD); - * - * If entry is null upon return, then either the table is severely overloaded, - * and memory can't be allocated for entry storage via table->ops->allocTable; - * Or if table->ops->initEntry is non-null, the table->ops->initEntry op may - * have returned false. - * - * Otherwise, entry->keyHash has been set so that JS_DHASH_ENTRY_IS_BUSY(entry) - * is true, and it is up to the caller to initialize the key and value parts - * of the entry sub-type, if they have not been set already (i.e. if entry was - * not already in the table, and if the optional initEntry hook was not used). - * - * To remove an entry identified by key from table, call: - * - * (void) JS_DHashTableOperate(table, key, JS_DHASH_REMOVE); - * - * If key's entry is found, it is cleared (via table->ops->clearEntry) and - * the entry is marked so that JS_DHASH_ENTRY_IS_FREE(entry). This operation - * returns null unconditionally; you should ignore its return value. - */ -extern JS_PUBLIC_API(JSDHashEntryHdr *) JS_DHASH_FASTCALL -JS_DHashTableOperate(JSDHashTable *table, const void *key, JSDHashOperator op); - -/* - * Remove an entry already accessed via LOOKUP or ADD. - * - * NB: this is a "raw" or low-level routine, intended to be used only where - * the inefficiency of a full JS_DHashTableOperate (which rehashes in order - * to find the entry given its key) is not tolerable. This function does not - * shrink the table if it is underloaded. It does not update stats #ifdef - * JS_DHASHMETER, either. - */ -extern JS_PUBLIC_API(void) -JS_DHashTableRawRemove(JSDHashTable *table, JSDHashEntryHdr *entry); - -/* - * Enumerate entries in table using etor: - * - * count = JS_DHashTableEnumerate(table, etor, arg); - * - * JS_DHashTableEnumerate calls etor like so: - * - * op = etor(table, entry, number, arg); - * - * where number is a zero-based ordinal assigned to live entries according to - * their order in table->entryStore. - * - * The return value, op, is treated as a set of flags. If op is JS_DHASH_NEXT, - * then continue enumerating. If op contains JS_DHASH_REMOVE, then clear (via - * table->ops->clearEntry) and free entry. Then we check whether op contains - * JS_DHASH_STOP; if so, stop enumerating and return the number of live entries - * that were enumerated so far. Return the total number of live entries when - * enumeration completes normally. - * - * If etor calls JS_DHashTableOperate on table with op != JS_DHASH_LOOKUP, it - * must return JS_DHASH_STOP; otherwise undefined behavior results. - * - * If any enumerator returns JS_DHASH_REMOVE, table->entryStore may be shrunk - * or compressed after enumeration, but before JS_DHashTableEnumerate returns. - * Such an enumerator therefore can't safely set aside entry pointers, but an - * enumerator that never returns JS_DHASH_REMOVE can set pointers to entries - * aside, e.g., to avoid copying live entries into an array of the entry type. - * Copying entry pointers is cheaper, and safe so long as the caller of such a - * "stable" Enumerate doesn't use the set-aside pointers after any call either - * to PL_DHashTableOperate, or to an "unstable" form of Enumerate, which might - * grow or shrink entryStore. - * - * If your enumerator wants to remove certain entries, but set aside pointers - * to other entries that it retains, it can use JS_DHashTableRawRemove on the - * entries to be removed, returning JS_DHASH_NEXT to skip them. Likewise, if - * you want to remove entries, but for some reason you do not want entryStore - * to be shrunk or compressed, you can call JS_DHashTableRawRemove safely on - * the entry being enumerated, rather than returning JS_DHASH_REMOVE. - */ -typedef JSDHashOperator -(* JSDHashEnumerator)(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 number, - void *arg); - -extern JS_PUBLIC_API(uint32) -JS_DHashTableEnumerate(JSDHashTable *table, JSDHashEnumerator etor, void *arg); - -#ifdef DEBUG -/** - * Mark a table as immutable for the remainder of its lifetime. This - * changes the implementation from ASSERTing one set of invariants to - * ASSERTing a different set. - * - * When a table is NOT marked as immutable, the table implementation - * asserts that the table is not mutated from its own callbacks. It - * assumes the caller protects the table from being accessed on multiple - * threads simultaneously. - * - * When the table is marked as immutable, the re-entry assertions will - * no longer trigger erroneously due to multi-threaded access. Instead, - * mutations will cause assertions. - */ -extern JS_PUBLIC_API(void) -JS_DHashMarkTableImmutable(JSDHashTable *table); -#endif - -#ifdef JS_DHASHMETER -#include - -extern JS_PUBLIC_API(void) -JS_DHashTableDumpMeter(JSDHashTable *table, JSDHashEnumerator dump, FILE *fp); -#endif - -JS_END_EXTERN_C - -#endif /* jsdhash_h___ */ diff --git a/x86/mozilla/include/jsdtoa.h b/x86/mozilla/include/jsdtoa.h deleted file mode 100644 index eacfb4d..0000000 --- a/x86/mozilla/include/jsdtoa.h +++ /dev/null @@ -1,148 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsdtoa_h___ -#define jsdtoa_h___ -/* - * Public interface to portable double-precision floating point to string - * and back conversion package. - */ - -#include "jscompat.h" - -JS_BEGIN_EXTERN_C - -struct DtoaState; - -DtoaState * -js_NewDtoaState(); - -void -js_DestroyDtoaState(DtoaState *state); - -/* - * js_strtod_harder() returns as a double-precision floating-point number the - * value represented by the character string pointed to by s00. The string is - * scanned up to the first unrecognized character. - * - * If se is not NULL, *se receives a pointer to the character terminating the - * scan. If no number can be formed, *se receives a pointer to the first - * unparseable character in s00, and zero is returned. - * - * *err is set to zero on success; it's set to JS_DTOA_ERANGE on range - * errors and JS_DTOA_ENOMEM on memory failure. - */ -#define JS_DTOA_ERANGE 1 -#define JS_DTOA_ENOMEM 2 -double -js_strtod_harder(DtoaState *state, const char *s00, char **se, int *err); - -/* - * Modes for converting floating-point numbers to strings. - * - * Some of the modes can round-trip; this means that if the number is converted to - * a string using one of these mode and then converted back to a number, the result - * will be identical to the original number (except that, due to ECMA, -0 will get converted - * to +0). These round-trip modes return the minimum number of significand digits that - * permit the round trip. - * - * Some of the modes take an integer parameter . - */ -/* NB: Keep this in sync with number_constants[]. */ -typedef enum JSDToStrMode { - DTOSTR_STANDARD, /* Either fixed or exponential format; round-trip */ - DTOSTR_STANDARD_EXPONENTIAL, /* Always exponential format; round-trip */ - DTOSTR_FIXED, /* Round to digits after the decimal point; exponential if number is large */ - DTOSTR_EXPONENTIAL, /* Always exponential format; significant digits */ - DTOSTR_PRECISION /* Either fixed or exponential format; significant digits */ -} JSDToStrMode; - - -/* Maximum number of characters (including trailing null) that a DTOSTR_STANDARD or DTOSTR_STANDARD_EXPONENTIAL - * conversion can produce. This maximum is reached for a number like -0.0000012345678901234567. */ -#define DTOSTR_STANDARD_BUFFER_SIZE 26 - -/* Maximum number of characters (including trailing null) that one of the other conversions - * can produce. This maximum is reached for TO_FIXED, which can generate up to 21 digits before the decimal point. */ -#define DTOSTR_VARIABLE_BUFFER_SIZE(precision) ((precision)+24 > DTOSTR_STANDARD_BUFFER_SIZE ? (precision)+24 : DTOSTR_STANDARD_BUFFER_SIZE) - -/* - * DO NOT USE THIS FUNCTION IF YOU CAN AVOID IT. js::NumberToCString() is a - * better function to use. - * - * Convert dval according to the given mode and return a pointer to the - * resulting ASCII string. If mode == DTOSTR_STANDARD and precision == 0 it's - * equivalent to ToString() as specified by ECMA-262-5 section 9.8.1, but it - * doesn't handle integers specially so should be avoided in that case (that's - * why js::NumberToCString() is better). - * - * The result is held somewhere in buffer, but not necessarily at the - * beginning. The size of buffer is given in bufferSize, and must be at least - * as large as given by the above macros. - * - * Return NULL if out of memory. - */ -char * -js_dtostr(DtoaState *state, char *buffer, size_t bufferSize, JSDToStrMode mode, int precision, - double dval); - -/* - * DO NOT USE THIS FUNCTION IF YOU CAN AVOID IT. js::NumberToCString() is a - * better function to use. - * - * Convert d to a string in the given base. The integral part of d will be - * printed exactly in that base, regardless of how large it is, because there - * is no exponential notation for non-base-ten numbers. The fractional part - * will be rounded to as few digits as possible while still preserving the - * round-trip property (analogous to that of printing decimal numbers). In - * other words, if one were to read the resulting string in via a hypothetical - * base-number-reading routine that rounds to the nearest IEEE double (and to - * an even significand if there are two equally near doubles), then the result - * would equal d (except for -0.0, which converts to "0", and NaN, which is - * not equal to itself). - * - * Return NULL if out of memory. If the result is not NULL, it must be - * released via js_free(). - */ -char * -js_dtobasestr(DtoaState *state, int base, double d); - -JS_END_EXTERN_C - -#endif /* jsdtoa_h___ */ diff --git a/x86/mozilla/include/jsemit.h b/x86/mozilla/include/jsemit.h deleted file mode 100644 index 7d7ca67..0000000 --- a/x86/mozilla/include/jsemit.h +++ /dev/null @@ -1,1071 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=79: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsemit_h___ -#define jsemit_h___ -/* - * JS bytecode generation. - */ -#include "jstypes.h" -#include "jsatom.h" -#include "jsopcode.h" -#include "jsparse.h" -#include "jsscript.h" -#include "jsprvtd.h" -#include "jspubtd.h" - -JS_BEGIN_EXTERN_C - -/* - * NB: If you add enumerators for scope statements, add them between STMT_WITH - * and STMT_CATCH, or you will break the STMT_TYPE_IS_SCOPE macro. If you add - * non-looping statement enumerators, add them before STMT_DO_LOOP or you will - * break the STMT_TYPE_IS_LOOP macro. - * - * Also remember to keep the statementName array in jsemit.c in sync. - */ -typedef enum JSStmtType { - STMT_LABEL, /* labeled statement: L: s */ - STMT_IF, /* if (then) statement */ - STMT_ELSE, /* else clause of if statement */ - STMT_SEQ, /* synthetic sequence of statements */ - STMT_BLOCK, /* compound statement: { s1[;... sN] } */ - STMT_SWITCH, /* switch statement */ - STMT_WITH, /* with statement */ - STMT_CATCH, /* catch block */ - STMT_TRY, /* try block */ - STMT_FINALLY, /* finally block */ - STMT_SUBROUTINE, /* gosub-target subroutine body */ - STMT_DO_LOOP, /* do/while loop statement */ - STMT_FOR_LOOP, /* for loop statement */ - STMT_FOR_IN_LOOP, /* for/in loop statement */ - STMT_WHILE_LOOP, /* while loop statement */ - STMT_LIMIT -} JSStmtType; - -#define STMT_TYPE_IN_RANGE(t,b,e) ((uint)((t) - (b)) <= (uintN)((e) - (b))) - -/* - * A comment on the encoding of the JSStmtType enum and type-testing macros: - * - * STMT_TYPE_MAYBE_SCOPE tells whether a statement type is always, or may - * become, a lexical scope. It therefore includes block and switch (the two - * low-numbered "maybe" scope types) and excludes with (with has dynamic scope - * pending the "reformed with" in ES4/JS2). It includes all try-catch-finally - * types, which are high-numbered maybe-scope types. - * - * STMT_TYPE_LINKS_SCOPE tells whether a JSStmtInfo of the given type eagerly - * links to other scoping statement info records. It excludes the two early - * "maybe" types, block and switch, as well as the try and both finally types, - * since try and the other trailing maybe-scope types don't need block scope - * unless they contain let declarations. - * - * We treat WITH as a static scope because it prevents lexical binding from - * continuing further up the static scope chain. With the lost "reformed with" - * proposal for ES4, we would be able to model it statically, too. - */ -#define STMT_TYPE_MAYBE_SCOPE(type) \ - (type != STMT_WITH && \ - STMT_TYPE_IN_RANGE(type, STMT_BLOCK, STMT_SUBROUTINE)) - -#define STMT_TYPE_LINKS_SCOPE(type) \ - STMT_TYPE_IN_RANGE(type, STMT_WITH, STMT_CATCH) - -#define STMT_TYPE_IS_TRYING(type) \ - STMT_TYPE_IN_RANGE(type, STMT_TRY, STMT_SUBROUTINE) - -#define STMT_TYPE_IS_LOOP(type) ((type) >= STMT_DO_LOOP) - -#define STMT_MAYBE_SCOPE(stmt) STMT_TYPE_MAYBE_SCOPE((stmt)->type) -#define STMT_LINKS_SCOPE(stmt) (STMT_TYPE_LINKS_SCOPE((stmt)->type) || \ - ((stmt)->flags & SIF_SCOPE)) -#define STMT_IS_TRYING(stmt) STMT_TYPE_IS_TRYING((stmt)->type) -#define STMT_IS_LOOP(stmt) STMT_TYPE_IS_LOOP((stmt)->type) - -typedef struct JSStmtInfo JSStmtInfo; - -struct JSStmtInfo { - uint16 type; /* statement type */ - uint16 flags; /* flags, see below */ - uint32 blockid; /* for simplified dominance computation */ - ptrdiff_t update; /* loop update offset (top if none) */ - ptrdiff_t breaks; /* offset of last break in loop */ - ptrdiff_t continues; /* offset of last continue in loop */ - union { - JSAtom *label; /* name of LABEL */ - JSObjectBox *blockBox; /* block scope object */ - }; - JSStmtInfo *down; /* info for enclosing statement */ - JSStmtInfo *downScope; /* next enclosing lexical scope */ -}; - -#define SIF_SCOPE 0x0001 /* statement has its own lexical scope */ -#define SIF_BODY_BLOCK 0x0002 /* STMT_BLOCK type is a function body */ -#define SIF_FOR_BLOCK 0x0004 /* for (let ...) induced block scope */ - -/* - * To reuse space in JSStmtInfo, rename breaks and continues for use during - * try/catch/finally code generation and backpatching. To match most common - * use cases, the macro argument is a struct, not a struct pointer. Only a - * loop, switch, or label statement info record can have breaks and continues, - * and only a for loop has an update backpatch chain, so it's safe to overlay - * these for the "trying" JSStmtTypes. - */ -#define CATCHNOTE(stmt) ((stmt).update) -#define GOSUBS(stmt) ((stmt).breaks) -#define GUARDJUMP(stmt) ((stmt).continues) - -#define SET_STATEMENT_TOP(stmt, top) \ - ((stmt)->update = (top), (stmt)->breaks = (stmt)->continues = (-1)) - -#ifdef JS_SCOPE_DEPTH_METER -# define JS_SCOPE_DEPTH_METERING(code) ((void) (code)) -# define JS_SCOPE_DEPTH_METERING_IF(cond, code) ((cond) ? (void) (code) : (void) 0) -#else -# define JS_SCOPE_DEPTH_METERING(code) ((void) 0) -# define JS_SCOPE_DEPTH_METERING_IF(code, x) ((void) 0) -#endif - -#define TCF_COMPILING 0x01 /* JSTreeContext is JSCodeGenerator */ -#define TCF_IN_FUNCTION 0x02 /* parsing inside function body */ -#define TCF_RETURN_EXPR 0x04 /* function has 'return expr;' */ -#define TCF_RETURN_VOID 0x08 /* function has 'return;' */ -#define TCF_IN_FOR_INIT 0x10 /* parsing init expr of for; exclude 'in' */ -#define TCF_FUN_SETS_OUTER_NAME 0x20 /* function set outer name (lexical or free) */ -#define TCF_FUN_PARAM_ARGUMENTS 0x40 /* function has parameter named arguments */ -#define TCF_FUN_USES_ARGUMENTS 0x80 /* function uses arguments except as a - parameter name */ -#define TCF_FUN_HEAVYWEIGHT 0x100 /* function needs Call object per call */ -#define TCF_FUN_IS_GENERATOR 0x200 /* parsed yield statement in function */ -#define TCF_FUN_USES_OWN_NAME 0x400 /* named function expression that uses its - own name */ -#define TCF_HAS_FUNCTION_STMT 0x800 /* block contains a function statement */ -#define TCF_GENEXP_LAMBDA 0x1000 /* flag lambda from generator expression */ -#define TCF_COMPILE_N_GO 0x2000 /* compile-and-go mode of script, can - optimize name references based on scope - chain */ -#define TCF_NO_SCRIPT_RVAL 0x4000 /* API caller does not want result value - from global script */ -#define TCF_HAS_SHARPS 0x8000 /* source contains sharp defs or uses */ - -/* - * Set when parsing a declaration-like destructuring pattern. This - * flag causes PrimaryExpr to create PN_NAME parse nodes for variable - * references which are not hooked into any definition's use chain, - * added to any tree context's AtomList, etc. etc. CheckDestructuring - * will do that work later. - * - * The comments atop CheckDestructuring explain the distinction - * between assignment-like and declaration-like destructuring - * patterns, and why they need to be treated differently. - */ -#define TCF_DECL_DESTRUCTURING 0x10000 - -/* - * A request flag passed to Compiler::compileScript and then down via - * JSCodeGenerator to js_NewScriptFromCG, from script_compile_sub and any - * kindred functions that need to make mutable scripts (even empty ones; - * i.e., they can't share the const JSScript::emptyScript() singleton). - */ -#define TCF_NEED_MUTABLE_SCRIPT 0x20000 - -/* - * This function/global/eval code body contained a Use Strict Directive. Treat - * certain strict warnings as errors, and forbid the use of 'with'. See also - * TSF_STRICT_MODE_CODE, JSScript::strictModeCode, and JSREPORT_STRICT_ERROR. - */ -#define TCF_STRICT_MODE_CODE 0x40000 - -/* bit 0x80000 is unused */ - -/* - * Flag signifying that the current function seems to be a constructor that - * sets this.foo to define "methods", at least one of which can't be a null - * closure, so we should avoid over-specializing property cache entries and - * trace inlining guards to method function object identity, which will vary - * per instance. - */ -#define TCF_FUN_UNBRAND_THIS 0x100000 - -/* - * "Module pattern", i.e., a lambda that is immediately applied and the whole - * of an expression statement. - */ -#define TCF_FUN_MODULE_PATTERN 0x200000 - -/* - * Flag to prevent a non-escaping function from being optimized into a null - * closure (i.e., a closure that needs only its global object for free variable - * resolution), because this function contains a closure that needs one or more - * scope objects surrounding it (i.e., a Call object for an outer heavyweight - * function). See bug 560234. - */ -#define TCF_FUN_ENTRAINS_SCOPES 0x400000 - -/* The function calls 'eval'. */ -#define TCF_FUN_CALLS_EVAL 0x800000 - -/* The function mutates a positional (non-destructuring) parameter. */ -#define TCF_FUN_MUTATES_PARAMETER 0x1000000 - -/* - * Compiling an eval() script. - */ -#define TCF_COMPILE_FOR_EVAL 0x2000000 - -/* - * The function or a function that encloses it may define new local names - * at runtime through means other than calling eval. - */ -#define TCF_FUN_MIGHT_ALIAS_LOCALS 0x4000000 - -/* - * The script contains singleton initialiser JSOP_OBJECT. - */ -#define TCF_HAS_SINGLETONS 0x8000000 - -/* - * Some enclosing scope is a with-statement or E4X filter-expression. - */ -#define TCF_IN_WITH 0x10000000 - -/* - * Flags to check for return; vs. return expr; in a function. - */ -#define TCF_RETURN_FLAGS (TCF_RETURN_EXPR | TCF_RETURN_VOID) - -/* - * Sticky deoptimization flags to propagate from FunctionBody. - */ -#define TCF_FUN_FLAGS (TCF_FUN_SETS_OUTER_NAME | \ - TCF_FUN_USES_ARGUMENTS | \ - TCF_FUN_PARAM_ARGUMENTS | \ - TCF_FUN_HEAVYWEIGHT | \ - TCF_FUN_IS_GENERATOR | \ - TCF_FUN_USES_OWN_NAME | \ - TCF_HAS_SHARPS | \ - TCF_FUN_CALLS_EVAL | \ - TCF_FUN_MIGHT_ALIAS_LOCALS | \ - TCF_FUN_MUTATES_PARAMETER | \ - TCF_STRICT_MODE_CODE) - -struct JSTreeContext { /* tree context for semantic checks */ - uint32 flags; /* statement state flags, see above */ - uint32 bodyid; /* block number of program/function body */ - uint32 blockidGen; /* preincremented block number generator */ - JSStmtInfo *topStmt; /* top of statement info stack */ - JSStmtInfo *topScopeStmt; /* top lexical scope statement */ - JSObjectBox *blockChainBox; /* compile time block scope chain (NB: one - deeper than the topScopeStmt/downScope - chain when in head of let block/expr) */ - JSParseNode *blockNode; /* parse node for a block with let declarations - (block with its own lexical scope) */ - JSAtomList decls; /* function, const, and var declarations */ - js::Parser *parser; /* ptr to common parsing and lexing data */ - - private: - union { - JSFunction *fun_; /* function to store argument and variable - names when flags & TCF_IN_FUNCTION */ - JSObject *scopeChain_; /* scope chain object for the script */ - }; - - public: - JSFunction *fun() const { - JS_ASSERT(inFunction()); - return fun_; - } - void setFunction(JSFunction *fun) { - JS_ASSERT(inFunction()); - fun_ = fun; - } - JSObject *scopeChain() const { - JS_ASSERT(!inFunction()); - return scopeChain_; - } - void setScopeChain(JSObject *scopeChain) { - JS_ASSERT(!inFunction()); - scopeChain_ = scopeChain; - } - - JSAtomList lexdeps; /* unresolved lexical name dependencies */ - JSTreeContext *parent; /* enclosing function or global context */ - uintN staticLevel; /* static compilation unit nesting level */ - - JSFunctionBox *funbox; /* null or box for function we're compiling - if (flags & TCF_IN_FUNCTION) and not in - Compiler::compileFunctionBody */ - JSFunctionBox *functionList; - - JSParseNode *innermostWith; /* innermost WITH parse node */ - - js::Bindings bindings; /* bindings in this code, including - arguments if we're compiling a function */ - -#ifdef JS_SCOPE_DEPTH_METER - uint16 scopeDepth; /* current lexical scope chain depth */ - uint16 maxScopeDepth; /* maximum lexical scope chain depth */ -#endif - - void trace(JSTracer *trc); - - JSTreeContext(js::Parser *prs) - : flags(0), bodyid(0), blockidGen(0), topStmt(NULL), topScopeStmt(NULL), - blockChainBox(NULL), blockNode(NULL), parser(prs), scopeChain_(NULL), parent(prs->tc), - staticLevel(0), funbox(NULL), functionList(NULL), innermostWith(NULL), bindings(prs->context), - sharpSlotBase(-1) - { - prs->tc = this; - JS_SCOPE_DEPTH_METERING(scopeDepth = maxScopeDepth = 0); - } - - /* - * For functions the tree context is constructed and destructed a second - * time during code generation. To avoid a redundant stats update in such - * cases, we store uint16(-1) in maxScopeDepth. - */ - ~JSTreeContext() { - parser->tc = this->parent; - JS_SCOPE_DEPTH_METERING_IF((maxScopeDepth != uint16(-1)), - JS_BASIC_STATS_ACCUM(&parser - ->context - ->runtime - ->lexicalScopeDepthStats, - maxScopeDepth)); - } - - uintN blockid() { return topStmt ? topStmt->blockid : bodyid; } - - JSObject *blockChain() { - return blockChainBox ? blockChainBox->object : NULL; - } - - /* - * True if we are at the topmost level of a entire script or function body. - * For example, while parsing this code we would encounter f1 and f2 at - * body level, but we would not encounter f3 or f4 at body level: - * - * function f1() { function f2() { } } - * if (cond) { function f3() { if (cond) { function f4() { } } } } - */ - bool atBodyLevel() { return !topStmt || (topStmt->flags & SIF_BODY_BLOCK); } - - /* Test whether we're in a statement of given type. */ - bool inStatement(JSStmtType type); - - bool inStrictMode() const { - return flags & TCF_STRICT_MODE_CODE; - } - - inline bool needStrictChecks(); - - /* - * sharpSlotBase is -1 or first slot of pair for [sharpArray, sharpDepth]. - * The parser calls ensureSharpSlots to allocate these two stack locals. - */ - int sharpSlotBase; - bool ensureSharpSlots(); - - js::Compiler *compiler() { return (js::Compiler *)parser; } - - // Return true there is a generator function within |skip| lexical scopes - // (going upward) from this context's lexical scope. Always return true if - // this context is itself a generator. - bool skipSpansGenerator(unsigned skip); - - bool compileAndGo() const { return flags & TCF_COMPILE_N_GO; } - bool inFunction() const { return flags & TCF_IN_FUNCTION; } - - bool compiling() const { return flags & TCF_COMPILING; } - inline JSCodeGenerator *asCodeGenerator(); - - bool usesArguments() const { - return flags & TCF_FUN_USES_ARGUMENTS; - } - - void noteCallsEval() { - flags |= TCF_FUN_CALLS_EVAL; - } - - bool callsEval() const { - return flags & TCF_FUN_CALLS_EVAL; - } - - void noteMightAliasLocals() { - flags |= TCF_FUN_MIGHT_ALIAS_LOCALS; - } - - bool mightAliasLocals() const { - return flags & TCF_FUN_MIGHT_ALIAS_LOCALS; - } - - void noteParameterMutation() { - JS_ASSERT(inFunction()); - flags |= TCF_FUN_MUTATES_PARAMETER; - } - - bool mutatesParameter() const { - JS_ASSERT(inFunction()); - return flags & TCF_FUN_MUTATES_PARAMETER; - } - - void noteArgumentsUse() { - JS_ASSERT(inFunction()); - flags |= TCF_FUN_USES_ARGUMENTS; - if (funbox) - funbox->node->pn_dflags |= PND_FUNARG; - } - - bool needsEagerArguments() const { - return inStrictMode() && ((usesArguments() && mutatesParameter()) || callsEval()); - } -}; - -/* - * Return true if we need to check for conditions that elicit - * JSOPTION_STRICT warnings or strict mode errors. - */ -inline bool JSTreeContext::needStrictChecks() { - return parser->context->hasStrictOption() || inStrictMode(); -} - -/* - * Span-dependent instructions are jumps whose span (from the jump bytecode to - * the jump target) may require 2 or 4 bytes of immediate operand. - */ -typedef struct JSSpanDep JSSpanDep; -typedef struct JSJumpTarget JSJumpTarget; - -struct JSSpanDep { - ptrdiff_t top; /* offset of first bytecode in an opcode */ - ptrdiff_t offset; /* offset - 1 within opcode of jump operand */ - ptrdiff_t before; /* original offset - 1 of jump operand */ - JSJumpTarget *target; /* tagged target pointer or backpatch delta */ -}; - -/* - * Jump targets are stored in an AVL tree, for O(log(n)) lookup with targets - * sorted by offset from left to right, so that targets after a span-dependent - * instruction whose jump offset operand must be extended can be found quickly - * and adjusted upward (toward higher offsets). - */ -struct JSJumpTarget { - ptrdiff_t offset; /* offset of span-dependent jump target */ - int balance; /* AVL tree balance number */ - JSJumpTarget *kids[2]; /* left and right AVL tree child pointers */ -}; - -#define JT_LEFT 0 -#define JT_RIGHT 1 -#define JT_OTHER_DIR(dir) (1 - (dir)) -#define JT_IMBALANCE(dir) (((dir) << 1) - 1) -#define JT_DIR(imbalance) (((imbalance) + 1) >> 1) - -/* - * Backpatch deltas are encoded in JSSpanDep.target if JT_TAG_BIT is clear, - * so we can maintain backpatch chains when using span dependency records to - * hold jump offsets that overflow 16 bits. - */ -#define JT_TAG_BIT ((jsword) 1) -#define JT_UNTAG_SHIFT 1 -#define JT_SET_TAG(jt) ((JSJumpTarget *)((jsword)(jt) | JT_TAG_BIT)) -#define JT_CLR_TAG(jt) ((JSJumpTarget *)((jsword)(jt) & ~JT_TAG_BIT)) -#define JT_HAS_TAG(jt) ((jsword)(jt) & JT_TAG_BIT) - -#define BITS_PER_PTRDIFF (sizeof(ptrdiff_t) * JS_BITS_PER_BYTE) -#define BITS_PER_BPDELTA (BITS_PER_PTRDIFF - 1 - JT_UNTAG_SHIFT) -#define BPDELTA_MAX (((ptrdiff_t)1 << BITS_PER_BPDELTA) - 1) -#define BPDELTA_TO_JT(bp) ((JSJumpTarget *)((bp) << JT_UNTAG_SHIFT)) -#define JT_TO_BPDELTA(jt) ((ptrdiff_t)((jsword)(jt) >> JT_UNTAG_SHIFT)) - -#define SD_SET_TARGET(sd,jt) ((sd)->target = JT_SET_TAG(jt)) -#define SD_GET_TARGET(sd) (JS_ASSERT(JT_HAS_TAG((sd)->target)), \ - JT_CLR_TAG((sd)->target)) -#define SD_SET_BPDELTA(sd,bp) ((sd)->target = BPDELTA_TO_JT(bp)) -#define SD_GET_BPDELTA(sd) (JS_ASSERT(!JT_HAS_TAG((sd)->target)), \ - JT_TO_BPDELTA((sd)->target)) - -/* Avoid asserting twice by expanding SD_GET_TARGET in the "then" clause. */ -#define SD_SPAN(sd,pivot) (SD_GET_TARGET(sd) \ - ? JT_CLR_TAG((sd)->target)->offset - (pivot) \ - : 0) - -typedef struct JSTryNode JSTryNode; - -struct JSTryNode { - JSTryNote note; - JSTryNode *prev; -}; - -struct JSCGObjectList { - uint32 length; /* number of emitted so far objects */ - JSObjectBox *lastbox; /* last emitted object */ - - JSCGObjectList() : length(0), lastbox(NULL) {} - - uintN index(JSObjectBox *objbox); - void finish(JSObjectArray *array); -}; - -class JSGCConstList { - js::Vector list; - public: - JSGCConstList(JSContext *cx) : list(cx) {} - bool append(js::Value v) { return list.append(v); } - size_t length() const { return list.length(); } - void finish(JSConstArray *array); - -}; - -struct JSCodeGenerator : public JSTreeContext -{ - JSArenaPool *codePool; /* pointer to thread code arena pool */ - JSArenaPool *notePool; /* pointer to thread srcnote arena pool */ - void *codeMark; /* low watermark in cg->codePool */ - void *noteMark; /* low watermark in cg->notePool */ - - struct { - jsbytecode *base; /* base of JS bytecode vector */ - jsbytecode *limit; /* one byte beyond end of bytecode */ - jsbytecode *next; /* pointer to next free bytecode */ - jssrcnote *notes; /* source notes, see below */ - uintN noteCount; /* number of source notes so far */ - uintN noteMask; /* growth increment for notes */ - ptrdiff_t lastNoteOffset; /* code offset for last source note */ - uintN currentLine; /* line number for tree-based srcnote gen */ - } prolog, main, *current; - - JSAtomList atomList; /* literals indexed for mapping */ - uintN firstLine; /* first line, for js_NewScriptFromCG */ - - intN stackDepth; /* current stack depth in script frame */ - uintN maxStackDepth; /* maximum stack depth so far */ - - uintN ntrynotes; /* number of allocated so far try notes */ - JSTryNode *lastTryNode; /* the last allocated try node */ - - JSSpanDep *spanDeps; /* span dependent instruction records */ - JSJumpTarget *jumpTargets; /* AVL tree of jump target offsets */ - JSJumpTarget *jtFreeList; /* JT_LEFT-linked list of free structs */ - uintN numSpanDeps; /* number of span dependencies */ - uintN numJumpTargets; /* number of jump targets */ - ptrdiff_t spanDepTodo; /* offset from main.base of potentially - unoptimized spandeps */ - - uintN arrayCompDepth; /* stack depth of array in comprehension */ - - uintN emitLevel; /* js_EmitTree recursion level */ - - typedef js::HashMap ConstMap; - ConstMap constMap; /* compile time constants */ - - JSGCConstList constList; /* constants to be included with the script */ - - JSCGObjectList objectList; /* list of emitted objects */ - JSCGObjectList regexpList; /* list of emitted regexp that will be - cloned during execution */ - - JSAtomList upvarList; /* map of atoms to upvar indexes */ - JSUpvarArray upvarMap; /* indexed upvar pairs (JS_realloc'ed) */ - - typedef js::Vector GlobalUseVector; - - GlobalUseVector globalUses; /* per-script global uses */ - JSAtomList globalMap; /* per-script map of global name to globalUses vector */ - - /* Vectors of pn_cookie slot values. */ - typedef js::Vector SlotVector; - SlotVector closedArgs; - SlotVector closedVars; - - uint16 traceIndex; /* index for the next JSOP_TRACE instruction */ - - /* - * Initialize cg to allocate bytecode space from codePool, source note - * space from notePool, and all other arena-allocated temporaries from - * parser->context->tempPool. - */ - JSCodeGenerator(js::Parser *parser, - JSArenaPool *codePool, JSArenaPool *notePool, - uintN lineno); - bool init(); - - /* - * Release cg->codePool, cg->notePool, and parser->context->tempPool to - * marks set by JSCodeGenerator's ctor. Note that cgs are magic: they own - * the arena pool "tops-of-stack" space above their codeMark, noteMark, and - * tempMark points. This means you cannot alloc from tempPool and save the - * pointer beyond the next JSCodeGenerator destructor call. - */ - ~JSCodeGenerator(); - - /* - * Adds a use of a variable that is statically known to exist on the - * global object. - * - * The actual slot of the variable on the global object is not known - * until after compilation. Properties must be resolved before being - * added, to avoid aliasing properties that should be resolved. This makes - * slot prediction based on the global object's free slot impossible. So, - * we use the slot to index into cg->globalScope->defs, and perform a - * fixup of the script at the very end of compilation. - * - * If the global use can be cached, |cookie| will be set to |slot|. - * Otherwise, |cookie| is set to the free cookie value. - */ - bool addGlobalUse(JSAtom *atom, uint32 slot, js::UpvarCookie *cookie); - - bool hasSharps() const { - bool rv = !!(flags & TCF_HAS_SHARPS); - JS_ASSERT((sharpSlotBase >= 0) == rv); - return rv; - } - - uintN sharpSlots() const { - return hasSharps() ? SHARP_NSLOTS : 0; - } - - bool compilingForEval() const { return !!(flags & TCF_COMPILE_FOR_EVAL); } - JSVersion version() const { return parser->versionWithFlags(); } - - bool shouldNoteClosedName(JSParseNode *pn); - - bool checkSingletonContext() { - if (!compileAndGo() || inFunction()) - return false; - for (JSStmtInfo *stmt = topStmt; stmt; stmt = stmt->down) { - if (STMT_IS_LOOP(stmt)) - return false; - } - flags |= TCF_HAS_SINGLETONS; - return true; - } -}; - -#define CG_TS(cg) TS((cg)->parser) - -#define CG_BASE(cg) ((cg)->current->base) -#define CG_LIMIT(cg) ((cg)->current->limit) -#define CG_NEXT(cg) ((cg)->current->next) -#define CG_CODE(cg,offset) (CG_BASE(cg) + (offset)) -#define CG_OFFSET(cg) (CG_NEXT(cg) - CG_BASE(cg)) - -#define CG_NOTES(cg) ((cg)->current->notes) -#define CG_NOTE_COUNT(cg) ((cg)->current->noteCount) -#define CG_NOTE_MASK(cg) ((cg)->current->noteMask) -#define CG_LAST_NOTE_OFFSET(cg) ((cg)->current->lastNoteOffset) -#define CG_CURRENT_LINE(cg) ((cg)->current->currentLine) - -#define CG_PROLOG_BASE(cg) ((cg)->prolog.base) -#define CG_PROLOG_LIMIT(cg) ((cg)->prolog.limit) -#define CG_PROLOG_NEXT(cg) ((cg)->prolog.next) -#define CG_PROLOG_CODE(cg,poff) (CG_PROLOG_BASE(cg) + (poff)) -#define CG_PROLOG_OFFSET(cg) (CG_PROLOG_NEXT(cg) - CG_PROLOG_BASE(cg)) - -#define CG_SWITCH_TO_MAIN(cg) ((cg)->current = &(cg)->main) -#define CG_SWITCH_TO_PROLOG(cg) ((cg)->current = &(cg)->prolog) - -inline JSCodeGenerator * -JSTreeContext::asCodeGenerator() -{ - JS_ASSERT(compiling()); - return static_cast(this); -} - -/* - * Emit one bytecode. - */ -extern ptrdiff_t -js_Emit1(JSContext *cx, JSCodeGenerator *cg, JSOp op); - -/* - * Emit two bytecodes, an opcode (op) with a byte of immediate operand (op1). - */ -extern ptrdiff_t -js_Emit2(JSContext *cx, JSCodeGenerator *cg, JSOp op, jsbytecode op1); - -/* - * Emit three bytecodes, an opcode with two bytes of immediate operands. - */ -extern ptrdiff_t -js_Emit3(JSContext *cx, JSCodeGenerator *cg, JSOp op, jsbytecode op1, - jsbytecode op2); - -/* - * Emit five bytecodes, an opcode with two 16-bit immediates. - */ -extern ptrdiff_t -js_Emit5(JSContext *cx, JSCodeGenerator *cg, JSOp op, uint16 op1, - uint16 op2); - -/* - * Emit (1 + extra) bytecodes, for N bytes of op and its immediate operand. - */ -extern ptrdiff_t -js_EmitN(JSContext *cx, JSCodeGenerator *cg, JSOp op, size_t extra); - -/* - * Unsafe macro to call js_SetJumpOffset and return false if it does. - */ -#define CHECK_AND_SET_JUMP_OFFSET_CUSTOM(cx,cg,pc,off,BAD_EXIT) \ - JS_BEGIN_MACRO \ - if (!js_SetJumpOffset(cx, cg, pc, off)) { \ - BAD_EXIT; \ - } \ - JS_END_MACRO - -#define CHECK_AND_SET_JUMP_OFFSET(cx,cg,pc,off) \ - CHECK_AND_SET_JUMP_OFFSET_CUSTOM(cx,cg,pc,off,return JS_FALSE) - -#define CHECK_AND_SET_JUMP_OFFSET_AT_CUSTOM(cx,cg,off,BAD_EXIT) \ - CHECK_AND_SET_JUMP_OFFSET_CUSTOM(cx, cg, CG_CODE(cg,off), \ - CG_OFFSET(cg) - (off), BAD_EXIT) - -#define CHECK_AND_SET_JUMP_OFFSET_AT(cx,cg,off) \ - CHECK_AND_SET_JUMP_OFFSET_AT_CUSTOM(cx, cg, off, return JS_FALSE) - -extern JSBool -js_SetJumpOffset(JSContext *cx, JSCodeGenerator *cg, jsbytecode *pc, - ptrdiff_t off); - -/* - * Push the C-stack-allocated struct at stmt onto the stmtInfo stack. - */ -extern void -js_PushStatement(JSTreeContext *tc, JSStmtInfo *stmt, JSStmtType type, - ptrdiff_t top); - -/* - * Push a block scope statement and link blockObj into tc->blockChain. To pop - * this statement info record, use js_PopStatement as usual, or if appropriate - * (if generating code), js_PopStatementCG. - */ -extern void -js_PushBlockScope(JSTreeContext *tc, JSStmtInfo *stmt, JSObjectBox *blockBox, - ptrdiff_t top); - -/* - * Pop tc->topStmt. If the top JSStmtInfo struct is not stack-allocated, it - * is up to the caller to free it. - */ -extern void -js_PopStatement(JSTreeContext *tc); - -/* - * Like js_PopStatement(cg), also patch breaks and continues unless the top - * statement info record represents a try-catch-finally suite. May fail if a - * jump offset overflows. - */ -extern JSBool -js_PopStatementCG(JSContext *cx, JSCodeGenerator *cg); - -/* - * Define and lookup a primitive jsval associated with the const named by atom. - * js_DefineCompileTimeConstant analyzes the constant-folded initializer at pn - * and saves the const's value in cg->constList, if it can be used at compile - * time. It returns true unless an error occurred. - * - * If the initializer's value could not be saved, js_DefineCompileTimeConstant - * calls will return the undefined value. js_DefineCompileTimeConstant tries - * to find a const value memorized for atom, returning true with *vp set to a - * value other than undefined if the constant was found, true with *vp set to - * JSVAL_VOID if not found, and false on error. - */ -extern JSBool -js_DefineCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom, - JSParseNode *pn); - -/* - * Find a lexically scoped variable (one declared by let, catch, or an array - * comprehension) named by atom, looking in tc's compile-time scopes. - * - * If a WITH statement is reached along the scope stack, return its statement - * info record, so callers can tell that atom is ambiguous. If slotp is not - * null, then if atom is found, set *slotp to its stack slot, otherwise to -1. - * This means that if slotp is not null, all the block objects on the lexical - * scope chain must have had their depth slots computed by the code generator, - * so the caller must be under js_EmitTree. - * - * In any event, directly return the statement info record in which atom was - * found. Otherwise return null. - */ -extern JSStmtInfo * -js_LexicalLookup(JSTreeContext *tc, JSAtom *atom, jsint *slotp, - JSStmtInfo *stmt = NULL); - -/* - * Emit code into cg for the tree rooted at pn. - */ -extern JSBool -js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn); - -/* - * Emit function code using cg for the tree rooted at body. - */ -extern JSBool -js_EmitFunctionScript(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body); - -/* - * Source notes generated along with bytecode for decompiling and debugging. - * A source note is a uint8 with 5 bits of type and 3 of offset from the pc of - * the previous note. If 3 bits of offset aren't enough, extended delta notes - * (SRC_XDELTA) consisting of 2 set high order bits followed by 6 offset bits - * are emitted before the next note. Some notes have operand offsets encoded - * immediately after them, in note bytes or byte-triples. - * - * Source Note Extended Delta - * +7-6-5-4-3+2-1-0+ +7-6-5+4-3-2-1-0+ - * |note-type|delta| |1 1| ext-delta | - * +---------+-----+ +---+-----------+ - * - * At most one "gettable" note (i.e., a note of type other than SRC_NEWLINE, - * SRC_SETLINE, and SRC_XDELTA) applies to a given bytecode. - * - * NB: the js_SrcNoteSpec array in jsemit.c is indexed by this enum, so its - * initializers need to match the order here. - * - * Note on adding new source notes: every pair of bytecodes (A, B) where A and - * B have disjoint sets of source notes that could apply to each bytecode may - * reuse the same note type value for two notes (snA, snB) that have the same - * arity, offsetBias, and isSpanDep initializers in js_SrcNoteSpec. This is - * why SRC_IF and SRC_INITPROP have the same value below. For bad historical - * reasons, some bytecodes below that could be overlayed have not been, but - * before using SRC_EXTENDED, consider compressing the existing note types. - * - * Don't forget to update JSXDR_BYTECODE_VERSION in jsxdrapi.h for all such - * incompatible source note or other bytecode changes. - */ -typedef enum JSSrcNoteType { - SRC_NULL = 0, /* terminates a note vector */ - SRC_IF = 1, /* JSOP_IFEQ bytecode is from an if-then */ - SRC_BREAK = 1, /* JSOP_GOTO is a break */ - SRC_INITPROP = 1, /* disjoint meaning applied to JSOP_INITELEM or - to an index label in a regular (structuring) - or a destructuring object initialiser */ - SRC_GENEXP = 1, /* JSOP_LAMBDA from generator expression */ - SRC_IF_ELSE = 2, /* JSOP_IFEQ bytecode is from an if-then-else */ - SRC_FOR_IN = 2, /* JSOP_GOTO to for-in loop condition from - before loop (same arity as SRC_IF_ELSE) */ - SRC_FOR = 3, /* JSOP_NOP or JSOP_POP in for(;;) loop head */ - SRC_WHILE = 4, /* JSOP_GOTO to for or while loop condition - from before loop, else JSOP_NOP at top of - do-while loop */ - SRC_TRACE = 4, /* For JSOP_TRACE; includes distance to loop end */ - SRC_CONTINUE = 5, /* JSOP_GOTO is a continue, not a break; - also used on JSOP_ENDINIT if extra comma - at end of array literal: [1,2,,]; - JSOP_DUP continuing destructuring pattern */ - SRC_DECL = 6, /* type of a declaration (var, const, let*) */ - SRC_DESTRUCT = 6, /* JSOP_DUP starting a destructuring assignment - operation, with SRC_DECL_* offset operand */ - SRC_PCDELTA = 7, /* distance forward from comma-operator to - next POP, or from CONDSWITCH to first CASE - opcode, etc. -- always a forward delta */ - SRC_GROUPASSIGN = 7, /* SRC_DESTRUCT variant for [a, b] = [c, d] */ - SRC_ASSIGNOP = 8, /* += or another assign-op follows */ - SRC_COND = 9, /* JSOP_IFEQ is from conditional ?: operator */ - SRC_BRACE = 10, /* mandatory brace, for scope or to avoid - dangling else */ - SRC_HIDDEN = 11, /* opcode shouldn't be decompiled */ - SRC_PCBASE = 12, /* distance back from annotated getprop or - setprop op to left-most obj.prop.subprop - bytecode -- always a backward delta */ - SRC_LABEL = 13, /* JSOP_NOP for label: with atomid immediate */ - SRC_LABELBRACE = 14, /* JSOP_NOP for label: {...} begin brace */ - SRC_ENDBRACE = 15, /* JSOP_NOP for label: {...} end brace */ - SRC_BREAK2LABEL = 16, /* JSOP_GOTO for 'break label' with atomid */ - SRC_CONT2LABEL = 17, /* JSOP_GOTO for 'continue label' with atomid */ - SRC_SWITCH = 18, /* JSOP_*SWITCH with offset to end of switch, - 2nd off to first JSOP_CASE if condswitch */ - SRC_FUNCDEF = 19, /* JSOP_NOP for function f() with atomid */ - SRC_CATCH = 20, /* catch block has guard */ - SRC_EXTENDED = 21, /* extended source note, 32-159, in next byte */ - SRC_NEWLINE = 22, /* bytecode follows a source newline */ - SRC_SETLINE = 23, /* a file-absolute source line number note */ - SRC_XDELTA = 24 /* 24-31 are for extended delta notes */ -} JSSrcNoteType; - -/* - * Constants for the SRC_DECL source note. Note that span-dependent bytecode - * selection means that any SRC_DECL offset greater than SRC_DECL_LET may need - * to be adjusted, but these "offsets" are too small to span a span-dependent - * instruction, so can be used to denote distinct declaration syntaxes to the - * decompiler. - * - * NB: the var_prefix array in jsopcode.c depends on these dense indexes from - * SRC_DECL_VAR through SRC_DECL_LET. - */ -#define SRC_DECL_VAR 0 -#define SRC_DECL_CONST 1 -#define SRC_DECL_LET 2 -#define SRC_DECL_NONE 3 - -#define SN_TYPE_BITS 5 -#define SN_DELTA_BITS 3 -#define SN_XDELTA_BITS 6 -#define SN_TYPE_MASK (JS_BITMASK(SN_TYPE_BITS) << SN_DELTA_BITS) -#define SN_DELTA_MASK ((ptrdiff_t)JS_BITMASK(SN_DELTA_BITS)) -#define SN_XDELTA_MASK ((ptrdiff_t)JS_BITMASK(SN_XDELTA_BITS)) - -#define SN_MAKE_NOTE(sn,t,d) (*(sn) = (jssrcnote) \ - (((t) << SN_DELTA_BITS) \ - | ((d) & SN_DELTA_MASK))) -#define SN_MAKE_XDELTA(sn,d) (*(sn) = (jssrcnote) \ - ((SRC_XDELTA << SN_DELTA_BITS) \ - | ((d) & SN_XDELTA_MASK))) - -#define SN_IS_XDELTA(sn) ((*(sn) >> SN_DELTA_BITS) >= SRC_XDELTA) -#define SN_TYPE(sn) ((JSSrcNoteType)(SN_IS_XDELTA(sn) \ - ? SRC_XDELTA \ - : *(sn) >> SN_DELTA_BITS)) -#define SN_SET_TYPE(sn,type) SN_MAKE_NOTE(sn, type, SN_DELTA(sn)) -#define SN_IS_GETTABLE(sn) (SN_TYPE(sn) < SRC_NEWLINE) - -#define SN_DELTA(sn) ((ptrdiff_t)(SN_IS_XDELTA(sn) \ - ? *(sn) & SN_XDELTA_MASK \ - : *(sn) & SN_DELTA_MASK)) -#define SN_SET_DELTA(sn,delta) (SN_IS_XDELTA(sn) \ - ? SN_MAKE_XDELTA(sn, delta) \ - : SN_MAKE_NOTE(sn, SN_TYPE(sn), delta)) - -#define SN_DELTA_LIMIT ((ptrdiff_t)JS_BIT(SN_DELTA_BITS)) -#define SN_XDELTA_LIMIT ((ptrdiff_t)JS_BIT(SN_XDELTA_BITS)) - -/* - * Offset fields follow certain notes and are frequency-encoded: an offset in - * [0,0x7f] consumes one byte, an offset in [0x80,0x7fffff] takes three, and - * the high bit of the first byte is set. - */ -#define SN_3BYTE_OFFSET_FLAG 0x80 -#define SN_3BYTE_OFFSET_MASK 0x7f - -typedef struct JSSrcNoteSpec { - const char *name; /* name for disassembly/debugging output */ - int8 arity; /* number of offset operands */ - uint8 offsetBias; /* bias of offset(s) from annotated pc */ - int8 isSpanDep; /* 1 or -1 if offsets could span extended ops, - 0 otherwise; sign tells span direction */ -} JSSrcNoteSpec; - -extern JS_FRIEND_DATA(JSSrcNoteSpec) js_SrcNoteSpec[]; -extern JS_FRIEND_API(uintN) js_SrcNoteLength(jssrcnote *sn); - -#define SN_LENGTH(sn) ((js_SrcNoteSpec[SN_TYPE(sn)].arity == 0) ? 1 \ - : js_SrcNoteLength(sn)) -#define SN_NEXT(sn) ((sn) + SN_LENGTH(sn)) - -/* A source note array is terminated by an all-zero element. */ -#define SN_MAKE_TERMINATOR(sn) (*(sn) = SRC_NULL) -#define SN_IS_TERMINATOR(sn) (*(sn) == SRC_NULL) - -/* - * Append a new source note of the given type (and therefore size) to cg's - * notes dynamic array, updating cg->noteCount. Return the new note's index - * within the array pointed at by cg->current->notes. Return -1 if out of - * memory. - */ -extern intN -js_NewSrcNote(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type); - -extern intN -js_NewSrcNote2(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type, - ptrdiff_t offset); - -extern intN -js_NewSrcNote3(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type, - ptrdiff_t offset1, ptrdiff_t offset2); - -/* - * NB: this function can add at most one extra extended delta note. - */ -extern jssrcnote * -js_AddToSrcNoteDelta(JSContext *cx, JSCodeGenerator *cg, jssrcnote *sn, - ptrdiff_t delta); - -/* - * Get and set the offset operand identified by which (0 for the first, etc.). - */ -extern JS_FRIEND_API(ptrdiff_t) -js_GetSrcNoteOffset(jssrcnote *sn, uintN which); - -extern JSBool -js_SetSrcNoteOffset(JSContext *cx, JSCodeGenerator *cg, uintN index, - uintN which, ptrdiff_t offset); - -/* - * Finish taking source notes in cx's notePool, copying final notes to the new - * stable store allocated by the caller and passed in via notes. Return false - * on malloc failure, which means this function reported an error. - * - * To compute the number of jssrcnotes to allocate and pass in via notes, use - * the CG_COUNT_FINAL_SRCNOTES macro. This macro knows a lot about details of - * js_FinishTakingSrcNotes, SO DON'T CHANGE jsemit.c's js_FinishTakingSrcNotes - * FUNCTION WITHOUT CHECKING WHETHER THIS MACRO NEEDS CORRESPONDING CHANGES! - */ -#define CG_COUNT_FINAL_SRCNOTES(cg, cnt) \ - JS_BEGIN_MACRO \ - ptrdiff_t diff_ = CG_PROLOG_OFFSET(cg) - (cg)->prolog.lastNoteOffset; \ - cnt = (cg)->prolog.noteCount + (cg)->main.noteCount + 1; \ - if ((cg)->prolog.noteCount && \ - (cg)->prolog.currentLine != (cg)->firstLine) { \ - if (diff_ > SN_DELTA_MASK) \ - cnt += JS_HOWMANY(diff_ - SN_DELTA_MASK, SN_XDELTA_MASK); \ - cnt += 2 + (((cg)->firstLine > SN_3BYTE_OFFSET_MASK) << 1); \ - } else if (diff_ > 0) { \ - if (cg->main.noteCount) { \ - jssrcnote *sn_ = (cg)->main.notes; \ - diff_ -= SN_IS_XDELTA(sn_) \ - ? SN_XDELTA_MASK - (*sn_ & SN_XDELTA_MASK) \ - : SN_DELTA_MASK - (*sn_ & SN_DELTA_MASK); \ - } \ - if (diff_ > 0) \ - cnt += JS_HOWMANY(diff_, SN_XDELTA_MASK); \ - } \ - JS_END_MACRO - -extern JSBool -js_FinishTakingSrcNotes(JSContext *cx, JSCodeGenerator *cg, jssrcnote *notes); - -extern void -js_FinishTakingTryNotes(JSCodeGenerator *cg, JSTryNoteArray *array); - -JS_END_EXTERN_C - -#endif /* jsemit_h___ */ diff --git a/x86/mozilla/include/jsfriendapi.h b/x86/mozilla/include/jsfriendapi.h deleted file mode 100644 index a609381..0000000 --- a/x86/mozilla/include/jsfriendapi.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * - * The Original Code is SpiderMonkey code. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsfriendapi_h___ -#define jsfriendapi_h___ - -#include "jspubtd.h" -#include "jsprvtd.h" - -JS_BEGIN_EXTERN_C - -extern JS_FRIEND_API(JSString *) -JS_GetAnonymousString(JSRuntime *rt); - -JS_END_EXTERN_C - -#endif /* jsfriendapi_h___ */ diff --git a/x86/mozilla/include/jsfun.h b/x86/mozilla/include/jsfun.h deleted file mode 100644 index a52092c..0000000 --- a/x86/mozilla/include/jsfun.h +++ /dev/null @@ -1,613 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsfun_h___ -#define jsfun_h___ -/* - * JS function definitions. - */ -#include "jsprvtd.h" -#include "jspubtd.h" -#include "jsobj.h" -#include "jsatom.h" -#include "jsscript.h" -#include "jsstr.h" -#include "jsopcode.h" - -/* - * The high two bits of JSFunction.flags encode whether the function is native - * or interpreted, and if interpreted, what kind of optimized closure form (if - * any) it might be. - * - * 00 not interpreted - * 01 interpreted, neither flat nor null closure - * 10 interpreted, flat closure - * 11 interpreted, null closure - * - * FUN_FLAT_CLOSURE implies FUN_INTERPRETED and u.i.script->upvarsOffset != 0. - * FUN_NULL_CLOSURE implies FUN_INTERPRETED and u.i.script->upvarsOffset == 0. - * - * FUN_INTERPRETED but not FUN_FLAT_CLOSURE and u.i.script->upvarsOffset != 0 - * is an Algol-like function expression or nested function, i.e., a function - * that never escapes upward or downward (heapward), and is only ever called. - * - * Finally, FUN_INTERPRETED and u.i.script->upvarsOffset == 0 could be either - * a non-closure (a global function definition, or any function that uses no - * outer names), or a closure of an escaping function that uses outer names - * whose values can't be snapshot (because the outer names could be reassigned - * after the closure is formed, or because assignments could not be analyzed - * due to with or eval). - * - * Such a hard-case function must use JSOP_NAME, etc., and reify outer function - * activations' call objects, etc. if it's not a global function. - * - * NB: JSFUN_EXPR_CLOSURE reuses JSFUN_STUB_GSOPS, which is an API request flag - * bit only, never stored in fun->flags. - * - * If we need more bits in the future, all flags for FUN_INTERPRETED functions - * can move to u.i.script->flags. For now we use function flag bits to minimize - * pointer-chasing. - */ -#define JSFUN_JOINABLE 0x0001 /* function is null closure that does not - appear to call itself via its own name - or arguments.callee */ - -#define JSFUN_PROTOTYPE 0x0800 /* function is Function.prototype for some - global object */ - -#define JSFUN_EXPR_CLOSURE 0x1000 /* expression closure: function(x) x*x */ -#define JSFUN_TRCINFO 0x2000 /* when set, u.n.trcinfo is non-null, - JSFunctionSpec::call points to a - JSNativeTraceInfo. */ -#define JSFUN_INTERPRETED 0x4000 /* use u.i if kind >= this value else u.n */ -#define JSFUN_FLAT_CLOSURE 0x8000 /* flag (aka "display") closure */ -#define JSFUN_NULL_CLOSURE 0xc000 /* null closure entrains no scope chain */ -#define JSFUN_KINDMASK 0xc000 /* encode interp vs. native and closure - optimization level -- see above */ - -#define FUN_OBJECT(fun) (static_cast(fun)) -#define FUN_KIND(fun) ((fun)->flags & JSFUN_KINDMASK) -#define FUN_SET_KIND(fun,k) ((fun)->flags = ((fun)->flags & ~JSFUN_KINDMASK) | (k)) -#define FUN_INTERPRETED(fun) (FUN_KIND(fun) >= JSFUN_INTERPRETED) -#define FUN_FLAT_CLOSURE(fun)(FUN_KIND(fun) == JSFUN_FLAT_CLOSURE) -#define FUN_NULL_CLOSURE(fun)(FUN_KIND(fun) == JSFUN_NULL_CLOSURE) -#define FUN_SCRIPT(fun) (FUN_INTERPRETED(fun) ? (fun)->u.i.script : NULL) -#define FUN_CLASP(fun) (JS_ASSERT(!FUN_INTERPRETED(fun)), \ - fun->u.n.clasp) -#define FUN_TRCINFO(fun) (JS_ASSERT(!FUN_INTERPRETED(fun)), \ - JS_ASSERT((fun)->flags & JSFUN_TRCINFO), \ - fun->u.n.trcinfo) - -struct JSFunction : public JSObject_Slots2 -{ - /* Functions always have two fixed slots (FUN_CLASS_RESERVED_SLOTS). */ - - uint16 nargs; /* maximum number of specified arguments, - reflected as f.length/f.arity */ - uint16 flags; /* flags, see JSFUN_* below and in jsapi.h */ - union U { - struct { - js::Native native; /* native method pointer or null */ - js::Class *clasp; /* class of objects constructed - by this function */ - JSNativeTraceInfo *trcinfo; - } n; - struct Scripted { - JSScript *script; /* interpreted bytecode descriptor or null */ - uint16 skipmin; /* net skip amount up (toward zero) from - script->staticLevel to nearest upvar, - including upvars in nested functions */ - JSPackedBool wrapper; /* true if this function is a wrapper that - rewrites bytecode optimized for a function - judged non-escaping by the compiler, which - then escaped via the debugger or a rogue - indirect eval; if true, then this function - object's proto is the wrapped object */ - js::Shape *names; /* argument and variable names */ - } i; - void *nativeOrScript; - } u; - JSAtom *atom; /* name for diagnostics and decompiling */ - - bool optimizedClosure() const { return FUN_KIND(this) > JSFUN_INTERPRETED; } - bool needsWrapper() const { return FUN_NULL_CLOSURE(this) && u.i.skipmin != 0; } - bool isInterpreted() const { return FUN_INTERPRETED(this); } - bool isNative() const { return !FUN_INTERPRETED(this); } - bool isConstructor() const { return flags & JSFUN_CONSTRUCTOR; } - bool isHeavyweight() const { return JSFUN_HEAVYWEIGHT_TEST(flags); } - bool isFlatClosure() const { return FUN_KIND(this) == JSFUN_FLAT_CLOSURE; } - - bool isFunctionPrototype() const { return flags & JSFUN_PROTOTYPE; } - - /* Returns the strictness of this function, which must be interpreted. */ - inline bool inStrictMode() const; - - void setArgCount(uint16 nargs) { - JS_ASSERT(this->nargs == 0); - this->nargs = nargs; - } - - /* uint16 representation bounds number of call object dynamic slots. */ - enum { MAX_ARGS_AND_VARS = 2 * ((1U << 16) - 1) }; - -#define JS_LOCAL_NAME_TO_ATOM(nameWord) ((JSAtom *) ((nameWord) & ~(jsuword) 1)) -#define JS_LOCAL_NAME_IS_CONST(nameWord) ((((nameWord) & (jsuword) 1)) != 0) - - bool mightEscape() const { - return isInterpreted() && (isFlatClosure() || !script()->bindings.hasUpvars()); - } - - bool joinable() const { - return flags & JSFUN_JOINABLE; - } - - JSObject &compiledFunObj() { - return *this; - } - - private: - /* - * js_FunctionClass reserves two slots, which are free in JSObject::fslots - * without requiring dslots allocation. Null closures that can be joined to - * a compiler-created function object use the first one to hold a mutable - * methodAtom() state variable, needed for correct foo.caller handling. - */ - enum { - METHOD_ATOM_SLOT = JSSLOT_FUN_METHOD_ATOM - }; - - public: - void setJoinable() { - JS_ASSERT(FUN_INTERPRETED(this)); - getSlotRef(METHOD_ATOM_SLOT).setNull(); - flags |= JSFUN_JOINABLE; - } - - /* - * Method name imputed from property uniquely assigned to or initialized, - * where the function does not need to be cloned to carry a scope chain or - * flattened upvars. - */ - JSAtom *methodAtom() const { - return (joinable() && getSlot(METHOD_ATOM_SLOT).isString()) - ? STRING_TO_ATOM(getSlot(METHOD_ATOM_SLOT).toString()) - : NULL; - } - - void setMethodAtom(JSAtom *atom) { - JS_ASSERT(joinable()); - getSlotRef(METHOD_ATOM_SLOT).setString(ATOM_TO_STRING(atom)); - } - - js::Native maybeNative() const { - return isInterpreted() ? NULL : u.n.native; - } - - JSScript *script() const { - JS_ASSERT(isInterpreted()); - return u.i.script; - } - - static uintN offsetOfNativeOrScript() { - JS_STATIC_ASSERT(offsetof(U, n.native) == offsetof(U, i.script)); - JS_STATIC_ASSERT(offsetof(U, n.native) == offsetof(U, nativeOrScript)); - return offsetof(JSFunction, u.nativeOrScript); - } - - /* Number of extra fixed function object slots. */ - static const uint32 CLASS_RESERVED_SLOTS = JSObject::FUN_CLASS_RESERVED_SLOTS; -}; - -/* - * Trace-annotated native. This expands to a JSFunctionSpec initializer (like - * JS_FN in jsapi.h). fastcall is a FastNative; trcinfo is a - * JSNativeTraceInfo*. - */ -#ifdef JS_TRACER -/* MSVC demands the intermediate (void *) cast here. */ -# define JS_TN(name,fastcall,nargs,flags,trcinfo) \ - JS_FN(name, JS_DATA_TO_FUNC_PTR(Native, trcinfo), nargs, \ - (flags) | JSFUN_STUB_GSOPS | JSFUN_TRCINFO) -#else -# define JS_TN(name,fastcall,nargs,flags,trcinfo) \ - JS_FN(name, fastcall, nargs, flags) -#endif - -/* - * NB: the Arguments classes are uninitialized internal classes that masquerade - * (according to Object.prototype.toString.call(arguments)) as "Arguments", - * while having Object.getPrototypeOf(arguments) === Object.prototype. - * - * WARNING (to alert embedders reading this private .h file): arguments objects - * are *not* thread-safe and should not be used concurrently -- they should be - * used by only one thread at a time, preferably by only one thread over their - * lifetime (a JS worker that migrates from one OS thread to another but shares - * nothing is ok). - * - * Yes, this is an incompatible change, which prefigures the impending move to - * single-threaded objects and GC heaps. - */ -extern js::Class js_ArgumentsClass; - -namespace js { - -extern Class StrictArgumentsClass; - -struct ArgumentsData { - js::Value callee; - js::Value slots[1]; -}; - -} - -inline bool -JSObject::isNormalArguments() const -{ - return getClass() == &js_ArgumentsClass; -} - -inline bool -JSObject::isStrictArguments() const -{ - return getClass() == &js::StrictArgumentsClass; -} - -inline bool -JSObject::isArguments() const -{ - return isNormalArguments() || isStrictArguments(); -} - -#define JS_ARGUMENTS_OBJECT_ON_TRACE ((void *)0xa126) - -extern JS_PUBLIC_DATA(js::Class) js_CallClass; -extern JS_PUBLIC_DATA(js::Class) js_FunctionClass; -extern js::Class js_DeclEnvClass; - -inline bool -JSObject::isCall() const -{ - return getClass() == &js_CallClass; -} - -inline bool -JSObject::isFunction() const -{ - return getClass() == &js_FunctionClass; -} - -inline JSFunction * -JSObject::getFunctionPrivate() const -{ - JS_ASSERT(isFunction()); - return reinterpret_cast(getPrivate()); -} - -namespace js { - -/* - * Construct a call object for the given bindings. If this is a call object - * for a function invocation, callee should be the function being called. - * Otherwise it must be a call object for eval of strict mode code, and callee - * must be null. - */ -extern JSObject * -NewCallObject(JSContext *cx, js::Bindings *bindings, JSObject &scopeChain, JSObject *callee); - -/* - * NB: jsapi.h and jsobj.h must be included before any call to this macro. - */ -#define VALUE_IS_FUNCTION(cx, v) \ - (!JSVAL_IS_PRIMITIVE(v) && JSVAL_TO_OBJECT(v)->isFunction()) - -static JS_ALWAYS_INLINE bool -IsFunctionObject(const js::Value &v) -{ - return v.isObject() && v.toObject().isFunction(); -} - -static JS_ALWAYS_INLINE bool -IsFunctionObject(const js::Value &v, JSObject **funobj) -{ - return v.isObject() && (*funobj = &v.toObject())->isFunction(); -} - -static JS_ALWAYS_INLINE bool -IsFunctionObject(const js::Value &v, JSFunction **fun) -{ - JSObject *funobj; - bool b = IsFunctionObject(v, &funobj); - if (b) - *fun = funobj->getFunctionPrivate(); - return b; -} - -extern JS_ALWAYS_INLINE bool -SameTraceType(const Value &lhs, const Value &rhs) -{ - return SameType(lhs, rhs) && - (lhs.isPrimitive() || - lhs.toObject().isFunction() == rhs.toObject().isFunction()); -} - -/* - * Macro to access the private slot of the function object after the slot is - * initialized. - */ -#define GET_FUNCTION_PRIVATE(cx, funobj) \ - (JS_ASSERT((funobj)->isFunction()), \ - (JSFunction *) (funobj)->getPrivate()) - -/* - * Return true if this is a compiler-created internal function accessed by - * its own object. Such a function object must not be accessible to script - * or embedding code. - */ -inline bool -IsInternalFunctionObject(JSObject *funobj) -{ - JS_ASSERT(funobj->isFunction()); - JSFunction *fun = (JSFunction *) funobj->getPrivate(); - return funobj == fun && (fun->flags & JSFUN_LAMBDA) && !funobj->getParent(); -} - -/* Valueified JS_IsConstructing. */ -static JS_ALWAYS_INLINE bool -IsConstructing(const Value *vp) -{ -#ifdef DEBUG - JSObject *callee = &JS_CALLEE(cx, vp).toObject(); - if (callee->isFunction()) { - JSFunction *fun = callee->getFunctionPrivate(); - JS_ASSERT((fun->flags & JSFUN_CONSTRUCTOR) != 0); - } else { - JS_ASSERT(callee->getClass()->construct != NULL); - } -#endif - return vp[1].isMagic(); -} - -static JS_ALWAYS_INLINE bool -IsConstructing_PossiblyWithGivenThisObject(const Value *vp, JSObject **ctorThis) -{ -#ifdef DEBUG - JSObject *callee = &JS_CALLEE(cx, vp).toObject(); - if (callee->isFunction()) { - JSFunction *fun = callee->getFunctionPrivate(); - JS_ASSERT((fun->flags & JSFUN_CONSTRUCTOR) != 0); - } else { - JS_ASSERT(callee->getClass()->construct != NULL); - } -#endif - bool isCtor = vp[1].isMagic(); - if (isCtor) - *ctorThis = vp[1].getMagicObjectOrNullPayload(); - return isCtor; -} - -inline const char * -GetFunctionNameBytes(JSContext *cx, JSFunction *fun, JSAutoByteString *bytes) -{ - if (fun->atom) - return bytes->encode(cx, ATOM_TO_STRING(fun->atom)); - return js_anonymous_str; -} - -extern JS_FRIEND_API(bool) -IsBuiltinFunctionConstructor(JSFunction *fun); - -/* - * Preconditions: funobj->isInterpreted() && !funobj->isFunctionPrototype() && - * !funobj->isBoundFunction(). This is sufficient to establish that funobj has - * a non-configurable non-method .prototype data property, thought it might not - * have been resolved yet, and its value could be anything. - * - * Return the shape of the .prototype property of funobj, resolving it if - * needed. On error, return NULL. - * - * This is not safe to call on trace because it defines properties, which can - * trigger lookups that could reenter. - */ -const Shape * -LookupInterpretedFunctionPrototype(JSContext *cx, JSObject *funobj); - -} /* namespace js */ - -extern JSString * -fun_toStringHelper(JSContext *cx, JSObject *obj, uintN indent); - -extern JSFunction * -js_NewFunction(JSContext *cx, JSObject *funobj, js::Native native, uintN nargs, - uintN flags, JSObject *parent, JSAtom *atom); - -extern JSObject * -js_InitFunctionClass(JSContext *cx, JSObject *obj); - -extern JSObject * -js_InitArgumentsClass(JSContext *cx, JSObject *obj); - -extern void -js_TraceFunction(JSTracer *trc, JSFunction *fun); - -extern void -js_FinalizeFunction(JSContext *cx, JSFunction *fun); - -extern JSObject * JS_FASTCALL -js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent, - JSObject *proto); - -inline JSObject * -CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent) -{ - JS_ASSERT(parent); - JSObject *proto; - if (!js_GetClassPrototype(cx, parent, JSProto_Function, &proto)) - return NULL; - return js_CloneFunctionObject(cx, fun, parent, proto); -} - -extern JSObject * JS_FASTCALL -js_AllocFlatClosure(JSContext *cx, JSFunction *fun, JSObject *scopeChain); - -extern JSObject * -js_NewFlatClosure(JSContext *cx, JSFunction *fun, JSOp op, size_t oplen); - -extern JS_REQUIRES_STACK JSObject * -js_NewDebuggableFlatClosure(JSContext *cx, JSFunction *fun); - -extern JSFunction * -js_DefineFunction(JSContext *cx, JSObject *obj, jsid id, js::Native native, - uintN nargs, uintN flags); - -/* - * Flags for js_ValueToFunction and js_ReportIsNotFunction. We depend on the - * fact that JSINVOKE_CONSTRUCT (aka JSFRAME_CONSTRUCTING) is 1, and test that - * with #if/#error in jsfun.c. - */ -#define JSV2F_CONSTRUCT JSINVOKE_CONSTRUCT -#define JSV2F_SEARCH_STACK 0x10000 - -extern JSFunction * -js_ValueToFunction(JSContext *cx, const js::Value *vp, uintN flags); - -extern JSObject * -js_ValueToFunctionObject(JSContext *cx, js::Value *vp, uintN flags); - -extern JSObject * -js_ValueToCallableObject(JSContext *cx, js::Value *vp, uintN flags); - -extern void -js_ReportIsNotFunction(JSContext *cx, const js::Value *vp, uintN flags); - -extern JSObject * -js_GetCallObject(JSContext *cx, JSStackFrame *fp); - -extern JSObject * JS_FASTCALL -js_CreateCallObjectOnTrace(JSContext *cx, JSFunction *fun, JSObject *callee, JSObject *scopeChain); - -extern void -js_PutCallObject(JSContext *cx, JSStackFrame *fp); - -extern JSBool JS_FASTCALL -js_PutCallObjectOnTrace(JSContext *cx, JSObject *scopeChain, uint32 nargs, - js::Value *argv, uint32 nvars, js::Value *slots); - -namespace js { - -extern JSBool -GetCallArg(JSContext *cx, JSObject *obj, jsid id, js::Value *vp); - -extern JSBool -GetCallVar(JSContext *cx, JSObject *obj, jsid id, js::Value *vp); - -/* - * Slower version of js_GetCallVar used when call_resolve detects an attempt to - * leak an optimized closure via indirect or debugger eval. - */ -extern JSBool -GetCallVarChecked(JSContext *cx, JSObject *obj, jsid id, js::Value *vp); - -extern JSBool -GetCallUpvar(JSContext *cx, JSObject *obj, jsid id, js::Value *vp); - -extern JSBool -SetCallArg(JSContext *cx, JSObject *obj, jsid id, JSBool strict, js::Value *vp); - -extern JSBool -SetCallVar(JSContext *cx, JSObject *obj, jsid id, JSBool strict, js::Value *vp); - -extern JSBool -SetCallUpvar(JSContext *cx, JSObject *obj, jsid id, JSBool strict, js::Value *vp); - -} // namespace js - -extern JSBool -js_GetArgsValue(JSContext *cx, JSStackFrame *fp, js::Value *vp); - -extern JSBool -js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id, js::Value *vp); - -/* - * Get the arguments object for the given frame. If the frame is strict mode - * code, its current arguments will be copied into the arguments object. - * - * NB: Callers *must* get the arguments object before any parameters are - * mutated when the frame is strict mode code! The emitter ensures this - * occurs for strict mode functions containing syntax which might mutate a - * named parameter by synthesizing an arguments access at the start of the - * function. - */ -extern JSObject * -js_GetArgsObject(JSContext *cx, JSStackFrame *fp); - -extern void -js_PutArgsObject(JSContext *cx, JSStackFrame *fp); - -inline bool -js_IsNamedLambda(JSFunction *fun) { return (fun->flags & JSFUN_LAMBDA) && fun->atom; } - -/* - * Maximum supported value of arguments.length. It bounds the maximum number of - * arguments that can be supplied via the second (so-called |argArray|) param - * to Function.prototype.apply. This value also bounds the number of elements - * parsed in an array initialiser. - * - * The thread's stack is the limiting factor for this number. It is currently - * 2MB, which fits a little less than 2^19 arguments (once the stack frame, - * callstack, etc. are included). Pick a max args length that is a little less. - */ -const uint32 JS_ARGS_LENGTH_MAX = JS_BIT(19) - 1024; - -/* - * JSSLOT_ARGS_LENGTH stores ((argc << 1) | overwritten_flag) as an Int32 - * Value. Thus (JS_ARGS_LENGTH_MAX << 1) | 1 must be less than JSVAL_INT_MAX. - */ -JS_STATIC_ASSERT(JS_ARGS_LENGTH_MAX <= JS_BIT(30)); -JS_STATIC_ASSERT(((JS_ARGS_LENGTH_MAX << 1) | 1) <= JSVAL_INT_MAX); - -extern JSBool -js_XDRFunctionObject(JSXDRState *xdr, JSObject **objp); - -extern JSBool -js_fun_apply(JSContext *cx, uintN argc, js::Value *vp); - -extern JSBool -js_fun_call(JSContext *cx, uintN argc, js::Value *vp); - -#endif /* jsfun_h___ */ diff --git a/x86/mozilla/include/jsgc.h b/x86/mozilla/include/jsgc.h deleted file mode 100644 index bb666e6..0000000 --- a/x86/mozilla/include/jsgc.h +++ /dev/null @@ -1,1114 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsgc_h___ -#define jsgc_h___ - -/* Gross special case for Gecko, which defines malloc/calloc/free. */ -#ifdef mozilla_mozalloc_macro_wrappers_h -# define JS_GC_UNDEFD_MOZALLOC_WRAPPERS -/* The "anti-header" */ -# include "mozilla/mozalloc_undef_macro_wrappers.h" -#endif - -/* - * JS Garbage Collector. - */ -#include - -#include "jstypes.h" -#include "jsprvtd.h" -#include "jspubtd.h" -#include "jsdhash.h" -#include "jsbit.h" -#include "jsgcchunk.h" -#include "jsutil.h" -#include "jsvector.h" -#include "jsversion.h" -#include "jsobj.h" -#include "jsfun.h" -#include "jsgcstats.h" -#include "jscell.h" - -struct JSCompartment; - -extern "C" void -js_TraceXML(JSTracer *trc, JSXML* thing); - -#if JS_STACK_GROWTH_DIRECTION > 0 -# define JS_CHECK_STACK_SIZE(limit, lval) ((jsuword)(lval) < limit) -#else -# define JS_CHECK_STACK_SIZE(limit, lval) ((jsuword)(lval) > limit) -#endif - -namespace js { - -struct Shape; - -namespace gc { - -/* - * The kind of GC thing with a finalizer. The external strings follow the - * ordinary string to simplify js_GetExternalStringGCType. - */ -enum FinalizeKind { - FINALIZE_OBJECT0, - FINALIZE_OBJECT2, - FINALIZE_OBJECT4, - FINALIZE_OBJECT8, - FINALIZE_OBJECT12, - FINALIZE_OBJECT16, - FINALIZE_OBJECT_LAST = FINALIZE_OBJECT16, - FINALIZE_FUNCTION, -#if JS_HAS_XML_SUPPORT - FINALIZE_XML, -#endif - FINALIZE_SHORT_STRING, - FINALIZE_STRING, - FINALIZE_EXTERNAL_STRING, - FINALIZE_LIMIT -}; - -const uintN JS_FINALIZE_OBJECT_LIMIT = 6; - -/* Every arena has a header. */ -struct ArenaHeader { - JSCompartment *compartment; - Arena *next; - FreeCell *freeList; - unsigned thingKind; - bool isUsed; - size_t thingSize; -#ifdef DEBUG - bool hasFreeThings; -#endif -}; - -template -union ThingOrCell { - T t; - FreeCell cell; -}; - -template -struct Things { - ThingOrCell things[N]; - char filler[R]; -}; - -template -struct Things { - ThingOrCell things[N]; -}; - -template -struct Arena { - static const size_t ArenaSize = 4096; - - struct AlignedArenaHeader { - T align[(sizeof(ArenaHeader) + sizeof(T) - 1) / sizeof(T)]; - }; - - /* We want things in the arena to be aligned, so align the header. */ - union { - ArenaHeader aheader; - AlignedArenaHeader align; - }; - - static const size_t ThingsPerArena = (ArenaSize - sizeof(AlignedArenaHeader)) / sizeof(T); - static const size_t FillerSize = ArenaSize - sizeof(AlignedArenaHeader) - sizeof(T) * ThingsPerArena; - Things t; - - inline Chunk *chunk() const; - inline size_t arenaIndex() const; - - inline ArenaHeader *header() { return &aheader; }; - - inline MarkingDelay *getMarkingDelay() const; - inline ArenaBitmap *bitmap() const; - - inline ConservativeGCTest mark(T *thing, JSTracer *trc); - void markDelayedChildren(JSTracer *trc); - inline bool inFreeList(void *thing) const; - inline T *getAlignedThing(void *thing); -#ifdef DEBUG - inline bool assureThingIsAligned(void *thing); -#endif - - void init(JSCompartment *compartment, unsigned thingKind); -}; -JS_STATIC_ASSERT(sizeof(Arena) == 4096); - -/* - * Live objects are marked black. How many other additional colors are available - * depends on the size of the GCThing. - */ -static const uint32 BLACK = 0; - -/* An arena bitmap contains enough mark bits for all the cells in an arena. */ -struct ArenaBitmap { - static const size_t BitCount = Arena::ArenaSize / Cell::CellSize; - static const size_t BitWords = BitCount / JS_BITS_PER_WORD; - - uintptr_t bitmap[BitWords]; - - JS_ALWAYS_INLINE bool isMarked(size_t bit, uint32 color) { - bit += color; - JS_ASSERT(bit < BitCount); - uintptr_t *word = &bitmap[bit / JS_BITS_PER_WORD]; - return *word & (uintptr_t(1) << (bit % JS_BITS_PER_WORD)); - } - - JS_ALWAYS_INLINE bool markIfUnmarked(size_t bit, uint32 color) { - JS_ASSERT(bit + color < BitCount); - uintptr_t *word = &bitmap[bit / JS_BITS_PER_WORD]; - uintptr_t mask = (uintptr_t(1) << (bit % JS_BITS_PER_WORD)); - if (*word & mask) - return false; - *word |= mask; - if (color != BLACK) { - bit += color; - word = &bitmap[bit / JS_BITS_PER_WORD]; - mask = (uintptr_t(1) << (bit % JS_BITS_PER_WORD)); - if (*word & mask) - return false; - *word |= mask; - } - return true; - } - - JS_ALWAYS_INLINE void unmark(size_t bit, uint32 color) { - bit += color; - JS_ASSERT(bit < BitCount); - uintptr_t *word = &bitmap[bit / JS_BITS_PER_WORD]; - *word &= ~(uintptr_t(1) << (bit % JS_BITS_PER_WORD)); - } - -#ifdef DEBUG - bool noBitsSet() { - for (unsigned i = 0; i < BitWords; i++) { - if (bitmap[i] != uintptr_t(0)) - return false; - } - return true; - } -#endif -}; - -/* Ensure that bitmap covers the whole arena. */ -JS_STATIC_ASSERT(Arena::ArenaSize % Cell::CellSize == 0); -JS_STATIC_ASSERT(ArenaBitmap::BitCount % JS_BITS_PER_WORD == 0); - -/* Marking delay is used to resume marking later when recursive marking uses too much stack. */ -struct MarkingDelay { - Arena *link; - uintptr_t unmarkedChildren; - jsuword start; - - void init() - { - link = NULL; - unmarkedChildren = 0; - } -}; - -struct EmptyArenaLists { - /* Arenas with no internal freelist prepared. */ - Arena *cellFreeList; - - /* Arenas with internal freelists prepared for a given finalize kind. */ - Arena *freeLists[FINALIZE_LIMIT]; - - void init() { - PodZero(this); - } - - Arena *getOtherArena() { - Arena *arena = cellFreeList; - if (arena) { - cellFreeList = arena->header()->next; - return arena; - } - for (int i = 0; i < FINALIZE_LIMIT; i++) { - if ((arena = (Arena *) freeLists[i])) { - freeLists[i] = freeLists[i]->header()->next; - return arena; - } - } - JS_NOT_REACHED("No arena"); - return NULL; - } - - template - inline Arena *getTypedFreeList(unsigned thingKind); - - template - inline Arena *getNext(JSCompartment *comp, unsigned thingKind); - - template - inline void insert(Arena *arena); -}; - -template -inline Arena * -EmptyArenaLists::getTypedFreeList(unsigned thingKind) { - JS_ASSERT(thingKind < FINALIZE_LIMIT); - Arena *arena = (Arena*) freeLists[thingKind]; - if (arena) { - freeLists[thingKind] = freeLists[thingKind]->header()->next; - return arena; - } - return NULL; -} - -template -inline Arena * -EmptyArenaLists::getNext(JSCompartment *comp, unsigned thingKind) { - Arena *arena = getTypedFreeList(thingKind); - if (arena) { - JS_ASSERT(arena->header()->isUsed == false); - JS_ASSERT(arena->header()->thingSize == sizeof(T)); - arena->header()->isUsed = true; - arena->header()->thingKind = thingKind; - arena->header()->compartment = comp; - return arena; - } - arena = (Arena *)getOtherArena(); - JS_ASSERT(arena->header()->isUsed == false); - arena->init(comp, thingKind); - return arena; -} - -template -inline void -EmptyArenaLists::insert(Arena *arena) { - unsigned thingKind = arena->header()->thingKind; - JS_ASSERT(thingKind < FINALIZE_LIMIT); - arena->header()->next = freeLists[thingKind]; - freeLists[thingKind] = (Arena *) arena; -} - -/* The chunk header (located at the end of the chunk to preserve arena alignment). */ -struct ChunkInfo { - Chunk *link; - JSRuntime *runtime; - EmptyArenaLists emptyArenaLists; - size_t age; - size_t numFree; -}; - -/* Chunks contain arenas and associated data structures (mark bitmap, delayed marking state). */ -struct Chunk { - static const size_t BytesPerArena = sizeof(Arena) + - sizeof(ArenaBitmap) + - sizeof(MarkingDelay); - - static const size_t ArenasPerChunk = (GC_CHUNK_SIZE - sizeof(ChunkInfo)) / BytesPerArena; - - Arena arenas[ArenasPerChunk]; - ArenaBitmap bitmaps[ArenasPerChunk]; - MarkingDelay markingDelay[ArenasPerChunk]; - - ChunkInfo info; - - void clearMarkBitmap(); - void init(JSRuntime *rt); - - bool unused(); - bool hasAvailableArenas(); - bool withinArenasRange(Cell *cell); - - template - Arena *allocateArena(JSCompartment *comp, unsigned thingKind); - - template - void releaseArena(Arena *a); - - JSRuntime *getRuntime(); -}; -JS_STATIC_ASSERT(sizeof(Chunk) <= GC_CHUNK_SIZE); -JS_STATIC_ASSERT(sizeof(Chunk) + Chunk::BytesPerArena > GC_CHUNK_SIZE); - -Arena * -Cell::arena() const -{ - uintptr_t addr = uintptr_t(this); - JS_ASSERT(addr % sizeof(FreeCell) == 0); - addr &= ~(Arena::ArenaSize - 1); - return reinterpret_cast *>(addr); -} - -Chunk * -Cell::chunk() const -{ - uintptr_t addr = uintptr_t(this); - JS_ASSERT(addr % sizeof(FreeCell) == 0); - addr &= ~(GC_CHUNK_SIZE - 1); - return reinterpret_cast(addr); -} - -ArenaBitmap * -Cell::bitmap() const -{ - return &chunk()->bitmaps[arena()->arenaIndex()]; -} - -STATIC_POSTCONDITION_ASSUME(return < ArenaBitmap::BitCount) -size_t -Cell::cellIndex() const -{ - return reinterpret_cast(this) - reinterpret_cast(&arena()->t); -} - -template -Chunk * -Arena::chunk() const -{ - uintptr_t addr = uintptr_t(this); - JS_ASSERT(addr % sizeof(FreeCell) == 0); - addr &= ~(GC_CHUNK_SIZE - 1); - return reinterpret_cast(addr); -} - -template -size_t -Arena::arenaIndex() const -{ - return reinterpret_cast *>(this) - chunk()->arenas; -} - -template -MarkingDelay * -Arena::getMarkingDelay() const -{ - return &chunk()->markingDelay[arenaIndex()]; -} - -template -ArenaBitmap * -Arena::bitmap() const -{ - return &chunk()->bitmaps[arenaIndex()]; -} - -template -inline T * -Arena::getAlignedThing(void *thing) -{ - jsuword start = reinterpret_cast(&t.things[0]); - jsuword offset = reinterpret_cast(thing) - start; - offset -= offset % aheader.thingSize; - return reinterpret_cast(start + offset); -} - -#ifdef DEBUG -template -inline bool -Arena::assureThingIsAligned(void *thing) -{ - return (getAlignedThing(thing) == thing); -} -#endif - -static void -AssertValidColor(const void *thing, uint32 color) -{ - JS_ASSERT_IF(color, color < reinterpret_cast(thing)->arena()->header()->thingSize / sizeof(FreeCell)); -} - -inline bool -Cell::isMarked(uint32 color = BLACK) const -{ - AssertValidColor(this, color); - return bitmap()->isMarked(cellIndex(), color); -} - -bool -Cell::markIfUnmarked(uint32 color = BLACK) const -{ - AssertValidColor(this, color); - return bitmap()->markIfUnmarked(cellIndex(), color); -} - -void -Cell::unmark(uint32 color) const -{ - JS_ASSERT(color != BLACK); - AssertValidColor(this, color); - bitmap()->unmark(cellIndex(), color); -} - -JSCompartment * -Cell::compartment() const -{ - return arena()->header()->compartment; -} - -template -static inline -Arena * -GetArena(Cell *cell) -{ - return reinterpret_cast *>(cell->arena()); -} - -#define JSTRACE_XML 2 - -/* - * One past the maximum trace kind. - */ -#define JSTRACE_LIMIT 3 - -/* - * Lower limit after which we limit the heap growth - */ -const size_t GC_ARENA_ALLOCATION_TRIGGER = 30 * js::GC_CHUNK_SIZE; - -/* - * A GC is triggered once the number of newly allocated arenas - * is GC_HEAP_GROWTH_FACTOR times the number of live arenas after - * the last GC starting after the lower limit of - * GC_ARENA_ALLOCATION_TRIGGER. - */ -const float GC_HEAP_GROWTH_FACTOR = 3.0f; - -static inline size_t -GetFinalizableTraceKind(size_t thingKind) -{ - JS_STATIC_ASSERT(JSExternalString::TYPE_LIMIT == 8); - - static const uint8 map[FINALIZE_LIMIT] = { - JSTRACE_OBJECT, /* FINALIZE_OBJECT0 */ - JSTRACE_OBJECT, /* FINALIZE_OBJECT2 */ - JSTRACE_OBJECT, /* FINALIZE_OBJECT4 */ - JSTRACE_OBJECT, /* FINALIZE_OBJECT8 */ - JSTRACE_OBJECT, /* FINALIZE_OBJECT12 */ - JSTRACE_OBJECT, /* FINALIZE_OBJECT16 */ - JSTRACE_OBJECT, /* FINALIZE_FUNCTION */ -#if JS_HAS_XML_SUPPORT /* FINALIZE_XML */ - JSTRACE_XML, -#endif - JSTRACE_STRING, /* FINALIZE_SHORT_STRING */ - JSTRACE_STRING, /* FINALIZE_STRING */ - JSTRACE_STRING, /* FINALIZE_EXTERNAL_STRING */ - }; - - JS_ASSERT(thingKind < FINALIZE_LIMIT); - return map[thingKind]; -} - -static inline bool -IsFinalizableStringKind(unsigned thingKind) -{ - return unsigned(FINALIZE_SHORT_STRING) <= thingKind && - thingKind <= unsigned(FINALIZE_EXTERNAL_STRING); -} - -/* - * Get the type of the external string or -1 if the string was not created - * with JS_NewExternalString. - */ -static inline intN -GetExternalStringGCType(JSExternalString *str) -{ - JS_STATIC_ASSERT(FINALIZE_STRING + 1 == FINALIZE_EXTERNAL_STRING); - JS_ASSERT(!JSString::isStatic(str)); - - unsigned thingKind = str->externalStringType; - JS_ASSERT(IsFinalizableStringKind(thingKind)); - return intN(thingKind); -} - -static inline uint32 -GetGCThingTraceKind(void *thing) -{ - JS_ASSERT(thing); - if (JSString::isStatic(thing)) - return JSTRACE_STRING; - Cell *cell = reinterpret_cast(thing); - return GetFinalizableTraceKind(cell->arena()->header()->thingKind); -} - -static inline JSRuntime * -GetGCThingRuntime(void *thing) -{ - return reinterpret_cast(thing)->chunk()->info.runtime; -} - -#ifdef DEBUG -extern bool -checkArenaListsForThing(JSCompartment *comp, jsuword thing); -#endif - -/* The arenas in a list have uniform kind. */ -struct ArenaList { - Arena *head; /* list start */ - Arena *cursor; /* arena with free things */ - - inline void init() { - head = NULL; - cursor = NULL; - } - - inline Arena *getNextWithFreeList() { - Arena *a; - while (cursor != NULL) { - ArenaHeader *aheader = cursor->header(); - a = cursor; - cursor = aheader->next; - if (aheader->freeList) - return a; - } - return NULL; - } - -#ifdef DEBUG - template - bool arenasContainThing(void *thing) { - for (Arena *a = (Arena *) head; a; a = (Arena *) a->header()->next) { - JS_ASSERT(a->header()->isUsed); - if (thing >= &a->t.things[0] && thing < &a->t.things[a->ThingsPerArena]) - return true; - } - return false; - } - - bool markedThingsInArenaList() { - for (Arena *a = (Arena *) head; a; a = (Arena *) a->header()->next) { - if (!a->bitmap()->noBitsSet()) - return true; - } - return false; - } -#endif - - inline void insert(Arena *a) { - a->header()->next = head; - head = a; - } - - void releaseAll() { - while (head) { - Arena *next = head->header()->next; - head->chunk()->releaseArena(head); - head = next; - } - head = NULL; - cursor = NULL; - } - - inline bool isEmpty() const { - return (head == NULL); - } -}; - -struct FreeLists { - FreeCell **finalizables[FINALIZE_LIMIT]; - - void purge(); - - inline FreeCell *getNext(uint32 kind) { - FreeCell *top = NULL; - if (finalizables[kind]) { - top = *finalizables[kind]; - if (top) { - *finalizables[kind] = top->link; - } else { - finalizables[kind] = NULL; - } -#ifdef DEBUG - if (top && !top->link) - top->arena()->header()->hasFreeThings = false; -#endif - } - return top; - } - - template - inline void populate(Arena *a, uint32 thingKind) { - finalizables[thingKind] = &a->header()->freeList; - } - -#ifdef DEBUG - bool isEmpty() const { - for (size_t i = 0; i != JS_ARRAY_LENGTH(finalizables); ++i) { - if (finalizables[i]) - return false; - } - return true; - } -#endif -}; -} - -typedef Vector GCChunks; - -struct GCPtrHasher -{ - typedef void *Lookup; - - static HashNumber hash(void *key) { - return HashNumber(uintptr_t(key) >> JS_GCTHING_ZEROBITS); - } - - static bool match(void *l, void *k) { return l == k; } -}; - -typedef HashMap GCLocks; - -struct RootInfo { - RootInfo() {} - RootInfo(const char *name, JSGCRootType type) : name(name), type(type) {} - const char *name; - JSGCRootType type; -}; - -typedef js::HashMap, - js::SystemAllocPolicy> RootedValueMap; - -/* If HashNumber grows, need to change WrapperHasher. */ -JS_STATIC_ASSERT(sizeof(HashNumber) == 4); - -struct WrapperHasher -{ - typedef Value Lookup; - - static HashNumber hash(Value key) { - uint64 bits = JSVAL_BITS(Jsvalify(key)); - return (uint32)bits ^ (uint32)(bits >> 32); - } - - static bool match(const Value &l, const Value &k) { return l == k; } -}; - -typedef HashMap WrapperMap; - -class AutoValueVector; -class AutoIdVector; -} - -static inline void -CheckGCFreeListLink(js::gc::FreeCell *cell) -{ - /* - * The GC things on the free lists come from one arena and the things on - * the free list are linked in ascending address order. - */ - JS_ASSERT_IF(cell->link, - cell->arena() == - cell->link->arena()); - JS_ASSERT_IF(cell->link, cell < cell->link); -} - -extern bool -RefillFinalizableFreeList(JSContext *cx, unsigned thingKind); - -#ifdef DEBUG -extern bool -CheckAllocation(JSContext *cx); -#endif - -/* - * Get the type of the external string or -1 if the string was not created - * with JS_NewExternalString. - */ -extern intN -js_GetExternalStringGCType(JSString *str); - -extern JS_FRIEND_API(uint32) -js_GetGCThingTraceKind(void *thing); - -#if 1 -/* - * Since we're forcing a GC from JS_GC anyway, don't bother wasting cycles - * loading oldval. XXX remove implied force, fix jsinterp.c's "second arg - * ignored", etc. - */ -#define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JS_TRUE) -#else -#define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JSVAL_IS_GCTHING(oldval)) -#endif - -extern JSBool -js_InitGC(JSRuntime *rt, uint32 maxbytes); - -extern void -js_FinishGC(JSRuntime *rt); - -extern JSBool -js_AddRoot(JSContext *cx, js::Value *vp, const char *name); - -extern JSBool -js_AddGCThingRoot(JSContext *cx, void **rp, const char *name); - -#ifdef DEBUG -extern void -js_DumpNamedRoots(JSRuntime *rt, - void (*dump)(const char *name, void *rp, JSGCRootType type, void *data), - void *data); -#endif - -extern uint32 -js_MapGCRoots(JSRuntime *rt, JSGCRootMapFun map, void *data); - -/* Table of pointers with count valid members. */ -typedef struct JSPtrTable { - size_t count; - void **array; -} JSPtrTable; - -extern JSBool -js_RegisterCloseableIterator(JSContext *cx, JSObject *obj); - -#ifdef JS_TRACER -extern JSBool -js_ReserveObjects(JSContext *cx, size_t nobjects); -#endif - -extern JSBool -js_LockGCThingRT(JSRuntime *rt, void *thing); - -extern void -js_UnlockGCThingRT(JSRuntime *rt, void *thing); - -extern JS_FRIEND_API(bool) -IsAboutToBeFinalized(JSContext *cx, void *thing); - -extern JS_FRIEND_API(bool) -js_GCThingIsMarked(void *thing, uintN color); - -extern void -js_TraceStackFrame(JSTracer *trc, JSStackFrame *fp); - -namespace js { - -extern JS_REQUIRES_STACK void -MarkRuntime(JSTracer *trc); - -extern void -TraceRuntime(JSTracer *trc); - -extern JS_REQUIRES_STACK JS_FRIEND_API(void) -MarkContext(JSTracer *trc, JSContext *acx); - -/* Must be called with GC lock taken. */ -extern void -TriggerGC(JSRuntime *rt); - -/* Must be called with GC lock taken. */ -extern void -TriggerCompartmentGC(JSCompartment *comp); - -extern void -MaybeGC(JSContext *cx); - -} /* namespace js */ - -/* - * Kinds of js_GC invocation. - */ -typedef enum JSGCInvocationKind { - /* Normal invocation. */ - GC_NORMAL = 0, - - /* - * Called from js_DestroyContext for last JSContext in a JSRuntime, when - * it is imperative that rt->gcPoke gets cleared early in js_GC. - */ - GC_LAST_CONTEXT = 1 -} JSGCInvocationKind; - -/* Pass NULL for |comp| to get a full GC. */ -extern void -js_GC(JSContext *cx, JSCompartment *comp, JSGCInvocationKind gckind); - -#ifdef JS_THREADSAFE -/* - * This is a helper for code at can potentially run outside JS request to - * ensure that the GC is not running when the function returns. - * - * This function must be called with the GC lock held. - */ -extern void -js_WaitForGC(JSRuntime *rt); - -#else /* !JS_THREADSAFE */ - -# define js_WaitForGC(rt) ((void) 0) - -#endif - -extern void -js_DestroyScriptsToGC(JSContext *cx, JSCompartment *comp); - -namespace js { - -#ifdef JS_THREADSAFE - -/* - * During the finalization we do not free immediately. Rather we add the - * corresponding pointers to a buffer which we later release on a separated - * thread. - * - * The buffer is implemented as a vector of 64K arrays of pointers, not as a - * simple vector, to avoid realloc calls during the vector growth and to not - * bloat the binary size of the inlined freeLater method. Any OOM during - * buffer growth results in the pointer being freed immediately. - */ -class GCHelperThread { - static const size_t FREE_ARRAY_SIZE = size_t(1) << 16; - static const size_t FREE_ARRAY_LENGTH = FREE_ARRAY_SIZE / sizeof(void *); - - PRThread* thread; - PRCondVar* wakeup; - PRCondVar* sweepingDone; - bool shutdown; - bool sweeping; - - Vector freeVector; - void **freeCursor; - void **freeCursorEnd; - - JS_FRIEND_API(void) - replenishAndFreeLater(void *ptr); - - static void freeElementsAndArray(void **array, void **end) { - JS_ASSERT(array <= end); - for (void **p = array; p != end; ++p) - js_free(*p); - js_free(array); - } - - static void threadMain(void* arg); - - void threadLoop(JSRuntime *rt); - void doSweep(); - - public: - GCHelperThread() - : thread(NULL), - wakeup(NULL), - sweepingDone(NULL), - shutdown(false), - sweeping(false), - freeCursor(NULL), - freeCursorEnd(NULL) { } - - bool init(JSRuntime *rt); - void finish(JSRuntime *rt); - - /* Must be called with GC lock taken. */ - void startBackgroundSweep(JSRuntime *rt); - - /* Must be called outside the GC lock. */ - void waitBackgroundSweepEnd(JSRuntime *rt); - - void freeLater(void *ptr) { - JS_ASSERT(!sweeping); - if (freeCursor != freeCursorEnd) - *freeCursor++ = ptr; - else - replenishAndFreeLater(ptr); - } -}; - -#endif /* JS_THREADSAFE */ - -struct GCChunkHasher { - typedef gc::Chunk *Lookup; - - /* - * Strip zeros for better distribution after multiplying by the golden - * ratio. - */ - static HashNumber hash(gc::Chunk *chunk) { - JS_ASSERT(!(jsuword(chunk) & GC_CHUNK_MASK)); - return HashNumber(jsuword(chunk) >> GC_CHUNK_SHIFT); - } - - static bool match(gc::Chunk *k, gc::Chunk *l) { - JS_ASSERT(!(jsuword(k) & GC_CHUNK_MASK)); - JS_ASSERT(!(jsuword(l) & GC_CHUNK_MASK)); - return k == l; - } -}; - -typedef HashSet GCChunkSet; - -struct ConservativeGCThreadData { - - /* - * The GC scans conservatively between JSThreadData::nativeStackBase and - * nativeStackTop unless the latter is NULL. - */ - jsuword *nativeStackTop; - - union { - jmp_buf jmpbuf; - jsuword words[JS_HOWMANY(sizeof(jmp_buf), sizeof(jsuword))]; - } registerSnapshot; - - /* - * Cycle collector uses this to communicate that the native stack of the - * GC thread should be scanned only if the thread have more than the given - * threshold of requests. - */ - unsigned requestThreshold; - - JS_NEVER_INLINE void recordStackTop(); - -#ifdef JS_THREADSAFE - void updateForRequestEnd(unsigned suspendCount) { - if (suspendCount) - recordStackTop(); - else - nativeStackTop = NULL; - } -#endif - - bool hasStackToScan() const { - return !!nativeStackTop; - } -}; - -struct GCMarker : public JSTracer { - private: - /* The color is only applied to objects, functions and xml. */ - uint32 color; - public: - jsuword stackLimit; - /* See comments before delayMarkingChildren is jsgc.cpp. */ - js::gc::Arena *unmarkedArenaStackTop; -#ifdef DEBUG - size_t markLaterCount; -#endif - -#if defined(JS_DUMP_CONSERVATIVE_GC_ROOTS) || defined(JS_GCMETER) - js::gc::ConservativeGCStats conservativeStats; -#endif - -#ifdef JS_DUMP_CONSERVATIVE_GC_ROOTS - struct ConservativeRoot { void *thing; uint32 thingKind; }; - Vector conservativeRoots; - const char *conservativeDumpFileName; - - void dumpConservativeRoots(); -#endif - - public: - explicit GCMarker(JSContext *cx); - ~GCMarker(); - - uint32 getMarkColor() const { - return color; - } - - void setMarkColor(uint32 newColor) { - /* - * We must process any delayed marking here, otherwise we confuse - * colors. - */ - markDelayedChildren(); - color = newColor; - } - - void delayMarkingChildren(void *thing); - - JS_FRIEND_API(void) markDelayedChildren(); -}; - -void -MarkStackRangeConservatively(JSTracer *trc, Value *begin, Value *end); - -} /* namespace js */ - -extern void -js_FinalizeStringRT(JSRuntime *rt, JSString *str); - -/* - * This function is defined in jsdbgapi.cpp but is declared here to avoid - * polluting jsdbgapi.h, a public API header, with internal functions. - */ -extern void -js_MarkTraps(JSTracer *trc); - -namespace js { -namespace gc { - -/* - * Macro to test if a traversal is the marking phase of GC to avoid exposing - * ScriptFilenameEntry to traversal implementations. - */ -#define IS_GC_MARKING_TRACER(trc) ((trc)->callback == NULL) - -#if JS_HAS_XML_SUPPORT -# define JS_IS_VALID_TRACE_KIND(kind) ((uint32)(kind) < JSTRACE_LIMIT) -#else -# define JS_IS_VALID_TRACE_KIND(kind) ((uint32)(kind) <= JSTRACE_STRING) -#endif - -/* - * Set object's prototype while checking that doing so would not create - * a cycle in the proto chain. The cycle check and proto change are done - * only when all other requests are finished or suspended to ensure exclusive - * access to the chain. If there is a cycle, return false without reporting - * an error. Otherwise, set the proto and return true. - */ -extern bool -SetProtoCheckingForCycles(JSContext *cx, JSObject *obj, JSObject *proto); - -JSCompartment * -NewCompartment(JSContext *cx, JSPrincipals *principals); - -} /* namespace js */ -} /* namespace gc */ - -inline JSCompartment * -JSObject::getCompartment() const -{ - return compartment(); -} - -#ifdef JS_GC_UNDEFD_MOZALLOC_WRAPPERS -# include "mozilla/mozalloc_macro_wrappers.h" -#endif - -#endif /* jsgc_h___ */ diff --git a/x86/mozilla/include/jsgcchunk.h b/x86/mozilla/include/jsgcchunk.h deleted file mode 100644 index c4fb923..0000000 --- a/x86/mozilla/include/jsgcchunk.h +++ /dev/null @@ -1,97 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=4 sw=4 et tw=99 ft=cpp: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla SpiderMonkey JavaScript 1.9.1 code, released - * June 30, 2009. - * - * The Initial Developer of the Original Code is - * The Mozilla Foundation - * - * Contributor(s): - * Igor Bukanov - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsgchunk_h__ -#define jsgchunk_h__ - -#include "jsprvtd.h" -#include "jsutil.h" - -namespace js { - -#if defined(WINCE) && !defined(MOZ_MEMORY_WINCE6) -const size_t GC_CHUNK_SHIFT = 21; -#else -const size_t GC_CHUNK_SHIFT = 20; -#endif - -const size_t GC_CHUNK_SIZE = size_t(1) << GC_CHUNK_SHIFT; -const size_t GC_CHUNK_MASK = GC_CHUNK_SIZE - 1; - -JS_FRIEND_API(void *) -AllocGCChunk(); - -JS_FRIEND_API(void) -FreeGCChunk(void *p); - -class GCChunkAllocator { - public: - GCChunkAllocator() {} - - void *alloc() { - void *chunk = doAlloc(); - JS_ASSERT(!(reinterpret_cast(chunk) & GC_CHUNK_MASK)); - return chunk; - } - - void free(void *chunk) { - JS_ASSERT(chunk); - JS_ASSERT(!(reinterpret_cast(chunk) & GC_CHUNK_MASK)); - doFree(chunk); - } - - private: - virtual void *doAlloc() { - return AllocGCChunk(); - } - - virtual void doFree(void *chunk) { - FreeGCChunk(chunk); - } - - /* No copy or assignment semantics. */ - GCChunkAllocator(const GCChunkAllocator &); - void operator=(const GCChunkAllocator &); -}; - -extern GCChunkAllocator defaultGCChunkAllocator; - -} - -#endif /* jsgchunk_h__ */ diff --git a/x86/mozilla/include/jsgcstats.h b/x86/mozilla/include/jsgcstats.h deleted file mode 100644 index 8f3b623..0000000 --- a/x86/mozilla/include/jsgcstats.h +++ /dev/null @@ -1,180 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=4 sw=4 et tw=99 ft=cpp: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released - * June 30, 2010 - * - * The Initial Developer of the Original Code is - * the Mozilla Corporation. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsgcstats_h___ -#define jsgcstats_h___ - -#if !defined JS_DUMP_CONSERVATIVE_GC_ROOTS && defined DEBUG -# define JS_DUMP_CONSERVATIVE_GC_ROOTS 1 -#endif - -/* Define JS_GCMETER here if wanted */ -#if defined JS_GCMETER -const bool JS_WANT_GC_METER_PRINT = true; -const bool JS_WANT_GC_PER_COMPARTMENT_PRINT = true; -const bool JS_WANT_CONSERVATIVE_GC_PRINT = true; -#elif defined DEBUG -# define JS_GCMETER 1 -const bool JS_WANT_GC_METER_PRINT = false; -const bool JS_WANT_GC_PER_COMPARTMENT_PRINT = false; -const bool JS_WANT_CONSERVATIVE_GC_PRINT = false; -#endif - -namespace js { -namespace gc { -/* - * The conservative GC test for a word shows that it is either a valid GC - * thing or is not for one of the following reasons. - */ -enum ConservativeGCTest { - CGCT_VALID, - CGCT_VALIDWITHOFFSET, /* points within an object */ - CGCT_LOWBITSET, /* excluded because one of the low bits was set */ - CGCT_NOTARENA, /* not within arena range in a chunk */ - CGCT_NOTCHUNK, /* not within a valid chunk */ - CGCT_FREEARENA, /* within arena containing only free things */ - CGCT_WRONGTAG, /* tagged pointer but wrong type */ - CGCT_NOTLIVE, /* gcthing is not allocated */ - CGCT_END -}; - -struct ConservativeGCStats { - uint32 counter[gc::CGCT_END]; /* ConservativeGCTest classification - counters */ - - void add(const ConservativeGCStats &another) { - for (size_t i = 0; i != JS_ARRAY_LENGTH(counter); ++i) - counter[i] += another.counter[i]; - } - - void dump(FILE *fp); -}; - -#ifdef JS_GCMETER -struct JSGCArenaStats { - uint32 alloc; /* allocation attempts */ - uint32 localalloc; /* allocations from local lists */ - uint32 nthings; /* live GC things */ - uint32 maxthings; /* maximum of live GC cells */ - double totalthings; /* live GC things the GC scanned so far */ - uint32 narenas; /* number of arena in list before the GC */ - uint32 newarenas; /* new arenas allocated before the last GC */ - uint32 livearenas; /* number of live arenas after the last GC */ - uint32 maxarenas; /* maximum of allocated arenas */ - uint32 totalarenas; /* total number of arenas with live things that - GC scanned so far */ -}; -#endif - -#ifdef JS_GCMETER - -struct JSGCStats { - uint32 lock; /* valid lock calls */ - uint32 unlock; /* valid unlock calls */ - uint32 unmarked; /* number of times marking of GC thing's children were - delayed due to a low C stack */ - uint32 lastditch; /* number of times the last ditch GC run */ - uint32 fail; /* allocation failures */ -#ifdef DEBUG - uint32 maxunmarked;/* maximum number of things with children to mark - later */ -#endif - uint32 poke; /* number of potentially useful GC calls */ - uint32 afree; /* thing arenas freed so far */ - uint32 nallarenas; /* number of all allocated arenas */ - uint32 maxnallarenas; /* maximum number of all allocated arenas */ - uint32 nchunks; /* number of allocated chunks */ - uint32 maxnchunks; /* maximum number of allocated chunks */ - - ConservativeGCStats conservative; -}; - -extern void -UpdateCompartmentStats(JSCompartment *comp, unsigned thingKind, uint32 nlivearenas, - uint32 nkilledArenas, uint32 nthings); -#endif /* JS_GCMETER */ - -#if defined JS_DUMP_CONSERVATIVE_GC_ROOTS -void *GetAlignedThing(void *thing, int thingKind); -#endif - -} //gc - -#ifdef MOZ_GCTIMER - -const bool JS_WANT_GC_SUITE_PRINT = false; //false for gnuplot output - -extern jsrefcount newChunkCount; -extern jsrefcount destroyChunkCount; - -struct GCTimer { - uint64 enter; - uint64 startMark; - uint64 startSweep; - uint64 sweepObjectEnd; - uint64 sweepStringEnd; - uint64 sweepShapeEnd; - uint64 sweepDestroyEnd; - uint64 end; - - GCTimer(); - - uint64 getFirstEnter(); - - void finish(bool lastGC); -}; - -# define GCTIMER_PARAM , GCTimer &gcTimer -# define GCTIMER_ARG , gcTimer -# define TIMESTAMP(x) (gcTimer.x = rdtsc()) -# define GCTIMER_BEGIN() GCTimer gcTimer -# define GCTIMER_END(last) (gcTimer.finish(last)) -#else -# define GCTIMER_PARAM -# define GCTIMER_ARG -# define TIMESTAMP(x) ((void) 0) -# define GCTIMER_BEGIN() ((void) 0) -# define GCTIMER_END(last) ((void) 0) -#endif - -} //js - -extern JS_FRIEND_API(void) -js_DumpGCStats(JSRuntime *rt, FILE *fp); - -#endif /* jsgcstats_h__ */ diff --git a/x86/mozilla/include/jshash.h b/x86/mozilla/include/jshash.h deleted file mode 100644 index a365a51..0000000 --- a/x86/mozilla/include/jshash.h +++ /dev/null @@ -1,153 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jshash_h___ -#define jshash_h___ -/* - * API to portable hash table code. - */ -#include -#include -#include "jstypes.h" -#include "jscompat.h" - -JS_BEGIN_EXTERN_C - -typedef uint32 JSHashNumber; -typedef struct JSHashEntry JSHashEntry; -typedef struct JSHashTable JSHashTable; - -#define JS_HASH_BITS 32 -#define JS_GOLDEN_RATIO 0x9E3779B9U - -typedef JSHashNumber (* JSHashFunction)(const void *key); -typedef intN (* JSHashComparator)(const void *v1, const void *v2); -typedef intN (* JSHashEnumerator)(JSHashEntry *he, intN i, void *arg); - -/* Flag bits in JSHashEnumerator's return value */ -#define HT_ENUMERATE_NEXT 0 /* continue enumerating entries */ -#define HT_ENUMERATE_STOP 1 /* stop enumerating entries */ -#define HT_ENUMERATE_REMOVE 2 /* remove and free the current entry */ - -typedef struct JSHashAllocOps { - void * (*allocTable)(void *pool, size_t size); - void (*freeTable)(void *pool, void *item, size_t size); - JSHashEntry * (*allocEntry)(void *pool, const void *key); - void (*freeEntry)(void *pool, JSHashEntry *he, uintN flag); -} JSHashAllocOps; - -#define HT_FREE_VALUE 0 /* just free the entry's value */ -#define HT_FREE_ENTRY 1 /* free value and entire entry */ - -struct JSHashEntry { - JSHashEntry *next; /* hash chain linkage */ - JSHashNumber keyHash; /* key hash function result */ - const void *key; /* ptr to opaque key */ - void *value; /* ptr to opaque value */ -}; - -struct JSHashTable { - JSHashEntry **buckets; /* vector of hash buckets */ - uint32 nentries; /* number of entries in table */ - uint32 shift; /* multiplicative hash shift */ - JSHashFunction keyHash; /* key hash function */ - JSHashComparator keyCompare; /* key comparison function */ - JSHashComparator valueCompare; /* value comparison function */ - JSHashAllocOps *allocOps; /* allocation operations */ - void *allocPriv; /* allocation private data */ -#ifdef JS_HASHMETER - uint32 nlookups; /* total number of lookups */ - uint32 nsteps; /* number of hash chains traversed */ - uint32 ngrows; /* number of table expansions */ - uint32 nshrinks; /* number of table contractions */ -#endif -}; - -/* - * Create a new hash table. - * If allocOps is null, use default allocator ops built on top of malloc(). - */ -extern JS_PUBLIC_API(JSHashTable *) -JS_NewHashTable(uint32 n, JSHashFunction keyHash, - JSHashComparator keyCompare, JSHashComparator valueCompare, - JSHashAllocOps *allocOps, void *allocPriv); - -extern JS_PUBLIC_API(void) -JS_HashTableDestroy(JSHashTable *ht); - -/* Low level access methods */ -extern JS_PUBLIC_API(JSHashEntry **) -JS_HashTableRawLookup(JSHashTable *ht, JSHashNumber keyHash, const void *key); - -#ifdef __cplusplus -extern JS_PUBLIC_API(JSHashEntry *) -JS_HashTableRawAdd(JSHashTable *ht, JSHashEntry **&hep, JSHashNumber keyHash, - const void *key, void *value); -#endif - -extern JS_PUBLIC_API(void) -JS_HashTableRawRemove(JSHashTable *ht, JSHashEntry **hep, JSHashEntry *he); - -/* Higher level access methods */ -extern JS_PUBLIC_API(JSHashEntry *) -JS_HashTableAdd(JSHashTable *ht, const void *key, void *value); - -extern JS_PUBLIC_API(JSBool) -JS_HashTableRemove(JSHashTable *ht, const void *key); - -extern JS_PUBLIC_API(intN) -JS_HashTableEnumerateEntries(JSHashTable *ht, JSHashEnumerator f, void *arg); - -extern JS_PUBLIC_API(void *) -JS_HashTableLookup(JSHashTable *ht, const void *key); - -extern JS_PUBLIC_API(intN) -JS_HashTableDump(JSHashTable *ht, JSHashEnumerator dump, FILE *fp); - -/* General-purpose C string hash function. */ -extern JS_PUBLIC_API(JSHashNumber) -JS_HashString(const void *key); - -/* Stub function just returns v1 == v2 */ -extern JS_PUBLIC_API(intN) -JS_CompareValues(const void *v1, const void *v2); - -JS_END_EXTERN_C - -#endif /* jshash_h___ */ diff --git a/x86/mozilla/include/jshashtable.h b/x86/mozilla/include/jshashtable.h deleted file mode 100644 index c0969d0..0000000 --- a/x86/mozilla/include/jshashtable.h +++ /dev/null @@ -1,1124 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99 ft=cpp: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released - * November 13, 2009. - * - * The Initial Developer of the Original Code is - * the Mozilla Corporation. - * - * Contributor(s): - * Brendan Eich (Original Author) - * Chris Waterson - * L. David Baron , Mozilla Corporation - * Luke Wagner - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jshashtable_h_ -#define jshashtable_h_ - -#include "jstl.h" - -namespace js { - -/* Integral types for all hash functions. */ -typedef uint32 HashNumber; - -namespace detail { - -/* Reusable implementation of HashMap and HashSet. */ -template -class HashTable : AllocPolicy -{ - typedef typename tl::StripConst::result NonConstT; - typedef typename HashPolicy::KeyType Key; - typedef typename HashPolicy::Lookup Lookup; - - /* - * T::operator= is a private operation for HashMap::Entry. HashMap::Entry - * makes HashTable a friend, but MSVC does not allow HashMap::Entry to make - * HashTable::Entry a friend. So do assignment here: - */ - static void assignT(NonConstT &dst, const T &src) { dst = src; } - - public: - class Entry { - HashNumber keyHash; - - public: - Entry() : keyHash(0), t() {} - void operator=(const Entry &rhs) { keyHash = rhs.keyHash; assignT(t, rhs.t); } - - NonConstT t; - - bool isFree() const { return keyHash == sFreeKey; } - void setFree() { keyHash = sFreeKey; assignT(t, T()); } - bool isRemoved() const { return keyHash == sRemovedKey; } - void setRemoved() { keyHash = sRemovedKey; assignT(t, T()); } - bool isLive() const { return isLiveHash(keyHash); } - void setLive(HashNumber hn) { JS_ASSERT(isLiveHash(hn)); keyHash = hn; } - - void setCollision() { JS_ASSERT(isLive()); keyHash |= sCollisionBit; } - void setCollision(HashNumber collisionBit) { - JS_ASSERT(isLive()); keyHash |= collisionBit; - } - void unsetCollision() { JS_ASSERT(isLive()); keyHash &= ~sCollisionBit; } - bool hasCollision() const { JS_ASSERT(isLive()); return keyHash & sCollisionBit; } - bool matchHash(HashNumber hn) { return (keyHash & ~sCollisionBit) == hn; } - HashNumber getKeyHash() const { JS_ASSERT(!hasCollision()); return keyHash; } - }; - - /* - * A nullable pointer to a hash table element. A Ptr |p| can be tested - * either explicitly |if (p.found()) p->...| or using boolean conversion - * |if (p) p->...|. Ptr objects must not be used after any mutating hash - * table operations unless |generation()| is tested. - */ - class Ptr - { - friend class HashTable; - typedef void (Ptr::* ConvertibleToBool)(); - void nonNull() {} - - Entry *entry; - - protected: - Ptr(Entry &entry) : entry(&entry) {} - - public: - bool found() const { return entry->isLive(); } - operator ConvertibleToBool() const { return found() ? &Ptr::nonNull : 0; } - bool operator==(const Ptr &rhs) const { JS_ASSERT(found() && rhs.found()); return entry == rhs.entry; } - bool operator!=(const Ptr &rhs) const { return !(*this == rhs); } - - T &operator*() const { return entry->t; } - T *operator->() const { return &entry->t; } - }; - - /* A Ptr that can be used to add a key after a failed lookup. */ - class AddPtr : public Ptr - { - friend class HashTable; - HashNumber keyHash; -#ifdef DEBUG - uint64 mutationCount; - - AddPtr(Entry &entry, HashNumber hn, uint64 mutationCount) - : Ptr(entry), keyHash(hn), mutationCount(mutationCount) {} -#else - AddPtr(Entry &entry, HashNumber hn) : Ptr(entry), keyHash(hn) {} -#endif - }; - - /* - * A collection of hash table entries. The collection is enumerated by - * calling |front()| followed by |popFront()| as long as |!empty()|. As - * with Ptr/AddPtr, Range objects must not be used after any mutating hash - * table operation unless the |generation()| is tested. - */ - class Range - { - protected: - friend class HashTable; - - Range(Entry *c, Entry *e) : cur(c), end(e) { - while (cur != end && !cur->isLive()) - ++cur; - } - - Entry *cur, *end; - - public: - bool empty() const { - return cur == end; - } - - T &front() const { - JS_ASSERT(!empty()); - return cur->t; - } - - void popFront() { - JS_ASSERT(!empty()); - while (++cur != end && !cur->isLive()); - } - }; - - /* - * A Range whose lifetime delimits a mutating enumeration of a hash table. - * Since rehashing when elements were removed during enumeration would be - * bad, it is postponed until |endEnumeration()| is called. If - * |endEnumeration()| is not called before an Enum's constructor, it will - * be called automatically. Since |endEnumeration()| touches the hash - * table, the user must ensure that the hash table is still alive when this - * happens. - */ - class Enum : public Range - { - friend class HashTable; - - HashTable &table; - bool removed; - - /* Not copyable. */ - Enum(const Enum &); - void operator=(const Enum &); - - public: - template explicit - Enum(Map &map) : Range(map.all()), table(map.impl), removed(false) {} - - /* - * Removes the |front()| element from the table, leaving |front()| - * invalid until the next call to |popFront()|. For example: - * - * HashSet s; - * for (HashSet::Enum e(s); !e.empty(); e.popFront()) - * if (e.front() == 42) - * e.removeFront(); - */ - void removeFront() { - table.remove(*this->cur); - removed = true; - } - - /* Potentially rehashes the table. */ - ~Enum() { - if (removed) - table.checkUnderloaded(); - } - - /* Can be used to end the enumeration before the destructor. */ - void endEnumeration() { - if (removed) { - table.checkUnderloaded(); - removed = false; - } - } - }; - - private: - uint32 hashShift; /* multiplicative hash shift */ - uint32 tableCapacity; /* = JS_BIT(sHashBits - hashShift) */ - uint32 entryCount; /* number of entries in table */ - uint32 gen; /* entry storage generation number */ - uint32 removedCount; /* removed entry sentinels in table */ - Entry *table; /* entry storage */ - - void setTableSizeLog2(unsigned sizeLog2) { - hashShift = sHashBits - sizeLog2; - tableCapacity = JS_BIT(sizeLog2); - } - -#ifdef DEBUG - mutable struct Stats { - uint32 searches; /* total number of table searches */ - uint32 steps; /* hash chain links traversed */ - uint32 hits; /* searches that found key */ - uint32 misses; /* searches that didn't find key */ - uint32 addOverRemoved; /* adds that recycled a removed entry */ - uint32 removes; /* calls to remove */ - uint32 removeFrees; /* calls to remove that freed the entry */ - uint32 grows; /* table expansions */ - uint32 shrinks; /* table contractions */ - uint32 compresses; /* table compressions */ - } stats; -# define METER(x) x -#else -# define METER(x) -#endif - -#ifdef DEBUG - friend class js::ReentrancyGuard; - mutable bool entered; - uint64 mutationCount; -#endif - - static const unsigned sMinSizeLog2 = 4; - static const unsigned sMinSize = 1 << sMinSizeLog2; - static const unsigned sSizeLimit = JS_BIT(24); - static const unsigned sHashBits = tl::BitSize::result; - static const uint8 sMinAlphaFrac = 64; /* (0x100 * .25) taken from jsdhash.h */ - static const uint8 sMaxAlphaFrac = 192; /* (0x100 * .75) taken from jsdhash.h */ - static const uint8 sInvMaxAlpha = 171; /* (ceil(0x100 / .75) >> 1) */ - static const HashNumber sGoldenRatio = 0x9E3779B9U; /* taken from jsdhash.h */ - static const HashNumber sCollisionBit = 1; - static const HashNumber sFreeKey = 0; - static const HashNumber sRemovedKey = 1; - - static bool isLiveHash(HashNumber hash) - { - return hash > sRemovedKey; - } - - static HashNumber prepareHash(const Lookup& l) - { - HashNumber keyHash = HashPolicy::hash(l); - - /* Improve keyHash distribution. */ - keyHash *= sGoldenRatio; - - /* Avoid reserved hash codes. */ - if (!isLiveHash(keyHash)) - keyHash -= (sRemovedKey + 1); - return keyHash & ~sCollisionBit; - } - - static Entry *createTable(AllocPolicy &alloc, uint32 capacity) - { - Entry *newTable = (Entry *)alloc.malloc(capacity * sizeof(Entry)); - if (!newTable) - return NULL; - for (Entry *e = newTable, *end = e + capacity; e != end; ++e) - new(e) Entry(); - return newTable; - } - - static void destroyTable(AllocPolicy &alloc, Entry *oldTable, uint32 capacity) - { - for (Entry *e = oldTable, *end = e + capacity; e != end; ++e) - e->~Entry(); - alloc.free(oldTable); - } - - public: - HashTable(AllocPolicy ap) - : AllocPolicy(ap), - entryCount(0), - gen(0), - removedCount(0), - table(NULL) -#ifdef DEBUG - , entered(false), - mutationCount(0) -#endif - {} - - bool init(uint32 length) - { - /* Make sure that init isn't called twice. */ - JS_ASSERT(table == NULL); - - /* - * Correct for sMaxAlphaFrac such that the table will not resize - * when adding 'length' entries. - */ - JS_ASSERT(length < (uint32(1) << 23)); - uint32 capacity = (length * sInvMaxAlpha) >> 7; - - if (capacity < sMinSize) - capacity = sMinSize; - - /* FIXME: use JS_CEILING_LOG2 when PGO stops crashing (bug 543034). */ - uint32 roundUp = sMinSize, roundUpLog2 = sMinSizeLog2; - while (roundUp < capacity) { - roundUp <<= 1; - ++roundUpLog2; - } - - capacity = roundUp; - if (capacity >= sSizeLimit) { - this->reportAllocOverflow(); - return false; - } - - table = createTable(*this, capacity); - if (!table) - return false; - - setTableSizeLog2(roundUpLog2); - METER(memset(&stats, 0, sizeof(stats))); - return true; - } - - bool initialized() const - { - return !!table; - } - - ~HashTable() - { - if (table) - destroyTable(*this, table, tableCapacity); - } - - private: - static HashNumber hash1(HashNumber hash0, uint32 shift) { - return hash0 >> shift; - } - - static HashNumber hash2(HashNumber hash0, uint32 log2, uint32 shift) { - return ((hash0 << log2) >> shift) | 1; - } - - bool overloaded() { - return entryCount + removedCount >= ((sMaxAlphaFrac * tableCapacity) >> 8); - } - - bool underloaded() { - return tableCapacity > sMinSize && - entryCount <= ((sMinAlphaFrac * tableCapacity) >> 8); - } - - static bool match(Entry &e, const Lookup &l) { - return HashPolicy::match(HashPolicy::getKey(e.t), l); - } - - Entry &lookup(const Lookup &l, HashNumber keyHash, unsigned collisionBit) const - { - JS_ASSERT(isLiveHash(keyHash)); - JS_ASSERT(!(keyHash & sCollisionBit)); - JS_ASSERT(collisionBit == 0 || collisionBit == sCollisionBit); - JS_ASSERT(table); - METER(stats.searches++); - - /* Compute the primary hash address. */ - HashNumber h1 = hash1(keyHash, hashShift); - Entry *entry = &table[h1]; - - /* Miss: return space for a new entry. */ - if (entry->isFree()) { - METER(stats.misses++); - return *entry; - } - - /* Hit: return entry. */ - if (entry->matchHash(keyHash) && match(*entry, l)) { - METER(stats.hits++); - return *entry; - } - - /* Collision: double hash. */ - unsigned sizeLog2 = sHashBits - hashShift; - HashNumber h2 = hash2(keyHash, sizeLog2, hashShift); - HashNumber sizeMask = (HashNumber(1) << sizeLog2) - 1; - - /* Save the first removed entry pointer so we can recycle later. */ - Entry *firstRemoved = NULL; - - while(true) { - if (JS_UNLIKELY(entry->isRemoved())) { - if (!firstRemoved) - firstRemoved = entry; - } else { - entry->setCollision(collisionBit); - } - - METER(stats.steps++); - h1 -= h2; - h1 &= sizeMask; - - entry = &table[h1]; - if (entry->isFree()) { - METER(stats.misses++); - return firstRemoved ? *firstRemoved : *entry; - } - - if (entry->matchHash(keyHash) && match(*entry, l)) { - METER(stats.hits++); - return *entry; - } - } - } - - /* - * This is a copy of lookup hardcoded to the assumptions: - * 1. the lookup is a lookupForAdd - * 2. the key, whose |keyHash| has been passed is not in the table, - * 3. no entries have been removed from the table. - * This specialized search avoids the need for recovering lookup values - * from entries, which allows more flexible Lookup/Key types. - */ - Entry &findFreeEntry(HashNumber keyHash) - { - METER(stats.searches++); - JS_ASSERT(!(keyHash & sCollisionBit)); - - /* N.B. the |keyHash| has already been distributed. */ - - /* Compute the primary hash address. */ - HashNumber h1 = hash1(keyHash, hashShift); - Entry *entry = &table[h1]; - - /* Miss: return space for a new entry. */ - if (entry->isFree()) { - METER(stats.misses++); - return *entry; - } - - /* Collision: double hash. */ - unsigned sizeLog2 = sHashBits - hashShift; - HashNumber h2 = hash2(keyHash, sizeLog2, hashShift); - HashNumber sizeMask = (HashNumber(1) << sizeLog2) - 1; - - while(true) { - JS_ASSERT(!entry->isRemoved()); - entry->setCollision(); - - METER(stats.steps++); - h1 -= h2; - h1 &= sizeMask; - - entry = &table[h1]; - if (entry->isFree()) { - METER(stats.misses++); - return *entry; - } - } - } - - bool changeTableSize(int deltaLog2) - { - /* Look, but don't touch, until we succeed in getting new entry store. */ - Entry *oldTable = table; - uint32 oldCap = tableCapacity; - uint32 newLog2 = sHashBits - hashShift + deltaLog2; - uint32 newCapacity = JS_BIT(newLog2); - if (newCapacity >= sSizeLimit) { - this->reportAllocOverflow(); - return false; - } - - Entry *newTable = createTable(*this, newCapacity); - if (!newTable) - return false; - - /* We can't fail from here on, so update table parameters. */ - setTableSizeLog2(newLog2); - removedCount = 0; - gen++; - table = newTable; - - /* Copy only live entries, leaving removed ones behind. */ - for (Entry *src = oldTable, *end = src + oldCap; src != end; ++src) { - if (src->isLive()) { - src->unsetCollision(); - findFreeEntry(src->getKeyHash()) = *src; - } - } - - destroyTable(*this, oldTable, oldCap); - return true; - } - - void remove(Entry &e) - { - METER(stats.removes++); - if (e.hasCollision()) { - e.setRemoved(); - removedCount++; - } else { - METER(stats.removeFrees++); - e.setFree(); - } - entryCount--; -#ifdef DEBUG - mutationCount++; -#endif - } - - void checkUnderloaded() - { - if (underloaded()) { - METER(stats.shrinks++); - (void) changeTableSize(-1); - } - } - - public: - void clear() - { - for (Entry *e = table, *end = table + tableCapacity; e != end; ++e) - *e = Entry(); - removedCount = 0; - entryCount = 0; -#ifdef DEBUG - mutationCount++; -#endif - } - - Range all() const { - return Range(table, table + tableCapacity); - } - - bool empty() const { - return !entryCount; - } - - uint32 count() const{ - return entryCount; - } - - uint32 generation() const { - return gen; - } - - Ptr lookup(const Lookup &l) const { - ReentrancyGuard g(*this); - HashNumber keyHash = prepareHash(l); - return Ptr(lookup(l, keyHash, 0)); - } - - AddPtr lookupForAdd(const Lookup &l) const { - ReentrancyGuard g(*this); - HashNumber keyHash = prepareHash(l); - Entry &entry = lookup(l, keyHash, sCollisionBit); -#ifdef DEBUG - return AddPtr(entry, keyHash, mutationCount); -#else - return AddPtr(entry, keyHash); -#endif - } - - bool add(AddPtr &p) - { - ReentrancyGuard g(*this); - JS_ASSERT(mutationCount == p.mutationCount); - JS_ASSERT(table); - JS_ASSERT(!p.found()); - JS_ASSERT(!(p.keyHash & sCollisionBit)); - - /* - * Changing an entry from removed to live does not affect whether we - * are overloaded and can be handled separately. - */ - if (p.entry->isRemoved()) { - METER(stats.addOverRemoved++); - removedCount--; - p.keyHash |= sCollisionBit; - } else { - /* If alpha is >= .75, grow or compress the table. */ - if (overloaded()) { - /* Compress if a quarter or more of all entries are removed. */ - int deltaLog2; - if (removedCount >= (tableCapacity >> 2)) { - METER(stats.compresses++); - deltaLog2 = 0; - } else { - METER(stats.grows++); - deltaLog2 = 1; - } - - if (!changeTableSize(deltaLog2)) - return false; - - /* Preserve the validity of |p.entry|. */ - p.entry = &findFreeEntry(p.keyHash); - } - } - - p.entry->setLive(p.keyHash); - entryCount++; -#ifdef DEBUG - mutationCount++; -#endif - return true; - } - - /* - * There is an important contract between the caller and callee for this - * function: if add() returns true, the caller must assign the T value - * which produced p before using the hashtable again. - */ - bool add(AddPtr &p, T** pentry) - { - if (!add(p)) - return false; - *pentry = &p.entry->t; - return true; - } - - bool add(AddPtr &p, const T &t) - { - if (!add(p)) - return false; - p.entry->t = t; - return true; - } - - bool relookupOrAdd(AddPtr& p, const Lookup &l, const T& t) - { -#ifdef DEBUG - p.mutationCount = mutationCount; -#endif - { - ReentrancyGuard g(*this); - p.entry = &lookup(l, p.keyHash, sCollisionBit); - } - return p.found() || add(p, t); - } - - void remove(Ptr p) - { - ReentrancyGuard g(*this); - JS_ASSERT(p.found()); - remove(*p.entry); - checkUnderloaded(); - } -#undef METER -}; - -} - -/* - * Hash policy - * - * A hash policy P for a hash table with key-type Key must provide: - * - a type |P::Lookup| to use to lookup table entries; - * - a static member function |P::hash| with signature - * - * static js::HashNumber hash(Lookup) - * - * to use to hash the lookup type; and - * - a static member function |P::match| with signature - * - * static bool match(Key, Lookup) - * - * to use to test equality of key and lookup values. - * - * Normally, Lookup = Key. In general, though, different values and types of - * values can be used to lookup and store. If a Lookup value |l| is != to the - * added Key value |k|, the user must ensure that |P::match(k,l)|. E.g.: - * - * js::HashSet::AddPtr p = h.lookup(l); - * if (!p) { - * assert(P::match(k, l)); // must hold - * h.add(p, k); - * } - */ - -/* Default hashing policies. */ -template -struct DefaultHasher -{ - typedef Key Lookup; - static HashNumber hash(const Lookup &l) { - /* Hash if can implicitly cast to hash number type. */ - return l; - } - static bool match(const Key &k, const Lookup &l) { - /* Use builtin or overloaded operator==. */ - return k == l; - } -}; - -/* Specialized hashing policy for pointer types. */ -template -struct DefaultHasher -{ - typedef T *Lookup; - static HashNumber hash(T *l) { - /* - * Strip often-0 lower bits for better distribution after multiplying - * by the sGoldenRatio. - */ - return HashNumber(reinterpret_cast(l) >> - tl::FloorLog2::result); - } - static bool match(T *k, T *l) { - return k == l; - } -}; - -/* - * JS-friendly, STL-like container providing a hash-based map from keys to - * values. In particular, HashMap calls constructors and destructors of all - * objects added so non-PODs may be used safely. - * - * Key/Value requirements: - * - default constructible, copyable, destructible, assignable - * HashPolicy requirements: - * - see "Hash policy" above (default js::DefaultHasher) - * AllocPolicy: - * - see "Allocation policies" in jstl.h (default js::ContextAllocPolicy) - * - * N.B: HashMap is not reentrant: Key/Value/HashPolicy/AllocPolicy members - * called by HashMap must not call back into the same HashMap object. - * N.B: Due to the lack of exception handling, the user must call |init()|. - */ -template -class HashMap -{ - public: - typedef typename HashPolicy::Lookup Lookup; - - class Entry - { - template friend class detail::HashTable; - void operator=(const Entry &rhs) { - const_cast(key) = rhs.key; - value = rhs.value; - } - - public: - Entry() : key(), value() {} - Entry(const Key &k, const Value &v) : key(k), value(v) {} - - const Key key; - Value value; - }; - - private: - /* Implement HashMap using HashTable. Lift |Key| operations to |Entry|. */ - struct MapHashPolicy : HashPolicy - { - typedef Key KeyType; - static const Key &getKey(Entry &e) { return e.key; } - }; - typedef detail::HashTable Impl; - - friend class Impl::Enum; - - /* Not implicitly copyable (expensive). May add explicit |clone| later. */ - HashMap(const HashMap &); - HashMap &operator=(const HashMap &); - - Impl impl; - - public: - /* - * HashMap construction is fallible (due to OOM); thus the user must call - * init after constructing a HashMap and check the return value. - */ - HashMap(AllocPolicy a = AllocPolicy()) : impl(a) {} - bool init(uint32 len = 0) { return impl.init(len); } - bool initialized() const { return impl.initialized(); } - - /* - * Return whether the given lookup value is present in the map. E.g.: - * - * typedef HashMap HM; - * HM h; - * if (HM::Ptr p = h.lookup(3)) { - * const HM::Entry &e = *p; // p acts like a pointer to Entry - * assert(p->key == 3); // Entry contains the key - * char val = p->value; // and value - * } - * - * Also see the definition of Ptr in HashTable above (with T = Entry). - */ - typedef typename Impl::Ptr Ptr; - Ptr lookup(const Lookup &l) const { return impl.lookup(l); } - - /* Assuming |p.found()|, remove |*p|. */ - void remove(Ptr p) { impl.remove(p); } - - /* - * Like |lookup(l)|, but on miss, |p = lookupForAdd(l)| allows efficient - * insertion of Key |k| (where |HashPolicy::match(k,l) == true|) using - * |add(p,k,v)|. After |add(p,k,v)|, |p| points to the new Entry. E.g.: - * - * typedef HashMap HM; - * HM h; - * HM::AddPtr p = h.lookupForAdd(3); - * if (!p) { - * if (!h.add(p, 3, 'a')) - * return false; - * } - * const HM::Entry &e = *p; // p acts like a pointer to Entry - * assert(p->key == 3); // Entry contains the key - * char val = p->value; // and value - * - * Also see the definition of AddPtr in HashTable above (with T = Entry). - * - * N.B. The caller must ensure that no mutating hash table operations - * occur between a pair of |lookupForAdd| and |add| calls. To avoid - * looking up the key a second time, the caller may use the more efficient - * relookupOrAdd method. This method reuses part of the hashing computation - * to more efficiently insert the key if it has not been added. For - * example, a mutation-handling version of the previous example: - * - * HM::AddPtr p = h.lookupForAdd(3); - * if (!p) { - * call_that_may_mutate_h(); - * if (!h.relookupOrAdd(p, 3, 'a')) - * return false; - * } - * const HM::Entry &e = *p; - * assert(p->key == 3); - * char val = p->value; - */ - typedef typename Impl::AddPtr AddPtr; - AddPtr lookupForAdd(const Lookup &l) const { - return impl.lookupForAdd(l); - } - - bool add(AddPtr &p, const Key &k, const Value &v) { - Entry *pentry; - if (!impl.add(p, &pentry)) - return false; - const_cast(pentry->key) = k; - pentry->value = v; - return true; - } - - bool add(AddPtr &p, const Key &k) { - Entry *pentry; - if (!impl.add(p, &pentry)) - return false; - const_cast(pentry->key) = k; - return true; - } - - bool relookupOrAdd(AddPtr &p, const Key &k, const Value &v) { - return impl.relookupOrAdd(p, k, Entry(k, v)); - } - - /* - * |all()| returns a Range containing |count()| elements. E.g.: - * - * typedef HashMap HM; - * HM h; - * for (HM::Range r = h.all(); !r.empty(); r.popFront()) - * char c = r.front().value; - * - * Also see the definition of Range in HashTable above (with T = Entry). - */ - typedef typename Impl::Range Range; - Range all() const { return impl.all(); } - size_t count() const { return impl.count(); } - - /* - * Typedef for the enumeration class. An Enum may be used to examine and - * remove table entries: - * - * typedef HashMap HM; - * HM s; - * for (HM::Enum e(s); !e.empty(); e.popFront()) - * if (e.front().value == 'l') - * e.removeFront(); - * - * Table resize may occur in Enum's destructor. Also see the definition of - * Enum in HashTable above (with T = Entry). - */ - typedef typename Impl::Enum Enum; - - /* Remove all entries. */ - void clear() { impl.clear(); } - - /* Does the table contain any entries? */ - bool empty() const { return impl.empty(); } - - /* - * If |generation()| is the same before and after a HashMap operation, - * pointers into the table remain valid. - */ - unsigned generation() const { return impl.generation(); } - - /* Shorthand operations: */ - - bool has(const Lookup &l) const { - return impl.lookup(l) != NULL; - } - - Entry *put(const Key &k, const Value &v) { - AddPtr p = lookupForAdd(k); - if (p) { - p->value = v; - return &*p; - } - return add(p, k, v) ? &*p : NULL; - } - - void remove(const Lookup &l) { - if (Ptr p = lookup(l)) - remove(p); - } -}; - -/* - * JS-friendly, STL-like container providing a hash-based set of values. In - * particular, HashSet calls constructors and destructors of all objects added - * so non-PODs may be used safely. - * - * T requirements: - * - default constructible, copyable, destructible, assignable - * HashPolicy requirements: - * - see "Hash policy" above (default js::DefaultHasher) - * AllocPolicy: - * - see "Allocation policies" in jstl.h (default js::ContextAllocPolicy) - * - * N.B: HashSet is not reentrant: T/HashPolicy/AllocPolicy members called by - * HashSet must not call back into the same HashSet object. - * N.B: Due to the lack of exception handling, the user must call |init()|. - */ -template -class HashSet -{ - typedef typename HashPolicy::Lookup Lookup; - - /* Implement HashSet in terms of HashTable. */ - struct SetOps : HashPolicy { - typedef T KeyType; - static const KeyType &getKey(const T &t) { return t; } - }; - typedef detail::HashTable Impl; - - friend class Impl::Enum; - - /* Not implicitly copyable (expensive). May add explicit |clone| later. */ - HashSet(const HashSet &); - HashSet &operator=(const HashSet &); - - Impl impl; - - public: - /* - * HashSet construction is fallible (due to OOM); thus the user must call - * init after constructing a HashSet and check the return value. - */ - HashSet(AllocPolicy a = AllocPolicy()) : impl(a) {} - bool init(uint32 len = 0) { return impl.init(len); } - bool initialized() const { return impl.initialized(); } - - /* - * Return whether the given lookup value is present in the map. E.g.: - * - * typedef HashSet HS; - * HS h; - * if (HS::Ptr p = h.lookup(3)) { - * assert(*p == 3); // p acts like a pointer to int - * } - * - * Also see the definition of Ptr in HashTable above. - */ - typedef typename Impl::Ptr Ptr; - Ptr lookup(const Lookup &l) const { return impl.lookup(l); } - - /* Assuming |p.found()|, remove |*p|. */ - void remove(Ptr p) { impl.remove(p); } - - /* - * Like |lookup(l)|, but on miss, |p = lookupForAdd(l)| allows efficient - * insertion of T value |t| (where |HashPolicy::match(t,l) == true|) using - * |add(p,t)|. After |add(p,t)|, |p| points to the new element. E.g.: - * - * typedef HashSet HS; - * HS h; - * HS::AddPtr p = h.lookupForAdd(3); - * if (!p) { - * if (!h.add(p, 3)) - * return false; - * } - * assert(*p == 3); // p acts like a pointer to int - * - * Also see the definition of AddPtr in HashTable above. - * - * N.B. The caller must ensure that no mutating hash table operations - * occur between a pair of |lookupForAdd| and |add| calls. To avoid - * looking up the key a second time, the caller may use the more efficient - * relookupOrAdd method. This method reuses part of the hashing computation - * to more efficiently insert the key if it has not been added. For - * example, a mutation-handling version of the previous example: - * - * HS::AddPtr p = h.lookupForAdd(3); - * if (!p) { - * call_that_may_mutate_h(); - * if (!h.relookupOrAdd(p, 3, 3)) - * return false; - * } - * assert(*p == 3); - * - * Note that relookupOrAdd(p,l,t) performs Lookup using l and adds the - * entry t, where the caller ensures match(l,t). - */ - typedef typename Impl::AddPtr AddPtr; - AddPtr lookupForAdd(const Lookup &l) const { - return impl.lookupForAdd(l); - } - - bool add(AddPtr &p, const T &t) { - return impl.add(p, t); - } - - bool relookupOrAdd(AddPtr &p, const Lookup &l, const T &t) { - return impl.relookupOrAdd(p, l, t); - } - - /* - * |all()| returns a Range containing |count()| elements: - * - * typedef HashSet HS; - * HS h; - * for (HS::Range r = h.all(); !r.empty(); r.popFront()) - * int i = r.front(); - * - * Also see the definition of Range in HashTable above. - */ - typedef typename Impl::Range Range; - Range all() const { return impl.all(); } - size_t count() const { return impl.count(); } - - /* - * Typedef for the enumeration class. An Enum may be used to examine and - * remove table entries: - * - * typedef HashSet HS; - * HS s; - * for (HS::Enum e(s); !e.empty(); e.popFront()) - * if (e.front() == 42) - * e.removeFront(); - * - * Table resize may occur in Enum's destructor. Also see the definition of - * Enum in HashTable above. - */ - typedef typename Impl::Enum Enum; - - /* Remove all entries. */ - void clear() { impl.clear(); } - - /* Does the table contain any entries? */ - bool empty() const { return impl.empty(); } - - /* - * If |generation()| is the same before and after a HashSet operation, - * pointers into the table remain valid. - */ - unsigned generation() const { return impl.generation(); } - - /* Shorthand operations: */ - - bool has(const Lookup &l) const { - return impl.lookup(l) != NULL; - } - - const T *put(const T &t) { - AddPtr p = lookupForAdd(t); - return p ? &*p : (add(p, t) ? &*p : NULL); - } - - void remove(const Lookup &l) { - if (Ptr p = lookup(l)) - remove(p); - } -}; - -} /* namespace js */ - -#endif diff --git a/x86/mozilla/include/jshotloop.h b/x86/mozilla/include/jshotloop.h deleted file mode 100644 index a47ae76..0000000 --- a/x86/mozilla/include/jshotloop.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Mozilla SpiderMonkey JaegerMonkey implementation - * - * The Initial Developer of the Original Code is - * Mozilla Foundation - * Portions created by the Initial Developer are Copyright (C) 2002-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jshotloop_h___ -#define jshotloop_h___ - -#include "jscntxt.h" - -namespace js { - -uint32 -GetHotloop(JSContext *cx); - -} - -#endif diff --git a/x86/mozilla/include/jsinterp.h b/x86/mozilla/include/jsinterp.h deleted file mode 100644 index b2e490e..0000000 --- a/x86/mozilla/include/jsinterp.h +++ /dev/null @@ -1,1122 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=4 sw=4 et tw=78: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsinterp_h___ -#define jsinterp_h___ -/* - * JS interpreter interface. - */ -#include "jsprvtd.h" -#include "jspubtd.h" -#include "jsfun.h" -#include "jsopcode.h" -#include "jsscript.h" -#include "jsvalue.h" - -struct JSFrameRegs -{ - STATIC_SKIP_INFERENCE - js::Value *sp; /* stack pointer */ - jsbytecode *pc; /* program counter */ - JSStackFrame *fp; /* active frame */ -}; - -/* Flags to toggle js::Interpret() execution. */ -enum JSInterpMode -{ - JSINTERP_NORMAL = 0, /* interpreter is running normally */ - JSINTERP_RECORD = 1, /* interpreter has been started to record/run traces */ - JSINTERP_SAFEPOINT = 2, /* interpreter should leave on a method JIT safe point */ - JSINTERP_PROFILE = 3 /* interpreter should profile a loop */ -}; - -/* Flags used in JSStackFrame::flags_ */ -enum JSFrameFlags -{ - /* Primary frame type */ - JSFRAME_GLOBAL = 0x1, /* frame pushed for a global script */ - JSFRAME_FUNCTION = 0x2, /* frame pushed for a scripted call */ - JSFRAME_DUMMY = 0x4, /* frame pushed for bookkeeping */ - - /* Frame subtypes */ - JSFRAME_EVAL = 0x8, /* frame pushed for eval() or debugger eval */ - JSFRAME_DEBUGGER = 0x10, /* frame pushed for debugger eval */ - JSFRAME_GENERATOR = 0x20, /* frame is associated with a generator */ - JSFRAME_FLOATING_GENERATOR = 0x40, /* frame is is in generator obj, not on stack */ - JSFRAME_CONSTRUCTING = 0x80, /* frame is for a constructor invocation */ - - /* Temporary frame states */ - JSFRAME_ASSIGNING = 0x100, /* not-JOF_ASSIGNING op is assigning */ - JSFRAME_YIELDING = 0x200, /* js::Interpret dispatched JSOP_YIELD */ - JSFRAME_FINISHED_IN_INTERPRETER = 0x400, /* set if frame finished in Interpret() */ - - /* Concerning function arguments */ - JSFRAME_OVERRIDE_ARGS = 0x1000, /* overridden arguments local variable */ - JSFRAME_OVERFLOW_ARGS = 0x2000, /* numActualArgs > numFormalArgs */ - JSFRAME_UNDERFLOW_ARGS = 0x4000, /* numActualArgs < numFormalArgs */ - - /* Lazy frame initialization */ - JSFRAME_HAS_IMACRO_PC = 0x8000, /* frame has imacpc value available */ - JSFRAME_HAS_CALL_OBJ = 0x10000, /* frame has a callobj reachable from scopeChain_ */ - JSFRAME_HAS_ARGS_OBJ = 0x20000, /* frame has an argsobj in JSStackFrame::args */ - JSFRAME_HAS_HOOK_DATA = 0x40000, /* frame has hookData_ set */ - JSFRAME_HAS_ANNOTATION = 0x80000, /* frame has annotation_ set */ - JSFRAME_HAS_RVAL = 0x100000, /* frame has rval_ set */ - JSFRAME_HAS_SCOPECHAIN = 0x200000, /* frame has scopeChain_ set */ - JSFRAME_HAS_PREVPC = 0x400000 /* frame has prevpc_ set */ -}; - -namespace js { namespace mjit { struct JITScript; } } - -/* - * A stack frame is a part of a stack segment (see js::StackSegment) which is - * on the per-thread VM stack (see js::StackSpace). - */ -struct JSStackFrame -{ - private: - mutable uint32 flags_; /* bits described by JSFrameFlags */ - union { /* describes what code is executing in a */ - JSScript *script; /* global frame */ - JSFunction *fun; /* function frame, pre GetScopeChain */ - } exec; - union { /* describes the arguments of a function */ - uintN nactual; /* pre GetArgumentsObject */ - JSObject *obj; /* post GetArgumentsObject */ - JSScript *script; /* eval has no args, but needs a script */ - } args; - mutable JSObject *scopeChain_; /* current scope chain */ - JSStackFrame *prev_; /* previous cx->regs->fp */ - void *ncode_; /* return address for method JIT */ - - /* Lazily initialized */ - js::Value rval_; /* return value of the frame */ - jsbytecode *prevpc_; /* pc of previous frame*/ - jsbytecode *imacropc_; /* pc of macro caller */ - void *hookData_; /* closure returned by call hook */ - void *annotation_; /* perhaps remove with bug 546848 */ - - friend class js::StackSpace; - friend class js::FrameRegsIter; - friend struct JSContext; - - inline void initPrev(JSContext *cx); - - public: - /* - * Stack frame sort (see JSStackFrame comment above) - * - * A stack frame may have one of three types, which determines which - * members of the frame may be accessed and other invariants: - * - * global frame: execution of global code or an eval in global code - * function frame: execution of function code or an eval in a function - * dummy frame: bookkeeping frame (read: hack) - * - * As noted, global and function frames may optionally be 'eval frames', which - * further restricts the stack frame members which may be used. Namely, the - * argument-related members of function eval frames are not valid, since an eval - * shares its containing function's arguments rather than having its own. - */ - - bool isFunctionFrame() const { - return !!(flags_ & JSFRAME_FUNCTION); - } - - bool isGlobalFrame() const { - return !!(flags_ & JSFRAME_GLOBAL); - } - - bool isDummyFrame() const { - return !!(flags_ & JSFRAME_DUMMY); - } - - bool isScriptFrame() const { - return !!(flags_ & (JSFRAME_FUNCTION | JSFRAME_GLOBAL)); - } - - bool isEvalFrame() const { - JS_ASSERT_IF(flags_ & JSFRAME_EVAL, isScriptFrame()); - return flags_ & JSFRAME_EVAL; - } - - bool isExecuteFrame() const { - return !!(flags_ & (JSFRAME_GLOBAL | JSFRAME_EVAL)); - } - - /* - * Frame initialization - * - * After acquiring a pointer to an uninitialized stack frame on the VM - * stack from js::StackSpace, these members are used to initialize the - * stack frame before officially pushing the frame into the context. - * Collecting frame initialization into a set of inline helpers allows - * simpler reasoning and makes call-optimization easier. - */ - - /* Used for Invoke, Interpret, trace-jit LeaveTree, and method-jit stubs. */ - inline void initCallFrame(JSContext *cx, JSObject &callee, JSFunction *fun, - uint32 nactual, uint32 flags); - - /* Used for SessionInvoke. */ - inline void resetInvokeCallFrame(); - - /* Called by method-jit stubs and serve as a specification for jit-code. */ - inline void initCallFrameCallerHalf(JSContext *cx, uint32 flags, void *ncode); - inline void initCallFrameEarlyPrologue(JSFunction *fun, uint32 nactual); - inline void initCallFrameLatePrologue(); - - /* Used for eval. */ - inline void initEvalFrame(JSContext *cx, JSScript *script, JSStackFrame *prev, - uint32 flags); - inline void initGlobalFrame(JSScript *script, JSObject &chain, uint32 flags); - - /* Used when activating generators. */ - inline void stealFrameAndSlots(js::Value *vp, JSStackFrame *otherfp, - js::Value *othervp, js::Value *othersp); - - /* Perhaps one fine day we will remove dummy frames. */ - inline void initDummyFrame(JSContext *cx, JSObject &chain); - - /* - * Previous frame - * - * A frame's 'prev' frame is either null or the previous frame pointed to - * by cx->regs->fp when this frame was pushed. Often, given two prev-linked - * frames, the next-frame is a function or eval that was called by the - * prev-frame, but not always: the prev-frame may have called a native that - * reentered the VM through JS_CallFunctionValue on the same context - * (without calling JS_SaveFrameChain) which pushed the next-frame. Thus, - * 'prev' has little semantic meaning and basically just tells the VM what - * to set cx->regs->fp to when this frame is popped. - */ - - JSStackFrame *prev() const { - return prev_; - } - - inline void resetGeneratorPrev(JSContext *cx); - - /* - * Frame slots - * - * A frame's 'slots' are the fixed slots associated with the frame (like - * local variables) followed by an expression stack holding temporary - * values. A frame's 'base' is the base of the expression stack. - */ - - js::Value *slots() const { - return (js::Value *)(this + 1); - } - - js::Value *base() const { - return slots() + script()->nfixed; - } - - js::Value &varSlot(uintN i) { - JS_ASSERT(i < script()->nfixed); - JS_ASSERT_IF(maybeFun(), i < script()->bindings.countVars()); - return slots()[i]; - } - - /* - * Script - * - * All function and global frames have an associated JSScript which holds - * the bytecode being executed for the frame. - */ - - /* - * Get the frame's current bytecode, assuming |this| is in |cx|. - * next is frame whose prev == this, NULL if not known or if this == cx->fp(). - */ - jsbytecode *pc(JSContext *cx, JSStackFrame *next = NULL); - - jsbytecode *prevpc() { - JS_ASSERT((prev_ != NULL) && (flags_ & JSFRAME_HAS_PREVPC)); - return prevpc_; - } - - JSScript *script() const { - JS_ASSERT(isScriptFrame()); - return isFunctionFrame() - ? isEvalFrame() ? args.script : fun()->script() - : exec.script; - } - - JSScript *functionScript() const { - JS_ASSERT(isFunctionFrame()); - return isEvalFrame() ? args.script : fun()->script(); - } - - JSScript *globalScript() const { - JS_ASSERT(isGlobalFrame()); - return exec.script; - } - - JSScript *maybeScript() const { - return isScriptFrame() ? script() : NULL; - } - - size_t numFixed() const { - return script()->nfixed; - } - - size_t numSlots() const { - return script()->nslots; - } - - size_t numGlobalVars() const { - JS_ASSERT(isGlobalFrame()); - return exec.script->nfixed; - } - - /* - * Function - * - * All function frames have an associated interpreted JSFunction. - */ - - JSFunction* fun() const { - JS_ASSERT(isFunctionFrame()); - return exec.fun; - } - - JSFunction* maybeFun() const { - return isFunctionFrame() ? fun() : NULL; - } - - /* - * Arguments - * - * Only non-eval function frames have arguments. A frame follows its - * arguments contiguously in memory. The arguments pushed by the caller are - * the 'actual' arguments. The declared arguments of the callee are the - * 'formal' arguments. When the caller passes less or equal actual - * arguments, the actual and formal arguments are the same array (but with - * different extents). When the caller passes too many arguments, the - * formal subset of the actual arguments is copied onto the top of the - * stack. This allows the engine to maintain a jit-time constant offset of - * arguments from the frame pointer. Since the formal subset of the actual - * arguments is potentially on the stack twice, it is important for all - * reads/writes to refer to the same canonical memory location. - * - * An arguments object (the object returned by the 'arguments' keyword) is - * lazily created, so a given function frame may or may not have one. - */ - - /* True if this frame has arguments. Contrast with hasArgsObj. */ - bool hasArgs() const { - return isFunctionFrame() && !isEvalFrame(); - } - - uintN numFormalArgs() const { - JS_ASSERT(hasArgs()); - return fun()->nargs; - } - - js::Value &formalArg(uintN i) const { - JS_ASSERT(i < numFormalArgs()); - return formalArgs()[i]; - } - - js::Value *formalArgs() const { - JS_ASSERT(hasArgs()); - return (js::Value *)this - numFormalArgs(); - } - - js::Value *formalArgsEnd() const { - JS_ASSERT(hasArgs()); - return (js::Value *)this; - } - - js::Value *maybeFormalArgs() const { - return (flags_ & (JSFRAME_FUNCTION | JSFRAME_EVAL)) == JSFRAME_FUNCTION - ? formalArgs() - : NULL; - } - - inline uintN numActualArgs() const; - inline js::Value *actualArgs() const; - inline js::Value *actualArgsEnd() const; - - inline js::Value &canonicalActualArg(uintN i) const; - template inline void forEachCanonicalActualArg(Op op); - template inline void forEachFormalArg(Op op); - - inline void clearMissingArgs(); - - bool hasArgsObj() const { - return !!(flags_ & JSFRAME_HAS_ARGS_OBJ); - } - - JSObject &argsObj() const { - JS_ASSERT(hasArgsObj()); - JS_ASSERT(!isEvalFrame()); - return *args.obj; - } - - JSObject *maybeArgsObj() const { - return hasArgsObj() ? &argsObj() : NULL; - } - - inline void setArgsObj(JSObject &obj); - inline void clearArgsObj(); - - /* - * This value - * - * Every frame has a this value although, until 'this' is computed, the - * value may not be the semantically-correct 'this' value. - * - * The 'this' value is stored before the formal arguments for function - * frames and directly before the frame for global frames. The *Args - * members assert !isEvalFrame(), so we implement specialized inline - * methods for accessing 'this'. When the caller has static knowledge that - * a frame is a function or global frame, 'functionThis' and 'globalThis', - * respectively, allow more efficient access. - */ - - js::Value &functionThis() const { - JS_ASSERT(isFunctionFrame()); - if (isEvalFrame()) - return ((js::Value *)this)[-1]; - return formalArgs()[-1]; - } - - JSObject &constructorThis() const { - JS_ASSERT(hasArgs()); - return formalArgs()[-1].toObject(); - } - - js::Value &globalThis() const { - JS_ASSERT(isGlobalFrame()); - return ((js::Value *)this)[-1]; - } - - js::Value &thisValue() const { - if (flags_ & (JSFRAME_EVAL | JSFRAME_GLOBAL)) - return ((js::Value *)this)[-1]; - return formalArgs()[-1]; - } - - inline bool computeThis(JSContext *cx); - - /* - * Callee - * - * Only function frames have a callee. An eval frame in a function has the - * same caller as its containing function frame. - */ - - js::Value &calleeValue() const { - JS_ASSERT(isFunctionFrame()); - if (isEvalFrame()) - return ((js::Value *)this)[-2]; - return formalArgs()[-2]; - } - - JSObject &callee() const { - JS_ASSERT(isFunctionFrame()); - return calleeValue().toObject(); - } - - JSObject *maybeCallee() const { - return isFunctionFrame() ? &callee() : NULL; - } - - /* - * getValidCalleeObject is a fallible getter to compute the correct callee - * function object, which may require deferred cloning due to the JSObject - * methodReadBarrier. For a non-function frame, return true with *vp set - * from calleeValue, which may not be an object (it could be undefined). - */ - bool getValidCalleeObject(JSContext *cx, js::Value *vp); - - /* - * Scope chain - * - * Every frame has a scopeChain which, when traversed via the 'parent' link - * to the root, indicates the current global object. A 'call object' is a - * node on a scope chain representing a function's activation record. A - * call object is used for dynamically-scoped name lookup and lexically- - * scoped upvar access. The call object holds the values of locals and - * arguments when a function returns (and its stack frame is popped). For - * performance reasons, call objects are created lazily for 'lightweight' - * functions, i.e., functions which are not statically known to require a - * call object. Thus, a given function frame may or may not have a call - * object. When a function does have a call object, it is found by walking - * up the scope chain until the first call object. Thus, it is important, - * when setting the scope chain, to indicate whether the new scope chain - * contains a new call object and thus changes the 'hasCallObj' state. - */ - - JSObject &scopeChain() const { - JS_ASSERT_IF(!(flags_ & JSFRAME_HAS_SCOPECHAIN), isFunctionFrame()); - if (!(flags_ & JSFRAME_HAS_SCOPECHAIN)) { - scopeChain_ = callee().getParent(); - flags_ |= JSFRAME_HAS_SCOPECHAIN; - } - return *scopeChain_; - } - - bool hasCallObj() const { - return !!(flags_ & JSFRAME_HAS_CALL_OBJ); - } - - inline JSObject &callObj() const; - inline JSObject *maybeCallObj() const; - inline void setScopeChainNoCallObj(JSObject &obj); - inline void setScopeChainAndCallObj(JSObject &obj); - inline void clearCallObj(); - - /* - * Imacropc - * - * A frame's IMacro pc is the bytecode address when an imacro started - * executing (guaranteed non-null). An imacro does not push a frame, so - * when the imacro finishes, the frame's IMacro pc becomes the current pc. - */ - - bool hasImacropc() const { - return flags_ & JSFRAME_HAS_IMACRO_PC; - } - - jsbytecode *imacropc() const { - JS_ASSERT(hasImacropc()); - return imacropc_; - } - - jsbytecode *maybeImacropc() const { - return hasImacropc() ? imacropc() : NULL; - } - - void clearImacropc() { - flags_ &= ~JSFRAME_HAS_IMACRO_PC; - } - - void setImacropc(jsbytecode *pc) { - JS_ASSERT(pc); - JS_ASSERT(!(flags_ & JSFRAME_HAS_IMACRO_PC)); - imacropc_ = pc; - flags_ |= JSFRAME_HAS_IMACRO_PC; - } - - /* Annotation (will be removed after bug 546848) */ - - void* annotation() const { - return (flags_ & JSFRAME_HAS_ANNOTATION) ? annotation_ : NULL; - } - - void setAnnotation(void *annot) { - flags_ |= JSFRAME_HAS_ANNOTATION; - annotation_ = annot; - } - - /* Debugger hook data */ - - bool hasHookData() const { - return !!(flags_ & JSFRAME_HAS_HOOK_DATA); - } - - void* hookData() const { - JS_ASSERT(hasHookData()); - return hookData_; - } - - void* maybeHookData() const { - return hasHookData() ? hookData_ : NULL; - } - - void setHookData(void *v) { - hookData_ = v; - flags_ |= JSFRAME_HAS_HOOK_DATA; - } - - /* Return value */ - - const js::Value &returnValue() { - if (!(flags_ & JSFRAME_HAS_RVAL)) - rval_.setUndefined(); - return rval_; - } - - void markReturnValue() { - flags_ |= JSFRAME_HAS_RVAL; - } - - void setReturnValue(const js::Value &v) { - rval_ = v; - markReturnValue(); - } - - void clearReturnValue() { - rval_.setUndefined(); - markReturnValue(); - } - - /* Native-code return address */ - - void *nativeReturnAddress() const { - return ncode_; - } - - void setNativeReturnAddress(void *addr) { - ncode_ = addr; - } - - void **addressOfNativeReturnAddress() { - return &ncode_; - } - - /* - * Generator-specific members - * - * A non-eval function frame may optionally be the activation of a - * generator. For the most part, generator frames act like ordinary frames. - * For exceptions, see js_FloatingFrameIfGenerator. - */ - - bool isGeneratorFrame() const { - return !!(flags_ & JSFRAME_GENERATOR); - } - - bool isFloatingGenerator() const { - JS_ASSERT_IF(flags_ & JSFRAME_FLOATING_GENERATOR, isGeneratorFrame()); - return !!(flags_ & JSFRAME_FLOATING_GENERATOR); - } - - void initFloatingGenerator() { - JS_ASSERT(!(flags_ & JSFRAME_GENERATOR)); - flags_ |= (JSFRAME_GENERATOR | JSFRAME_FLOATING_GENERATOR); - } - - void unsetFloatingGenerator() { - flags_ &= ~JSFRAME_FLOATING_GENERATOR; - } - - void setFloatingGenerator() { - flags_ |= JSFRAME_FLOATING_GENERATOR; - } - - /* - * Other flags - */ - - bool isConstructing() const { - return !!(flags_ & JSFRAME_CONSTRUCTING); - } - - uint32 isConstructingFlag() const { - JS_ASSERT(isFunctionFrame()); - JS_ASSERT((flags_ & ~(JSFRAME_CONSTRUCTING | JSFRAME_FUNCTION)) == 0); - return flags_; - } - - bool isDebuggerFrame() const { - return !!(flags_ & JSFRAME_DEBUGGER); - } - - bool isEvalOrDebuggerFrame() const { - return !!(flags_ & (JSFRAME_EVAL | JSFRAME_DEBUGGER)); - } - - bool hasOverriddenArgs() const { - return !!(flags_ & JSFRAME_OVERRIDE_ARGS); - } - - bool hasOverflowArgs() const { - return !!(flags_ & JSFRAME_OVERFLOW_ARGS); - } - - void setOverriddenArgs() { - flags_ |= JSFRAME_OVERRIDE_ARGS; - } - - bool isAssigning() const { - return !!(flags_ & JSFRAME_ASSIGNING); - } - - void setAssigning() { - flags_ |= JSFRAME_ASSIGNING; - } - - void clearAssigning() { - flags_ &= ~JSFRAME_ASSIGNING; - } - - bool isYielding() { - return !!(flags_ & JSFRAME_YIELDING); - } - - void setYielding() { - flags_ |= JSFRAME_YIELDING; - } - - void clearYielding() { - flags_ &= ~JSFRAME_YIELDING; - } - - void setFinishedInInterpreter() { - flags_ |= JSFRAME_FINISHED_IN_INTERPRETER; - } - - bool finishedInInterpreter() const { - return !!(flags_ & JSFRAME_FINISHED_IN_INTERPRETER); - } - - /* - * Variables object accessors - * - * A stack frame's 'varobj' refers to the 'variables object' (ES3 term) - * associated with the Execution Context's VariableEnvironment (ES5 10.3). - * - * To compute the frame's varobj, the caller must supply the segment - * containing the frame (see js::StackSegment comment). As an abbreviation, - * the caller may pass the context if the frame is contained in that - * context's active segment. - */ - - inline JSObject &varobj(js::StackSegment *seg) const; - inline JSObject &varobj(JSContext *cx) const; - - /* Access to privates from the jits. */ - - static size_t offsetOfFlags() { - return offsetof(JSStackFrame, flags_); - } - - static size_t offsetOfExec() { - return offsetof(JSStackFrame, exec); - } - - void *addressOfArgs() { - return &args; - } - - static size_t offsetOfScopeChain() { - return offsetof(JSStackFrame, scopeChain_); - } - - JSObject **addressOfScopeChain() { - JS_ASSERT(flags_ & JSFRAME_HAS_SCOPECHAIN); - return &scopeChain_; - } - - static size_t offsetOfPrev() { - return offsetof(JSStackFrame, prev_); - } - - static size_t offsetOfReturnValue() { - return offsetof(JSStackFrame, rval_); - } - - static ptrdiff_t offsetOfncode() { - return offsetof(JSStackFrame, ncode_); - } - - static ptrdiff_t offsetOfCallee(JSFunction *fun) { - JS_ASSERT(fun != NULL); - return -(fun->nargs + 2) * sizeof(js::Value); - } - - static ptrdiff_t offsetOfThis(JSFunction *fun) { - return fun == NULL - ? -1 * ptrdiff_t(sizeof(js::Value)) - : -(fun->nargs + 1) * ptrdiff_t(sizeof(js::Value)); - } - - static ptrdiff_t offsetOfFormalArg(JSFunction *fun, uintN i) { - JS_ASSERT(i < fun->nargs); - return (-(int)fun->nargs + i) * sizeof(js::Value); - } - - static size_t offsetOfFixed(uintN i) { - return sizeof(JSStackFrame) + i * sizeof(js::Value); - } - - /* Workaround for static asserts on private members. */ - - void staticAsserts() { - JS_STATIC_ASSERT(offsetof(JSStackFrame, rval_) % sizeof(js::Value) == 0); - JS_STATIC_ASSERT(sizeof(JSStackFrame) % sizeof(js::Value) == 0); - } - -#ifdef JS_METHODJIT - js::mjit::JITScript *jit() { - return script()->getJIT(isConstructing()); - } -#endif - - void methodjitStaticAsserts(); - -#ifdef DEBUG - /* Poison scopeChain value set before a frame is flushed. */ - static JSObject *const sInvalidScopeChain; -#endif -}; - -namespace js { - -static const size_t VALUES_PER_STACK_FRAME = sizeof(JSStackFrame) / sizeof(Value); - -extern JSObject * -GetBlockChain(JSContext *cx, JSStackFrame *fp); - -extern JSObject * -GetBlockChainFast(JSContext *cx, JSStackFrame *fp, JSOp op, size_t oplen); - -extern JSObject * -GetScopeChain(JSContext *cx); - -/* - * Refresh and return fp->scopeChain. It may be stale if block scopes are - * active but not yet reflected by objects in the scope chain. If a block - * scope contains a with, eval, XML filtering predicate, or similar such - * dynamically scoped construct, then compile-time block scope at fp->blocks - * must reflect at runtime. - */ -extern JSObject * -GetScopeChain(JSContext *cx, JSStackFrame *fp); - -extern JSObject * -GetScopeChainFast(JSContext *cx, JSStackFrame *fp, JSOp op, size_t oplen); - -/* - * Report an error that the this value passed as |this| in the given arguments - * vector is not compatible with the specified class. - */ -void -ReportIncompatibleMethod(JSContext *cx, Value *vp, Class *clasp); - -/* - * Given a context and a vector of [callee, this, args...] for a function - * whose JSFUN_PRIMITIVE_THIS flag is set, set |*v| to the primitive value - * of |this|. If |this| is an object, insist that it be an instance of the - * appropriate wrapper class for T, and set |*v| to its private slot value. - * If |this| is a primitive, unbox it into |*v| if it's of the required - * type, and throw an error otherwise. - */ -template -bool GetPrimitiveThis(JSContext *cx, Value *vp, T *v); - -inline void -PutActivationObjects(JSContext *cx, JSStackFrame *fp); - -inline void -PutOwnedActivationObjects(JSContext *cx, JSStackFrame *fp); - -/* - * For a call's vp (which necessarily includes callee at vp[0] and the original - * specified |this| at vp[1]), convert null/undefined |this| into the global - * object for the callee and replace other primitives with boxed versions. The - * callee must not be strict mode code. - */ -extern bool -BoxThisForVp(JSContext *cx, js::Value *vp); - -/* - * Abstracts the layout of the stack passed to natives from the engine and from - * natives to js::Invoke. - */ -struct CallArgs -{ - Value *argv_; - uintN argc_; - protected: - CallArgs() {} - CallArgs(Value *argv, uintN argc) : argv_(argv), argc_(argc) {} - public: - Value *base() const { return argv_ - 2; } - Value &callee() const { return argv_[-2]; } - Value &thisv() const { return argv_[-1]; } - Value &operator[](unsigned i) const { JS_ASSERT(i < argc_); return argv_[i]; } - Value *argv() const { return argv_; } - uintN argc() const { return argc_; } - Value &rval() const { return argv_[-2]; } -}; - -/* - * The js::InvokeArgumentsGuard passed to js_Invoke must come from an - * immediately-enclosing successful call to js::StackSpace::pushInvokeArgs, - * i.e., there must have been no un-popped pushes to cx->stack(). Furthermore, - * |args.getvp()[0]| should be the callee, |args.getvp()[1]| should be |this|, - * and the range [args.getvp() + 2, args.getvp() + 2 + args.getArgc()) should - * be initialized actual arguments. - */ -extern JS_REQUIRES_STACK bool -Invoke(JSContext *cx, const CallArgs &args, uint32 flags); - -/* - * Natives like sort/forEach/replace call Invoke repeatedly with the same - * callee, this, and number of arguments. To optimize this, such natives can - * start an "invoke session" to factor out much of the dynamic setup logic - * required by a normal Invoke. Usage is: - * - * InvokeSessionGuard session(cx); - * if (!session.start(cx, callee, thisp, argc, &session)) - * ... - * - * while (...) { - * // write actual args (not callee, this) - * session[0] = ... - * ... - * session[argc - 1] = ... - * - * if (!session.invoke(cx, session)) - * ... - * - * ... = session.rval(); - * } - * - * // session ended by ~InvokeSessionGuard - */ -class InvokeSessionGuard; - -/* - * Consolidated js_Invoke flags simply rename certain JSFRAME_* flags, so that - * we can share bits stored in JSStackFrame.flags and passed to: - * - * js_Invoke - * js_InternalInvoke - * js_ValueToFunction - * js_ValueToFunctionObject - * js_ValueToCallableObject - * js_ReportIsNotFunction - * - * See jsfun.h for the latter four and flag renaming macros. - */ -#define JSINVOKE_CONSTRUCT JSFRAME_CONSTRUCTING - -/* - * Mask to isolate construct and iterator flags for use with jsfun.h functions. - */ -#define JSINVOKE_FUNFLAGS JSINVOKE_CONSTRUCT - -/* - * "External" calls may come from C or C++ code using a JSContext on which no - * JS is running (!cx->fp), so they may need to push a dummy JSStackFrame. - */ - -extern bool -ExternalInvoke(JSContext *cx, const Value &thisv, const Value &fval, - uintN argc, Value *argv, Value *rval); - -extern bool -ExternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, const Value &fval, - JSAccessMode mode, uintN argc, Value *argv, Value *rval); - -/* - * These two functions invoke a function called from a constructor context - * (e.g. 'new'). InvokeConstructor handles the general case where a new object - * needs to be created for/by the constructor. ConstructWithGivenThis directly - * calls the constructor with the given 'this', hence the caller must - * understand the semantics of the constructor call. - */ - -extern JS_REQUIRES_STACK bool -InvokeConstructor(JSContext *cx, const CallArgs &args); - -extern JS_REQUIRES_STACK bool -InvokeConstructorWithGivenThis(JSContext *cx, JSObject *thisobj, const Value &fval, - uintN argc, Value *argv, Value *rval); - -extern bool -ExternalInvokeConstructor(JSContext *cx, const Value &fval, uintN argc, Value *argv, - Value *rval); - -/* - * Performs a direct eval for the given arguments, which must correspond to the - * currently-executing stack frame, which must be a script frame. evalfun must - * be the built-in eval function and must correspond to the callee in vp[0]. - * When this function succeeds it returns the result in *vp, adjusts the JS - * stack pointer, and returns true. - */ -extern JS_REQUIRES_STACK bool -DirectEval(JSContext *cx, JSFunction *evalfun, uint32 argc, Value *vp); - -/* - * Performs a direct eval for the given arguments, which must correspond to the - * currently-executing stack frame, which must be a script frame. evalfun must - * be the built-in eval function and must correspond to the callee in vp[0]. - * When this function succeeds it returns the result in *vp, adjusts the JS - * stack pointer, and returns true. - */ -extern JS_REQUIRES_STACK bool -DirectEval(JSContext *cx, JSFunction *evalfun, uint32 argc, Value *vp); - -/* - * Executes a script with the given scope chain in the context of the given - * frame. - */ -extern JS_FORCES_STACK bool -Execute(JSContext *cx, JSObject *chain, JSScript *script, - JSStackFrame *prev, uintN flags, Value *result); - -/* - * Execute the caller-initialized frame for a user-defined script or function - * pointed to by cx->fp until completion or error. - */ -extern JS_REQUIRES_STACK JS_NEVER_INLINE bool -Interpret(JSContext *cx, JSStackFrame *stopFp, uintN inlineCallCount = 0, JSInterpMode mode = JSINTERP_NORMAL); - -extern JS_REQUIRES_STACK bool -RunScript(JSContext *cx, JSScript *script, JSStackFrame *fp); - -extern bool -CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs); - -extern bool -StrictlyEqual(JSContext *cx, const Value &lval, const Value &rval, JSBool *equal); - -/* === except that NaN is the same as NaN and -0 is not the same as +0. */ -extern bool -SameValue(JSContext *cx, const Value &v1, const Value &v2, JSBool *same); - -extern JSType -TypeOfValue(JSContext *cx, const Value &v); - -inline bool -InstanceOf(JSContext *cx, JSObject *obj, Class *clasp, Value *argv) -{ - if (obj && obj->getClass() == clasp) - return true; - extern bool InstanceOfSlow(JSContext *, JSObject *, Class *, Value *); - return InstanceOfSlow(cx, obj, clasp, argv); -} - -extern JSBool -HasInstance(JSContext *cx, JSObject *obj, const js::Value *v, JSBool *bp); - -inline void * -GetInstancePrivate(JSContext *cx, JSObject *obj, Class *clasp, Value *argv) -{ - if (!InstanceOf(cx, obj, clasp, argv)) - return NULL; - return obj->getPrivate(); -} - -extern bool -ValueToId(JSContext *cx, const Value &v, jsid *idp); - -/* - * @param closureLevel The static level of the closure that the cookie - * pertains to. - * @param cookie Level amount is a "skip" (delta) value from the - * closure level. - * @return The value of the upvar. - */ -extern const js::Value & -GetUpvar(JSContext *cx, uintN level, js::UpvarCookie cookie); - -} /* namespace js */ - -/* - * JS_LONE_INTERPRET indicates that the compiler should see just the code for - * the js_Interpret function when compiling jsinterp.cpp. The rest of the code - * from the file should be visible only when compiling jsinvoke.cpp. It allows - * platform builds to optimize selectively js_Interpret when the granularity - * of the optimizations with the given compiler is a compilation unit. - * - * JS_STATIC_INTERPRET is the modifier for functions defined in jsinterp.cpp - * that only js_Interpret calls. When JS_LONE_INTERPRET is true all such - * functions are declared below. - */ -#ifndef JS_LONE_INTERPRET -# ifdef _MSC_VER -# define JS_LONE_INTERPRET 0 -# else -# define JS_LONE_INTERPRET 1 -# endif -#endif - -#define JS_MAX_INLINE_CALL_COUNT 3000 - -#if !JS_LONE_INTERPRET -# define JS_STATIC_INTERPRET static -#else -# define JS_STATIC_INTERPRET - -extern JS_REQUIRES_STACK JSBool -js_EnterWith(JSContext *cx, jsint stackIndex, JSOp op, size_t oplen); - -extern JS_REQUIRES_STACK void -js_LeaveWith(JSContext *cx); - -/* - * Find the results of incrementing or decrementing *vp. For pre-increments, - * both *vp and *vp2 will contain the result on return. For post-increments, - * vp will contain the original value converted to a number and vp2 will get - * the result. Both vp and vp2 must be roots. - */ -extern JSBool -js_DoIncDec(JSContext *cx, const JSCodeSpec *cs, js::Value *vp, js::Value *vp2); - -/* - * Opcode tracing helper. When len is not 0, cx->fp->regs->pc[-len] gives the - * previous opcode. - */ -extern JS_REQUIRES_STACK void -js_LogOpcode(JSContext *cx); - -/* - * JS_OPMETER helper functions. - */ -extern void -js_MeterOpcodePair(JSOp op1, JSOp op2); - -extern void -js_MeterSlotOpcode(JSOp op, uint32 slot); - -#endif /* JS_LONE_INTERPRET */ -/* - * Unwind block and scope chains to match the given depth. The function sets - * fp->sp on return to stackDepth. - */ -extern JS_REQUIRES_STACK JSBool -js_UnwindScope(JSContext *cx, jsint stackDepth, JSBool normalUnwind); - -extern JSBool -js_OnUnknownMethod(JSContext *cx, js::Value *vp); - -extern JS_REQUIRES_STACK js::Class * -js_IsActiveWithOrBlock(JSContext *cx, JSObject *obj, int stackDepth); - -#endif /* jsinterp_h___ */ diff --git a/x86/mozilla/include/jsinttypes.h b/x86/mozilla/include/jsinttypes.h deleted file mode 100644 index 5f90eaa..0000000 --- a/x86/mozilla/include/jsinttypes.h +++ /dev/null @@ -1,144 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released - * May 28, 2008. - * - * The Initial Developer of the Original Code is - * Jim Blandy - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsinttypes_h___ -#define jsinttypes_h___ - -#include "js-config.h" - -/* - * Types: - * JSInt, JSUint (for = 8, 16, 32, and 64) - * JSIntPtr, JSUIntPtr - * - * JSInt and JSUint are signed and unsigned types known to be - * bits long. Note that neither JSInt8 nor JSUInt8 is necessarily - * equivalent to a plain "char". - * - * JSIntPtr and JSUintPtr are signed and unsigned types capable of - * holding an object pointer. - * - * Use these types in public SpiderMonkey header files, not the - * corresponding types from the C standard header. Windows - * doesn't support , and Microsoft says it has no plans to - * do so in the future; this means that projects that embed - * SpiderMonkey often take matters into their own hands and define the - * standard types themselves. If we define them in our public - * headers, our definitions may conflict with embedders' (see bug - * 479258). The JS* types are in our namespace, and can be used - * without troubling anyone. - * - * Internal SpiderMonkey code wishing to use the type names ISO C - * defines in the standard header can #include - * "jsstdint.h", which provides those types regardless of whether - * itself is available. - */ - -#if defined(JS_HAVE_STDINT_H) || \ - defined(JS_SYS_TYPES_H_DEFINES_EXACT_SIZE_TYPES) - -#if defined(JS_HAVE_STDINT_H) -#include -#else -#include -#endif - -typedef int8_t JSInt8; -typedef int16_t JSInt16; -typedef int32_t JSInt32; -typedef int64_t JSInt64; -typedef intptr_t JSIntPtr; - -typedef uint8_t JSUint8; -typedef uint16_t JSUint16; -typedef uint32_t JSUint32; -typedef uint64_t JSUint64; -typedef uintptr_t JSUintPtr; - -#else - -#if defined(JS_HAVE___INTN) - -typedef __int8 JSInt8; -typedef __int16 JSInt16; -typedef __int32 JSInt32; -typedef __int64 JSInt64; - -typedef unsigned __int8 JSUint8; -typedef unsigned __int16 JSUint16; -typedef unsigned __int32 JSUint32; -typedef unsigned __int64 JSUint64; - -#elif defined(JS_INT8_TYPE) - -typedef signed JS_INT8_TYPE JSInt8; -typedef signed JS_INT16_TYPE JSInt16; -typedef signed JS_INT32_TYPE JSInt32; -typedef signed JS_INT64_TYPE JSInt64; - -typedef unsigned JS_INT8_TYPE JSUint8; -typedef unsigned JS_INT16_TYPE JSUint16; -typedef unsigned JS_INT32_TYPE JSUint32; -typedef unsigned JS_INT64_TYPE JSUint64; - -#else -#error "couldn't find exact-width integer types" -#endif - -/* Microsoft Visual C/C++ defines intptr_t and uintptr_t in . */ -#if defined(JS_STDDEF_H_HAS_INTPTR_T) -#include -typedef intptr_t JSIntPtr; -typedef uintptr_t JSUintPtr; - -/* Windows Mobile defines intptr_t and uintptr_t in . Why not? */ -#elif defined(JS_CRTDEFS_H_HAS_INTPTR_T) -#include -typedef intptr_t JSIntPtr; -typedef uintptr_t JSUintPtr; - -/* Failing that, the configure script will have found something. */ -#elif defined(JS_INTPTR_TYPE) -typedef signed JS_INTPTR_TYPE JSIntPtr; -typedef unsigned JS_INTPTR_TYPE JSUintPtr; - -#else -#error "couldn't find pointer-sized integer types" -#endif - -#endif /* JS_HAVE_STDINT_H */ - -#endif /* jsinttypes_h___ */ diff --git a/x86/mozilla/include/jsiter.h b/x86/mozilla/include/jsiter.h deleted file mode 100644 index 9ae01d3..0000000 --- a/x86/mozilla/include/jsiter.h +++ /dev/null @@ -1,248 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=78: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsiter_h___ -#define jsiter_h___ - -/* - * JavaScript iterators. - */ -#include "jscntxt.h" -#include "jsprvtd.h" -#include "jspubtd.h" -#include "jsversion.h" - -/* - * NB: these flag bits are encoded into the bytecode stream in the immediate - * operand of JSOP_ITER, so don't change them without advancing jsxdrapi.h's - * JSXDR_BYTECODE_VERSION. - */ -#define JSITER_ENUMERATE 0x1 /* for-in compatible hidden default iterator */ -#define JSITER_FOREACH 0x2 /* return [key, value] pair rather than key */ -#define JSITER_KEYVALUE 0x4 /* destructuring for-in wants [key, value] */ -#define JSITER_OWNONLY 0x8 /* iterate over obj's own properties only */ -#define JSITER_HIDDEN 0x10 /* also enumerate non-enumerable properties */ - -/* - * For cacheable native iterators, whether the iterator is currently active. - * Not serialized by XDR. - */ -#define JSITER_ACTIVE 0x1000 -#define JSITER_UNREUSABLE 0x2000 - -namespace js { - -struct NativeIterator { - JSObject *obj; - jsid *props_array; - jsid *props_cursor; - jsid *props_end; - uint32 *shapes_array; - uint32 shapes_length; - uint32 shapes_key; - uint32 flags; - JSObject *next; /* Forms cx->enumerators list, garbage otherwise. */ - - bool isKeyIter() const { return (flags & JSITER_FOREACH) == 0; } - - inline jsid *begin() const { - return props_array; - } - - inline jsid *end() const { - return props_end; - } - - size_t numKeys() const { - return end() - begin(); - } - - jsid *current() const { - JS_ASSERT(props_cursor < props_end); - return props_cursor; - } - - void incCursor() { - props_cursor = props_cursor + 1; - } - - static NativeIterator *allocateIterator(JSContext *cx, uint32 slength, - const js::AutoIdVector &props); - void init(JSObject *obj, uintN flags, uint32 slength, uint32 key); - - void mark(JSTracer *trc); -}; - -bool -VectorToIdArray(JSContext *cx, js::AutoIdVector &props, JSIdArray **idap); - -JS_FRIEND_API(bool) -GetPropertyNames(JSContext *cx, JSObject *obj, uintN flags, js::AutoIdVector *props); - -bool -GetIterator(JSContext *cx, JSObject *obj, uintN flags, js::Value *vp); - -bool -VectorToKeyIterator(JSContext *cx, JSObject *obj, uintN flags, js::AutoIdVector &props, js::Value *vp); - -bool -VectorToValueIterator(JSContext *cx, JSObject *obj, uintN flags, js::AutoIdVector &props, js::Value *vp); - -/* - * Creates either a key or value iterator, depending on flags. For a value - * iterator, performs value-lookup to convert the given list of jsids. - */ -bool -EnumeratedIdVectorToIterator(JSContext *cx, JSObject *obj, uintN flags, js::AutoIdVector &props, js::Value *vp); - -} - -/* - * Convert the value stored in *vp to its iteration object. The flags should - * contain JSITER_ENUMERATE if js_ValueToIterator is called when enumerating - * for-in semantics are required, and when the caller can guarantee that the - * iterator will never be exposed to scripts. - */ -extern JS_FRIEND_API(JSBool) -js_ValueToIterator(JSContext *cx, uintN flags, js::Value *vp); - -extern JS_FRIEND_API(JSBool) -js_CloseIterator(JSContext *cx, JSObject *iterObj); - -bool -js_SuppressDeletedProperty(JSContext *cx, JSObject *obj, jsid id); - -bool -js_SuppressDeletedIndexProperties(JSContext *cx, JSObject *obj, jsint begin, jsint end); - -/* - * IteratorMore() indicates whether another value is available. It might - * internally call iterobj.next() and then cache the value until its - * picked up by IteratorNext(). The value is cached in the current context. - */ -extern JSBool -js_IteratorMore(JSContext *cx, JSObject *iterobj, js::Value *rval); - -extern JSBool -js_IteratorNext(JSContext *cx, JSObject *iterobj, js::Value *rval); - -extern JSBool -js_ThrowStopIteration(JSContext *cx); - -#if JS_HAS_GENERATORS - -/* - * Generator state codes. - */ -typedef enum JSGeneratorState { - JSGEN_NEWBORN, /* not yet started */ - JSGEN_OPEN, /* started by a .next() or .send(undefined) call */ - JSGEN_RUNNING, /* currently executing via .next(), etc., call */ - JSGEN_CLOSING, /* close method is doing asynchronous return */ - JSGEN_CLOSED /* closed, cannot be started or closed again */ -} JSGeneratorState; - -struct JSGenerator { - JSObject *obj; - JSGeneratorState state; - JSFrameRegs regs; - JSObject *enumerators; - JSStackFrame *floating; - js::Value floatingStack[1]; - - JSStackFrame *floatingFrame() { - return floating; - } - - JSStackFrame *liveFrame() { - JS_ASSERT((state == JSGEN_RUNNING || state == JSGEN_CLOSING) == - (regs.fp != floatingFrame())); - return regs.fp; - } -}; - -extern JSObject * -js_NewGenerator(JSContext *cx); - -/* - * Generator stack frames do not have stable pointers since they get copied to - * and from the generator object and the stack (see SendToGenerator). This is a - * problem for Block and With objects, which need to store a pointer to the - * enclosing stack frame. The solution is for Block and With objects to store - * a pointer to the "floating" stack frame stored in the generator object, - * since it is stable, and maintain, in the generator object, a pointer to the - * "live" stack frame (either a copy on the stack or the floating frame). Thus, - * Block and With objects must "normalize" to and from the floating/live frames - * in the case of generators using the following functions. - */ -inline JSStackFrame * -js_FloatingFrameIfGenerator(JSContext *cx, JSStackFrame *fp) -{ - JS_ASSERT(cx->stack().contains(fp)); - if (JS_UNLIKELY(fp->isGeneratorFrame())) - return cx->generatorFor(fp)->floatingFrame(); - return fp; -} - -/* Given a floating frame, given the JSGenerator containing it. */ -extern JSGenerator * -js_FloatingFrameToGenerator(JSStackFrame *fp); - -inline JSStackFrame * -js_LiveFrameIfGenerator(JSStackFrame *fp) -{ - return fp->isGeneratorFrame() ? js_FloatingFrameToGenerator(fp)->liveFrame() : fp; -} - -#endif - -extern js::Class js_GeneratorClass; -extern js::Class js_IteratorClass; -extern js::Class js_StopIterationClass; - -static inline bool -js_ValueIsStopIteration(const js::Value &v) -{ - return v.isObject() && v.toObject().getClass() == &js_StopIterationClass; -} - -extern JSObject * -js_InitIteratorClasses(JSContext *cx, JSObject *obj); - -#endif /* jsiter_h___ */ diff --git a/x86/mozilla/include/jslock.h b/x86/mozilla/include/jslock.h deleted file mode 100644 index d3b9067..0000000 --- a/x86/mozilla/include/jslock.h +++ /dev/null @@ -1,239 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -#ifndef jslock_h__ -#define jslock_h__ - -#include "jstypes.h" -#include "jsapi.h" -#include "jsprvtd.h" - -#ifdef JS_THREADSAFE -# include "pratom.h" -# include "prlock.h" -# include "prcvar.h" -# include "prthread.h" -#endif - -JS_BEGIN_EXTERN_C - -#ifdef JS_THREADSAFE - -#if (defined(_WIN32) && defined(_M_IX86)) || \ - (defined(_WIN64) && (defined(_M_AMD64) || defined(_M_X64))) || \ - (defined(__i386) && (defined(__GNUC__) || defined(__SUNPRO_CC))) || \ - (defined(__x86_64) && (defined(__GNUC__) || defined(__SUNPRO_CC))) || \ - (defined(__sparc) && (defined(__GNUC__) || defined(__SUNPRO_CC))) || \ - defined(AIX) || \ - defined(USE_ARM_KUSER) -# define JS_HAS_NATIVE_COMPARE_AND_SWAP 1 -#else -# define JS_HAS_NATIVE_COMPARE_AND_SWAP 0 -#endif - -#if defined(JS_USE_ONLY_NSPR_LOCKS) || !JS_HAS_NATIVE_COMPARE_AND_SWAP -# define NSPR_LOCK 1 -#else -# undef NSPR_LOCK -#endif - -#define Thin_GetWait(W) ((jsword)(W) & 0x1) -#define Thin_SetWait(W) ((jsword)(W) | 0x1) -#define Thin_RemoveWait(W) ((jsword)(W) & ~0x1) - -typedef struct JSFatLock JSFatLock; - -typedef struct JSThinLock { - jsword owner; - JSFatLock *fat; -} JSThinLock; - -#define CX_THINLOCK_ID(cx) ((jsword)(cx)->thread) -#define CURRENT_THREAD_IS_ME(me) (((JSThread *)me)->id == js_CurrentThreadId()) - -typedef PRLock JSLock; - -/* - * Atomic increment and decrement for a reference counter, given jsrefcount *p. - * NB: jsrefcount is int32, aka PRInt32, so that pratom.h functions work. - */ -#define JS_ATOMIC_INCREMENT(p) PR_AtomicIncrement((PRInt32 *)(p)) -#define JS_ATOMIC_DECREMENT(p) PR_AtomicDecrement((PRInt32 *)(p)) -#define JS_ATOMIC_ADD(p,v) PR_AtomicAdd((PRInt32 *)(p), (PRInt32)(v)) -#define JS_ATOMIC_SET(p,v) PR_AtomicSet((PRInt32 *)(p), (PRInt32)(v)) - -#define js_CurrentThreadId() PR_GetCurrentThread() -#define JS_NEW_LOCK() PR_NewLock() -#define JS_DESTROY_LOCK(l) PR_DestroyLock(l) -#define JS_ACQUIRE_LOCK(l) PR_Lock(l) -#define JS_RELEASE_LOCK(l) PR_Unlock(l) - -#define JS_NEW_CONDVAR(l) PR_NewCondVar(l) -#define JS_DESTROY_CONDVAR(cv) PR_DestroyCondVar(cv) -#define JS_WAIT_CONDVAR(cv,to) PR_WaitCondVar(cv,to) -#define JS_NO_TIMEOUT PR_INTERVAL_NO_TIMEOUT -#define JS_NOTIFY_CONDVAR(cv) PR_NotifyCondVar(cv) -#define JS_NOTIFY_ALL_CONDVAR(cv) PR_NotifyAllCondVar(cv) - -#define JS_LOCK(cx, tl) js_Lock(cx, tl) -#define JS_UNLOCK(cx, tl) js_Unlock(cx, tl) - -#define JS_LOCK_RUNTIME(rt) js_LockRuntime(rt) -#define JS_UNLOCK_RUNTIME(rt) js_UnlockRuntime(rt) - -extern void js_Lock(JSContext *cx, JSThinLock *tl); -extern void js_Unlock(JSContext *cx, JSThinLock *tl); -extern void js_LockRuntime(JSRuntime *rt); -extern void js_UnlockRuntime(JSRuntime *rt); -extern int js_SetupLocks(int,int); -extern void js_CleanupLocks(); -extern void js_InitLock(JSThinLock *); -extern void js_FinishLock(JSThinLock *); - -#ifdef DEBUG - -#define JS_IS_RUNTIME_LOCKED(rt) js_IsRuntimeLocked(rt) - -extern JSBool js_IsRuntimeLocked(JSRuntime *rt); - -#else - -#define JS_IS_RUNTIME_LOCKED(rt) 0 - -#endif /* DEBUG */ - -#else /* !JS_THREADSAFE */ - -#define JS_ATOMIC_INCREMENT(p) (++*(p)) -#define JS_ATOMIC_DECREMENT(p) (--*(p)) -#define JS_ATOMIC_ADD(p,v) (*(p) += (v)) -#define JS_ATOMIC_SET(p,v) (*(p) = (v)) - -#define JS_CurrentThreadId() 0 -#define JS_NEW_LOCK() NULL -#define JS_DESTROY_LOCK(l) ((void)0) -#define JS_ACQUIRE_LOCK(l) ((void)0) -#define JS_RELEASE_LOCK(l) ((void)0) -#define JS_LOCK(cx, tl) ((void)0) -#define JS_UNLOCK(cx, tl) ((void)0) - -#define JS_NEW_CONDVAR(l) NULL -#define JS_DESTROY_CONDVAR(cv) ((void)0) -#define JS_WAIT_CONDVAR(cv,to) ((void)0) -#define JS_NOTIFY_CONDVAR(cv) ((void)0) -#define JS_NOTIFY_ALL_CONDVAR(cv) ((void)0) - -#define JS_LOCK_RUNTIME(rt) ((void)0) -#define JS_UNLOCK_RUNTIME(rt) ((void)0) - -#define JS_IS_RUNTIME_LOCKED(rt) 1 - -#endif /* !JS_THREADSAFE */ - -#define JS_LOCK_RUNTIME_VOID(rt,e) \ - JS_BEGIN_MACRO \ - JS_LOCK_RUNTIME(rt); \ - e; \ - JS_UNLOCK_RUNTIME(rt); \ - JS_END_MACRO - -#define JS_LOCK_GC(rt) JS_ACQUIRE_LOCK((rt)->gcLock) -#define JS_UNLOCK_GC(rt) JS_RELEASE_LOCK((rt)->gcLock) -#define JS_AWAIT_GC_DONE(rt) JS_WAIT_CONDVAR((rt)->gcDone, JS_NO_TIMEOUT) -#define JS_NOTIFY_GC_DONE(rt) JS_NOTIFY_ALL_CONDVAR((rt)->gcDone) -#define JS_AWAIT_REQUEST_DONE(rt) JS_WAIT_CONDVAR((rt)->requestDone, \ - JS_NO_TIMEOUT) -#define JS_NOTIFY_REQUEST_DONE(rt) JS_NOTIFY_CONDVAR((rt)->requestDone) - -#ifndef JS_SET_OBJ_INFO -#define JS_SET_OBJ_INFO(obj,f,l) ((void)0) -#endif -#ifndef JS_SET_TITLE_INFO -#define JS_SET_TITLE_INFO(title,f,l) ((void)0) -#endif - -#ifdef JS_THREADSAFE - -extern JSBool -js_CompareAndSwap(volatile jsword *w, jsword ov, jsword nv); - -/* Atomically bitwise-or the mask into the word *w using compare and swap. */ -extern void -js_AtomicSetMask(volatile jsword *w, jsword mask); - -/* - * Atomically bitwise-and the complement of the mask into the word *w using - * compare and swap. - */ -extern void -js_AtomicClearMask(volatile jsword *w, jsword mask); - -#define JS_ATOMIC_SET_MASK(w, mask) js_AtomicSetMask(w, mask) -#define JS_ATOMIC_CLEAR_MASK(w, mask) js_AtomicClearMask(w, mask) - -#else - -static inline JSBool -js_CompareAndSwap(jsword *w, jsword ov, jsword nv) -{ - return (*w == ov) ? *w = nv, JS_TRUE : JS_FALSE; -} - -#define JS_ATOMIC_SET_MASK(w, mask) (*(w) |= (mask)) -#define JS_ATOMIC_CLEAR_MASK(w, mask) (*(w) &= ~(mask)) - -#endif /* JS_THREADSAFE */ - -JS_END_EXTERN_C - -#if defined JS_THREADSAFE && defined __cplusplus -namespace js { - -class AutoLock { - private: - JSLock *lock; - - public: - AutoLock(JSLock *lock) : lock(lock) { JS_ACQUIRE_LOCK(lock); } - ~AutoLock() { JS_RELEASE_LOCK(lock); } -}; - -} -#endif - -#endif /* jslock_h___ */ diff --git a/x86/mozilla/include/jslong.h b/x86/mozilla/include/jslong.h deleted file mode 100644 index 4a1fccc..0000000 --- a/x86/mozilla/include/jslong.h +++ /dev/null @@ -1,167 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* -** File: jslong.h -** Description: Portable access to 64 bit numerics -** -** Long-long (64-bit signed integer type) support. Some C compilers -** don't support 64 bit integers yet, so we use these macros to -** support both machines that do and don't. -**/ -#ifndef jslong_h___ -#define jslong_h___ - -#include "jstypes.h" - -JS_BEGIN_EXTERN_C - -#define JSLL_INIT(hi, lo) ((((JSInt64)(hi)) << 32) + (JSInt64)(lo)) - -/*********************************************************************** -** MACROS: JSLL_* -** DESCRIPTION: -** The following macros define portable access to the 64 bit -** math facilities. -** -***********************************************************************/ - -/*********************************************************************** -** MACROS: JSLL_ -** -** JSLL_IS_ZERO Test for zero -** JSLL_EQ Test for equality -** JSLL_NE Test for inequality -** JSLL_GE_ZERO Test for zero or positive -** JSLL_CMP Compare two values -***********************************************************************/ -#define JSLL_IS_ZERO(a) ((a) == 0) -#define JSLL_EQ(a, b) ((a) == (b)) -#define JSLL_NE(a, b) ((a) != (b)) -#define JSLL_GE_ZERO(a) ((a) >= 0) -#define JSLL_CMP(a, op, b) ((JSInt64)(a) op (JSInt64)(b)) -#define JSLL_UCMP(a, op, b) ((JSUint64)(a) op (JSUint64)(b)) - -/*********************************************************************** -** MACROS: JSLL_ -** -** JSLL_AND Logical and -** JSLL_OR Logical or -** JSLL_XOR Logical exclusion -** JSLL_OR2 A disgusting deviation -** JSLL_NOT Negation (one's compliment) -***********************************************************************/ -#define JSLL_AND(r, a, b) ((r) = (a) & (b)) -#define JSLL_OR(r, a, b) ((r) = (a) | (b)) -#define JSLL_XOR(r, a, b) ((r) = (a) ^ (b)) -#define JSLL_OR2(r, a) ((r) = (r) | (a)) -#define JSLL_NOT(r, a) ((r) = ~(a)) - -/*********************************************************************** -** MACROS: JSLL_ -** -** JSLL_NEG Negation (two's compliment) -** JSLL_ADD Summation (two's compliment) -** JSLL_SUB Difference (two's compliment) -***********************************************************************/ -#define JSLL_NEG(r, a) ((r) = -(a)) -#define JSLL_ADD(r, a, b) ((r) = (a) + (b)) -#define JSLL_SUB(r, a, b) ((r) = (a) - (b)) - -/*********************************************************************** -** MACROS: JSLL_ -** -** JSLL_MUL Product (two's compliment) -** JSLL_DIV Quotient (two's compliment) -** JSLL_MOD Modulus (two's compliment) -***********************************************************************/ -#define JSLL_MUL(r, a, b) ((r) = (a) * (b)) -#define JSLL_DIV(r, a, b) ((r) = (a) / (b)) -#define JSLL_MOD(r, a, b) ((r) = (a) % (b)) - -/*********************************************************************** -** MACROS: JSLL_ -** -** JSLL_SHL Shift left [0..64] bits -** JSLL_SHR Shift right [0..64] bits with sign extension -** JSLL_USHR Unsigned shift right [0..64] bits -** JSLL_ISHL Signed shift left [0..64] bits -***********************************************************************/ -#define JSLL_SHL(r, a, b) ((r) = (JSInt64)(a) << (b)) -#define JSLL_SHR(r, a, b) ((r) = (JSInt64)(a) >> (b)) -#define JSLL_USHR(r, a, b) ((r) = (JSUint64)(a) >> (b)) -#define JSLL_ISHL(r, a, b) ((r) = (JSInt64)(a) << (b)) - -/*********************************************************************** -** MACROS: JSLL_ -** -** JSLL_L2I Convert to signed 32 bit -** JSLL_L2UI Convert to unsigned 32 bit -** JSLL_L2F Convert to floating point -** JSLL_L2D Convert to floating point -** JSLL_I2L Convert signed to 64 bit -** JSLL_UI2L Convert unsigned to 64 bit -** JSLL_F2L Convert float to 64 bit -** JSLL_D2L Convert float to 64 bit -***********************************************************************/ -#define JSLL_L2I(i, l) ((i) = (JSInt32)(l)) -#define JSLL_L2UI(ui, l) ((ui) = (JSUint32)(l)) -#define JSLL_L2F(f, l) ((f) = (JSFloat64)(l)) -#define JSLL_L2D(d, l) ((d) = (JSFloat64)(l)) - -#define JSLL_I2L(l, i) ((l) = (JSInt64)(i)) -#define JSLL_UI2L(l, ui) ((l) = (JSInt64)(ui)) -#define JSLL_F2L(l, f) ((l) = (JSInt64)(f)) -#define JSLL_D2L(l, d) ((l) = (JSInt64)(d)) - -/*********************************************************************** -** MACROS: JSLL_UDIVMOD -** DESCRIPTION: -** Produce both a quotient and a remainder given an unsigned -** INPUTS: JSUint64 a: The dividend of the operation -** JSUint64 b: The quotient of the operation -** OUTPUTS: JSUint64 *qp: pointer to quotient -** JSUint64 *rp: pointer to remainder -***********************************************************************/ -#define JSLL_UDIVMOD(qp, rp, a, b) \ - (*(qp) = ((JSUint64)(a) / (b)), \ - *(rp) = ((JSUint64)(a) % (b))) - -JS_END_EXTERN_C - -#endif /* jslong_h___ */ diff --git a/x86/mozilla/include/jsmath.h b/x86/mozilla/include/jsmath.h deleted file mode 100644 index b6e059d..0000000 --- a/x86/mozilla/include/jsmath.h +++ /dev/null @@ -1,123 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998-1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsmath_h___ -#define jsmath_h___ - -namespace js { - -typedef double (*UnaryFunType)(double); - -class MathCache -{ - static const unsigned SizeLog2 = 12; - static const unsigned Size = 1 << SizeLog2; - struct Entry { double in; UnaryFunType f; double out; }; - Entry table[Size]; - - public: - MathCache(); - - uintN hash(double x) { - union { double d; struct { uint32 one, two; } s; } u = { x }; - uint32 hash32 = u.s.one ^ u.s.two; - uint16 hash16 = (uint16)(hash32 ^ (hash32 >> 16)); - return (hash16 & (Size - 1)) ^ (hash16 >> (16 - SizeLog2)); - } - - /* - * N.B. lookup uses double-equality. This is only safe if hash() maps +0 - * and -0 to different table entries, which is asserted in MathCache(). - */ - double lookup(UnaryFunType f, double x) { - uintN index = hash(x); - Entry &e = table[index]; - if (e.in == x && e.f == f) - return e.out; - e.in = x; - e.f = f; - return (e.out = f(x)); - } -}; - -} /* namespace js */ - -/* - * JS math functions. - */ - -extern js::Class js_MathClass; - -extern JSObject * -js_InitMathClass(JSContext *cx, JSObject *obj); - -extern bool -js_IsMathFunction(JSNative native); - -extern void -js_InitRandom(JSContext *cx); - -extern JSBool -js_math_abs(JSContext *cx, uintN argc, js::Value *vp); - -extern JSBool -js_math_ceil(JSContext *cx, uintN argc, js::Value *vp); - -extern JSBool -js_math_floor(JSContext *cx, uintN argc, js::Value *vp); - -extern JSBool -js_math_max(JSContext *cx, uintN argc, js::Value *vp); - -extern JSBool -js_math_min(JSContext *cx, uintN argc, js::Value *vp); - -extern JSBool -js_math_round(JSContext *cx, uintN argc, js::Value *vp); - -extern jsdouble -js_math_ceil_impl(jsdouble x); - -extern jsdouble -js_math_floor_impl(jsdouble x); - -extern jsdouble -js_math_round_impl(jsdouble x); - -#endif /* jsmath_h___ */ diff --git a/x86/mozilla/include/jsobj.h b/x86/mozilla/include/jsobj.h deleted file mode 100644 index 176a911..0000000 --- a/x86/mozilla/include/jsobj.h +++ /dev/null @@ -1,1945 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=78: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsobj_h___ -#define jsobj_h___ - -/* Gross special case for Gecko, which defines malloc/calloc/free. */ -#ifdef mozilla_mozalloc_macro_wrappers_h -# define JS_OBJ_UNDEFD_MOZALLOC_WRAPPERS -/* The "anti-header" */ -# include "mozilla/mozalloc_undef_macro_wrappers.h" -#endif - -/* - * JS object definitions. - * - * A JS object consists of a possibly-shared object descriptor containing - * ordered property names, called the map; and a dense vector of property - * values, called slots. The map/slot pointer pair is GC'ed, while the map - * is reference counted and the slot vector is malloc'ed. - */ -#include "jsapi.h" -#include "jshash.h" -#include "jspubtd.h" -#include "jsprvtd.h" -#include "jslock.h" -#include "jsvalue.h" -#include "jsvector.h" -#include "jscell.h" - -namespace js { - -class JSProxyHandler; -class AutoPropDescArrayRooter; - -namespace mjit { -class Compiler; -} - -static inline PropertyOp -CastAsPropertyOp(JSObject *object) -{ - return JS_DATA_TO_FUNC_PTR(PropertyOp, object); -} - -static inline StrictPropertyOp -CastAsStrictPropertyOp(JSObject *object) -{ - return JS_DATA_TO_FUNC_PTR(StrictPropertyOp, object); -} - -static inline JSPropertyOp -CastAsJSPropertyOp(JSObject *object) -{ - return JS_DATA_TO_FUNC_PTR(JSPropertyOp, object); -} - -static inline JSStrictPropertyOp -CastAsJSStrictPropertyOp(JSObject *object) -{ - return JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, object); -} - -inline JSObject * -CastAsObject(PropertyOp op) -{ - return JS_FUNC_TO_DATA_PTR(JSObject *, op); -} - -inline JSObject * -CastAsObject(StrictPropertyOp op) -{ - return JS_FUNC_TO_DATA_PTR(JSObject *, op); -} - -inline Value -CastAsObjectJsval(PropertyOp op) -{ - return ObjectOrNullValue(CastAsObject(op)); -} - -inline Value -CastAsObjectJsval(StrictPropertyOp op) -{ - return ObjectOrNullValue(CastAsObject(op)); -} - -} /* namespace js */ - -/* - * A representation of ECMA-262 ed. 5's internal property descriptor data - * structure. - */ -struct PropDesc { - friend class js::AutoPropDescArrayRooter; - - PropDesc(); - - public: - /* 8.10.5 ToPropertyDescriptor(Obj) */ - bool initialize(JSContext* cx, jsid id, const js::Value &v); - - /* 8.10.1 IsAccessorDescriptor(desc) */ - bool isAccessorDescriptor() const { - return hasGet || hasSet; - } - - /* 8.10.2 IsDataDescriptor(desc) */ - bool isDataDescriptor() const { - return hasValue || hasWritable; - } - - /* 8.10.3 IsGenericDescriptor(desc) */ - bool isGenericDescriptor() const { - return !isAccessorDescriptor() && !isDataDescriptor(); - } - - bool configurable() const { - return (attrs & JSPROP_PERMANENT) == 0; - } - - bool enumerable() const { - return (attrs & JSPROP_ENUMERATE) != 0; - } - - bool writable() const { - return (attrs & JSPROP_READONLY) == 0; - } - - JSObject* getterObject() const { - return get.isUndefined() ? NULL : &get.toObject(); - } - JSObject* setterObject() const { - return set.isUndefined() ? NULL : &set.toObject(); - } - - const js::Value &getterValue() const { - return get; - } - const js::Value &setterValue() const { - return set; - } - - js::PropertyOp getter() const { - return js::CastAsPropertyOp(getterObject()); - } - js::StrictPropertyOp setter() const { - return js::CastAsStrictPropertyOp(setterObject()); - } - - js::Value pd; - jsid id; - js::Value value, get, set; - - /* Property descriptor boolean fields. */ - uint8 attrs; - - /* Bits indicating which values are set. */ - bool hasGet : 1; - bool hasSet : 1; - bool hasValue : 1; - bool hasWritable : 1; - bool hasEnumerable : 1; - bool hasConfigurable : 1; -}; - -namespace js { - -typedef Vector PropDescArray; - -} /* namespace js */ - -struct JSObjectMap { - uint32 shape; /* shape identifier */ - uint32 slotSpan; /* one more than maximum live slot number */ - - static JS_FRIEND_DATA(const JSObjectMap) sharedNonNative; - - explicit JSObjectMap(uint32 shape) : shape(shape), slotSpan(0) {} - JSObjectMap(uint32 shape, uint32 slotSpan) : shape(shape), slotSpan(slotSpan) {} - - enum { INVALID_SHAPE = 0x8fffffff, SHAPELESS = 0xffffffff }; - - bool isNative() const { return this != &sharedNonNative; } - - private: - /* No copy or assignment semantics. */ - JSObjectMap(JSObjectMap &); - void operator=(JSObjectMap &); -}; - -/* - * Unlike js_DefineNativeProperty, propp must be non-null. On success, and if - * id was found, return true with *objp non-null and with a property of *objp - * stored in *propp. If successful but id was not found, return true with both - * *objp and *propp null. - */ -extern JS_FRIEND_API(JSBool) -js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, - JSProperty **propp); - -extern JSBool -js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, const js::Value *value, - js::PropertyOp getter, js::StrictPropertyOp setter, uintN attrs); - -extern JSBool -js_GetProperty(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, js::Value *vp); - -inline JSBool -js_GetProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *vp) -{ - return js_GetProperty(cx, obj, obj, id, vp); -} - -namespace js { - -extern JSBool -GetPropertyDefault(JSContext *cx, JSObject *obj, jsid id, const Value &def, Value *vp); - -} /* namespace js */ - -extern JSBool -js_SetProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *vp, JSBool strict); - -extern JSBool -js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp); - -extern JSBool -js_SetAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp); - -extern JSBool -js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *rval, JSBool strict); - -extern JS_FRIEND_API(JSBool) -js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, - js::Value *statep, jsid *idp); - -extern JSType -js_TypeOf(JSContext *cx, JSObject *obj); - -namespace js { - -struct NativeIterator; - -} - -struct JSFunction; - -namespace nanojit { -class ValidateWriter; -} - -/* - * JSObject struct, with members sized to fit in 32 bytes on 32-bit targets, - * 64 bytes on 64-bit systems. The JSFunction struct is an extension of this - * struct allocated from a larger GC size-class. - * - * The clasp member stores the js::Class pointer for this object. We do *not* - * synchronize updates of clasp or flags -- API clients must take care. - * - * An object is a delegate if it is on another object's prototype (the proto - * field) or scope chain (the parent field), and therefore the delegate might - * be asked implicitly to get or set a property on behalf of another object. - * Delegates may be accessed directly too, as may any object, but only those - * objects linked after the head of any prototype or scope chain are flagged - * as delegates. This definition helps to optimize shape-based property cache - * invalidation (see Purge{Scope,Proto}Chain in jsobj.cpp). - * - * The meaning of the system object bit is defined by the API client. It is - * set in JS_NewSystemObject and is queried by JS_IsSystemObject (jsdbgapi.h), - * but it has no intrinsic meaning to SpiderMonkey. Further, JSFILENAME_SYSTEM - * and JS_FlagScriptFilenamePrefix (also exported via jsdbgapi.h) are intended - * to be complementary to this bit, but it is up to the API client to implement - * any such association. - * - * Both these flag bits are initially zero; they may be set or queried using - * the (is|set)(Delegate|System) inline methods. - * - * The slots member is a pointer to the slot vector for the object. - * This can be either a fixed array allocated immediately after the object, - * or a dynamically allocated array. A dynamic array can be tested for with - * hasSlotsArray(). In all cases, capacity gives the number of usable slots. - * Two objects with the same shape have the same number of fixed slots, - * and either both have or neither have dynamically allocated slot arrays. - * - * If you change this struct, you'll probably need to change the AccSet values - * in jsbuiltins.h. - */ -struct JSObject : js::gc::Cell { - /* - * TraceRecorder must be a friend because it generates code that - * manipulates JSObjects, which requires peeking under any encapsulation. - * ValidateWriter must be a friend because it works in tandem with - * TraceRecorder. - */ - friend class js::TraceRecorder; - friend class nanojit::ValidateWriter; - friend class GetPropCompiler; - - /* - * Private pointer to the last added property and methods to manipulate the - * list it links among properties in this scope. The {remove,insert} pair - * for DictionaryProperties assert that the scope is in dictionary mode and - * any reachable properties are flagged as dictionary properties. - * - * For native objects, this field is always a Shape. For non-native objects, - * it points to the singleton sharedNonNative JSObjectMap, whose shape field - * is SHAPELESS. - * - * NB: these private methods do *not* update this scope's shape to track - * lastProp->shape after they finish updating the linked list in the case - * where lastProp is updated. It is up to calling code in jsscope.cpp to - * call updateShape(cx) after updating lastProp. - */ - union { - js::Shape *lastProp; - JSObjectMap *map; - }; - - js::Class *clasp; - - private: - inline void setLastProperty(const js::Shape *shape); - inline void removeLastProperty(); - -#ifdef DEBUG - void checkShapeConsistency(); -#endif - - public: - inline const js::Shape *lastProperty() const; - - inline js::Shape **nativeSearch(jsid id, bool adding = false); - inline const js::Shape *nativeLookup(jsid id); - - inline bool nativeContains(jsid id); - inline bool nativeContains(const js::Shape &shape); - - enum { - DELEGATE = 0x01, - SYSTEM = 0x02, - NOT_EXTENSIBLE = 0x04, - BRANDED = 0x08, - GENERIC = 0x10, - METHOD_BARRIER = 0x20, - INDEXED = 0x40, - OWN_SHAPE = 0x80, - BOUND_FUNCTION = 0x100, - HAS_EQUALITY = 0x200, - METHOD_THRASH_COUNT_MASK = 0xc00, - METHOD_THRASH_COUNT_SHIFT = 10, - METHOD_THRASH_COUNT_MAX = METHOD_THRASH_COUNT_MASK >> METHOD_THRASH_COUNT_SHIFT - }; - - /* - * Impose a sane upper bound, originally checked only for dense arrays, on - * number of slots in an object. - */ - enum { - NSLOTS_BITS = 29, - NSLOTS_LIMIT = JS_BIT(NSLOTS_BITS) - }; - - uint32 flags; /* flags */ - uint32 objShape; /* copy of lastProp->shape, or override if different */ - - /* If prototype, lazily filled array of empty shapes for each object size. */ - js::EmptyShape **emptyShapes; - - JSObject *proto; /* object's prototype */ - JSObject *parent; /* object's parent */ - void *privateData; /* private data */ - jsuword capacity; /* capacity of slots */ - js::Value *slots; /* dynamically allocated slots, - or pointer to fixedSlots() */ - - /* - * Return an immutable, shareable, empty shape with the same clasp as this - * and the same slotSpan as this had when empty. - * - * If |this| is the scope of an object |proto|, the resulting scope can be - * used as the scope of a new object whose prototype is |proto|. - */ - inline bool canProvideEmptyShape(js::Class *clasp); - inline js::EmptyShape *getEmptyShape(JSContext *cx, js::Class *aclasp, - /* gc::FinalizeKind */ unsigned kind); - - bool isNative() const { return map->isNative(); } - - js::Class *getClass() const { return clasp; } - JSClass *getJSClass() const { return Jsvalify(clasp); } - - bool hasClass(const js::Class *c) const { - return c == clasp; - } - - const js::ObjectOps *getOps() const { - return &getClass()->ops; - } - - inline void trace(JSTracer *trc); - - uint32 shape() const { - JS_ASSERT(objShape != JSObjectMap::INVALID_SHAPE); - return objShape; - } - - bool isDelegate() const { return !!(flags & DELEGATE); } - void setDelegate() { flags |= DELEGATE; } - void clearDelegate() { flags &= ~DELEGATE; } - - bool isBoundFunction() const { return !!(flags & BOUND_FUNCTION); } - - static void setDelegateNullSafe(JSObject *obj) { - if (obj) - obj->setDelegate(); - } - - bool isSystem() const { return !!(flags & SYSTEM); } - void setSystem() { flags |= SYSTEM; } - - /* - * A branded object contains plain old methods (function-valued properties - * without magic getters and setters), and its shape evolves whenever a - * function value changes. - */ - bool branded() { return !!(flags & BRANDED); } - - /* - * NB: these return false on shape overflow but do not report any error. - * Callers who depend on shape guarantees should therefore bail off trace, - * e.g., on false returns. - */ - bool brand(JSContext *cx); - bool unbrand(JSContext *cx); - - bool generic() { return !!(flags & GENERIC); } - void setGeneric() { flags |= GENERIC; } - - uintN getMethodThrashCount() const { - return (flags & METHOD_THRASH_COUNT_MASK) >> METHOD_THRASH_COUNT_SHIFT; - } - - void setMethodThrashCount(uintN count) { - JS_ASSERT(count <= METHOD_THRASH_COUNT_MAX); - flags = (flags & ~METHOD_THRASH_COUNT_MASK) | (count << METHOD_THRASH_COUNT_SHIFT); - } - - bool hasSpecialEquality() const { return !!(flags & HAS_EQUALITY); } - void assertSpecialEqualitySynced() const { - JS_ASSERT(!!clasp->ext.equality == hasSpecialEquality()); - } - - /* Sets an object's HAS_EQUALITY flag based on its clasp. */ - inline void syncSpecialEquality(); - - private: - void generateOwnShape(JSContext *cx); - - void setOwnShape(uint32 s) { flags |= OWN_SHAPE; objShape = s; } - void clearOwnShape() { flags &= ~OWN_SHAPE; objShape = map->shape; } - - public: - inline bool nativeEmpty() const; - - bool hasOwnShape() const { return !!(flags & OWN_SHAPE); } - - void setMap(const JSObjectMap *amap) { - JS_ASSERT(!hasOwnShape()); - map = const_cast(amap); - objShape = map->shape; - } - - void setSharedNonNativeMap() { - setMap(&JSObjectMap::sharedNonNative); - } - - void deletingShapeChange(JSContext *cx, const js::Shape &shape); - const js::Shape *methodShapeChange(JSContext *cx, const js::Shape &shape); - bool methodShapeChange(JSContext *cx, uint32 slot); - void protoShapeChange(JSContext *cx); - void shadowingShapeChange(JSContext *cx, const js::Shape &shape); - bool globalObjectOwnShapeChange(JSContext *cx); - void watchpointOwnShapeChange(JSContext *cx) { generateOwnShape(cx); } - - void extensibleShapeChange(JSContext *cx) { - /* This will do for now. */ - generateOwnShape(cx); - } - - /* - * A scope has a method barrier when some compiler-created "null closure" - * function objects (functions that do not use lexical bindings above their - * scope, only free variable names) that have a correct JSSLOT_PARENT value - * thanks to the COMPILE_N_GO optimization are stored as newly added direct - * property values of the scope's object. - * - * The de-facto standard JS language requires each evaluation of such a - * closure to result in a unique (according to === and observable effects) - * function object. ES3 tried to allow implementations to "join" such - * objects to a single compiler-created object, but this makes an overt - * mutation hazard, also an "identity hazard" against interoperation among - * implementations that join and do not join. - * - * To stay compatible with the de-facto standard, we store the compiler- - * created function object as the method value and set the METHOD_BARRIER - * flag. - * - * The method value is part of the method property tree node's identity, so - * it effectively brands the scope with a predictable shape corresponding - * to the method value, but without the overhead of setting the BRANDED - * flag, which requires assigning a new shape peculiar to each branded - * scope. Instead the shape is shared via the property tree among all the - * scopes referencing the method property tree node. - * - * Then when reading from a scope for which scope->hasMethodBarrier() is - * true, we count on the scope's qualified/guarded shape being unique and - * add a read barrier that clones the compiler-created function object on - * demand, reshaping the scope. - * - * This read barrier is bypassed when evaluating the callee sub-expression - * of a call expression (see the JOF_CALLOP opcodes in jsopcode.tbl), since - * such ops do not present an identity or mutation hazard. The compiler - * performs this optimization only for null closures that do not use their - * own name or equivalent built-in references (arguments.callee). - * - * The BRANDED write barrier, JSObject::methodWriteBarrer, must check for - * METHOD_BARRIER too, and regenerate this scope's shape if the method's - * value is in fact changing. - */ - bool hasMethodBarrier() { return !!(flags & METHOD_BARRIER); } - void setMethodBarrier() { flags |= METHOD_BARRIER; } - - /* - * Test whether this object may be branded due to method calls, which means - * any assignment to a function-valued property must regenerate shape; else - * test whether this object has method properties, which require a method - * write barrier. - */ - bool brandedOrHasMethodBarrier() { return !!(flags & (BRANDED | METHOD_BARRIER)); } - - /* - * Read barrier to clone a joined function object stored as a method. - * Defined in jsobjinlines.h, but not declared inline per standard style in - * order to avoid gcc warnings. - */ - const js::Shape *methodReadBarrier(JSContext *cx, const js::Shape &shape, js::Value *vp); - - /* - * Write barrier to check for a change of method value. Defined inline in - * jsobjinlines.h after methodReadBarrier. The slot flavor is required by - * JSOP_*GVAR, which deals in slots not shapes, while not deoptimizing to - * map slot to shape unless JSObject::flags show that this is necessary. - * The methodShapeChange overload (above) parallels this. - */ - const js::Shape *methodWriteBarrier(JSContext *cx, const js::Shape &shape, const js::Value &v); - bool methodWriteBarrier(JSContext *cx, uint32 slot, const js::Value &v); - - bool isIndexed() const { return !!(flags & INDEXED); } - void setIndexed() { flags |= INDEXED; } - - /* - * Return true if this object is a native one that has been converted from - * shared-immutable prototype-rooted shape storage to dictionary-shapes in - * a doubly-linked list. - */ - inline bool inDictionaryMode() const; - - inline uint32 propertyCount() const; - - inline bool hasPropertyTable() const; - - /* gc::FinalizeKind */ unsigned finalizeKind() const; - - uint32 numSlots() const { return capacity; } - - size_t slotsAndStructSize(uint32 nslots) const; - size_t slotsAndStructSize() const { return slotsAndStructSize(numSlots()); } - - inline js::Value* fixedSlots() const; - inline size_t numFixedSlots() const; - - static inline size_t getFixedSlotOffset(size_t slot); - - public: - /* Minimum size for dynamically allocated slots. */ - static const uint32 SLOT_CAPACITY_MIN = 8; - - bool allocSlots(JSContext *cx, size_t nslots); - bool growSlots(JSContext *cx, size_t nslots); - void shrinkSlots(JSContext *cx, size_t nslots); - - bool ensureSlots(JSContext *cx, size_t nslots) { - if (numSlots() < nslots) - return growSlots(cx, nslots); - return true; - } - - /* - * Ensure that the object has at least JSCLASS_RESERVED_SLOTS(clasp) + - * nreserved slots. - * - * This method may be called only for native objects freshly created using - * NewObject or one of its variant where the new object will both (a) never - * escape to script and (b) never be extended with ad-hoc properties that - * would try to allocate higher slots without the fresh object first having - * its map set to a shape path that maps those slots. - * - * Block objects satisfy (a) and (b), as there is no evil eval-based way to - * add ad-hoc properties to a Block instance. Call objects satisfy (a) and - * (b) as well, because the compiler-created Shape path that covers args, - * vars, and upvars, stored in their callee function in u.i.names, becomes - * their initial map. - */ - bool ensureInstanceReservedSlots(JSContext *cx, size_t nreserved); - - /* - * Get a direct pointer to the object's slots. - * This can be reallocated if the object is modified, watch out! - */ - js::Value *getSlots() const { - return slots; - } - - /* - * NB: ensureClassReservedSlotsForEmptyObject asserts that nativeEmpty() - * Use ensureClassReservedSlots for any object, either empty or already - * extended with properties. - */ - bool ensureClassReservedSlotsForEmptyObject(JSContext *cx); - - inline bool ensureClassReservedSlots(JSContext *cx); - - uint32 slotSpan() const { return map->slotSpan; } - - bool containsSlot(uint32 slot) const { return slot < slotSpan(); } - - js::Value& getSlotRef(uintN slot) { - JS_ASSERT(slot < capacity); - return slots[slot]; - } - - js::Value &nativeGetSlotRef(uintN slot) { - JS_ASSERT(isNative()); - JS_ASSERT(containsSlot(slot)); - return getSlotRef(slot); - } - - const js::Value &getSlot(uintN slot) const { - JS_ASSERT(slot < capacity); - return slots[slot]; - } - - const js::Value &nativeGetSlot(uintN slot) const { - JS_ASSERT(isNative()); - JS_ASSERT(containsSlot(slot)); - return getSlot(slot); - } - - void setSlot(uintN slot, const js::Value &value) { - JS_ASSERT(slot < capacity); - slots[slot] = value; - } - - void nativeSetSlot(uintN slot, const js::Value &value) { - JS_ASSERT(isNative()); - JS_ASSERT(containsSlot(slot)); - return setSlot(slot, value); - } - - inline js::Value getReservedSlot(uintN index) const; - - /* Defined in jsscopeinlines.h to avoid including implementation dependencies here. */ - inline void updateShape(JSContext *cx); - inline void updateFlags(const js::Shape *shape, bool isDefinitelyAtom = false); - - /* Extend this object to have shape as its last-added property. */ - inline void extend(JSContext *cx, const js::Shape *shape, bool isDefinitelyAtom = false); - - JSObject *getProto() const { return proto; } - void clearProto() { proto = NULL; } - - void setProto(JSObject *newProto) { -#ifdef DEBUG - for (JSObject *obj = newProto; obj; obj = obj->getProto()) - JS_ASSERT(obj != this); -#endif - setDelegateNullSafe(newProto); - proto = newProto; - } - - JSObject *getParent() const { - return parent; - } - - void clearParent() { - parent = NULL; - } - - void setParent(JSObject *newParent) { -#ifdef DEBUG - for (JSObject *obj = newParent; obj; obj = obj->getParent()) - JS_ASSERT(obj != this); -#endif - setDelegateNullSafe(newParent); - parent = newParent; - } - - JS_FRIEND_API(JSObject *) getGlobal() const; - - bool isGlobal() const { - return !!(getClass()->flags & JSCLASS_IS_GLOBAL); - } - - void *getPrivate() const { - JS_ASSERT(getClass()->flags & JSCLASS_HAS_PRIVATE); - return privateData; - } - - void setPrivate(void *data) { - JS_ASSERT(getClass()->flags & JSCLASS_HAS_PRIVATE); - privateData = data; - } - - - /* - * ES5 meta-object properties and operations. - */ - - private: - enum ImmutabilityType { SEAL, FREEZE }; - - /* - * The guts of Object.seal (ES5 15.2.3.8) and Object.freeze (ES5 15.2.3.9): mark the - * object as non-extensible, and adjust each property's attributes appropriately: each - * property becomes non-configurable, and if |freeze|, data properties become - * read-only as well. - */ - bool sealOrFreeze(JSContext *cx, ImmutabilityType it); - - public: - bool isExtensible() const { return !(flags & NOT_EXTENSIBLE); } - bool preventExtensions(JSContext *cx, js::AutoIdVector *props); - - /* ES5 15.2.3.8: non-extensible, all props non-configurable */ - inline bool seal(JSContext *cx) { return sealOrFreeze(cx, SEAL); } - /* ES5 15.2.3.9: non-extensible, all properties non-configurable, all data props read-only */ - bool freeze(JSContext *cx) { return sealOrFreeze(cx, FREEZE); } - - /* - * Primitive-specific getters and setters. - */ - - private: - static const uint32 JSSLOT_PRIMITIVE_THIS = 0; - - public: - inline const js::Value &getPrimitiveThis() const; - inline void setPrimitiveThis(const js::Value &pthis); - - /* - * Array-specific getters and setters (for both dense and slow arrays). - */ - - inline uint32 getArrayLength() const; - inline void setArrayLength(uint32 length); - - inline uint32 getDenseArrayCapacity(); - inline js::Value* getDenseArrayElements(); - inline const js::Value &getDenseArrayElement(uintN idx); - inline js::Value* addressOfDenseArrayElement(uintN idx); - inline void setDenseArrayElement(uintN idx, const js::Value &val); - inline void shrinkDenseArrayElements(JSContext *cx, uintN cap); - - /* - * ensureDenseArrayElements ensures that the dense array can hold at least - * index + extra elements. It returns ED_OK on success, ED_FAILED on - * failure to grow the array, ED_SPARSE when the array is too sparse to - * grow (this includes the case of index + extra overflow). In the last - * two cases the array is kept intact. - */ - enum EnsureDenseResult { ED_OK, ED_FAILED, ED_SPARSE }; - inline EnsureDenseResult ensureDenseArrayElements(JSContext *cx, uintN index, uintN extra); - - /* - * Check if after growing the dense array will be too sparse. - * newElementsHint is an estimated number of elements to be added. - */ - bool willBeSparseDenseArray(uintN requiredCapacity, uintN newElementsHint); - - JSBool makeDenseArraySlow(JSContext *cx); - - /* - * Arguments-specific getters and setters. - */ - - private: - /* - * We represent arguments objects using js_ArgumentsClass and - * js::StrictArgumentsClass. The two are structured similarly, and methods - * valid on arguments objects of one class are also generally valid on - * arguments objects of the other. - * - * Arguments objects of either class store arguments length in a slot: - * - * JSSLOT_ARGS_LENGTH - the number of actual arguments and a flag - * indicating whether arguments.length was - * overwritten. This slot is not used to represent - * arguments.length after that property has been - * assigned, even if the new value is integral: it's - * always the original length. - * - * Both arguments classes use a slot for storing arguments data: - * - * JSSLOT_ARGS_DATA - pointer to an ArgumentsData structure - * - * ArgumentsData for normal arguments stores the value of arguments.callee, - * as long as that property has not been overwritten. If arguments.callee - * is overwritten, the corresponding value in ArgumentsData is set to - * MagicValue(JS_ARGS_HOLE). Strict arguments do not store this value - * because arguments.callee is a poison pill for strict mode arguments. - * - * The ArgumentsData structure also stores argument values. For normal - * arguments this occurs after the corresponding function has returned, and - * for strict arguments this occurs when the arguments object is created, - * or sometimes shortly after (but not observably so). arguments[i] is - * stored in ArgumentsData.slots[i], accessible via getArgsElement() and - * setArgsElement(). Deletion of arguments[i] overwrites that slot with - * MagicValue(JS_ARGS_HOLE); subsequent redefinition of arguments[i] will - * use a normal property to store the value, ignoring the slot. - * - * Non-strict arguments have a private: - * - * private - the function's stack frame until the function - * returns, when it is replaced with null; also, - * JS_ARGUMENTS_OBJECT_ON_TRACE while on trace, if - * arguments was created on trace - * - * Technically strict arguments have a private, but it's always null. - * Conceptually it would be better to remove this oddity, but preserving it - * allows us to work with arguments objects of either kind more abstractly, - * so we keep it for now. - */ - static const uint32 JSSLOT_ARGS_DATA = 1; - - public: - /* Number of extra fixed arguments object slots besides JSSLOT_PRIVATE. */ - static const uint32 JSSLOT_ARGS_LENGTH = 0; - static const uint32 ARGS_CLASS_RESERVED_SLOTS = 2; - static const uint32 ARGS_FIRST_FREE_SLOT = ARGS_CLASS_RESERVED_SLOTS + 1; - - /* Lower-order bit stolen from the length slot. */ - static const uint32 ARGS_LENGTH_OVERRIDDEN_BIT = 0x1; - static const uint32 ARGS_PACKED_BITS_COUNT = 1; - - /* - * Set the initial length of the arguments, and mark it as not overridden. - */ - inline void setArgsLength(uint32 argc); - - /* - * Return the initial length of the arguments. This may differ from the - * current value of arguments.length! - */ - inline uint32 getArgsInitialLength() const; - - inline void setArgsLengthOverridden(); - inline bool isArgsLengthOverridden() const; - - inline js::ArgumentsData *getArgsData() const; - inline void setArgsData(js::ArgumentsData *data); - - inline const js::Value &getArgsCallee() const; - inline void setArgsCallee(const js::Value &callee); - - inline const js::Value &getArgsElement(uint32 i) const; - inline js::Value *getArgsElements() const; - inline js::Value *addressOfArgsElement(uint32 i); - inline void setArgsElement(uint32 i, const js::Value &v); - - private: - /* - * Reserved slot structure for Call objects: - * - * private - the stack frame corresponding to the Call object - * until js_PutCallObject or its on-trace analog - * is called, null thereafter - * JSSLOT_CALL_CALLEE - callee function for the stack frame, or null if - * the stack frame is for strict mode eval code - * JSSLOT_CALL_ARGUMENTS - arguments object for non-strict mode eval stack - * frames (not valid for strict mode eval frames) - */ - static const uint32 JSSLOT_CALL_CALLEE = 0; - static const uint32 JSSLOT_CALL_ARGUMENTS = 1; - - public: - /* Number of reserved slots. */ - static const uint32 CALL_RESERVED_SLOTS = 2; - - /* True if this is for a strict mode eval frame or for a function call. */ - inline bool callIsForEval() const; - - /* The stack frame for this Call object, if the frame is still active. */ - inline JSStackFrame *maybeCallObjStackFrame() const; - - /* - * The callee function if this Call object was created for a function - * invocation, or null if it was created for a strict mode eval frame. - */ - inline JSObject *getCallObjCallee() const; - inline JSFunction *getCallObjCalleeFunction() const; - inline void setCallObjCallee(JSObject *callee); - - inline const js::Value &getCallObjArguments() const; - inline void setCallObjArguments(const js::Value &v); - - /* Returns the formal argument at the given index. */ - inline const js::Value &callObjArg(uintN i) const; - inline js::Value &callObjArg(uintN i); - - /* Returns the variable at the given index. */ - inline const js::Value &callObjVar(uintN i) const; - inline js::Value &callObjVar(uintN i); - - /* - * Date-specific getters and setters. - */ - - static const uint32 JSSLOT_DATE_UTC_TIME = 0; - - /* - * Cached slots holding local properties of the date. - * These are undefined until the first actual lookup occurs - * and are reset to undefined whenever the date's time is modified. - */ - static const uint32 JSSLOT_DATE_COMPONENTS_START = 1; - - static const uint32 JSSLOT_DATE_LOCAL_TIME = 1; - static const uint32 JSSLOT_DATE_LOCAL_YEAR = 2; - static const uint32 JSSLOT_DATE_LOCAL_MONTH = 3; - static const uint32 JSSLOT_DATE_LOCAL_DATE = 4; - static const uint32 JSSLOT_DATE_LOCAL_DAY = 5; - static const uint32 JSSLOT_DATE_LOCAL_HOURS = 6; - static const uint32 JSSLOT_DATE_LOCAL_MINUTES = 7; - static const uint32 JSSLOT_DATE_LOCAL_SECONDS = 8; - - static const uint32 DATE_CLASS_RESERVED_SLOTS = 9; - - inline const js::Value &getDateUTCTime() const; - inline void setDateUTCTime(const js::Value &pthis); - - /* - * Function-specific getters and setters. - */ - - private: - friend struct JSFunction; - friend class js::mjit::Compiler; - - /* - * Flat closures with one or more upvars snapshot the upvars' values into a - * vector of js::Values referenced from this slot. - */ - static const uint32 JSSLOT_FLAT_CLOSURE_UPVARS = 0; - - /* - * Null closures set or initialized as methods have these slots. See the - * "method barrier" comments and methods. - */ - - static const uint32 JSSLOT_FUN_METHOD_ATOM = 0; - static const uint32 JSSLOT_FUN_METHOD_OBJ = 1; - - static const uint32 JSSLOT_BOUND_FUNCTION_THIS = 0; - static const uint32 JSSLOT_BOUND_FUNCTION_ARGS_COUNT = 1; - - public: - static const uint32 FUN_CLASS_RESERVED_SLOTS = 2; - - inline JSFunction *getFunctionPrivate() const; - - inline js::Value *getFlatClosureUpvars() const; - inline js::Value getFlatClosureUpvar(uint32 i) const; - inline js::Value &getFlatClosureUpvar(uint32 i); - inline void setFlatClosureUpvars(js::Value *upvars); - - inline bool hasMethodObj(const JSObject& obj) const; - inline void setMethodObj(JSObject& obj); - - inline bool initBoundFunction(JSContext *cx, const js::Value &thisArg, - const js::Value *args, uintN argslen); - - inline JSObject *getBoundFunctionTarget() const; - inline const js::Value &getBoundFunctionThis() const; - inline const js::Value *getBoundFunctionArguments(uintN &argslen) const; - - /* - * RegExp-specific getters and setters. - */ - - private: - static const uint32 JSSLOT_REGEXP_LAST_INDEX = 0; - - public: - static const uint32 REGEXP_CLASS_RESERVED_SLOTS = 1; - - inline const js::Value &getRegExpLastIndex() const; - inline void setRegExpLastIndex(const js::Value &v); - inline void setRegExpLastIndex(jsdouble d); - inline void zeroRegExpLastIndex(); - - /* - * Iterator-specific getters and setters. - */ - - inline js::NativeIterator *getNativeIterator() const; - inline void setNativeIterator(js::NativeIterator *); - - /* - * XML-related getters and setters. - */ - - /* - * Slots for XML-related classes are as follows: - * - js_NamespaceClass.base reserves the *_NAME_* and *_NAMESPACE_* slots. - * - js_QNameClass.base, js_AttributeNameClass, js_AnyNameClass reserve - * the *_NAME_* and *_QNAME_* slots. - * - Others (js_XMLClass, js_XMLFilterClass) don't reserve any slots. - */ - private: - static const uint32 JSSLOT_NAME_PREFIX = 0; // shared - static const uint32 JSSLOT_NAME_URI = 1; // shared - - static const uint32 JSSLOT_NAMESPACE_DECLARED = 2; - - static const uint32 JSSLOT_QNAME_LOCAL_NAME = 2; - - public: - static const uint32 NAMESPACE_CLASS_RESERVED_SLOTS = 3; - static const uint32 QNAME_CLASS_RESERVED_SLOTS = 3; - - inline JSLinearString *getNamePrefix() const; - inline jsval getNamePrefixVal() const; - inline void setNamePrefix(JSLinearString *prefix); - inline void clearNamePrefix(); - - inline JSLinearString *getNameURI() const; - inline jsval getNameURIVal() const; - inline void setNameURI(JSLinearString *uri); - - inline jsval getNamespaceDeclared() const; - inline void setNamespaceDeclared(jsval decl); - - inline JSLinearString *getQNameLocalName() const; - inline jsval getQNameLocalNameVal() const; - inline void setQNameLocalName(JSLinearString *name); - - /* - * Proxy-specific getters and setters. - */ - - inline js::JSProxyHandler *getProxyHandler() const; - inline const js::Value &getProxyPrivate() const; - inline void setProxyPrivate(const js::Value &priv); - inline const js::Value &getProxyExtra() const; - inline void setProxyExtra(const js::Value &extra); - - /* - * With object-specific getters and setters. - */ - inline JSObject *getWithThis() const; - inline void setWithThis(JSObject *thisp); - - /* - * Back to generic stuff. - */ - inline bool isCallable(); - - /* The map field is not initialized here and should be set separately. */ - void init(JSContext *cx, js::Class *aclasp, JSObject *proto, JSObject *parent, - void *priv, bool useHoles); - - inline void finish(JSContext *cx); - JS_ALWAYS_INLINE void finalize(JSContext *cx); - - /* - * Like init, but also initializes map. The catch: proto must be the result - * of a call to js_InitClass(...clasp, ...). - */ - inline bool initSharingEmptyShape(JSContext *cx, - js::Class *clasp, - JSObject *proto, - JSObject *parent, - void *priv, - /* gc::FinalizeKind */ unsigned kind); - - inline bool hasSlotsArray() const; - - /* This method can only be called when hasSlotsArray() returns true. */ - inline void freeSlotsArray(JSContext *cx); - - /* Free the slots array and copy slots that fit into the fixed array. */ - inline void revertToFixedSlots(JSContext *cx); - - inline bool hasProperty(JSContext *cx, jsid id, bool *foundp, uintN flags = 0); - - /* - * Allocate and free an object slot. Note that freeSlot is infallible: it - * returns true iff this is a dictionary-mode object and the freed slot was - * added to the freelist. - * - * FIXME: bug 593129 -- slot allocation should be done by object methods - * after calling object-parameter-free shape methods, avoiding coupling - * logic across the object vs. shape module wall. - */ - bool allocSlot(JSContext *cx, uint32 *slotp); - bool freeSlot(JSContext *cx, uint32 slot); - - public: - bool reportReadOnly(JSContext* cx, jsid id, uintN report = JSREPORT_ERROR); - bool reportNotConfigurable(JSContext* cx, jsid id, uintN report = JSREPORT_ERROR); - bool reportNotExtensible(JSContext *cx, uintN report = JSREPORT_ERROR); - - private: - js::Shape *getChildProperty(JSContext *cx, js::Shape *parent, js::Shape &child); - - /* - * Internal helper that adds a shape not yet mapped by this object. - * - * Notes: - * 1. getter and setter must be normalized based on flags (see jsscope.cpp). - * 2. !isExtensible() checking must be done by callers. - */ - const js::Shape *addPropertyInternal(JSContext *cx, jsid id, - js::PropertyOp getter, js::StrictPropertyOp setter, - uint32 slot, uintN attrs, - uintN flags, intN shortid, - js::Shape **spp); - - bool toDictionaryMode(JSContext *cx); - - public: - /* Add a property whose id is not yet in this scope. */ - const js::Shape *addProperty(JSContext *cx, jsid id, - js::PropertyOp getter, js::StrictPropertyOp setter, - uint32 slot, uintN attrs, - uintN flags, intN shortid); - - /* Add a data property whose id is not yet in this scope. */ - const js::Shape *addDataProperty(JSContext *cx, jsid id, uint32 slot, uintN attrs) { - JS_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER))); - return addProperty(cx, id, NULL, NULL, slot, attrs, 0, 0); - } - - /* Add or overwrite a property for id in this scope. */ - const js::Shape *putProperty(JSContext *cx, jsid id, - js::PropertyOp getter, js::StrictPropertyOp setter, - uint32 slot, uintN attrs, - uintN flags, intN shortid); - - /* Change the given property into a sibling with the same id in this scope. */ - const js::Shape *changeProperty(JSContext *cx, const js::Shape *shape, uintN attrs, uintN mask, - js::PropertyOp getter, js::StrictPropertyOp setter); - - /* Remove the property named by id from this object. */ - bool removeProperty(JSContext *cx, jsid id); - - /* Clear the scope, making it empty. */ - void clear(JSContext *cx); - - JSBool lookupProperty(JSContext *cx, jsid id, JSObject **objp, JSProperty **propp) { - js::LookupPropOp op = getOps()->lookupProperty; - return (op ? op : js_LookupProperty)(cx, this, id, objp, propp); - } - - JSBool defineProperty(JSContext *cx, jsid id, const js::Value &value, - js::PropertyOp getter = js::PropertyStub, - js::StrictPropertyOp setter = js::StrictPropertyStub, - uintN attrs = JSPROP_ENUMERATE) { - js::DefinePropOp op = getOps()->defineProperty; - return (op ? op : js_DefineProperty)(cx, this, id, &value, getter, setter, attrs); - } - - JSBool getProperty(JSContext *cx, JSObject *receiver, jsid id, js::Value *vp) { - js::PropertyIdOp op = getOps()->getProperty; - return (op ? op : (js::PropertyIdOp)js_GetProperty)(cx, this, receiver, id, vp); - } - - JSBool getProperty(JSContext *cx, jsid id, js::Value *vp) { - return getProperty(cx, this, id, vp); - } - - JSBool setProperty(JSContext *cx, jsid id, js::Value *vp, JSBool strict) { - js::StrictPropertyIdOp op = getOps()->setProperty; - return (op ? op : js_SetProperty)(cx, this, id, vp, strict); - } - - JSBool getAttributes(JSContext *cx, jsid id, uintN *attrsp) { - js::AttributesOp op = getOps()->getAttributes; - return (op ? op : js_GetAttributes)(cx, this, id, attrsp); - } - - JSBool setAttributes(JSContext *cx, jsid id, uintN *attrsp) { - js::AttributesOp op = getOps()->setAttributes; - return (op ? op : js_SetAttributes)(cx, this, id, attrsp); - } - - JSBool deleteProperty(JSContext *cx, jsid id, js::Value *rval, JSBool strict) { - js::DeleteIdOp op = getOps()->deleteProperty; - return (op ? op : js_DeleteProperty)(cx, this, id, rval, strict); - } - - JSBool enumerate(JSContext *cx, JSIterateOp iterop, js::Value *statep, jsid *idp) { - js::NewEnumerateOp op = getOps()->enumerate; - return (op ? op : js_Enumerate)(cx, this, iterop, statep, idp); - } - - JSType typeOf(JSContext *cx) { - js::TypeOfOp op = getOps()->typeOf; - return (op ? op : js_TypeOf)(cx, this); - } - - /* These four are time-optimized to avoid stub calls. */ - JSObject *thisObject(JSContext *cx) { - JSObjectOp op = getOps()->thisObject; - return op ? op(cx, this) : this; - } - - static bool thisObject(JSContext *cx, const js::Value &v, js::Value *vp); - - inline JSCompartment *getCompartment() const; - - inline JSObject *getThrowTypeError() const; - - JS_FRIEND_API(JSObject *) clone(JSContext *cx, JSObject *proto, JSObject *parent); - JS_FRIEND_API(bool) copyPropertiesFrom(JSContext *cx, JSObject *obj); - bool swap(JSContext *cx, JSObject *other); - - const js::Shape *defineBlockVariable(JSContext *cx, jsid id, intN index); - - inline bool canHaveMethodBarrier() const; - - inline bool isArguments() const; - inline bool isNormalArguments() const; - inline bool isStrictArguments() const; - inline bool isArray() const; - inline bool isDenseArray() const; - inline bool isSlowArray() const; - inline bool isNumber() const; - inline bool isBoolean() const; - inline bool isString() const; - inline bool isPrimitive() const; - inline bool isDate() const; - inline bool isFunction() const; - inline bool isObject() const; - inline bool isWith() const; - inline bool isBlock() const; - inline bool isStaticBlock() const; - inline bool isClonedBlock() const; - inline bool isCall() const; - inline bool isRegExp() const; - inline bool isXML() const; - inline bool isXMLId() const; - inline bool isNamespace() const; - inline bool isQName() const; - - inline bool isProxy() const; - inline bool isObjectProxy() const; - inline bool isFunctionProxy() const; - - JS_FRIEND_API(bool) isWrapper() const; - JS_FRIEND_API(JSObject *) unwrap(uintN *flagsp = NULL); - - inline void initArrayClass(); -}; - -/* Check alignment for any fixed slots allocated after the object. */ -JS_STATIC_ASSERT(sizeof(JSObject) % sizeof(js::Value) == 0); - -inline js::Value* -JSObject::fixedSlots() const { - return (js::Value*) (jsuword(this) + sizeof(JSObject)); -} - -inline bool -JSObject::hasSlotsArray() const { return this->slots != fixedSlots(); } - -/* static */ inline size_t -JSObject::getFixedSlotOffset(size_t slot) { - return sizeof(JSObject) + (slot * sizeof(js::Value)); -} - -struct JSObject_Slots2 : JSObject { js::Value fslots[2]; }; -struct JSObject_Slots4 : JSObject { js::Value fslots[4]; }; -struct JSObject_Slots8 : JSObject { js::Value fslots[8]; }; -struct JSObject_Slots12 : JSObject { js::Value fslots[12]; }; -struct JSObject_Slots16 : JSObject { js::Value fslots[16]; }; - -#define JSSLOT_FREE(clasp) JSCLASS_RESERVED_SLOTS(clasp) - -#ifdef JS_THREADSAFE - -/* - * The GC runs only when all threads except the one on which the GC is active - * are suspended at GC-safe points, so calling obj->getSlot() from the GC's - * thread is safe when rt->gcRunning is set. See jsgc.cpp for details. - */ -#define THREAD_IS_RUNNING_GC(rt, thread) \ - ((rt)->gcRunning && (rt)->gcThread == (thread)) - -#define CX_THREAD_IS_RUNNING_GC(cx) \ - THREAD_IS_RUNNING_GC((cx)->runtime, (cx)->thread) - -#endif /* JS_THREADSAFE */ - -inline void -OBJ_TO_INNER_OBJECT(JSContext *cx, JSObject *&obj) -{ - if (JSObjectOp op = obj->getClass()->ext.innerObject) - obj = op(cx, obj); -} - -inline void -OBJ_TO_OUTER_OBJECT(JSContext *cx, JSObject *&obj) -{ - if (JSObjectOp op = obj->getClass()->ext.outerObject) - obj = op(cx, obj); -} - -class JSValueArray { - public: - jsval *array; - size_t length; - - JSValueArray(jsval *v, size_t c) : array(v), length(c) {} -}; - -class ValueArray { - public: - js::Value *array; - size_t length; - - ValueArray(js::Value *v, size_t c) : array(v), length(c) {} -}; - -extern js::Class js_ObjectClass; -extern js::Class js_WithClass; -extern js::Class js_BlockClass; - -inline bool JSObject::isObject() const { return getClass() == &js_ObjectClass; } -inline bool JSObject::isWith() const { return getClass() == &js_WithClass; } -inline bool JSObject::isBlock() const { return getClass() == &js_BlockClass; } - -/* - * Block scope object macros. The slots reserved by js_BlockClass are: - * - * private JSStackFrame * active frame pointer or null - * JSSLOT_BLOCK_DEPTH int depth of block slots in frame - * - * After JSSLOT_BLOCK_DEPTH come one or more slots for the block locals. - * - * A With object is like a Block object, in that both have one reserved slot - * telling the stack depth of the relevant slots (the slot whose value is the - * object named in the with statement, the slots containing the block's local - * variables); and both have a private slot referring to the JSStackFrame in - * whose activation they were created (or null if the with or block object - * outlives the frame). - */ -static const uint32 JSSLOT_BLOCK_DEPTH = 0; -static const uint32 JSSLOT_BLOCK_FIRST_FREE_SLOT = JSSLOT_BLOCK_DEPTH + 1; - -inline bool -JSObject::isStaticBlock() const -{ - return isBlock() && !getProto(); -} - -inline bool -JSObject::isClonedBlock() const -{ - return isBlock() && !!getProto(); -} - -static const uint32 JSSLOT_WITH_THIS = 1; - -#define OBJ_BLOCK_COUNT(cx,obj) \ - (obj)->propertyCount() -#define OBJ_BLOCK_DEPTH(cx,obj) \ - (obj)->getSlot(JSSLOT_BLOCK_DEPTH).toInt32() -#define OBJ_SET_BLOCK_DEPTH(cx,obj,depth) \ - (obj)->setSlot(JSSLOT_BLOCK_DEPTH, Value(Int32Value(depth))) - -/* - * To make sure this slot is well-defined, always call js_NewWithObject to - * create a With object, don't call js_NewObject directly. When creating a - * With object that does not correspond to a stack slot, pass -1 for depth. - * - * When popping the stack across this object's "with" statement, client code - * must call withobj->setPrivate(NULL). - */ -extern JS_REQUIRES_STACK JSObject * -js_NewWithObject(JSContext *cx, JSObject *proto, JSObject *parent, jsint depth); - -inline JSObject * -js_UnwrapWithObject(JSContext *cx, JSObject *withobj) -{ - JS_ASSERT(withobj->getClass() == &js_WithClass); - return withobj->getProto(); -} - -/* - * Create a new block scope object not linked to any proto or parent object. - * Blocks are created by the compiler to reify let blocks and comprehensions. - * Only when dynamic scope is captured do they need to be cloned and spliced - * into an active scope chain. - */ -extern JSObject * -js_NewBlockObject(JSContext *cx); - -extern JSObject * -js_CloneBlockObject(JSContext *cx, JSObject *proto, JSStackFrame *fp); - -extern JS_REQUIRES_STACK JSBool -js_PutBlockObject(JSContext *cx, JSBool normalUnwind); - -JSBool -js_XDRBlockObject(JSXDRState *xdr, JSObject **objp); - -struct JSSharpObjectMap { - jsrefcount depth; - jsatomid sharpgen; - JSHashTable *table; -}; - -#define SHARP_BIT ((jsatomid) 1) -#define BUSY_BIT ((jsatomid) 2) -#define SHARP_ID_SHIFT 2 -#define IS_SHARP(he) (uintptr_t((he)->value) & SHARP_BIT) -#define MAKE_SHARP(he) ((he)->value = (void *) (uintptr_t((he)->value)|SHARP_BIT)) -#define IS_BUSY(he) (uintptr_t((he)->value) & BUSY_BIT) -#define MAKE_BUSY(he) ((he)->value = (void *) (uintptr_t((he)->value)|BUSY_BIT)) -#define CLEAR_BUSY(he) ((he)->value = (void *) (uintptr_t((he)->value)&~BUSY_BIT)) - -extern JSHashEntry * -js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap, - jschar **sp); - -extern void -js_LeaveSharpObject(JSContext *cx, JSIdArray **idap); - -/* - * Mark objects stored in map if GC happens between js_EnterSharpObject - * and js_LeaveSharpObject. GC calls this when map->depth > 0. - */ -extern void -js_TraceSharpMap(JSTracer *trc, JSSharpObjectMap *map); - -extern JSBool -js_HasOwnPropertyHelper(JSContext *cx, js::LookupPropOp lookup, uintN argc, - js::Value *vp); - -extern JSBool -js_HasOwnProperty(JSContext *cx, js::LookupPropOp lookup, JSObject *obj, jsid id, - JSObject **objp, JSProperty **propp); - -extern JSBool -js_NewPropertyDescriptorObject(JSContext *cx, jsid id, uintN attrs, - const js::Value &getter, const js::Value &setter, - const js::Value &value, js::Value *vp); - -extern JSBool -js_PropertyIsEnumerable(JSContext *cx, JSObject *obj, jsid id, js::Value *vp); - -#ifdef OLD_GETTER_SETTER_METHODS -JS_FRIEND_API(JSBool) js_obj_defineGetter(JSContext *cx, uintN argc, js::Value *vp); -JS_FRIEND_API(JSBool) js_obj_defineSetter(JSContext *cx, uintN argc, js::Value *vp); -#endif - -extern JSObject * -js_InitObjectClass(JSContext *cx, JSObject *obj); - -namespace js { -JSObject * -DefineConstructorAndPrototype(JSContext *cx, JSObject *obj, JSProtoKey key, JSAtom *atom, - JSObject *protoProto, Class *clasp, - Native constructor, uintN nargs, - JSPropertySpec *ps, JSFunctionSpec *fs, - JSPropertySpec *static_ps, JSFunctionSpec *static_fs); -} - -extern JSObject * -js_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, - js::Class *clasp, js::Native constructor, uintN nargs, - JSPropertySpec *ps, JSFunctionSpec *fs, - JSPropertySpec *static_ps, JSFunctionSpec *static_fs); - -/* - * Select Object.prototype method names shared between jsapi.cpp and jsobj.cpp. - */ -extern const char js_watch_str[]; -extern const char js_unwatch_str[]; -extern const char js_hasOwnProperty_str[]; -extern const char js_isPrototypeOf_str[]; -extern const char js_propertyIsEnumerable_str[]; - -#ifdef OLD_GETTER_SETTER_METHODS -extern const char js_defineGetter_str[]; -extern const char js_defineSetter_str[]; -extern const char js_lookupGetter_str[]; -extern const char js_lookupSetter_str[]; -#endif - -extern JSBool -js_PopulateObject(JSContext *cx, JSObject *newborn, JSObject *props); - -/* - * Fast access to immutable standard objects (constructors and prototypes). - */ -extern JSBool -js_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, - JSObject **objp); - -extern JSBool -js_SetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, - JSObject *cobj, JSObject *prototype); - -/* - * If protoKey is not JSProto_Null, then clasp is ignored. If protoKey is - * JSProto_Null, clasp must non-null. - */ -extern JSBool -js_FindClassObject(JSContext *cx, JSObject *start, JSProtoKey key, - js::Value *vp, js::Class *clasp = NULL); - -extern JSObject * -js_ConstructObject(JSContext *cx, js::Class *clasp, JSObject *proto, - JSObject *parent, uintN argc, js::Value *argv); - -// Specialized call for constructing |this| with a known function callee, -// and a known prototype. -extern JSObject * -js_CreateThisForFunctionWithProto(JSContext *cx, JSObject *callee, JSObject *proto); - -// Specialized call for constructing |this| with a known function callee. -extern JSObject * -js_CreateThisForFunction(JSContext *cx, JSObject *callee); - -// Generic call for constructing |this|. -extern JSObject * -js_CreateThis(JSContext *cx, JSObject *callee); - -extern jsid -js_CheckForStringIndex(jsid id); - -/* - * js_PurgeScopeChain does nothing if obj is not itself a prototype or parent - * scope, else it reshapes the scope and prototype chains it links. It calls - * js_PurgeScopeChainHelper, which asserts that obj is flagged as a delegate - * (i.e., obj has ever been on a prototype or parent chain). - */ -extern void -js_PurgeScopeChainHelper(JSContext *cx, JSObject *obj, jsid id); - -inline void -js_PurgeScopeChain(JSContext *cx, JSObject *obj, jsid id) -{ - if (obj->isDelegate()) - js_PurgeScopeChainHelper(cx, obj, id); -} - -/* - * Find or create a property named by id in obj's scope, with the given getter - * and setter, slot, attributes, and other members. - */ -extern const js::Shape * -js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id, - js::PropertyOp getter, js::StrictPropertyOp setter, uint32 slot, - uintN attrs, uintN flags, intN shortid); - -/* - * Change shape to have the given attrs, getter, and setter in scope, morphing - * it into a potentially new js::Shape. Return a pointer to the changed - * or identical property. - */ -extern const js::Shape * -js_ChangeNativePropertyAttrs(JSContext *cx, JSObject *obj, - const js::Shape *shape, uintN attrs, uintN mask, - js::PropertyOp getter, js::StrictPropertyOp setter); - -extern JSBool -js_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id, - const js::Value &descriptor, JSBool *bp); - -/* - * Flags for the defineHow parameter of js_DefineNativeProperty. - */ -const uintN JSDNP_CACHE_RESULT = 1; /* an interpreter call from JSOP_INITPROP */ -const uintN JSDNP_DONT_PURGE = 2; /* suppress js_PurgeScopeChain */ -const uintN JSDNP_SET_METHOD = 4; /* js_{DefineNativeProperty,SetPropertyHelper} - must pass the js::Shape::METHOD - flag on to JSObject::{add,put}Property */ -const uintN JSDNP_UNQUALIFIED = 8; /* Unqualified property set. Only used in - the defineHow argument of - js_SetPropertyHelper. */ - -/* - * On error, return false. On success, if propp is non-null, return true with - * obj locked and with a held property in *propp; if propp is null, return true - * but release obj's lock first. - */ -extern JSBool -js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const js::Value &value, - js::PropertyOp getter, js::StrictPropertyOp setter, uintN attrs, - uintN flags, intN shortid, JSProperty **propp, - uintN defineHow = 0); - -/* - * Specialized subroutine that allows caller to preset JSRESOLVE_* flags and - * returns the index along the prototype chain in which *propp was found, or - * the last index if not found, or -1 on error. - */ -extern int -js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags, - JSObject **objp, JSProperty **propp); - - -extern JS_FRIEND_DATA(js::Class) js_CallClass; -extern JS_FRIEND_DATA(js::Class) js_DeclEnvClass; - -namespace js { - -/* - * We cache name lookup results only for the global object or for native - * non-global objects without prototype or with prototype that never mutates, - * see bug 462734 and bug 487039. - */ -static inline bool -IsCacheableNonGlobalScope(JSObject *obj) -{ - JS_ASSERT(obj->getParent()); - - js::Class *clasp = obj->getClass(); - bool cacheable = (clasp == &js_CallClass || - clasp == &js_BlockClass || - clasp == &js_DeclEnvClass); - - JS_ASSERT_IF(cacheable, !obj->getOps()->lookupProperty); - return cacheable; -} - -} - -/* - * If cacheResult is false, return JS_NO_PROP_CACHE_FILL on success. - */ -extern js::PropertyCacheEntry * -js_FindPropertyHelper(JSContext *cx, jsid id, JSBool cacheResult, - JSObject **objp, JSObject **pobjp, JSProperty **propp); - -/* - * Return the index along the scope chain in which id was found, or the last - * index if not found, or -1 on error. - */ -extern JS_FRIEND_API(JSBool) -js_FindProperty(JSContext *cx, jsid id, JSObject **objp, JSObject **pobjp, - JSProperty **propp); - -extern JS_REQUIRES_STACK JSObject * -js_FindIdentifierBase(JSContext *cx, JSObject *scopeChain, jsid id); - -extern JSObject * -js_FindVariableScope(JSContext *cx, JSFunction **funp); - -/* - * JSGET_CACHE_RESULT is the analogue of JSDNP_CACHE_RESULT for js_GetMethod. - * - * JSGET_METHOD_BARRIER (the default, hence 0 but provided for documentation) - * enables a read barrier that preserves standard function object semantics (by - * default we assume our caller won't leak a joined callee to script, where it - * would create hazardous mutable object sharing as well as observable identity - * according to == and ===. - * - * JSGET_NO_METHOD_BARRIER avoids the performance overhead of the method read - * barrier, which is not needed when invoking a lambda that otherwise does not - * leak its callee reference (via arguments.callee or its name). - */ -const uintN JSGET_CACHE_RESULT = 1; // from a caching interpreter opcode -const uintN JSGET_METHOD_BARRIER = 0; // get can leak joined function object -const uintN JSGET_NO_METHOD_BARRIER = 2; // call to joined function can't leak - -/* - * NB: js_NativeGet and js_NativeSet are called with the scope containing shape - * (pobj's scope for Get, obj's for Set) locked, and on successful return, that - * scope is again locked. But on failure, both functions return false with the - * scope containing shape unlocked. - */ -extern JSBool -js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj, const js::Shape *shape, uintN getHow, - js::Value *vp); - -extern JSBool -js_NativeSet(JSContext *cx, JSObject *obj, const js::Shape *shape, bool added, - bool strict, js::Value *vp); - -extern JSBool -js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uint32 getHow, js::Value *vp); - -extern bool -js_GetPropertyHelperWithShape(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, - uint32 getHow, js::Value *vp, - const js::Shape **shapeOut, JSObject **holderOut); - -extern JSBool -js_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, js::Value *vp); - -extern JSBool -js_GetMethod(JSContext *cx, JSObject *obj, jsid id, uintN getHow, js::Value *vp); - -/* - * Check whether it is OK to assign an undeclared property with name - * propname of the global object in the current script on cx. Reports - * an error if one needs to be reported (in particular in all cases - * when it returns false). - */ -extern JS_FRIEND_API(bool) -js_CheckUndeclaredVarAssignment(JSContext *cx, JSString *propname); - -extern JSBool -js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow, - js::Value *vp, JSBool strict); - -/* - * Change attributes for the given native property. The caller must ensure - * that obj is locked and this function always unlocks obj on return. - */ -extern JSBool -js_SetNativeAttributes(JSContext *cx, JSObject *obj, js::Shape *shape, - uintN attrs); - -namespace js { - -/* - * If obj has a data property methodid which is a function object for the given - * native, return that function object. Otherwise, return NULL. - */ -extern JSObject * -HasNativeMethod(JSObject *obj, jsid methodid, Native native); - -extern bool -DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp); - -extern JSBool -CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, - js::Value *vp, uintN *attrsp); - -} /* namespace js */ - -extern bool -js_IsDelegate(JSContext *cx, JSObject *obj, const js::Value &v); - -/* - * If protoKey is not JSProto_Null, then clasp is ignored. If protoKey is - * JSProto_Null, clasp must non-null. - */ -extern JS_FRIEND_API(JSBool) -js_GetClassPrototype(JSContext *cx, JSObject *scope, JSProtoKey protoKey, - JSObject **protop, js::Class *clasp = NULL); - -extern JSBool -js_SetClassPrototype(JSContext *cx, JSObject *ctor, JSObject *proto, - uintN attrs); - -/* - * Wrap boolean, number or string as Boolean, Number or String object. - * *vp must not be an object, null or undefined. - */ -extern JSBool -js_PrimitiveToObject(JSContext *cx, js::Value *vp); - -/* - * v and vp may alias. On successful return, vp->isObjectOrNull(). If vp is not - * rooted, the caller must root vp before the next possible GC. - */ -extern JSBool -js_ValueToObjectOrNull(JSContext *cx, const js::Value &v, JSObject **objp); - -namespace js { - -/* - * Invokes the ES5 ToObject algorithm on *vp, writing back the object to vp. - * If *vp might already be an object, use ToObject. - */ -extern JSObject * -ToObjectSlow(JSContext *cx, js::Value *vp); - -JS_ALWAYS_INLINE JSObject * -ToObject(JSContext *cx, js::Value *vp) -{ - if (vp->isObject()) - return &vp->toObject(); - return ToObjectSlow(cx, vp); -} - -} - -/* - * v and vp may alias. On successful return, vp->isObject(). If vp is not - * rooted, the caller must root vp before the next possible GC. - */ -extern JSObject * -js_ValueToNonNullObject(JSContext *cx, const js::Value &v); - -extern JSBool -js_TryValueOf(JSContext *cx, JSObject *obj, JSType type, js::Value *rval); - -extern JSBool -js_TryMethod(JSContext *cx, JSObject *obj, JSAtom *atom, - uintN argc, js::Value *argv, js::Value *rval); - -extern JSBool -js_XDRObject(JSXDRState *xdr, JSObject **objp); - -extern void -js_TraceObject(JSTracer *trc, JSObject *obj); - -extern void -js_PrintObjectSlotName(JSTracer *trc, char *buf, size_t bufsize); - -extern void -js_ClearNative(JSContext *cx, JSObject *obj); - -extern bool -js_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, js::Value *vp); - -extern bool -js_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, const js::Value &v); - -extern JSBool -js_CheckPrincipalsAccess(JSContext *cx, JSObject *scopeobj, - JSPrincipals *principals, JSAtom *caller); - -/* For CSP -- checks if eval() and friends are allowed to run. */ -extern JSBool -js_CheckContentSecurityPolicy(JSContext *cx, JSObject *scopeObj); - -/* NB: Infallible. */ -extern const char * -js_ComputeFilename(JSContext *cx, JSStackFrame *caller, - JSPrincipals *principals, uintN *linenop); - -extern JSBool -js_ReportGetterOnlyAssignment(JSContext *cx); - -extern JS_FRIEND_API(JSBool) -js_GetterOnlyPropertyStub(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp); - -#ifdef DEBUG -JS_FRIEND_API(void) js_DumpChars(const jschar *s, size_t n); -JS_FRIEND_API(void) js_DumpString(JSString *str); -JS_FRIEND_API(void) js_DumpAtom(JSAtom *atom); -JS_FRIEND_API(void) js_DumpObject(JSObject *obj); -JS_FRIEND_API(void) js_DumpValue(const js::Value &val); -JS_FRIEND_API(void) js_DumpId(jsid id); -JS_FRIEND_API(void) js_DumpStackFrame(JSContext *cx, JSStackFrame *start = NULL); -#endif - -extern uintN -js_InferFlags(JSContext *cx, uintN defaultFlags); - -/* Object constructor native. Exposed only so the JIT can know its address. */ -JSBool -js_Object(JSContext *cx, uintN argc, js::Value *vp); - - -namespace js { - -extern bool -SetProto(JSContext *cx, JSObject *obj, JSObject *proto, bool checkForCycles); - -extern JSString * -obj_toStringHelper(JSContext *cx, JSObject *obj); - -enum EvalType { INDIRECT_EVAL, DIRECT_EVAL }; - -/* - * Common code implementing direct and indirect eval. - * - * Evaluate vp[2], if it is a string, in the context of the given calling - * frame, with the provided scope chain, with the semantics of either a direct - * or indirect eval (see ES5 10.4.2). If this is an indirect eval, scopeobj - * must be a global object. - * - * On success, store the completion value in *vp and return true. - */ -extern bool -EvalKernel(JSContext *cx, uintN argc, js::Value *vp, EvalType evalType, JSStackFrame *caller, - JSObject *scopeobj); - -extern JS_FRIEND_API(bool) -IsBuiltinEvalFunction(JSFunction *fun); - -} - -#ifdef JS_OBJ_UNDEFD_MOZALLOC_WRAPPERS -# include "mozilla/mozalloc_macro_wrappers.h" -#endif - -#endif /* jsobj_h___ */ diff --git a/x86/mozilla/include/jsobjinlines.h b/x86/mozilla/include/jsobjinlines.h deleted file mode 100644 index d60557c..0000000 --- a/x86/mozilla/include/jsobjinlines.h +++ /dev/null @@ -1,1222 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsobjinlines_h___ -#define jsobjinlines_h___ - -#include -#include "jsdate.h" -#include "jsfun.h" -#include "jsiter.h" -#include "jslock.h" -#include "jsobj.h" -#include "jsprobes.h" -#include "jspropertytree.h" -#include "jsproxy.h" -#include "jsscope.h" -#include "jsstaticcheck.h" -#include "jsxml.h" - -/* Headers included for inline implementations used by this header. */ -#include "jsbool.h" -#include "jscntxt.h" -#include "jsnum.h" -#include "jsscopeinlines.h" -#include "jsstr.h" - -#include "jsfuninlines.h" -#include "jsgcinlines.h" -#include "jsprobes.h" - -inline bool -JSObject::preventExtensions(JSContext *cx, js::AutoIdVector *props) -{ - JS_ASSERT(isExtensible()); - - if (js::FixOp fix = getOps()->fix) { - bool success; - if (!fix(cx, this, &success, props)) - return false; - if (!success) { - JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CHANGE_EXTENSIBILITY); - return false; - } - } else { - if (!GetPropertyNames(cx, this, JSITER_HIDDEN | JSITER_OWNONLY, props)) - return false; - } - - if (isNative()) - extensibleShapeChange(cx); - - flags |= NOT_EXTENSIBLE; - return true; -} - -inline bool -JSObject::brand(JSContext *cx) -{ - JS_ASSERT(!generic()); - JS_ASSERT(!branded()); - JS_ASSERT(isNative()); - generateOwnShape(cx); - if (js_IsPropertyCacheDisabled(cx)) // check for rt->shapeGen overflow - return false; - flags |= BRANDED; - return true; -} - -inline bool -JSObject::unbrand(JSContext *cx) -{ - JS_ASSERT(isNative()); - if (branded()) { - generateOwnShape(cx); - if (js_IsPropertyCacheDisabled(cx)) // check for rt->shapeGen overflow - return false; - flags &= ~BRANDED; - } - setGeneric(); - return true; -} - -inline void -JSObject::syncSpecialEquality() -{ - if (clasp->ext.equality) - flags |= JSObject::HAS_EQUALITY; -} - -inline void -JSObject::finalize(JSContext *cx) -{ - /* Cope with stillborn objects that have no map. */ - if (!map) - return; - - /* Finalize obj first, in case it needs map and slots. */ - js::Class *clasp = getClass(); - if (clasp->finalize) - clasp->finalize(cx, this); - - js::Probes::finalizeObject(this); - - finish(cx); -} - -/* - * Property read barrier for deferred cloning of compiler-created function - * objects optimized as typically non-escaping, ad-hoc methods in obj. - */ -inline const js::Shape * -JSObject::methodReadBarrier(JSContext *cx, const js::Shape &shape, js::Value *vp) -{ - JS_ASSERT(canHaveMethodBarrier()); - JS_ASSERT(hasMethodBarrier()); - JS_ASSERT(nativeContains(shape)); - JS_ASSERT(shape.isMethod()); - JS_ASSERT(&shape.methodObject() == &vp->toObject()); - JS_ASSERT(shape.writable()); - JS_ASSERT(shape.slot != SHAPE_INVALID_SLOT); - JS_ASSERT(shape.hasDefaultSetter() || shape.setterOp() == js_watch_set); - JS_ASSERT(!isGlobal()); /* i.e. we are not changing the global shape */ - - JSObject *funobj = &vp->toObject(); - JSFunction *fun = funobj->getFunctionPrivate(); - JS_ASSERT(fun == funobj); - JS_ASSERT(FUN_NULL_CLOSURE(fun)); - - funobj = CloneFunctionObject(cx, fun, funobj->getParent()); - if (!funobj) - return NULL; - funobj->setMethodObj(*this); - - /* - * Replace the method property with an ordinary data property. This is - * equivalent to this->setProperty(cx, shape.id, vp) except that any - * watchpoint on the property is not triggered. - */ - uint32 slot = shape.slot; - const js::Shape *newshape = methodShapeChange(cx, shape); - if (!newshape) - return NULL; - JS_ASSERT(!newshape->isMethod()); - JS_ASSERT(newshape->slot == slot); - vp->setObject(*funobj); - nativeSetSlot(slot, *vp); - -#ifdef DEBUG - if (cx->runtime->functionMeterFilename) { - JS_FUNCTION_METER(cx, mreadbarrier); - - typedef JSRuntime::FunctionCountMap HM; - HM &h = cx->runtime->methodReadBarrierCountMap; - HM::AddPtr p = h.lookupForAdd(fun); - if (!p) { - h.add(p, fun, 1); - } else { - JS_ASSERT(p->key == fun); - ++p->value; - } - } -#endif - return newshape; -} - -static JS_ALWAYS_INLINE bool -ChangesMethodValue(const js::Value &prev, const js::Value &v) -{ - JSObject *prevObj; - return prev.isObject() && (prevObj = &prev.toObject())->isFunction() && - (!v.isObject() || &v.toObject() != prevObj); -} - -inline const js::Shape * -JSObject::methodWriteBarrier(JSContext *cx, const js::Shape &shape, const js::Value &v) -{ - if (brandedOrHasMethodBarrier() && shape.slot != SHAPE_INVALID_SLOT) { - const js::Value &prev = nativeGetSlot(shape.slot); - - if (ChangesMethodValue(prev, v)) { - JS_FUNCTION_METER(cx, mwritebarrier); - return methodShapeChange(cx, shape); - } - } - return &shape; -} - -inline bool -JSObject::methodWriteBarrier(JSContext *cx, uint32 slot, const js::Value &v) -{ - if (brandedOrHasMethodBarrier()) { - const js::Value &prev = nativeGetSlot(slot); - - if (ChangesMethodValue(prev, v)) { - JS_FUNCTION_METER(cx, mwslotbarrier); - return methodShapeChange(cx, slot); - } - } - return true; -} - -inline bool -JSObject::ensureClassReservedSlots(JSContext *cx) -{ - return !nativeEmpty() || ensureClassReservedSlotsForEmptyObject(cx); -} - -inline js::Value -JSObject::getReservedSlot(uintN index) const -{ - return (index < numSlots()) ? getSlot(index) : js::UndefinedValue(); -} - -inline bool -JSObject::canHaveMethodBarrier() const -{ - return isObject() || isFunction() || isPrimitive() || isDate(); -} - -inline bool -JSObject::isPrimitive() const -{ - return isNumber() || isString() || isBoolean(); -} - -inline const js::Value & -JSObject::getPrimitiveThis() const -{ - JS_ASSERT(isPrimitive()); - return getSlot(JSSLOT_PRIMITIVE_THIS); -} - -inline void -JSObject::setPrimitiveThis(const js::Value &pthis) -{ - JS_ASSERT(isPrimitive()); - setSlot(JSSLOT_PRIMITIVE_THIS, pthis); -} - -inline /* gc::FinalizeKind */ unsigned -JSObject::finalizeKind() const -{ - return js::gc::FinalizeKind(arena()->header()->thingKind); -} - -inline size_t -JSObject::numFixedSlots() const -{ - if (isFunction()) - return JSObject::FUN_CLASS_RESERVED_SLOTS; - if (!hasSlotsArray()) - return capacity; - return js::gc::GetGCKindSlots(js::gc::FinalizeKind(finalizeKind())); -} - -inline size_t -JSObject::slotsAndStructSize(uint32 nslots) const -{ - bool isFun = isFunction() && this == (JSObject*) getPrivate(); - - int ndslots = hasSlotsArray() ? nslots : 0; - int nfslots = isFun ? 0 : numFixedSlots(); - - return sizeof(js::Value) * (ndslots + nfslots) - + isFun ? sizeof(JSFunction) : sizeof(JSObject); -} - -inline uint32 -JSObject::getArrayLength() const -{ - JS_ASSERT(isArray()); - return (uint32)(size_t) getPrivate(); -} - -inline void -JSObject::setArrayLength(uint32 length) -{ - JS_ASSERT(isArray()); - setPrivate((void*) length); -} - -inline uint32 -JSObject::getDenseArrayCapacity() -{ - JS_ASSERT(isDenseArray()); - return numSlots(); -} - -inline js::Value* -JSObject::getDenseArrayElements() -{ - JS_ASSERT(isDenseArray()); - return getSlots(); -} - -inline const js::Value & -JSObject::getDenseArrayElement(uintN idx) -{ - JS_ASSERT(isDenseArray()); - return getSlot(idx); -} - -inline js::Value * -JSObject::addressOfDenseArrayElement(uintN idx) -{ - JS_ASSERT(isDenseArray()); - return &getSlotRef(idx); -} - -inline void -JSObject::setDenseArrayElement(uintN idx, const js::Value &val) -{ - JS_ASSERT(isDenseArray()); - setSlot(idx, val); -} - -inline void -JSObject::shrinkDenseArrayElements(JSContext *cx, uintN cap) -{ - JS_ASSERT(isDenseArray()); - shrinkSlots(cx, cap); -} - -inline void -JSObject::setArgsLength(uint32 argc) -{ - JS_ASSERT(isArguments()); - JS_ASSERT(argc <= JS_ARGS_LENGTH_MAX); - JS_ASSERT(UINT32_MAX > (uint64(argc) << ARGS_PACKED_BITS_COUNT)); - getSlotRef(JSSLOT_ARGS_LENGTH).setInt32(argc << ARGS_PACKED_BITS_COUNT); - JS_ASSERT(!isArgsLengthOverridden()); -} - -inline uint32 -JSObject::getArgsInitialLength() const -{ - JS_ASSERT(isArguments()); - uint32 argc = uint32(getSlot(JSSLOT_ARGS_LENGTH).toInt32()) >> ARGS_PACKED_BITS_COUNT; - JS_ASSERT(argc <= JS_ARGS_LENGTH_MAX); - return argc; -} - -inline void -JSObject::setArgsLengthOverridden() -{ - JS_ASSERT(isArguments()); - getSlotRef(JSSLOT_ARGS_LENGTH).getInt32Ref() |= ARGS_LENGTH_OVERRIDDEN_BIT; -} - -inline bool -JSObject::isArgsLengthOverridden() const -{ - JS_ASSERT(isArguments()); - const js::Value &v = getSlot(JSSLOT_ARGS_LENGTH); - return v.toInt32() & ARGS_LENGTH_OVERRIDDEN_BIT; -} - -inline js::ArgumentsData * -JSObject::getArgsData() const -{ - JS_ASSERT(isArguments()); - return (js::ArgumentsData *) getSlot(JSSLOT_ARGS_DATA).toPrivate(); -} - -inline void -JSObject::setArgsData(js::ArgumentsData *data) -{ - JS_ASSERT(isArguments()); - getSlotRef(JSSLOT_ARGS_DATA).setPrivate(data); -} - -inline const js::Value & -JSObject::getArgsCallee() const -{ - return getArgsData()->callee; -} - -inline void -JSObject::setArgsCallee(const js::Value &callee) -{ - getArgsData()->callee = callee; -} - -inline const js::Value & -JSObject::getArgsElement(uint32 i) const -{ - JS_ASSERT(isArguments()); - JS_ASSERT(i < getArgsInitialLength()); - return getArgsData()->slots[i]; -} - -inline js::Value * -JSObject::getArgsElements() const -{ - JS_ASSERT(isArguments()); - return getArgsData()->slots; -} - -inline js::Value * -JSObject::addressOfArgsElement(uint32 i) -{ - JS_ASSERT(isArguments()); - JS_ASSERT(i < getArgsInitialLength()); - return &getArgsData()->slots[i]; -} - -inline void -JSObject::setArgsElement(uint32 i, const js::Value &v) -{ - JS_ASSERT(isArguments()); - JS_ASSERT(i < getArgsInitialLength()); - getArgsData()->slots[i] = v; -} - -inline bool -JSObject::callIsForEval() const -{ - JS_ASSERT(isCall()); - JS_ASSERT(getSlot(JSSLOT_CALL_CALLEE).isObjectOrNull()); - JS_ASSERT_IF(getSlot(JSSLOT_CALL_CALLEE).isObject(), - getSlot(JSSLOT_CALL_CALLEE).toObject().isFunction()); - return getSlot(JSSLOT_CALL_CALLEE).isNull(); -} - -inline JSStackFrame * -JSObject::maybeCallObjStackFrame() const -{ - JS_ASSERT(isCall()); - return reinterpret_cast(getPrivate()); -} - -inline void -JSObject::setCallObjCallee(JSObject *callee) -{ - JS_ASSERT(isCall()); - JS_ASSERT_IF(callee, callee->isFunction()); - return getSlotRef(JSSLOT_CALL_CALLEE).setObjectOrNull(callee); -} - -inline JSObject * -JSObject::getCallObjCallee() const -{ - JS_ASSERT(isCall()); - return getSlot(JSSLOT_CALL_CALLEE).toObjectOrNull(); -} - -inline JSFunction * -JSObject::getCallObjCalleeFunction() const -{ - JS_ASSERT(isCall()); - return getSlot(JSSLOT_CALL_CALLEE).toObject().getFunctionPrivate(); -} - -inline const js::Value & -JSObject::getCallObjArguments() const -{ - JS_ASSERT(isCall()); - JS_ASSERT(!callIsForEval()); - return getSlot(JSSLOT_CALL_ARGUMENTS); -} - -inline void -JSObject::setCallObjArguments(const js::Value &v) -{ - JS_ASSERT(isCall()); - JS_ASSERT(!callIsForEval()); - setSlot(JSSLOT_CALL_ARGUMENTS, v); -} - -inline const js::Value & -JSObject::callObjArg(uintN i) const -{ - JS_ASSERT(isCall()); - JS_ASSERT(i < getCallObjCalleeFunction()->nargs); - return getSlot(JSObject::CALL_RESERVED_SLOTS + i); -} - -inline js::Value & -JSObject::callObjArg(uintN i) -{ - JS_ASSERT(isCall()); - JS_ASSERT(i < getCallObjCalleeFunction()->nargs); - return getSlotRef(JSObject::CALL_RESERVED_SLOTS + i); -} - -inline const js::Value & -JSObject::callObjVar(uintN i) const -{ - JSFunction *fun = getCallObjCalleeFunction(); - JS_ASSERT(fun->nargs == fun->script()->bindings.countArgs()); - JS_ASSERT(i < fun->script()->bindings.countVars()); - return getSlot(JSObject::CALL_RESERVED_SLOTS + fun->nargs + i); -} - -inline js::Value & -JSObject::callObjVar(uintN i) -{ - JSFunction *fun = getCallObjCalleeFunction(); - JS_ASSERT(fun->nargs == fun->script()->bindings.countArgs()); - JS_ASSERT(i < fun->script()->bindings.countVars()); - return getSlotRef(JSObject::CALL_RESERVED_SLOTS + fun->nargs + i); -} - -inline const js::Value & -JSObject::getDateUTCTime() const -{ - JS_ASSERT(isDate()); - return getSlot(JSSLOT_DATE_UTC_TIME); -} - -inline void -JSObject::setDateUTCTime(const js::Value &time) -{ - JS_ASSERT(isDate()); - setSlot(JSSLOT_DATE_UTC_TIME, time); -} - -inline js::Value * -JSObject::getFlatClosureUpvars() const -{ -#ifdef DEBUG - JSFunction *fun = getFunctionPrivate(); - JS_ASSERT(fun->isFlatClosure()); - JS_ASSERT(fun->script()->bindings.countUpvars() == fun->script()->upvars()->length); -#endif - return (js::Value *) getSlot(JSSLOT_FLAT_CLOSURE_UPVARS).toPrivate(); -} - -inline js::Value -JSObject::getFlatClosureUpvar(uint32 i) const -{ - JS_ASSERT(i < getFunctionPrivate()->script()->bindings.countUpvars()); - return getFlatClosureUpvars()[i]; -} - -inline js::Value & -JSObject::getFlatClosureUpvar(uint32 i) -{ - JS_ASSERT(i < getFunctionPrivate()->script()->bindings.countUpvars()); - return getFlatClosureUpvars()[i]; -} - -inline void -JSObject::setFlatClosureUpvars(js::Value *upvars) -{ - JS_ASSERT(isFunction()); - JS_ASSERT(FUN_FLAT_CLOSURE(getFunctionPrivate())); - getSlotRef(JSSLOT_FLAT_CLOSURE_UPVARS).setPrivate(upvars); -} - -inline bool -JSObject::hasMethodObj(const JSObject& obj) const -{ - return JSSLOT_FUN_METHOD_OBJ < numSlots() && - getSlot(JSSLOT_FUN_METHOD_OBJ).isObject() && - &getSlot(JSSLOT_FUN_METHOD_OBJ).toObject() == &obj; -} - -inline void -JSObject::setMethodObj(JSObject& obj) -{ - getSlotRef(JSSLOT_FUN_METHOD_OBJ).setObject(obj); -} - -inline js::NativeIterator * -JSObject::getNativeIterator() const -{ - return (js::NativeIterator *) getPrivate(); -} - -inline void -JSObject::setNativeIterator(js::NativeIterator *ni) -{ - setPrivate(ni); -} - -inline JSLinearString * -JSObject::getNamePrefix() const -{ - JS_ASSERT(isNamespace() || isQName()); - const js::Value &v = getSlot(JSSLOT_NAME_PREFIX); - return !v.isUndefined() ? v.toString()->assertIsLinear() : NULL; -} - -inline jsval -JSObject::getNamePrefixVal() const -{ - JS_ASSERT(isNamespace() || isQName()); - return js::Jsvalify(getSlot(JSSLOT_NAME_PREFIX)); -} - -inline void -JSObject::setNamePrefix(JSLinearString *prefix) -{ - JS_ASSERT(isNamespace() || isQName()); - setSlot(JSSLOT_NAME_PREFIX, prefix ? js::StringValue(prefix) : js::UndefinedValue()); -} - -inline void -JSObject::clearNamePrefix() -{ - JS_ASSERT(isNamespace() || isQName()); - setSlot(JSSLOT_NAME_PREFIX, js::UndefinedValue()); -} - -inline JSLinearString * -JSObject::getNameURI() const -{ - JS_ASSERT(isNamespace() || isQName()); - const js::Value &v = getSlot(JSSLOT_NAME_URI); - return !v.isUndefined() ? v.toString()->assertIsLinear() : NULL; -} - -inline jsval -JSObject::getNameURIVal() const -{ - JS_ASSERT(isNamespace() || isQName()); - return js::Jsvalify(getSlot(JSSLOT_NAME_URI)); -} - -inline void -JSObject::setNameURI(JSLinearString *uri) -{ - JS_ASSERT(isNamespace() || isQName()); - setSlot(JSSLOT_NAME_URI, uri ? js::StringValue(uri) : js::UndefinedValue()); -} - -inline jsval -JSObject::getNamespaceDeclared() const -{ - JS_ASSERT(isNamespace()); - return js::Jsvalify(getSlot(JSSLOT_NAMESPACE_DECLARED)); -} - -inline void -JSObject::setNamespaceDeclared(jsval decl) -{ - JS_ASSERT(isNamespace()); - setSlot(JSSLOT_NAMESPACE_DECLARED, js::Valueify(decl)); -} - -inline JSLinearString * -JSObject::getQNameLocalName() const -{ - JS_ASSERT(isQName()); - const js::Value &v = getSlot(JSSLOT_QNAME_LOCAL_NAME); - return !v.isUndefined() ? v.toString()->assertIsLinear() : NULL; -} - -inline jsval -JSObject::getQNameLocalNameVal() const -{ - JS_ASSERT(isQName()); - return js::Jsvalify(getSlot(JSSLOT_QNAME_LOCAL_NAME)); -} - -inline void -JSObject::setQNameLocalName(JSLinearString *name) -{ - JS_ASSERT(isQName()); - setSlot(JSSLOT_QNAME_LOCAL_NAME, name ? js::StringValue(name) : js::UndefinedValue()); -} - -inline JSObject * -JSObject::getWithThis() const -{ - return &getSlot(JSSLOT_WITH_THIS).toObject(); -} - -inline void -JSObject::setWithThis(JSObject *thisp) -{ - getSlotRef(JSSLOT_WITH_THIS).setObject(*thisp); -} - -inline void -JSObject::init(JSContext *cx, js::Class *aclasp, JSObject *proto, JSObject *parent, - void *priv, bool useHoles) -{ - clasp = aclasp; - flags = 0; - -#ifdef DEBUG - /* - * NB: objShape must not be set here; rather, the caller must call setMap - * or setSharedNonNativeMap after calling init. To defend this requirement - * we set map to null in DEBUG builds, and set objShape to a value we then - * assert obj->shape() never returns. - */ - map = NULL; - objShape = JSObjectMap::INVALID_SHAPE; -#endif - - setProto(proto); - setParent(parent); - - privateData = priv; - slots = fixedSlots(); - - /* - * Fill the fixed slots with undefined or array holes. This object must - * already have its capacity filled in, as by js_NewGCObject. - */ - JS_ASSERT(capacity == numFixedSlots()); - ClearValueRange(slots, capacity, useHoles); - - emptyShapes = NULL; -} - -inline void -JSObject::finish(JSContext *cx) -{ -#ifdef DEBUG - if (isNative()) - JS_LOCK_RUNTIME_VOID(cx->runtime, cx->runtime->liveObjectProps -= propertyCount()); -#endif - if (hasSlotsArray()) - freeSlotsArray(cx); - if (emptyShapes) - cx->free(emptyShapes); -} - -inline bool -JSObject::initSharingEmptyShape(JSContext *cx, - js::Class *aclasp, - JSObject *proto, - JSObject *parent, - void *privateValue, - /* js::gc::FinalizeKind */ unsigned kind) -{ - init(cx, aclasp, proto, parent, privateValue, false); - - JS_ASSERT(!isDenseArray()); - - js::EmptyShape *empty = proto->getEmptyShape(cx, aclasp, kind); - if (!empty) - return false; - - setMap(empty); - return true; -} - -inline void -JSObject::freeSlotsArray(JSContext *cx) -{ - JS_ASSERT(hasSlotsArray()); - cx->free(slots); -} - -inline void -JSObject::revertToFixedSlots(JSContext *cx) -{ - JS_ASSERT(hasSlotsArray()); - size_t fixed = numFixedSlots(); - JS_ASSERT(capacity >= fixed); - memcpy(fixedSlots(), slots, fixed * sizeof(js::Value)); - freeSlotsArray(cx); - slots = fixedSlots(); - capacity = fixed; -} - -inline bool -JSObject::hasProperty(JSContext *cx, jsid id, bool *foundp, uintN flags) -{ - JSObject *pobj; - JSProperty *prop; - JSAutoResolveFlags rf(cx, flags); - if (!lookupProperty(cx, id, &pobj, &prop)) - return false; - *foundp = !!prop; - return true; -} - -inline bool -JSObject::isCallable() -{ - return isFunction() || getClass()->call; -} - -static inline bool -js_IsCallable(const js::Value &v) -{ - return v.isObject() && v.toObject().isCallable(); -} - -namespace js { - -class AutoPropDescArrayRooter : private AutoGCRooter -{ - public: - AutoPropDescArrayRooter(JSContext *cx) - : AutoGCRooter(cx, DESCRIPTORS), descriptors(cx) - { } - - PropDesc *append() { - if (!descriptors.append(PropDesc())) - return NULL; - return &descriptors.back(); - } - - PropDesc& operator[](size_t i) { - JS_ASSERT(i < descriptors.length()); - return descriptors[i]; - } - - friend void AutoGCRooter::trace(JSTracer *trc); - - private: - PropDescArray descriptors; -}; - -class AutoPropertyDescriptorRooter : private AutoGCRooter, public PropertyDescriptor -{ - public: - AutoPropertyDescriptorRooter(JSContext *cx) : AutoGCRooter(cx, DESCRIPTOR) { - obj = NULL; - attrs = 0; - getter = (PropertyOp) NULL; - setter = (StrictPropertyOp) NULL; - value.setUndefined(); - } - - AutoPropertyDescriptorRooter(JSContext *cx, PropertyDescriptor *desc) - : AutoGCRooter(cx, DESCRIPTOR) - { - obj = desc->obj; - attrs = desc->attrs; - getter = desc->getter; - setter = desc->setter; - value = desc->value; - } - - friend void AutoGCRooter::trace(JSTracer *trc); -}; - -static inline bool -InitScopeForObject(JSContext* cx, JSObject* obj, js::Class *clasp, JSObject* proto, - gc::FinalizeKind kind) -{ - JS_ASSERT(clasp->isNative()); - JS_ASSERT(proto == obj->getProto()); - - /* Share proto's emptyShape only if obj is similar to proto. */ - js::EmptyShape *empty = NULL; - - if (proto) { - if (proto->canProvideEmptyShape(clasp)) { - empty = proto->getEmptyShape(cx, clasp, kind); - if (!empty) - goto bad; - } - } - - if (!empty) { - empty = js::EmptyShape::create(cx, clasp); - if (!empty) - goto bad; - uint32 freeslot = JSSLOT_FREE(clasp); - if (freeslot > obj->numSlots() && !obj->allocSlots(cx, freeslot)) - goto bad; - } - - obj->setMap(empty); - return true; - - bad: - /* The GC nulls map initially. It should still be null on error. */ - JS_ASSERT(!obj->map); - return false; -} - -/* - * Helper optimized for creating a native instance of the given class (not the - * class's prototype object). Use this in preference to NewObject, but use - * NewBuiltinClassInstance if you need the default class prototype as proto, - * and its parent global as parent. - */ -static inline JSObject * -NewNativeClassInstance(JSContext *cx, Class *clasp, JSObject *proto, - JSObject *parent, gc::FinalizeKind kind) -{ - JS_ASSERT(proto); - JS_ASSERT(parent); - - /* - * Allocate an object from the GC heap and initialize all its fields before - * doing any operation that can potentially trigger GC. - */ - JSObject* obj = js_NewGCObject(cx, kind); - - if (obj) { - /* - * Default parent to the parent of the prototype, which was set from - * the parent of the prototype's constructor. - */ - bool useHoles = (clasp == &js_ArrayClass); - obj->init(cx, clasp, proto, parent, NULL, useHoles); - - JS_ASSERT(proto->canProvideEmptyShape(clasp)); - js::EmptyShape *empty = proto->getEmptyShape(cx, clasp, kind); - - if (empty) - obj->setMap(empty); - else - obj = NULL; - } - - return obj; -} - -static inline JSObject * -NewNativeClassInstance(JSContext *cx, Class *clasp, JSObject *proto, JSObject *parent) -{ - gc::FinalizeKind kind = gc::GetGCObjectKind(JSCLASS_RESERVED_SLOTS(clasp)); - return NewNativeClassInstance(cx, clasp, proto, parent, kind); -} - -bool -FindClassPrototype(JSContext *cx, JSObject *scope, JSProtoKey protoKey, JSObject **protop, - Class *clasp); - -/* - * Helper used to create Boolean, Date, RegExp, etc. instances of built-in - * classes with class prototypes of the same Class. See, e.g., jsdate.cpp, - * jsregexp.cpp, and js_PrimitiveToObject in jsobj.cpp. Use this to get the - * right default proto and parent for clasp in cx. - */ -static inline JSObject * -NewBuiltinClassInstance(JSContext *cx, Class *clasp, gc::FinalizeKind kind) -{ - VOUCH_DOES_NOT_REQUIRE_STACK(); - - JSProtoKey protoKey = JSCLASS_CACHED_PROTO_KEY(clasp); - JS_ASSERT(protoKey != JSProto_Null); - - /* NB: inline-expanded and specialized version of js_GetClassPrototype. */ - JSObject *global; - if (!cx->hasfp()) { - global = cx->globalObject; - OBJ_TO_INNER_OBJECT(cx, global); - if (!global) - return NULL; - } else { - global = cx->fp()->scopeChain().getGlobal(); - } - JS_ASSERT(global->isGlobal()); - - const Value &v = global->getReservedSlot(JSProto_LIMIT + protoKey); - JSObject *proto; - if (v.isObject()) { - proto = &v.toObject(); - JS_ASSERT(proto->getParent() == global); - } else { - if (!FindClassPrototype(cx, global, protoKey, &proto, clasp)) - return NULL; - } - - return NewNativeClassInstance(cx, clasp, proto, global, kind); -} - -static inline JSObject * -NewBuiltinClassInstance(JSContext *cx, Class *clasp) -{ - gc::FinalizeKind kind = gc::GetGCObjectKind(JSCLASS_RESERVED_SLOTS(clasp)); - return NewBuiltinClassInstance(cx, clasp, kind); -} - -static inline JSProtoKey -GetClassProtoKey(js::Class *clasp) -{ - JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(clasp); - if (key != JSProto_Null) - return key; - if (clasp->flags & JSCLASS_IS_ANONYMOUS) - return JSProto_Object; - return JSProto_Null; -} - -namespace WithProto { - enum e { - Class = 0, - Given = 1 - }; -} - -/* - * Create an instance of any class, native or not, JSFunction-sized or not. - * - * If withProto is 'Class': - * If proto is null: - * for a built-in class: - * use the memoized original value of the class constructor .prototype - * property object - * else if available - * the current value of .prototype - * else - * Object.prototype. - * - * If parent is null, default it to proto->getParent() if proto is non - * null, else to null. - * - * If withProto is 'Given': - * We allocate an object with exactly the given proto. A null parent - * defaults to proto->getParent() if proto is non-null (else to null). - * - * If isFunction is true, return a JSFunction-sized object. If isFunction is - * false, return a normal object. - * - * Note that as a template, there will be lots of instantiations, which means - * the internals will be specialized based on the template parameters. - */ -static JS_ALWAYS_INLINE bool -FindProto(JSContext *cx, js::Class *clasp, JSObject *parent, JSObject ** proto) -{ - JSProtoKey protoKey = GetClassProtoKey(clasp); - if (!js_GetClassPrototype(cx, parent, protoKey, proto, clasp)) - return false; - if (!(*proto) && !js_GetClassPrototype(cx, parent, JSProto_Object, proto)) - return false; - - return true; -} - -namespace detail -{ -template -static JS_ALWAYS_INLINE JSObject * -NewObject(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent, - gc::FinalizeKind kind) -{ - /* Bootstrap the ur-object, and make it the default prototype object. */ - if (withProto == WithProto::Class && !proto) { - if (!FindProto(cx, clasp, parent, &proto)) - return NULL; - } - - /* - * Allocate an object from the GC heap and initialize all its fields before - * doing any operation that can potentially trigger GC. Functions have a - * larger non-standard allocation size. - * - * The should be specialized by the template. - */ - JSObject* obj = isFunction ? js_NewGCFunction(cx) : js_NewGCObject(cx, kind); - if (!obj) - goto out; - - /* This needs to match up with the size of JSFunction::data_padding. */ - JS_ASSERT_IF(isFunction, kind == gc::FINALIZE_OBJECT2); - - /* - * Default parent to the parent of the prototype, which was set from - * the parent of the prototype's constructor. - */ - obj->init(cx, clasp, proto, - (!parent && proto) ? proto->getParent() : parent, - NULL, clasp == &js_ArrayClass); - - if (clasp->isNative()) { - if (!InitScopeForObject(cx, obj, clasp, proto, kind)) { - obj = NULL; - goto out; - } - } else { - obj->setSharedNonNativeMap(); - } - -out: - Probes::createObject(cx, obj); - return obj; -} -} /* namespace detail */ - -static JS_ALWAYS_INLINE JSObject * -NewFunction(JSContext *cx, JSObject *parent) -{ - return detail::NewObject(cx, &js_FunctionClass, NULL, parent, - gc::FINALIZE_OBJECT2); -} - -template -static JS_ALWAYS_INLINE JSObject * -NewNonFunction(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent, - gc::FinalizeKind kind) -{ - return detail::NewObject(cx, clasp, proto, parent, kind); -} - -template -static JS_ALWAYS_INLINE JSObject * -NewNonFunction(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent) -{ - gc::FinalizeKind kind = gc::GetGCObjectKind(JSCLASS_RESERVED_SLOTS(clasp)); - return detail::NewObject(cx, clasp, proto, parent, kind); -} - -template -static JS_ALWAYS_INLINE JSObject * -NewObject(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent, - gc::FinalizeKind kind) -{ - if (clasp == &js_FunctionClass) - return detail::NewObject(cx, clasp, proto, parent, kind); - return detail::NewObject(cx, clasp, proto, parent, kind); -} - -template -static JS_ALWAYS_INLINE JSObject * -NewObject(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent) -{ - gc::FinalizeKind kind = gc::GetGCObjectKind(JSCLASS_RESERVED_SLOTS(clasp)); - return NewObject(cx, clasp, proto, parent, kind); -} - -/* - * As for gc::GetGCObjectKind, where numSlots is a guess at the final size of - * the object, zero if the final size is unknown. - */ -static inline gc::FinalizeKind -GuessObjectGCKind(size_t numSlots, bool isArray) -{ - if (numSlots) - return gc::GetGCObjectKind(numSlots); - return isArray ? gc::FINALIZE_OBJECT8 : gc::FINALIZE_OBJECT4; -} - -/* - * Get the GC kind to use for scripted 'new' on the given class. - * FIXME bug 547327: estimate the size from the allocation site. - */ -static inline gc::FinalizeKind -NewObjectGCKind(JSContext *cx, js::Class *clasp) -{ - if (clasp == &js_ArrayClass || clasp == &js_SlowArrayClass) - return gc::FINALIZE_OBJECT8; - if (clasp == &js_FunctionClass) - return gc::FINALIZE_OBJECT2; - return gc::FINALIZE_OBJECT4; -} - -/* Make an object with pregenerated shape from a NEWOBJECT bytecode. */ -static inline JSObject * -CopyInitializerObject(JSContext *cx, JSObject *baseobj) -{ - JS_ASSERT(baseobj->getClass() == &js_ObjectClass); - JS_ASSERT(!baseobj->inDictionaryMode()); - - gc::FinalizeKind kind = gc::FinalizeKind(baseobj->finalizeKind()); - JSObject *obj = NewBuiltinClassInstance(cx, &js_ObjectClass, kind); - - if (!obj || !obj->ensureSlots(cx, baseobj->numSlots())) - return NULL; - - obj->flags = baseobj->flags; - obj->lastProp = baseobj->lastProp; - obj->objShape = baseobj->objShape; - - return obj; -} - -/* - * When we have an object of a builtin class, we don't quite know what its - * valueOf/toString methods are, since these methods may have been overwritten - * or shadowed. However, we can still do better than js_TryMethod by - * hard-coding the necessary properties for us to find the native we expect. - * - * TODO: a per-thread shape-based cache would be faster and simpler. - */ -static JS_ALWAYS_INLINE bool -ClassMethodIsNative(JSContext *cx, JSObject *obj, Class *clasp, jsid methodid, - Native native) -{ - JS_ASSERT(obj->getClass() == clasp); - - if (HasNativeMethod(obj, methodid, native)) - return true; - - JSObject *pobj = obj->getProto(); - return pobj && pobj->getClass() == clasp && - HasNativeMethod(pobj, methodid, native); -} - -} /* namespace js */ - -#endif /* jsobjinlines_h___ */ diff --git a/x86/mozilla/include/json.h b/x86/mozilla/include/json.h deleted file mode 100644 index de42073..0000000 --- a/x86/mozilla/include/json.h +++ /dev/null @@ -1,137 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is SpiderMonkey JSON. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998-1999 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Robert Sayre - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef json_h___ -#define json_h___ - -#include "jsprvtd.h" -#include "jspubtd.h" -#include "jsvalue.h" -#include "jsvector.h" - -#define JSON_MAX_DEPTH 2048 -#define JSON_PARSER_BUFSIZE 1024 - -extern js::Class js_JSONClass; - -extern JSObject * -js_InitJSONClass(JSContext *cx, JSObject *obj); - -extern JSBool -js_Stringify(JSContext *cx, js::Value *vp, JSObject *replacer, - const js::Value &space, js::StringBuffer &sb); - -extern JSBool js_TryJSON(JSContext *cx, js::Value *vp); - -/* JSON parsing states; most permit leading whitespace. */ -enum JSONParserState { - /* Start of string. */ - JSON_PARSE_STATE_INIT, - - /* JSON fully processed, expecting only trailing whitespace. */ - JSON_PARSE_STATE_FINISHED, - - /* Start of JSON value. */ - JSON_PARSE_STATE_VALUE, - - /* Start of first key/value pair in object, or at }. */ - JSON_PARSE_STATE_OBJECT_INITIAL_PAIR, - - /* Start of subsequent key/value pair in object, after delimiting comma. */ - JSON_PARSE_STATE_OBJECT_PAIR, - - /* At : in key/value pair in object. */ - JSON_PARSE_STATE_OBJECT_IN_PAIR, - - /* Immediately after key/value pair in object: at , or }. */ - JSON_PARSE_STATE_OBJECT_AFTER_PAIR, - - /* Start of first element of array or at ]. */ - JSON_PARSE_STATE_ARRAY_INITIAL_VALUE, - - /* Immediately after element in array: at , or ]. */ - JSON_PARSE_STATE_ARRAY_AFTER_ELEMENT, - - - /* The following states allow no leading whitespace. */ - - /* Within string literal. */ - JSON_PARSE_STATE_STRING, - - /* At first character after \ in string literal. */ - JSON_PARSE_STATE_STRING_ESCAPE, - - /* Within numbers in \uXXXX in string literal. */ - JSON_PARSE_STATE_STRING_HEX, - - /* Within numeric literal. */ - JSON_PARSE_STATE_NUMBER, - - /* Handling keywords (only null/true/false pass validity post-check). */ - JSON_PARSE_STATE_KEYWORD -}; - -struct JSONParser; - -extern JSONParser * -js_BeginJSONParse(JSContext *cx, js::Value *rootVal, bool suppressErrors = false); - -/* Aargh, Windows. */ -#ifdef STRICT -#undef STRICT -#endif -#ifdef LEGACY -#undef LEGACY -#endif - -/* - * The type of JSON decoding to perform. Strict decoding is to-the-spec; - * legacy decoding accepts a few non-JSON syntaxes historically accepted by the - * implementation. (Full description of these deviations is deliberately - * omitted.) New users should use strict decoding rather than legacy decoding, - * as legacy decoding might be removed at a future time. - */ -enum DecodingMode { STRICT, LEGACY }; - -extern JS_FRIEND_API(JSBool) -js_ConsumeJSONText(JSContext *cx, JSONParser *jp, const jschar *data, uint32 len, - DecodingMode decodingMode = STRICT); - -extern bool -js_FinishJSONParse(JSContext *cx, JSONParser *jp, const js::Value &reviver); - -#endif /* json_h___ */ diff --git a/x86/mozilla/include/jsopcode.h b/x86/mozilla/include/jsopcode.h deleted file mode 100644 index 68cf514..0000000 --- a/x86/mozilla/include/jsopcode.h +++ /dev/null @@ -1,512 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsopcode_h___ -#define jsopcode_h___ -/* - * JS bytecode definitions. - */ -#include -#include "jsprvtd.h" -#include "jspubtd.h" -#include "jsutil.h" - -#ifdef __cplusplus -# include "jsvalue.h" -#endif - -JS_BEGIN_EXTERN_C - -/* - * JS operation bytecodes. - */ -typedef enum JSOp { -#define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format) \ - op = val, -#include "jsopcode.tbl" -#undef OPDEF - JSOP_LIMIT, - - /* - * These pseudo-ops help js_DecompileValueGenerator decompile JSOP_SETNAME, - * JSOP_SETPROP, and JSOP_SETELEM, respectively. They are never stored in - * bytecode, so they don't preempt valid opcodes. - */ - JSOP_GETPROP2 = JSOP_LIMIT, - JSOP_GETELEM2 = JSOP_LIMIT + 1, - JSOP_FAKE_LIMIT = JSOP_GETELEM2 -} JSOp; - -/* - * JS bytecode formats. - */ -#define JOF_BYTE 0 /* single bytecode, no immediates */ -#define JOF_JUMP 1 /* signed 16-bit jump offset immediate */ -#define JOF_ATOM 2 /* unsigned 16-bit constant index */ -#define JOF_UINT16 3 /* unsigned 16-bit immediate operand */ -#define JOF_TABLESWITCH 4 /* table switch */ -#define JOF_LOOKUPSWITCH 5 /* lookup switch */ -#define JOF_QARG 6 /* quickened get/set function argument ops */ -#define JOF_LOCAL 7 /* var or block-local variable */ -#define JOF_SLOTATOM 8 /* uint16 slot + constant index */ -#define JOF_JUMPX 9 /* signed 32-bit jump offset immediate */ -#define JOF_TABLESWITCHX 10 /* extended (32-bit offset) table switch */ -#define JOF_LOOKUPSWITCHX 11 /* extended (32-bit offset) lookup switch */ -#define JOF_UINT24 12 /* extended unsigned 24-bit literal (index) */ -#define JOF_UINT8 13 /* uint8 immediate, e.g. top 8 bits of 24-bit - atom index */ -#define JOF_INT32 14 /* int32 immediate operand */ -#define JOF_OBJECT 15 /* unsigned 16-bit object index */ -#define JOF_SLOTOBJECT 16 /* uint16 slot index + object index */ -#define JOF_REGEXP 17 /* unsigned 16-bit regexp index */ -#define JOF_INT8 18 /* int8 immediate operand */ -#define JOF_ATOMOBJECT 19 /* uint16 constant index + object index */ -#define JOF_UINT16PAIR 20 /* pair of uint16 immediates */ -#define JOF_GLOBAL 21 /* uint16 global array index */ -#define JOF_TYPEMASK 0x001f /* mask for above immediate types */ - -#define JOF_NAME (1U<<5) /* name operation */ -#define JOF_PROP (2U<<5) /* obj.prop operation */ -#define JOF_ELEM (3U<<5) /* obj[index] operation */ -#define JOF_XMLNAME (4U<<5) /* XML name: *, a::b, @a, @a::b, etc. */ -#define JOF_VARPROP (5U<<5) /* x.prop for this, arg, var, or local x */ -#define JOF_MODEMASK (7U<<5) /* mask for above addressing modes */ -#define JOF_SET (1U<<8) /* set (i.e., assignment) operation */ -#define JOF_DEL (1U<<9) /* delete operation */ -#define JOF_DEC (1U<<10) /* decrement (--, not ++) opcode */ -#define JOF_INC (2U<<10) /* increment (++, not --) opcode */ -#define JOF_INCDEC (3U<<10) /* increment or decrement opcode */ -#define JOF_POST (1U<<12) /* postorder increment or decrement */ -#define JOF_FOR (1U<<13) /* for-in property op (akin to JOF_SET) */ -#define JOF_ASSIGNING JOF_SET /* hint for Class.resolve, used for ops - that do simplex assignment */ -#define JOF_DETECTING (1U<<14) /* object detection for JSNewResolveOp */ -#define JOF_BACKPATCH (1U<<15) /* backpatch placeholder during codegen */ -#define JOF_LEFTASSOC (1U<<16) /* left-associative operator */ -#define JOF_DECLARING (1U<<17) /* var, const, or function declaration op */ -#define JOF_INDEXBASE (1U<<18) /* atom segment base setting prefix op */ -#define JOF_CALLOP (1U<<19) /* call operation that pushes function and - this */ -#define JOF_PARENHEAD (1U<<20) /* opcode consumes value of expression in - parenthesized statement head */ -#define JOF_INVOKE (1U<<21) /* JSOP_CALL, JSOP_NEW, JSOP_EVAL */ -#define JOF_TMPSLOT (1U<<22) /* interpreter uses extra temporary slot - to root intermediate objects besides - the slots opcode uses */ -#define JOF_TMPSLOT2 (2U<<22) /* interpreter uses extra 2 temporary slot - besides the slots opcode uses */ -#define JOF_TMPSLOT3 (3U<<22) /* interpreter uses extra 3 temporary slot - besides the slots opcode uses */ -#define JOF_TMPSLOT_SHIFT 22 -#define JOF_TMPSLOT_MASK (JS_BITMASK(2) << JOF_TMPSLOT_SHIFT) - -#define JOF_SHARPSLOT (1U<<24) /* first immediate is uint16 stack slot no. - that needs fixup when in global code (see - Compiler::compileScript) */ -#define JOF_GNAME (1U<<25) /* predicted global name */ - -/* Shorthands for type from format and type from opcode. */ -#define JOF_TYPE(fmt) ((fmt) & JOF_TYPEMASK) -#define JOF_OPTYPE(op) JOF_TYPE(js_CodeSpec[op].format) - -/* Shorthands for mode from format and mode from opcode. */ -#define JOF_MODE(fmt) ((fmt) & JOF_MODEMASK) -#define JOF_OPMODE(op) JOF_MODE(js_CodeSpec[op].format) - -#define JOF_TYPE_IS_EXTENDED_JUMP(t) \ - ((unsigned)((t) - JOF_JUMPX) <= (unsigned)(JOF_LOOKUPSWITCHX - JOF_JUMPX)) - -/* - * Immediate operand getters, setters, and bounds. - */ - -/* Common uint16 immediate format helpers. */ -#define UINT16_LEN 2 -#define UINT16_HI(i) ((jsbytecode)((i) >> 8)) -#define UINT16_LO(i) ((jsbytecode)(i)) -#define GET_UINT16(pc) ((uintN)(((pc)[1] << 8) | (pc)[2])) -#define SET_UINT16(pc,i) ((pc)[1] = UINT16_HI(i), (pc)[2] = UINT16_LO(i)) -#define UINT16_LIMIT ((uintN)1 << 16) - -/* Short (2-byte signed offset) relative jump macros. */ -#define JUMP_OFFSET_LEN 2 -#define JUMP_OFFSET_HI(off) ((jsbytecode)((off) >> 8)) -#define JUMP_OFFSET_LO(off) ((jsbytecode)(off)) -#define GET_JUMP_OFFSET(pc) ((int16)GET_UINT16(pc)) -#define SET_JUMP_OFFSET(pc,off) ((pc)[1] = JUMP_OFFSET_HI(off), \ - (pc)[2] = JUMP_OFFSET_LO(off)) -#define JUMP_OFFSET_MIN ((int16)0x8000) -#define JUMP_OFFSET_MAX ((int16)0x7fff) - -/* - * When a short jump won't hold a relative offset, its 2-byte immediate offset - * operand is an unsigned index of a span-dependency record, maintained until - * code generation finishes -- after which some (but we hope not nearly all) - * span-dependent jumps must be extended (see OptimizeSpanDeps in jsemit.c). - * - * If the span-dependency record index overflows SPANDEP_INDEX_MAX, the jump - * offset will contain SPANDEP_INDEX_HUGE, indicating that the record must be - * found (via binary search) by its "before span-dependency optimization" pc - * offset (from script main entry point). - */ -#define GET_SPANDEP_INDEX(pc) ((uint16)GET_UINT16(pc)) -#define SET_SPANDEP_INDEX(pc,i) ((pc)[1] = JUMP_OFFSET_HI(i), \ - (pc)[2] = JUMP_OFFSET_LO(i)) -#define SPANDEP_INDEX_MAX ((uint16)0xfffe) -#define SPANDEP_INDEX_HUGE ((uint16)0xffff) - -/* Ultimately, if short jumps won't do, emit long (4-byte signed) offsets. */ -#define JUMPX_OFFSET_LEN 4 -#define JUMPX_OFFSET_B3(off) ((jsbytecode)((off) >> 24)) -#define JUMPX_OFFSET_B2(off) ((jsbytecode)((off) >> 16)) -#define JUMPX_OFFSET_B1(off) ((jsbytecode)((off) >> 8)) -#define JUMPX_OFFSET_B0(off) ((jsbytecode)(off)) -#define GET_JUMPX_OFFSET(pc) ((int32)(((pc)[1] << 24) | ((pc)[2] << 16) \ - | ((pc)[3] << 8) | (pc)[4])) -#define SET_JUMPX_OFFSET(pc,off)((pc)[1] = JUMPX_OFFSET_B3(off), \ - (pc)[2] = JUMPX_OFFSET_B2(off), \ - (pc)[3] = JUMPX_OFFSET_B1(off), \ - (pc)[4] = JUMPX_OFFSET_B0(off)) -#define JUMPX_OFFSET_MIN ((int32)0x80000000) -#define JUMPX_OFFSET_MAX ((int32)0x7fffffff) - -/* - * A literal is indexed by a per-script atom or object maps. Most scripts - * have relatively few literals, so the standard JOF_ATOM, JOF_OBJECT and - * JOF_REGEXP formats specifies a fixed 16 bits of immediate operand index. - * A script with more than 64K literals must wrap the bytecode into - * JSOP_INDEXBASE and JSOP_RESETBASE pair. - */ -#define INDEX_LEN 2 -#define INDEX_HI(i) ((jsbytecode)((i) >> 8)) -#define INDEX_LO(i) ((jsbytecode)(i)) -#define GET_INDEX(pc) GET_UINT16(pc) -#define SET_INDEX(pc,i) ((pc)[1] = INDEX_HI(i), (pc)[2] = INDEX_LO(i)) - -#define GET_INDEXBASE(pc) (JS_ASSERT(*(pc) == JSOP_INDEXBASE), \ - ((uintN)((pc)[1])) << 16) -#define INDEXBASE_LEN 1 - -#define UINT24_HI(i) ((jsbytecode)((i) >> 16)) -#define UINT24_MID(i) ((jsbytecode)((i) >> 8)) -#define UINT24_LO(i) ((jsbytecode)(i)) -#define GET_UINT24(pc) ((jsatomid)(((pc)[1] << 16) | \ - ((pc)[2] << 8) | \ - (pc)[3])) -#define SET_UINT24(pc,i) ((pc)[1] = UINT24_HI(i), \ - (pc)[2] = UINT24_MID(i), \ - (pc)[3] = UINT24_LO(i)) - -#define GET_INT8(pc) ((jsint)(int8)(pc)[1]) - -#define GET_INT32(pc) ((jsint)(((uint32)((pc)[1]) << 24) | \ - ((uint32)((pc)[2]) << 16) | \ - ((uint32)((pc)[3]) << 8) | \ - (uint32)(pc)[4])) -#define SET_INT32(pc,i) ((pc)[1] = (jsbytecode)((uint32)(i) >> 24), \ - (pc)[2] = (jsbytecode)((uint32)(i) >> 16), \ - (pc)[3] = (jsbytecode)((uint32)(i) >> 8), \ - (pc)[4] = (jsbytecode)(uint32)(i)) - -/* Index limit is determined by SN_3BYTE_OFFSET_FLAG, see jsemit.h. */ -#define INDEX_LIMIT_LOG2 23 -#define INDEX_LIMIT ((uint32)1 << INDEX_LIMIT_LOG2) - -/* Actual argument count operand format helpers. */ -#define ARGC_HI(argc) UINT16_HI(argc) -#define ARGC_LO(argc) UINT16_LO(argc) -#define GET_ARGC(pc) GET_UINT16(pc) -#define ARGC_LIMIT UINT16_LIMIT - -/* Synonyms for quick JOF_QARG and JOF_LOCAL bytecodes. */ -#define GET_ARGNO(pc) GET_UINT16(pc) -#define SET_ARGNO(pc,argno) SET_UINT16(pc,argno) -#define ARGNO_LEN 2 -#define ARGNO_LIMIT UINT16_LIMIT - -#define GET_SLOTNO(pc) GET_UINT16(pc) -#define SET_SLOTNO(pc,varno) SET_UINT16(pc,varno) -#define SLOTNO_LEN 2 -#define SLOTNO_LIMIT UINT16_LIMIT - -struct JSCodeSpec { - int8 length; /* length including opcode byte */ - int8 nuses; /* arity, -1 if variadic */ - int8 ndefs; /* number of stack results */ - uint8 prec; /* operator precedence */ - uint32 format; /* immediate operand format */ - -#ifdef __cplusplus - uint32 type() const { return JOF_TYPE(format); } -#endif -}; - -extern const JSCodeSpec js_CodeSpec[]; -extern uintN js_NumCodeSpecs; -extern const char *js_CodeName[]; -extern const char js_EscapeMap[]; - -/* Silence unreferenced formal parameter warnings */ -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4100) -#endif - -/* - * Return a GC'ed string containing the chars in str, with any non-printing - * chars or quotes (' or " as specified by the quote argument) escaped, and - * with the quote character at the beginning and end of the result string. - */ -extern JSString * -js_QuoteString(JSContext *cx, JSString *str, jschar quote); - -/* - * JSPrinter operations, for printf style message formatting. The return - * value from js_GetPrinterOutput() is the printer's cumulative output, in - * a GC'ed string. - * - * strict is true if the context in which the output will appear has - * already been marked as strict, thus indicating that nested - * functions need not be re-marked with a strict directive. It should - * be false in the outermost printer. - */ - -extern JSPrinter * -js_NewPrinter(JSContext *cx, const char *name, JSFunction *fun, - uintN indent, JSBool pretty, JSBool grouped, JSBool strict); - -extern void -js_DestroyPrinter(JSPrinter *jp); - -extern JSString * -js_GetPrinterOutput(JSPrinter *jp); - -extern int -js_printf(JSPrinter *jp, const char *format, ...); - -extern JSBool -js_puts(JSPrinter *jp, const char *s); - -/* - * Get index operand from the bytecode using a bytecode analysis to deduce the - * the index register. This function is infallible, in spite of taking cx as - * its first parameter; it uses only cx->runtime when calling JS_GetTrapOpcode. - * The GET_*_FROM_BYTECODE macros that call it pick up cx from their caller's - * lexical environments. - */ -uintN -js_GetIndexFromBytecode(JSContext *cx, JSScript *script, jsbytecode *pc, - ptrdiff_t pcoff); - -/* - * A slower version of GET_ATOM when the caller does not want to maintain - * the index segment register itself. - */ -#define GET_ATOM_FROM_BYTECODE(script, pc, pcoff, atom) \ - JS_BEGIN_MACRO \ - JS_ASSERT(*(pc) != JSOP_DOUBLE); \ - uintN index_ = js_GetIndexFromBytecode(cx, (script), (pc), (pcoff)); \ - JS_GET_SCRIPT_ATOM(script, pc, index_, atom); \ - JS_END_MACRO - -/* - * Variant for getting a double atom when we might be in an imacro. Bytecodes - * with literals that are only ever doubles must use this macro, and never use - * GET_ATOM_FROM_BYTECODE or JS_GET_SCRIPT_ATOM. - * - * Unfortunately some bytecodes such as JSOP_LOOKUPSWITCH have immediates that - * might be string or double atoms. Those opcodes cannot be used from imacros. - * See the assertions in the JSOP_DOUBLE and JSOP_LOOKUPSWTICH* opcode cases in - * jsinterp.cpp. - */ -#define GET_DOUBLE_FROM_BYTECODE(script, pc, pcoff, dbl) \ - JS_BEGIN_MACRO \ - uintN index_ = js_GetIndexFromBytecode(cx, (script), (pc), (pcoff)); \ - JS_ASSERT(index_ < (script)->consts()->length); \ - (dbl) = (script)->getConst(index_).toDouble(); \ - JS_END_MACRO - -#define GET_OBJECT_FROM_BYTECODE(script, pc, pcoff, obj) \ - JS_BEGIN_MACRO \ - uintN index_ = js_GetIndexFromBytecode(cx, (script), (pc), (pcoff)); \ - obj = (script)->getObject(index_); \ - JS_END_MACRO - -#define GET_FUNCTION_FROM_BYTECODE(script, pc, pcoff, fun) \ - JS_BEGIN_MACRO \ - uintN index_ = js_GetIndexFromBytecode(cx, (script), (pc), (pcoff)); \ - fun = (script)->getFunction(index_); \ - JS_END_MACRO - -#define GET_REGEXP_FROM_BYTECODE(script, pc, pcoff, obj) \ - JS_BEGIN_MACRO \ - uintN index_ = js_GetIndexFromBytecode(cx, (script), (pc), (pcoff)); \ - obj = (script)->getRegExp(index_); \ - JS_END_MACRO - -/* - * Get the length of variable-length bytecode like JSOP_TABLESWITCH. - */ -extern uintN -js_GetVariableBytecodeLength(jsbytecode *pc); - -/* - * Find the number of stack slots used by a variadic opcode such as JSOP_CALL - * (for such ops, JSCodeSpec.nuses is -1). - */ -extern uintN -js_GetVariableStackUses(JSOp op, jsbytecode *pc); - -/* - * Find the number of stack slots defined by JSOP_ENTERBLOCK (for this op, - * JSCodeSpec.ndefs is -1). - */ -extern uintN -js_GetEnterBlockStackDefs(JSContext *cx, JSScript *script, jsbytecode *pc); - -#ifdef __cplusplus /* Aargh, libgjs, bug 492720. */ -static JS_INLINE uintN -js_GetStackUses(const JSCodeSpec *cs, JSOp op, jsbytecode *pc) -{ - JS_ASSERT(cs == &js_CodeSpec[op]); - if (cs->nuses >= 0) - return cs->nuses; - return js_GetVariableStackUses(op, pc); -} - -static JS_INLINE uintN -js_GetStackDefs(JSContext *cx, const JSCodeSpec *cs, JSOp op, JSScript *script, - jsbytecode *pc) -{ - JS_ASSERT(cs == &js_CodeSpec[op]); - if (cs->ndefs >= 0) - return cs->ndefs; - - /* Only JSOP_ENTERBLOCK has a variable number of stack defs. */ - JS_ASSERT(op == JSOP_ENTERBLOCK); - return js_GetEnterBlockStackDefs(cx, script, pc); -} -#endif - -#ifdef DEBUG -/* - * Disassemblers, for debugging only. - */ -#include - -extern JS_FRIEND_API(JSBool) -js_Disassemble(JSContext *cx, JSScript *script, JSBool lines, FILE *fp); - -extern JS_FRIEND_API(uintN) -js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc, - JSBool lines, FILE *fp); -#endif /* DEBUG */ - -/* - * Decompilers, for script, function, and expression pretty-printing. - */ -extern JSBool -js_DecompileScript(JSPrinter *jp, JSScript *script); - -extern JSBool -js_DecompileFunctionBody(JSPrinter *jp); - -extern JSBool -js_DecompileFunction(JSPrinter *jp); - -/* - * Some C++ compilers treat the language linkage (extern "C" vs. - * extern "C++") as part of function (and thus pointer-to-function) - * types. The use of this typedef (defined in "C") ensures that - * js_DecompileToString's definition (in "C++") gets matched up with - * this declaration. - */ -typedef JSBool (* JSDecompilerPtr)(JSPrinter *); - -extern JSString * -js_DecompileToString(JSContext *cx, const char *name, JSFunction *fun, - uintN indent, JSBool pretty, JSBool grouped, JSBool strict, - JSDecompilerPtr decompiler); - -/* - * Find the source expression that resulted in v, and return a newly allocated - * C-string containing it. Fall back on v's string conversion (fallback) if we - * can't find the bytecode that generated and pushed v on the operand stack. - * - * Search the current stack frame if spindex is JSDVG_SEARCH_STACK. Don't - * look for v on the stack if spindex is JSDVG_IGNORE_STACK. Otherwise, - * spindex is the negative index of v, measured from cx->fp->sp, or from a - * lower frame's sp if cx->fp is native. - * - * The caller must call JS_free on the result after a succsesful call. - */ -extern char * -js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v, - JSString *fallback); - -#define JSDVG_IGNORE_STACK 0 -#define JSDVG_SEARCH_STACK 1 - -#ifdef __cplusplus -namespace js { - -static inline char * -DecompileValueGenerator(JSContext *cx, intN spindex, const Value &v, - JSString *fallback) -{ - return js_DecompileValueGenerator(cx, spindex, Jsvalify(v), fallback); -} - -} -#endif - -/* - * Given bytecode address pc in script's main program code, return the operand - * stack depth just before (JSOp) *pc executes. - */ -extern uintN -js_ReconstructStackDepth(JSContext *cx, JSScript *script, jsbytecode *pc); - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -JS_END_EXTERN_C - -#endif /* jsopcode_h___ */ diff --git a/x86/mozilla/include/jsopcode.tbl b/x86/mozilla/include/jsopcode.tbl deleted file mode 100644 index 02229e8..0000000 --- a/x86/mozilla/include/jsopcode.tbl +++ /dev/null @@ -1,618 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=0 ft=c: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * JavaScript operation bytecodes. If you need to allocate a bytecode, look - * for a name of the form JSOP_UNUSED* and claim it. Otherwise, always add at - * the end of the table. - * - * When changing the bytecode, don't forget to update JSXDR_BYTECODE_VERSION! - * - * Includers must define an OPDEF macro of the following form: - * - * #define OPDEF(op,val,name,image,length,nuses,ndefs,prec,format) ... - * - * Selected arguments can be expanded in initializers. The op argument is - * expanded followed by comma in the JSOp enum (jsopcode.h), e.g. The value - * field must be dense for now, because jsopcode.c uses an OPDEF() expansion - * inside the js_CodeSpec[] initializer. - * - * Field Description - * op Bytecode name, which is the JSOp enumerator name - * value Bytecode value, which is the JSOp enumerator value - * name C string containing name for disassembler - * image C string containing "image" for pretty-printer, null if ugly - * length Number of bytes including any immediate operands - * nuses Number of stack slots consumed by bytecode, -1 if variadic - * ndefs Number of stack slots produced by bytecode, -1 if variadic - * prec Operator precedence, zero if not an operator - * format Bytecode plus immediate operand encoding format - * - * Precedence Operators Opcodes - * 1 yield w JSOP_YIELD - * 2 , JSOP_POP with SRC_PCDELTA, JSOP_RETURN - * 3 =, +=, etc. JSOP_SETNAME, etc. (all JOF_SET); - * let (...) ... and JSOP_LEAVEBLOCKEXPR - * 4 ?: JSOP_IFEQ, JSOP_IFEQX - * 5 || JSOP_OR, JSOP_ORX - * 6 && JSOP_AND, JSOP_ANDX - * 7 | JSOP_BITOR - * 8 ^ JSOP_BITXOR - * 9 & JSOP_BITAND - * 10 ==, !=, etc. JSOP_EQ, JSOP_NE, etc. - * 11 <, in, etc. JSOP_LT, JSOP_IN, etc. - * 12 <<, >>, >>> JSOP_LSH, JSOP_RSH, JSOP_URSH - * 13 +, -, etc. JSOP_ADD, JSOP_SUB, etc. - * 14 *, /, % JSOP_MUL, JSOP_DIV, JSOP_MOD - * 15 !, ~, delete, etc. JSOP_NOT, JSOP_BITNOT, JSOP_DEL*, etc. - * 16 3.14, 0, etc. JSOP_DOUBLE, JSOP_ZERO, etc. - * 17 new JSOP_NEW - * 18 x.y, f(), etc. JSOP_GETPROP, JSOP_CALL, etc. - * 19 x, null, JSOP_NAME, JSOP_NULL, etc.; - * function (...) ... and JSOP_LAMBDA - * - * The push-numeric-constant operators, JSOP_ZERO, JSOP_DOUBLE, etc., have - * lower precedence than the member operators emitted for the . operator, to - * cause the decompiler to parenthesize the . left operand, e.g. (0).foo. - * Otherwise the . could be taken as a decimal point. - * - * Let expressions are "primary" when viewed from the left, but they eat up ops - * to the right as if assignment expressions and therefore have precedence 3. - * This makes the decompiler retain the parentheses in (let (a=0) x) ? a : 0 - * but omit the superfluous ones in (let (a=0) x), a. - * - * Yield expressions must be parenthesized even in comma-expressions and - * argument lists, so they have the lowest precedence. - * - * This file is best viewed with 128 columns: -12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678 - */ - -/* legend: op val name image len use def prec format */ - -/* - * Generic nop for the decompiler. - */ -OPDEF(JSOP_NOP, 0, "nop", NULL, 1, 0, 0, 0, JOF_BYTE) - -/* Long-standing JavaScript bytecodes. */ -OPDEF(JSOP_PUSH, 1, "push", NULL, 1, 0, 1, 0, JOF_BYTE) -OPDEF(JSOP_POPV, 2, "popv", NULL, 1, 1, 0, 2, JOF_BYTE) -OPDEF(JSOP_ENTERWITH, 3, "enterwith", NULL, 1, 1, 1, 0, JOF_BYTE|JOF_PARENHEAD) -OPDEF(JSOP_LEAVEWITH, 4, "leavewith", NULL, 1, 1, 0, 0, JOF_BYTE) -OPDEF(JSOP_RETURN, 5, "return", NULL, 1, 1, 0, 2, JOF_BYTE) -OPDEF(JSOP_GOTO, 6, "goto", NULL, 3, 0, 0, 0, JOF_JUMP) -OPDEF(JSOP_IFEQ, 7, "ifeq", NULL, 3, 1, 0, 4, JOF_JUMP|JOF_DETECTING) -OPDEF(JSOP_IFNE, 8, "ifne", NULL, 3, 1, 0, 0, JOF_JUMP|JOF_PARENHEAD) - -/* Get the arguments object for the current, lightweight function activation. */ -OPDEF(JSOP_ARGUMENTS, 9, js_arguments_str, js_arguments_str, 1, 0, 1, 18, JOF_BYTE) - -/* ECMA-compliant for-in loop with argument or local loop control. */ -OPDEF(JSOP_FORARG, 10, "forarg", NULL, 3, 1, 1, 19, JOF_QARG|JOF_NAME|JOF_FOR|JOF_TMPSLOT) -OPDEF(JSOP_FORLOCAL, 11, "forlocal", NULL, 3, 1, 1, 19, JOF_LOCAL|JOF_NAME|JOF_FOR|JOF_TMPSLOT) - -/* More long-standing bytecodes. */ -OPDEF(JSOP_DUP, 12, "dup", NULL, 1, 1, 2, 0, JOF_BYTE) -OPDEF(JSOP_DUP2, 13, "dup2", NULL, 1, 2, 4, 0, JOF_BYTE) -OPDEF(JSOP_SETCONST, 14, "setconst", NULL, 3, 1, 1, 3, JOF_ATOM|JOF_NAME|JOF_SET) -OPDEF(JSOP_BITOR, 15, "bitor", "|", 1, 2, 1, 7, JOF_BYTE|JOF_LEFTASSOC) -OPDEF(JSOP_BITXOR, 16, "bitxor", "^", 1, 2, 1, 8, JOF_BYTE|JOF_LEFTASSOC) -OPDEF(JSOP_BITAND, 17, "bitand", "&", 1, 2, 1, 9, JOF_BYTE|JOF_LEFTASSOC) -OPDEF(JSOP_EQ, 18, "eq", "==", 1, 2, 1, 10, JOF_BYTE|JOF_LEFTASSOC|JOF_DETECTING) -OPDEF(JSOP_NE, 19, "ne", "!=", 1, 2, 1, 10, JOF_BYTE|JOF_LEFTASSOC|JOF_DETECTING) -OPDEF(JSOP_LT, 20, "lt", "<", 1, 2, 1, 11, JOF_BYTE|JOF_LEFTASSOC) -OPDEF(JSOP_LE, 21, "le", "<=", 1, 2, 1, 11, JOF_BYTE|JOF_LEFTASSOC) -OPDEF(JSOP_GT, 22, "gt", ">", 1, 2, 1, 11, JOF_BYTE|JOF_LEFTASSOC) -OPDEF(JSOP_GE, 23, "ge", ">=", 1, 2, 1, 11, JOF_BYTE|JOF_LEFTASSOC) -OPDEF(JSOP_LSH, 24, "lsh", "<<", 1, 2, 1, 12, JOF_BYTE|JOF_LEFTASSOC) -OPDEF(JSOP_RSH, 25, "rsh", ">>", 1, 2, 1, 12, JOF_BYTE|JOF_LEFTASSOC) -OPDEF(JSOP_URSH, 26, "ursh", ">>>", 1, 2, 1, 12, JOF_BYTE|JOF_LEFTASSOC) -OPDEF(JSOP_ADD, 27, "add", "+", 1, 2, 1, 13, JOF_BYTE|JOF_LEFTASSOC) -OPDEF(JSOP_SUB, 28, "sub", "-", 1, 2, 1, 13, JOF_BYTE|JOF_LEFTASSOC) -OPDEF(JSOP_MUL, 29, "mul", "*", 1, 2, 1, 14, JOF_BYTE|JOF_LEFTASSOC) -OPDEF(JSOP_DIV, 30, "div", "/", 1, 2, 1, 14, JOF_BYTE|JOF_LEFTASSOC) -OPDEF(JSOP_MOD, 31, "mod", "%", 1, 2, 1, 14, JOF_BYTE|JOF_LEFTASSOC) -OPDEF(JSOP_NOT, 32, "not", "!", 1, 1, 1, 15, JOF_BYTE|JOF_DETECTING) -OPDEF(JSOP_BITNOT, 33, "bitnot", "~", 1, 1, 1, 15, JOF_BYTE) -OPDEF(JSOP_NEG, 34, "neg", "- ", 1, 1, 1, 15, JOF_BYTE) -OPDEF(JSOP_POS, 35, "pos", "+ ", 1, 1, 1, 15, JOF_BYTE) -OPDEF(JSOP_DELNAME, 36, "delname", NULL, 3, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_DEL) -OPDEF(JSOP_DELPROP, 37, "delprop", NULL, 3, 1, 1, 15, JOF_ATOM|JOF_PROP|JOF_DEL) -OPDEF(JSOP_DELELEM, 38, "delelem", NULL, 1, 2, 1, 15, JOF_BYTE |JOF_ELEM|JOF_DEL) -OPDEF(JSOP_TYPEOF, 39, js_typeof_str,NULL, 1, 1, 1, 15, JOF_BYTE|JOF_DETECTING) -OPDEF(JSOP_VOID, 40, js_void_str, NULL, 1, 1, 1, 15, JOF_BYTE) - -OPDEF(JSOP_INCNAME, 41, "incname", NULL, 3, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_INC|JOF_TMPSLOT3) -OPDEF(JSOP_INCPROP, 42, "incprop", NULL, 3, 1, 1, 15, JOF_ATOM|JOF_PROP|JOF_INC|JOF_TMPSLOT3) -OPDEF(JSOP_INCELEM, 43, "incelem", NULL, 1, 2, 1, 15, JOF_BYTE |JOF_ELEM|JOF_INC|JOF_TMPSLOT2) -OPDEF(JSOP_DECNAME, 44, "decname", NULL, 3, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_DEC|JOF_TMPSLOT3) -OPDEF(JSOP_DECPROP, 45, "decprop", NULL, 3, 1, 1, 15, JOF_ATOM|JOF_PROP|JOF_DEC|JOF_TMPSLOT3) -OPDEF(JSOP_DECELEM, 46, "decelem", NULL, 1, 2, 1, 15, JOF_BYTE |JOF_ELEM|JOF_DEC|JOF_TMPSLOT2) -OPDEF(JSOP_NAMEINC, 47, "nameinc", NULL, 3, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_INC|JOF_POST|JOF_TMPSLOT3) -OPDEF(JSOP_PROPINC, 48, "propinc", NULL, 3, 1, 1, 15, JOF_ATOM|JOF_PROP|JOF_INC|JOF_POST|JOF_TMPSLOT3) -OPDEF(JSOP_ELEMINC, 49, "eleminc", NULL, 1, 2, 1, 15, JOF_BYTE |JOF_ELEM|JOF_INC|JOF_POST|JOF_TMPSLOT2) -OPDEF(JSOP_NAMEDEC, 50, "namedec", NULL, 3, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_DEC|JOF_POST|JOF_TMPSLOT3) -OPDEF(JSOP_PROPDEC, 51, "propdec", NULL, 3, 1, 1, 15, JOF_ATOM|JOF_PROP|JOF_DEC|JOF_POST|JOF_TMPSLOT3) -OPDEF(JSOP_ELEMDEC, 52, "elemdec", NULL, 1, 2, 1, 15, JOF_BYTE |JOF_ELEM|JOF_DEC|JOF_POST|JOF_TMPSLOT2) - -OPDEF(JSOP_GETPROP, 53, "getprop", NULL, 3, 1, 1, 18, JOF_ATOM|JOF_PROP) -OPDEF(JSOP_SETPROP, 54, "setprop", NULL, 3, 2, 1, 3, JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING) -OPDEF(JSOP_GETELEM, 55, "getelem", NULL, 1, 2, 1, 18, JOF_BYTE |JOF_ELEM|JOF_LEFTASSOC) -OPDEF(JSOP_SETELEM, 56, "setelem", NULL, 1, 3, 1, 3, JOF_BYTE |JOF_ELEM|JOF_SET|JOF_DETECTING) -OPDEF(JSOP_CALLNAME, 57, "callname", NULL, 3, 0, 2, 19, JOF_ATOM|JOF_NAME|JOF_CALLOP) -OPDEF(JSOP_CALL, 58, "call", NULL, 3, -1, 1, 18, JOF_UINT16|JOF_INVOKE) -OPDEF(JSOP_NAME, 59, "name", NULL, 3, 0, 1, 19, JOF_ATOM|JOF_NAME) -OPDEF(JSOP_DOUBLE, 60, "double", NULL, 3, 0, 1, 16, JOF_ATOM) -OPDEF(JSOP_STRING, 61, "string", NULL, 3, 0, 1, 19, JOF_ATOM) -OPDEF(JSOP_ZERO, 62, "zero", "0", 1, 0, 1, 16, JOF_BYTE) -OPDEF(JSOP_ONE, 63, "one", "1", 1, 0, 1, 16, JOF_BYTE) -OPDEF(JSOP_NULL, 64, js_null_str, js_null_str, 1, 0, 1, 19, JOF_BYTE) -OPDEF(JSOP_THIS, 65, js_this_str, js_this_str, 1, 0, 1, 19, JOF_BYTE) -OPDEF(JSOP_FALSE, 66, js_false_str, js_false_str, 1, 0, 1, 19, JOF_BYTE) -OPDEF(JSOP_TRUE, 67, js_true_str, js_true_str, 1, 0, 1, 19, JOF_BYTE) -OPDEF(JSOP_OR, 68, "or", NULL, 3, 1, 0, 5, JOF_JUMP|JOF_DETECTING|JOF_LEFTASSOC) -OPDEF(JSOP_AND, 69, "and", NULL, 3, 1, 0, 6, JOF_JUMP|JOF_DETECTING|JOF_LEFTASSOC) - -/* The switch bytecodes have variable length. */ -OPDEF(JSOP_TABLESWITCH, 70, "tableswitch", NULL, -1, 1, 0, 0, JOF_TABLESWITCH|JOF_DETECTING|JOF_PARENHEAD) -OPDEF(JSOP_LOOKUPSWITCH, 71, "lookupswitch", NULL, -1, 1, 0, 0, JOF_LOOKUPSWITCH|JOF_DETECTING|JOF_PARENHEAD) - -/* New, infallible/transitive identity ops. */ -OPDEF(JSOP_STRICTEQ, 72, "stricteq", "===", 1, 2, 1, 10, JOF_BYTE|JOF_DETECTING|JOF_LEFTASSOC) -OPDEF(JSOP_STRICTNE, 73, "strictne", "!==", 1, 2, 1, 10, JOF_BYTE|JOF_DETECTING|JOF_LEFTASSOC) - -/* - * Host object extension: given 'o.item(i) = j', the left-hand side compiles - * JSOP_SETCALL after JSOP_CALL, JSOP_EVAL, JSOP_FUNAPPLY, or JSOP_FUNCALL. - */ -OPDEF(JSOP_SETCALL, 74, "setcall", NULL, 1, 1, 2, 18, JOF_BYTE) - -/* - * JSOP_ITER sets up a for-in or for-each-in loop using the JSITER_* flag bits - * in this op's uint8 immediate operand. It replaces the top of stack value - * with an iterator for that value. - * - * JSOP_MOREITER stores the next iterated value into cx->iterValue and pushes - * true if another value is available, and false otherwise. It is followed - * immediately by JSOP_IFNE{,X}. - * - * JSOP_ENDITER cleans up after the loop. It uses the slot above the iterator - * for temporary GC rooting. - */ -OPDEF(JSOP_ITER, 75, "iter", NULL, 2, 1, 1, 0, JOF_UINT8) -OPDEF(JSOP_MOREITER, 76, "moreiter", NULL, 1, 1, 2, 0, JOF_BYTE) -OPDEF(JSOP_ENDITER, 77, "enditer", NULL, 1, 1, 0, 0, JOF_BYTE) - -OPDEF(JSOP_FUNAPPLY, 78, "funapply", NULL, 3, -1, 1, 18, JOF_UINT16|JOF_INVOKE) -OPDEF(JSOP_SWAP, 79, "swap", NULL, 1, 2, 2, 0, JOF_BYTE) - -/* Push object literal: either an XML object or initialiser object. */ -OPDEF(JSOP_OBJECT, 80, "object", NULL, 3, 0, 1, 19, JOF_OBJECT) - -/* Pop value and discard it. */ -OPDEF(JSOP_POP, 81, "pop", NULL, 1, 1, 0, 2, JOF_BYTE) - -/* Convert value to number, for unary +. */ -OPDEF(JSOP_NEW, 82, js_new_str, NULL, 3, -1, 1, 17, JOF_UINT16|JOF_INVOKE) - -/* Trap into debugger for breakpoint, etc. */ -OPDEF(JSOP_TRAP, 83, "trap", NULL, 1, 0, 0, 0, JOF_BYTE) - -/* Fast get/set ops for function arguments and local variables. */ -OPDEF(JSOP_GETARG, 84, "getarg", NULL, 3, 0, 1, 19, JOF_QARG |JOF_NAME) -OPDEF(JSOP_SETARG, 85, "setarg", NULL, 3, 1, 1, 3, JOF_QARG |JOF_NAME|JOF_SET) -OPDEF(JSOP_GETLOCAL, 86,"getlocal", NULL, 3, 0, 1, 19, JOF_LOCAL|JOF_NAME) -OPDEF(JSOP_SETLOCAL, 87,"setlocal", NULL, 3, 1, 1, 3, JOF_LOCAL|JOF_NAME|JOF_SET|JOF_DETECTING) - -/* Push unsigned 16-bit int constant. */ -OPDEF(JSOP_UINT16, 88, "uint16", NULL, 3, 0, 1, 16, JOF_UINT16) - -/* - * Object and array literal support. NEWINIT takes the kind of initializer - * (JSProto_Array or JSProto_Object). NEWARRAY is an array initializer - * taking the final length, which can be filled in at the start and initialized - * directly. NEWOBJECT is an object initializer taking an object with the final - * shape, which can be set at the start and slots then filled in directly. - * NEWINIT has an extra byte so it can be exchanged with NEWOBJECT during emit. - */ -OPDEF(JSOP_NEWINIT, 89, "newinit", NULL, 3, 0, 1, 19, JOF_UINT8) -OPDEF(JSOP_NEWARRAY, 90, "newarray", NULL, 4, 0, 1, 19, JOF_UINT24) -OPDEF(JSOP_NEWOBJECT, 91, "newobject", NULL, 3, 0, 1, 19, JOF_OBJECT) -OPDEF(JSOP_ENDINIT, 92, "endinit", NULL, 1, 0, 0, 19, JOF_BYTE) -OPDEF(JSOP_INITPROP, 93, "initprop", NULL, 3, 2, 1, 3, JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING) -OPDEF(JSOP_INITELEM, 94, "initelem", NULL, 1, 3, 1, 3, JOF_BYTE|JOF_ELEM|JOF_SET|JOF_DETECTING) -OPDEF(JSOP_DEFSHARP, 95, "defsharp", NULL, 5, 0, 0, 0, JOF_UINT16PAIR|JOF_SHARPSLOT) -OPDEF(JSOP_USESHARP, 96, "usesharp", NULL, 5, 0, 1, 0, JOF_UINT16PAIR|JOF_SHARPSLOT) - -/* Fast inc/dec ops for args and locals. */ -OPDEF(JSOP_INCARG, 97, "incarg", NULL, 3, 0, 1, 15, JOF_QARG |JOF_NAME|JOF_INC|JOF_TMPSLOT3) -OPDEF(JSOP_DECARG, 98, "decarg", NULL, 3, 0, 1, 15, JOF_QARG |JOF_NAME|JOF_DEC|JOF_TMPSLOT3) -OPDEF(JSOP_ARGINC, 99, "arginc", NULL, 3, 0, 1, 15, JOF_QARG |JOF_NAME|JOF_INC|JOF_POST|JOF_TMPSLOT3) -OPDEF(JSOP_ARGDEC, 100, "argdec", NULL, 3, 0, 1, 15, JOF_QARG |JOF_NAME|JOF_DEC|JOF_POST|JOF_TMPSLOT3) - -OPDEF(JSOP_INCLOCAL, 101,"inclocal", NULL, 3, 0, 1, 15, JOF_LOCAL|JOF_NAME|JOF_INC|JOF_TMPSLOT3) -OPDEF(JSOP_DECLOCAL, 102,"declocal", NULL, 3, 0, 1, 15, JOF_LOCAL|JOF_NAME|JOF_DEC|JOF_TMPSLOT3) -OPDEF(JSOP_LOCALINC, 103,"localinc", NULL, 3, 0, 1, 15, JOF_LOCAL|JOF_NAME|JOF_INC|JOF_POST|JOF_TMPSLOT3) -OPDEF(JSOP_LOCALDEC, 104,"localdec", NULL, 3, 0, 1, 15, JOF_LOCAL|JOF_NAME|JOF_DEC|JOF_POST|JOF_TMPSLOT3) - -OPDEF(JSOP_IMACOP, 105,"imacop", NULL, 1, 0, 0, 0, JOF_BYTE) - -/* ECMA-compliant for/in ops. */ -OPDEF(JSOP_FORNAME, 106,"forname", NULL, 3, 1, 1, 19, JOF_ATOM|JOF_NAME|JOF_FOR|JOF_TMPSLOT3) -OPDEF(JSOP_FORPROP, 107,"forprop", NULL, 3, 2, 1, 18, JOF_ATOM|JOF_PROP|JOF_FOR|JOF_TMPSLOT3) -OPDEF(JSOP_FORELEM, 108,"forelem", NULL, 1, 1, 2, 18, JOF_BYTE |JOF_ELEM|JOF_FOR) -OPDEF(JSOP_POPN, 109,"popn", NULL, 3, -1, 0, 0, JOF_UINT16) - -/* ECMA-compliant assignment ops. */ -OPDEF(JSOP_BINDNAME, 110,"bindname", NULL, 3, 0, 1, 0, JOF_ATOM|JOF_NAME|JOF_SET) -OPDEF(JSOP_SETNAME, 111,"setname", NULL, 3, 2, 1, 3, JOF_ATOM|JOF_NAME|JOF_SET|JOF_DETECTING) - -/* Exception handling ops. */ -OPDEF(JSOP_THROW, 112,js_throw_str, NULL, 1, 1, 0, 0, JOF_BYTE) - -/* 'in' and 'instanceof' ops. */ -OPDEF(JSOP_IN, 113,js_in_str, js_in_str, 1, 2, 1, 11, JOF_BYTE|JOF_LEFTASSOC) -OPDEF(JSOP_INSTANCEOF,114,js_instanceof_str,js_instanceof_str,1,2,1,11,JOF_BYTE|JOF_LEFTASSOC|JOF_TMPSLOT) - -/* debugger op */ -OPDEF(JSOP_DEBUGGER, 115,"debugger", NULL, 1, 0, 0, 0, JOF_BYTE) - -/* gosub/retsub for finally handling */ -OPDEF(JSOP_GOSUB, 116,"gosub", NULL, 3, 0, 0, 0, JOF_JUMP) -OPDEF(JSOP_RETSUB, 117,"retsub", NULL, 1, 2, 0, 0, JOF_BYTE) - -/* More exception handling ops. */ -OPDEF(JSOP_EXCEPTION, 118,"exception", NULL, 1, 0, 1, 0, JOF_BYTE) - -/* Embedded lineno to speedup pc->line mapping. */ -OPDEF(JSOP_LINENO, 119,"lineno", NULL, 3, 0, 0, 0, JOF_UINT16) - -/* - * ECMA-compliant switch statement ops. - * CONDSWITCH is a decompilable NOP; CASE is ===, POP, jump if true, re-push - * lval if false; and DEFAULT is POP lval and GOTO. - */ -OPDEF(JSOP_CONDSWITCH,120,"condswitch", NULL, 1, 0, 0, 0, JOF_BYTE|JOF_PARENHEAD) -OPDEF(JSOP_CASE, 121,"case", NULL, 3, 2, 1, 0, JOF_JUMP) -OPDEF(JSOP_DEFAULT, 122,"default", NULL, 3, 1, 0, 0, JOF_JUMP) - -/* - * ECMA-compliant call to eval op - */ -OPDEF(JSOP_EVAL, 123,"eval", NULL, 3, -1, 1, 18, JOF_UINT16|JOF_INVOKE) - -/* - * ECMA-compliant helper for 'for (x[i] in o)' loops. - */ -OPDEF(JSOP_ENUMELEM, 124,"enumelem", NULL, 1, 3, 0, 3, JOF_BYTE |JOF_SET|JOF_TMPSLOT) - -/* - * Getter and setter prefix bytecodes. These modify the next bytecode, either - * an assignment or a property initializer code, which then defines a property - * getter or setter. - */ -OPDEF(JSOP_GETTER, 125,js_getter_str,NULL, 1, 0, 0, 0, JOF_BYTE) -OPDEF(JSOP_SETTER, 126,js_setter_str,NULL, 1, 0, 0, 0, JOF_BYTE) - -/* - * Prolog bytecodes for defining function, var, and const names. - */ -OPDEF(JSOP_DEFFUN, 127,"deffun", NULL, 3, 0, 0, 0, JOF_OBJECT|JOF_DECLARING) -OPDEF(JSOP_DEFCONST, 128,"defconst", NULL, 3, 0, 0, 0, JOF_ATOM|JOF_DECLARING) -OPDEF(JSOP_DEFVAR, 129,"defvar", NULL, 3, 0, 0, 0, JOF_ATOM|JOF_DECLARING) - -/* Push a closure for a named or anonymous function expression. */ -OPDEF(JSOP_LAMBDA, 130, "lambda", NULL, 3, 0, 1, 19, JOF_OBJECT) - -/* Used for named function expression self-naming, if lightweight. */ -OPDEF(JSOP_CALLEE, 131, "callee", NULL, 1, 0, 1, 19, JOF_BYTE) - -/* - * Like JSOP_SETLOCAL, but specialized to avoid requiring JSOP_POP immediately - * after to throw away the exception value. - */ -OPDEF(JSOP_SETLOCALPOP, 132, "setlocalpop", NULL, 3, 1, 0, 3, JOF_LOCAL|JOF_NAME|JOF_SET) - -/* Pick an element from the stack. */ -OPDEF(JSOP_PICK, 133, "pick", NULL, 2, 0, 0, 0, JOF_UINT8) - -/* - * Exception handling no-op, for more economical byte-coding than SRC_TRYFIN - * srcnote-annotated JSOP_NOPs and to simply stack balance handling. - */ -OPDEF(JSOP_TRY, 134,"try", NULL, 1, 0, 0, 0, JOF_BYTE) -OPDEF(JSOP_FINALLY, 135,"finally", NULL, 1, 0, 2, 0, JOF_BYTE) - -/* - * Get a slot from a flat closure function object that contains a snapshot of - * the closure-invariant upvar values. The immediate operand indexes the upvar - * in the function's u.i.script->upvars() array. The CALL variant computes the - * callee and this-object in preparation for a JSOP_CALL. - */ -OPDEF(JSOP_GETFCSLOT, 136,"getfcslot", NULL, 3, 0, 1, 19, JOF_UINT16|JOF_NAME) -OPDEF(JSOP_CALLFCSLOT, 137,"callfcslot", NULL, 3, 0, 2, 19, JOF_UINT16|JOF_NAME|JOF_CALLOP) - -/* - * Bytecodes that avoid making an arguments object in most cases: - * JSOP_ARGSUB gets arguments[i] from fp->argv, iff i is in [0, fp->argc-1]. - * JSOP_ARGCNT returns fp->argc. - */ -OPDEF(JSOP_ARGSUB, 138,"argsub", NULL, 3, 0, 1, 18, JOF_QARG |JOF_NAME) -OPDEF(JSOP_ARGCNT, 139,"argcnt", NULL, 1, 0, 1, 18, JOF_BYTE) - -/* - * Define a local function object as a local variable. - * The local variable's slot number is the first immediate two-byte operand. - * The function object's atom index is the second immediate operand. - */ -OPDEF(JSOP_DEFLOCALFUN, 140,"deflocalfun",NULL, 5, 0, 0, 0, JOF_SLOTOBJECT|JOF_DECLARING|JOF_TMPSLOT) - -/* Extended jumps. */ -OPDEF(JSOP_GOTOX, 141,"gotox", NULL, 5, 0, 0, 0, JOF_JUMPX) -OPDEF(JSOP_IFEQX, 142,"ifeqx", NULL, 5, 1, 0, 4, JOF_JUMPX|JOF_DETECTING) -OPDEF(JSOP_IFNEX, 143,"ifnex", NULL, 5, 1, 0, 0, JOF_JUMPX|JOF_PARENHEAD) -OPDEF(JSOP_ORX, 144,"orx", NULL, 5, 1, 0, 5, JOF_JUMPX|JOF_DETECTING) -OPDEF(JSOP_ANDX, 145,"andx", NULL, 5, 1, 0, 6, JOF_JUMPX|JOF_DETECTING) -OPDEF(JSOP_GOSUBX, 146,"gosubx", NULL, 5, 0, 0, 0, JOF_JUMPX) -OPDEF(JSOP_CASEX, 147,"casex", NULL, 5, 2, 1, 0, JOF_JUMPX) -OPDEF(JSOP_DEFAULTX, 148,"defaultx", NULL, 5, 1, 0, 0, JOF_JUMPX) -OPDEF(JSOP_TABLESWITCHX, 149,"tableswitchx",NULL, -1, 1, 0, 0, JOF_TABLESWITCHX|JOF_DETECTING|JOF_PARENHEAD) -OPDEF(JSOP_LOOKUPSWITCHX, 150,"lookupswitchx",NULL, -1, 1, 0, 0, JOF_LOOKUPSWITCHX|JOF_DETECTING|JOF_PARENHEAD) - -/* Placeholders for a real jump opcode set during backpatch chain fixup. */ -OPDEF(JSOP_BACKPATCH, 151,"backpatch",NULL, 3, 0, 0, 0, JOF_JUMP|JOF_BACKPATCH) -OPDEF(JSOP_BACKPATCH_POP, 152,"backpatch_pop",NULL, 3, 1, 0, 0, JOF_JUMP|JOF_BACKPATCH) - -/* Set pending exception from the stack, to trigger rethrow. */ -OPDEF(JSOP_THROWING, 153,"throwing", NULL, 1, 1, 0, 0, JOF_BYTE) - -/* Set and get return value pseudo-register in stack frame. */ -OPDEF(JSOP_SETRVAL, 154,"setrval", NULL, 1, 1, 0, 2, JOF_BYTE) -OPDEF(JSOP_RETRVAL, 155,"retrval", NULL, 1, 0, 0, 0, JOF_BYTE) - -/* Free variable references that must either be found on the global or a ReferenceError */ -OPDEF(JSOP_GETGNAME, 156,"getgname", NULL, 3, 0, 1, 19, JOF_ATOM|JOF_NAME|JOF_GNAME) -OPDEF(JSOP_SETGNAME, 157,"setgname", NULL, 3, 2, 1, 3, JOF_ATOM|JOF_NAME|JOF_SET|JOF_DETECTING|JOF_GNAME) -OPDEF(JSOP_INCGNAME, 158,"incgname", NULL, 3, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_INC|JOF_TMPSLOT3|JOF_GNAME) -OPDEF(JSOP_DECGNAME, 159,"decgname", NULL, 3, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_DEC|JOF_TMPSLOT3|JOF_GNAME) -OPDEF(JSOP_GNAMEINC, 160,"gnameinc", NULL, 3, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_INC|JOF_POST|JOF_TMPSLOT3|JOF_GNAME) -OPDEF(JSOP_GNAMEDEC, 161,"gnamedec", NULL, 3, 0, 1, 15, JOF_ATOM|JOF_NAME|JOF_DEC|JOF_POST|JOF_TMPSLOT3|JOF_GNAME) - -/* Regular expression literal requiring special "fork on exec" handling. */ -OPDEF(JSOP_REGEXP, 162,"regexp", NULL, 3, 0, 1, 19, JOF_REGEXP) - -/* XML (ECMA-357, a.k.a. "E4X") support. */ -OPDEF(JSOP_DEFXMLNS, 163,"defxmlns", NULL, 1, 1, 0, 0, JOF_BYTE) -OPDEF(JSOP_ANYNAME, 164,"anyname", NULL, 1, 0, 1, 19, JOF_BYTE|JOF_XMLNAME) -OPDEF(JSOP_QNAMEPART, 165,"qnamepart", NULL, 3, 0, 1, 19, JOF_ATOM|JOF_XMLNAME) -OPDEF(JSOP_QNAMECONST, 166,"qnameconst", NULL, 3, 1, 1, 19, JOF_ATOM|JOF_XMLNAME) -OPDEF(JSOP_QNAME, 167,"qname", NULL, 1, 2, 1, 0, JOF_BYTE|JOF_XMLNAME) -OPDEF(JSOP_TOATTRNAME, 168,"toattrname", NULL, 1, 1, 1, 19, JOF_BYTE|JOF_XMLNAME) -OPDEF(JSOP_TOATTRVAL, 169,"toattrval", NULL, 1, 1, 1, 19, JOF_BYTE) -OPDEF(JSOP_ADDATTRNAME, 170,"addattrname",NULL, 1, 2, 1, 13, JOF_BYTE) -OPDEF(JSOP_ADDATTRVAL, 171,"addattrval", NULL, 1, 2, 1, 13, JOF_BYTE) -OPDEF(JSOP_BINDXMLNAME, 172,"bindxmlname",NULL, 1, 1, 2, 3, JOF_BYTE|JOF_SET) -OPDEF(JSOP_SETXMLNAME, 173,"setxmlname", NULL, 1, 3, 1, 3, JOF_BYTE|JOF_SET|JOF_DETECTING) -OPDEF(JSOP_XMLNAME, 174,"xmlname", NULL, 1, 1, 1, 19, JOF_BYTE) -OPDEF(JSOP_DESCENDANTS, 175,"descendants",NULL, 1, 2, 1, 18, JOF_BYTE) -OPDEF(JSOP_FILTER, 176,"filter", NULL, 3, 1, 1, 0, JOF_JUMP) -OPDEF(JSOP_ENDFILTER, 177,"endfilter", NULL, 3, 2, 1, 18, JOF_JUMP) -OPDEF(JSOP_TOXML, 178,"toxml", NULL, 1, 1, 1, 19, JOF_BYTE) -OPDEF(JSOP_TOXMLLIST, 179,"toxmllist", NULL, 1, 1, 1, 19, JOF_BYTE) -OPDEF(JSOP_XMLTAGEXPR, 180,"xmltagexpr", NULL, 1, 1, 1, 0, JOF_BYTE) -OPDEF(JSOP_XMLELTEXPR, 181,"xmleltexpr", NULL, 1, 1, 1, 0, JOF_BYTE) -OPDEF(JSOP_NOTRACE, 182,"notrace", NULL, 3, 0, 0, 0, JOF_UINT16) -OPDEF(JSOP_XMLCDATA, 183,"xmlcdata", NULL, 3, 0, 1, 19, JOF_ATOM) -OPDEF(JSOP_XMLCOMMENT, 184,"xmlcomment", NULL, 3, 0, 1, 19, JOF_ATOM) -OPDEF(JSOP_XMLPI, 185,"xmlpi", NULL, 3, 1, 1, 19, JOF_ATOM) -OPDEF(JSOP_DELDESC, 186,"deldesc", NULL, 1, 2, 1, 15, JOF_BYTE|JOF_ELEM|JOF_DEL) - -OPDEF(JSOP_CALLPROP, 187,"callprop", NULL, 3, 1, 2, 18, JOF_ATOM|JOF_PROP|JOF_CALLOP|JOF_TMPSLOT3) - -/* - * These opcodes contain a reference to the current blockChain object. - * They are emitted directly after instructions, such as DEFFUN, that need fast access to - * the blockChain. The special NULLBLOCKCHAIN is needed because the JOF_OBJECT - * does not permit NULL object references, since it stores an index into a table of - * objects. - */ -OPDEF(JSOP_BLOCKCHAIN, 188,"blockchain", NULL, 3, 0, 0, 0, JOF_OBJECT) -OPDEF(JSOP_NULLBLOCKCHAIN,189,"nullblockchain",NULL, 1, 0, 0, 0, JOF_BYTE) - -/* - * Opcode to hold 24-bit immediate integer operands. - */ -OPDEF(JSOP_UINT24, 190,"uint24", NULL, 4, 0, 1, 16, JOF_UINT24) - -/* - * Opcodes to allow 24-bit atom or object indexes. Whenever an index exceeds - * the 16-bit limit, the index-accessing bytecode must be bracketed by - * JSOP_INDEXBASE and JSOP_RESETBASE to provide the upper bits of the index. - * See jsemit.c, EmitIndexOp. - */ -OPDEF(JSOP_INDEXBASE, 191,"indexbase", NULL, 2, 0, 0, 0, JOF_UINT8|JOF_INDEXBASE) -OPDEF(JSOP_RESETBASE, 192,"resetbase", NULL, 1, 0, 0, 0, JOF_BYTE) -OPDEF(JSOP_RESETBASE0, 193,"resetbase0", NULL, 1, 0, 0, 0, JOF_BYTE) - -/* - * Opcodes to help the decompiler deal with XML. - */ -OPDEF(JSOP_STARTXML, 194,"startxml", NULL, 1, 0, 0, 0, JOF_BYTE) -OPDEF(JSOP_STARTXMLEXPR, 195,"startxmlexpr",NULL, 1, 0, 0, 0, JOF_BYTE) - -OPDEF(JSOP_CALLELEM, 196, "callelem", NULL, 1, 2, 2, 18, JOF_BYTE |JOF_ELEM|JOF_LEFTASSOC|JOF_CALLOP) - -/* - * Stop interpretation, emitted at end of script to save the threaded bytecode - * interpreter an extra branch test on every DO_NEXT_OP (see jsinterp.c). - */ -OPDEF(JSOP_STOP, 197,"stop", NULL, 1, 0, 0, 0, JOF_BYTE) - -/* - * Get an extant property value, throwing ReferenceError if the identified - * property does not exist. - */ -OPDEF(JSOP_GETXPROP, 198,"getxprop", NULL, 3, 1, 1, 18, JOF_ATOM|JOF_PROP) - -OPDEF(JSOP_CALLXMLNAME, 199, "callxmlname", NULL, 1, 1, 2, 19, JOF_BYTE|JOF_CALLOP) - -/* - * Specialized JSOP_TYPEOF to avoid reporting undefined for typeof(0, undef). - */ -OPDEF(JSOP_TYPEOFEXPR, 200,"typeofexpr", NULL, 1, 1, 1, 15, JOF_BYTE|JOF_DETECTING) - -/* - * Block-local scope support. - */ -OPDEF(JSOP_ENTERBLOCK, 201,"enterblock", NULL, 3, 0, -1, 0, JOF_OBJECT) -OPDEF(JSOP_LEAVEBLOCK, 202,"leaveblock", NULL, 5, -1, 0, 0, JOF_UINT16) - -/* Jump to target if top of stack value is of primitive type. */ -OPDEF(JSOP_IFPRIMTOP, 203,"ifprimtop", NULL, 3, 1, 1, 0, JOF_JUMP|JOF_DETECTING) - -/* Throws a TypeError if the value at the top of the stack is not primitive. */ -OPDEF(JSOP_PRIMTOP, 204,"primtop", NULL, 2, 1, 1, 0, JOF_INT8) - -/* - * Generator and array comprehension support. - */ -OPDEF(JSOP_GENERATOR, 205,"generator", NULL, 1, 0, 0, 0, JOF_BYTE) -OPDEF(JSOP_YIELD, 206,"yield", NULL, 1, 1, 1, 1, JOF_BYTE) -OPDEF(JSOP_ARRAYPUSH, 207,"arraypush", NULL, 3, 1, 0, 3, JOF_LOCAL) - -/* - * Get the built-in function::foo namespace and push it. - */ -OPDEF(JSOP_GETFUNNS, 208,"getfunns", NULL, 1, 0, 1, 19, JOF_BYTE) - -/* - * Variant of JSOP_ENUMELEM for destructuring const (const [a, b] = ...). - */ -OPDEF(JSOP_ENUMCONSTELEM, 209,"enumconstelem",NULL, 1, 3, 0, 3, JOF_BYTE|JOF_SET) - -/* - * Variant of JSOP_LEAVEBLOCK has a result on the stack above the locals, - * which must be moved down when the block pops. - */ -OPDEF(JSOP_LEAVEBLOCKEXPR,210,"leaveblockexpr",NULL, 5, -1, 1, 3, JOF_UINT16) - -/* - * Optimize common JSOP_{THIS,GET{ARG,LOCAL}} -> JSOP_GETPROP cliches. - */ -OPDEF(JSOP_GETTHISPROP, 211,"getthisprop", NULL, 3, 0, 1, 18, JOF_ATOM|JOF_VARPROP) -OPDEF(JSOP_GETARGPROP, 212,"getargprop", NULL, 5, 0, 1, 18, JOF_SLOTATOM|JOF_VARPROP) -OPDEF(JSOP_GETLOCALPROP, 213,"getlocalprop", NULL, 5, 0, 1, 18, JOF_SLOTATOM|JOF_VARPROP) - -/* - * Optimize atom segments 1-3. These must be followed by JSOP_RESETBASE0 after - * the opcode that they prefix. - */ -OPDEF(JSOP_INDEXBASE1, 214,"indexbase1", NULL, 1, 0, 0, 0, JOF_BYTE |JOF_INDEXBASE) -OPDEF(JSOP_INDEXBASE2, 215,"indexbase2", NULL, 1, 0, 0, 0, JOF_BYTE |JOF_INDEXBASE) -OPDEF(JSOP_INDEXBASE3, 216,"indexbase3", NULL, 1, 0, 0, 0, JOF_BYTE |JOF_INDEXBASE) - -OPDEF(JSOP_CALLGNAME, 217, "callgname", NULL, 3, 0, 2, 19, JOF_ATOM|JOF_NAME|JOF_CALLOP|JOF_GNAME) -OPDEF(JSOP_CALLLOCAL, 218, "calllocal", NULL, 3, 0, 2, 19, JOF_LOCAL|JOF_NAME|JOF_CALLOP) -OPDEF(JSOP_CALLARG, 219, "callarg", NULL, 3, 0, 2, 19, JOF_QARG |JOF_NAME|JOF_CALLOP) -OPDEF(JSOP_BINDGNAME, 220, "bindgname", NULL, 3, 0, 1, 0, JOF_ATOM|JOF_NAME|JOF_SET|JOF_GNAME) - -/* - * Opcodes to hold 8-bit and 32-bit immediate integer operands. - */ -OPDEF(JSOP_INT8, 221, "int8", NULL, 2, 0, 1, 16, JOF_INT8) -OPDEF(JSOP_INT32, 222, "int32", NULL, 5, 0, 1, 16, JOF_INT32) - -/* - * Get the value of the 'length' property from a stacked object. - */ -OPDEF(JSOP_LENGTH, 223, "length", NULL, 1, 1, 1, 18, JOF_BYTE|JOF_PROP) - -/* - * Push a JSVAL_HOLE value onto the stack, representing an omitted property in - * an array literal (e.g. property 0 in the array [, 1]). This opcode is used - * with the JSOP_NEWARRAY opcode. - */ -OPDEF(JSOP_HOLE, 224, "hole", NULL, 1, 0, 1, 0, JOF_BYTE) - -/* - * Variants of JSOP_{DEF{,LOCAL}FUN,LAMBDA} optimized for the flat closure case. - */ -OPDEF(JSOP_DEFFUN_FC, 225,"deffun_fc", NULL, 3, 0, 0, 0, JOF_OBJECT|JOF_DECLARING) -OPDEF(JSOP_DEFLOCALFUN_FC,226,"deflocalfun_fc",NULL, 5, 0, 0, 0, JOF_SLOTOBJECT|JOF_DECLARING|JOF_TMPSLOT) -OPDEF(JSOP_LAMBDA_FC, 227,"lambda_fc", NULL, 3, 0, 1, 19, JOF_OBJECT) - -/* - * Ensure that the value on the top of the stack is an object. The one - * argument is an error message, defined in js.msg, that takes one parameter - * (the decompilation of the primitive value). - */ -OPDEF(JSOP_OBJTOP, 228,"objtop", NULL, 3, 0, 0, 0, JOF_UINT16) - -/* This opcode stores an index that is unique to the given loop. */ -OPDEF(JSOP_TRACE, 229, "trace", NULL, 3, 0, 0, 0, JOF_UINT16) - -/* - * Debugger versions of the flat closure (_FC) ops. - */ -OPDEF(JSOP_GETUPVAR_DBG, 230,"getupvar_dbg", NULL, 3, 0, 1, 19, JOF_UINT16|JOF_NAME) -OPDEF(JSOP_CALLUPVAR_DBG, 231,"callupvar_dbg", NULL, 3, 0, 2, 19, JOF_UINT16|JOF_NAME|JOF_CALLOP) -OPDEF(JSOP_DEFFUN_DBGFC, 232,"deffun_dbgfc", NULL, 3, 0, 0, 0, JOF_OBJECT|JOF_DECLARING) -OPDEF(JSOP_DEFLOCALFUN_DBGFC,233,"deflocalfun_dbgfc",NULL, 5, 0, 0, 0, JOF_SLOTOBJECT|JOF_DECLARING|JOF_TMPSLOT) -OPDEF(JSOP_LAMBDA_DBGFC, 234,"lambda_dbgfc", NULL, 3, 0, 1, 19, JOF_OBJECT) - -/* - * Joined function object as method optimization support. - */ -OPDEF(JSOP_SETMETHOD, 235,"setmethod", NULL, 3, 2, 1, 3, JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING) -OPDEF(JSOP_INITMETHOD, 236,"initmethod", NULL, 3, 2, 1, 3, JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING) -OPDEF(JSOP_UNBRAND, 237,"unbrand", NULL, 1, 1, 1, 0, JOF_BYTE) -OPDEF(JSOP_UNBRANDTHIS, 238,"unbrandthis", NULL, 1, 0, 0, 0, JOF_BYTE) - -OPDEF(JSOP_SHARPINIT, 239,"sharpinit", NULL, 3, 0, 0, 0, JOF_UINT16|JOF_SHARPSLOT) - -/* Static binding for globals. */ -OPDEF(JSOP_GETGLOBAL, 240,"getglobal", NULL, 3, 0, 1, 19, JOF_GLOBAL|JOF_NAME) -OPDEF(JSOP_CALLGLOBAL, 241,"callglobal", NULL, 3, 0, 2, 19, JOF_GLOBAL|JOF_NAME|JOF_CALLOP) - -/* Like JSOP_FUNAPPLY but for f.call instead of f.apply. */ -OPDEF(JSOP_FUNCALL, 242,"funcall", NULL, 3, -1, 1, 18, JOF_UINT16|JOF_INVOKE) - -OPDEF(JSOP_FORGNAME, 243,"forgname", NULL, 3, 1, 1, 19, JOF_ATOM|JOF_GNAME|JOF_FOR|JOF_TMPSLOT3) diff --git a/x86/mozilla/include/jsopcodeinlines.h b/x86/mozilla/include/jsopcodeinlines.h deleted file mode 100644 index 0eb05d5..0000000 --- a/x86/mozilla/include/jsopcodeinlines.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Mozilla SpiderMonkey JaegerMonkey implementation - * - * The Initial Developer of the Original Code is - * Mozilla Foundation - * Portions created by the Initial Developer are Copyright (C) 2002-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "jsautooplen.h" - -namespace js { - -/* - * Warning: this does not skip JSOP_RESETBASE* or JSOP_INDEXBASE* ops, so it is - * useful only when checking for optimization opportunities. - */ -JS_ALWAYS_INLINE jsbytecode * -AdvanceOverBlockchainOp(jsbytecode *pc) -{ - if (*pc == JSOP_NULLBLOCKCHAIN) - return pc + JSOP_NULLBLOCKCHAIN_LENGTH; - if (*pc == JSOP_BLOCKCHAIN) - return pc + JSOP_BLOCKCHAIN_LENGTH; - return pc; -} - -} diff --git a/x86/mozilla/include/jsotypes.h b/x86/mozilla/include/jsotypes.h deleted file mode 100644 index bfc85cc..0000000 --- a/x86/mozilla/include/jsotypes.h +++ /dev/null @@ -1,198 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * This section typedefs the old 'native' types to the new PRs. - * These definitions are scheduled to be eliminated at the earliest - * possible time. The NSPR API is implemented and documented using - * the new definitions. - */ - -/* - * Note that we test for PROTYPES_H, not JSOTYPES_H. This is to avoid - * double-definitions of scalar types such as uint32, if NSPR's - * protypes.h is also included. - */ -#ifndef PROTYPES_H -#define PROTYPES_H - -#ifdef XP_BEOS -/* BeOS defines most int types in SupportDefs.h (int8, uint8, int16, - * uint16, int32, uint32, int64, uint64), so in the interest of - * not conflicting with other definitions elsewhere we have to skip the - * #ifdef jungle below, duplicate some definitions, and do our stuff. - */ -#include - -typedef JSUintn uintn; -#ifndef _XP_Core_ -typedef JSIntn intn; -#endif - -#else - -/* SVR4 typedef of uint is commonly found on UNIX machines. */ -#ifdef XP_UNIX -#include -#else -typedef JSUintn uint; -#endif - -typedef JSUintn uintn; -typedef JSUint64 uint64; -typedef JSUint32 uint32; -typedef JSUint16 uint16; -typedef JSUint8 uint8; - -#ifndef _XP_Core_ -typedef JSIntn intn; -#endif - -/* - * On AIX 4.3, sys/inttypes.h (which is included by sys/types.h, a very - * common header file) defines the types int8, int16, int32, and int64. - * So we don't define these four types here to avoid conflicts in case - * the code also includes sys/types.h. - */ -#if defined(AIX) && defined(HAVE_SYS_INTTYPES_H) -#include -#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) -typedef JSInt64 int64; - -/* Explicit signed keyword for bitfield types is required. */ -/* Some compilers may treat them as unsigned without it. */ -typedef signed int int32; -typedef signed short int16; -typedef signed char int8; -#else -typedef JSInt64 int64; - -/* /usr/include/model.h on HP-UX defines int8, int16, and int32 */ -typedef JSInt32 int32; -typedef JSInt16 int16; -typedef JSInt8 int8; -#endif /* AIX && HAVE_SYS_INTTYPES_H */ - -#endif /* XP_BEOS */ - -typedef JSFloat64 float64; - -/* Re: jsbit.h */ -#define TEST_BIT JS_TEST_BIT -#define SET_BIT JS_SET_BIT -#define CLEAR_BIT JS_CLEAR_BIT - -/* Re: prarena.h->plarena.h */ -#define PRArena PLArena -#define PRArenaPool PLArenaPool -#define PRArenaStats PLArenaStats -#define PR_ARENA_ALIGN PL_ARENA_ALIGN -#define PR_INIT_ARENA_POOL PL_INIT_ARENA_POOL -#define PR_ARENA_ALLOCATE PL_ARENA_ALLOCATE -#define PR_ARENA_GROW PL_ARENA_GROW -#define PR_ARENA_MARK PL_ARENA_MARK -#define PR_CLEAR_UNUSED PL_CLEAR_UNUSED -#define PR_CLEAR_ARENA PL_CLEAR_ARENA -#define PR_ARENA_RELEASE PL_ARENA_RELEASE -#define PR_COUNT_ARENA PL_COUNT_ARENA -#define PR_ARENA_DESTROY PL_ARENA_DESTROY -#define PR_InitArenaPool PL_InitArenaPool -#define PR_FreeArenaPool PL_FreeArenaPool -#define PR_FinishArenaPool PL_FinishArenaPool -#define PR_CompactArenaPool PL_CompactArenaPool -#define PR_ArenaFinish PL_ArenaFinish -#define PR_ArenaAllocate PL_ArenaAllocate -#define PR_ArenaGrow PL_ArenaGrow -#define PR_ArenaRelease PL_ArenaRelease -#define PR_ArenaCountAllocation PL_ArenaCountAllocation -#define PR_ArenaCountInplaceGrowth PL_ArenaCountInplaceGrowth -#define PR_ArenaCountGrowth PL_ArenaCountGrowth -#define PR_ArenaCountRelease PL_ArenaCountRelease -#define PR_ArenaCountRetract PL_ArenaCountRetract - -/* Re: prevent.h->plevent.h */ -#define PREvent PLEvent -#define PREventQueue PLEventQueue -#define PR_CreateEventQueue PL_CreateEventQueue -#define PR_DestroyEventQueue PL_DestroyEventQueue -#define PR_GetEventQueueMonitor PL_GetEventQueueMonitor -#define PR_ENTER_EVENT_QUEUE_MONITOR PL_ENTER_EVENT_QUEUE_MONITOR -#define PR_EXIT_EVENT_QUEUE_MONITOR PL_EXIT_EVENT_QUEUE_MONITOR -#define PR_PostEvent PL_PostEvent -#define PR_PostSynchronousEvent PL_PostSynchronousEvent -#define PR_GetEvent PL_GetEvent -#define PR_EventAvailable PL_EventAvailable -#define PREventFunProc PLEventFunProc -#define PR_MapEvents PL_MapEvents -#define PR_RevokeEvents PL_RevokeEvents -#define PR_ProcessPendingEvents PL_ProcessPendingEvents -#define PR_WaitForEvent PL_WaitForEvent -#define PR_EventLoop PL_EventLoop -#define PR_GetEventQueueSelectFD PL_GetEventQueueSelectFD -#define PRHandleEventProc PLHandleEventProc -#define PRDestroyEventProc PLDestroyEventProc -#define PR_InitEvent PL_InitEvent -#define PR_GetEventOwner PL_GetEventOwner -#define PR_HandleEvent PL_HandleEvent -#define PR_DestroyEvent PL_DestroyEvent -#define PR_DequeueEvent PL_DequeueEvent -#define PR_GetMainEventQueue PL_GetMainEventQueue - -/* Re: prhash.h->plhash.h */ -#define PRHashEntry PLHashEntry -#define PRHashTable PLHashTable -#define PRHashNumber PLHashNumber -#define PRHashFunction PLHashFunction -#define PRHashComparator PLHashComparator -#define PRHashEnumerator PLHashEnumerator -#define PRHashAllocOps PLHashAllocOps -#define PR_NewHashTable PL_NewHashTable -#define PR_HashTableDestroy PL_HashTableDestroy -#define PR_HashTableRawLookup PL_HashTableRawLookup -#define PR_HashTableRawAdd PL_HashTableRawAdd -#define PR_HashTableRawRemove PL_HashTableRawRemove -#define PR_HashTableAdd PL_HashTableAdd -#define PR_HashTableRemove PL_HashTableRemove -#define PR_HashTableEnumerateEntries PL_HashTableEnumerateEntries -#define PR_HashTableLookup PL_HashTableLookup -#define PR_HashTableDump PL_HashTableDump -#define PR_HashString PL_HashString -#define PR_CompareStrings PL_CompareStrings -#define PR_CompareValues PL_CompareValues - -#endif /* !defined(PROTYPES_H) */ diff --git a/x86/mozilla/include/jsparse.h b/x86/mozilla/include/jsparse.h deleted file mode 100644 index 91bf7f9..0000000 --- a/x86/mozilla/include/jsparse.h +++ /dev/null @@ -1,1254 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=4 sw=4 et tw=78: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsparse_h___ -#define jsparse_h___ -/* - * JS parser definitions. - */ -#include "jsversion.h" -#include "jsprvtd.h" -#include "jspubtd.h" -#include "jsatom.h" -#include "jsscan.h" - -JS_BEGIN_EXTERN_C - -/* - * Parsing builds a tree of nodes that directs code generation. This tree is - * not a concrete syntax tree in all respects (for example, || and && are left - * associative, but (A && B && C) translates into the right-associated tree - * > so that code generation can emit a left-associative branch - * around when A is false). Nodes are labeled by token type, with a - * JSOp secondary label when needed: - * - * Label Variant Members - * ----- ------- ------- - * - * TOK_FUNCTION name pn_funbox: ptr to JSFunctionBox holding function - * object containing arg and var properties. We - * create the function object at parse (not emit) - * time to specialize arg and var bytecodes early. - * pn_body: TOK_UPVARS if the function's source body - * depends on outer names, else TOK_ARGSBODY - * if formal parameters, else TOK_LC node for - * function body statements, else TOK_RETURN - * for expression closure, else TOK_SEQ for - * expression closure with destructured - * formal parameters - * pn_cookie: static level and var index for function - * pn_dflags: PND_* definition/use flags (see below) - * pn_blockid: block id number - * TOK_ARGSBODY list list of formal parameters followed by TOK_LC node - * for function body statements as final element - * pn_count: 1 + number of formal parameters - * TOK_UPVARS nameset pn_names: lexical dependencies (JSDefinitions) - * defined in enclosing scopes, or ultimately not - * defined (free variables, either global property - * references or reference errors). - * pn_tree: TOK_ARGSBODY or TOK_LC node - * - * - * TOK_LC list pn_head: list of pn_count statements - * TOK_IF ternary pn_kid1: cond, pn_kid2: then, pn_kid3: else or null. - * In body of a comprehension or desugared generator - * expression, pn_kid2 is TOK_YIELD, TOK_ARRAYPUSH, - * or (if the push was optimized away) empty TOK_LC. - * TOK_SWITCH binary pn_left: discriminant - * pn_right: list of TOK_CASE nodes, with at most one - * TOK_DEFAULT node, or if there are let bindings - * in the top level of the switch body's cases, a - * TOK_LEXICALSCOPE node that contains the list of - * TOK_CASE nodes. - * TOK_CASE, binary pn_left: case expr or null if TOK_DEFAULT - * TOK_DEFAULT pn_right: TOK_LC node for this case's statements - * pn_val: constant value if lookup or table switch - * TOK_WHILE binary pn_left: cond, pn_right: body - * TOK_DO binary pn_left: body, pn_right: cond - * TOK_FOR binary pn_left: either - * for/in loop: a binary TOK_IN node with - * pn_left: TOK_VAR or TOK_NAME to left of 'in' - * if TOK_VAR, its pn_xflags may have PNX_POPVAR - * and PNX_FORINVAR bits set - * pn_right: object expr to right of 'in' - * for(;;) loop: a ternary TOK_RESERVED node with - * pn_kid1: init expr before first ';' - * pn_kid2: cond expr before second ';' - * pn_kid3: update expr after second ';' - * any kid may be null - * pn_right: body - * TOK_THROW unary pn_op: JSOP_THROW, pn_kid: exception - * TOK_TRY ternary pn_kid1: try block - * pn_kid2: null or TOK_RESERVED list of - * TOK_LEXICALSCOPE nodes, each with pn_expr pointing - * to a TOK_CATCH node - * pn_kid3: null or finally block - * TOK_CATCH ternary pn_kid1: TOK_NAME, TOK_RB, or TOK_RC catch var node - * (TOK_RB or TOK_RC if destructuring) - * pn_kid2: null or the catch guard expression - * pn_kid3: catch block statements - * TOK_BREAK name pn_atom: label or null - * TOK_CONTINUE name pn_atom: label or null - * TOK_WITH binary pn_left: head expr, pn_right: body - * TOK_VAR list pn_head: list of TOK_NAME or TOK_ASSIGN nodes - * each name node has - * pn_used: false - * pn_atom: variable name - * pn_expr: initializer or null - * each assignment node has - * pn_left: TOK_NAME with pn_used true and - * pn_lexdef (NOT pn_expr) set - * pn_right: initializer - * TOK_RETURN unary pn_kid: return expr or null - * TOK_SEMI unary pn_kid: expr or null statement - * pn_prologue: true if Directive Prologue member - * in original source, not introduced via - * constant folding or other tree rewriting - * TOK_COLON name pn_atom: label, pn_expr: labeled statement - * - * - * All left-associated binary trees of the same type are optimized into lists - * to avoid recursion when processing expression chains. - * TOK_COMMA list pn_head: list of pn_count comma-separated exprs - * TOK_ASSIGN binary pn_left: lvalue, pn_right: rvalue - * pn_op: JSOP_ADD for +=, etc. - * TOK_HOOK ternary pn_kid1: cond, pn_kid2: then, pn_kid3: else - * TOK_OR binary pn_left: first in || chain, pn_right: rest of chain - * TOK_AND binary pn_left: first in && chain, pn_right: rest of chain - * TOK_BITOR binary pn_left: left-assoc | expr, pn_right: ^ expr - * TOK_BITXOR binary pn_left: left-assoc ^ expr, pn_right: & expr - * TOK_BITAND binary pn_left: left-assoc & expr, pn_right: EQ expr - * TOK_EQOP binary pn_left: left-assoc EQ expr, pn_right: REL expr - * pn_op: JSOP_EQ, JSOP_NE, - * JSOP_STRICTEQ, JSOP_STRICTNE - * TOK_RELOP binary pn_left: left-assoc REL expr, pn_right: SH expr - * pn_op: JSOP_LT, JSOP_LE, JSOP_GT, JSOP_GE - * TOK_SHOP binary pn_left: left-assoc SH expr, pn_right: ADD expr - * pn_op: JSOP_LSH, JSOP_RSH, JSOP_URSH - * TOK_PLUS, binary pn_left: left-assoc ADD expr, pn_right: MUL expr - * pn_xflags: if a left-associated binary TOK_PLUS - * tree has been flattened into a list (see above - * under ), pn_xflags will contain - * PNX_STRCAT if at least one list element is a - * string literal (TOK_STRING); if such a list has - * any non-string, non-number term, pn_xflags will - * contain PNX_CANTFOLD. - * pn_ - * TOK_MINUS pn_op: JSOP_ADD, JSOP_SUB - * TOK_STAR, binary pn_left: left-assoc MUL expr, pn_right: UNARY expr - * TOK_DIVOP pn_op: JSOP_MUL, JSOP_DIV, JSOP_MOD - * TOK_UNARYOP unary pn_kid: UNARY expr, pn_op: JSOP_NEG, JSOP_POS, - * JSOP_NOT, JSOP_BITNOT, JSOP_TYPEOF, JSOP_VOID - * TOK_INC, unary pn_kid: MEMBER expr - * TOK_DEC - * TOK_NEW list pn_head: list of ctor, arg1, arg2, ... argN - * pn_count: 1 + N (where N is number of args) - * ctor is a MEMBER expr - * TOK_DELETE unary pn_kid: MEMBER expr - * TOK_DOT, name pn_expr: MEMBER expr to left of . - * TOK_DBLDOT pn_atom: name to right of . - * TOK_LB binary pn_left: MEMBER expr to left of [ - * pn_right: expr between [ and ] - * TOK_LP list pn_head: list of call, arg1, arg2, ... argN - * pn_count: 1 + N (where N is number of args) - * call is a MEMBER expr naming a callable object - * TOK_RB list pn_head: list of pn_count array element exprs - * [,,] holes are represented by TOK_COMMA nodes - * pn_xflags: PN_ENDCOMMA if extra comma at end - * TOK_RC list pn_head: list of pn_count binary TOK_COLON nodes - * TOK_COLON binary key-value pair in object initializer or - * destructuring lhs - * pn_left: property id, pn_right: value - * var {x} = object destructuring shorthand shares - * PN_NAME node for x on left and right of TOK_COLON - * node in TOK_RC's list, has PNX_DESTRUCT flag - * TOK_DEFSHARP unary pn_num: jsint value of n in #n= - * pn_kid: primary function, paren, name, object or - * array literal expressions - * TOK_USESHARP nullary pn_num: jsint value of n in #n# - * TOK_NAME, name pn_atom: name, string, or object atom - * TOK_STRING, pn_op: JSOP_NAME, JSOP_STRING, or JSOP_OBJECT, or - * JSOP_REGEXP - * TOK_REGEXP If JSOP_NAME, pn_op may be JSOP_*ARG or JSOP_*VAR - * with pn_cookie telling (staticLevel, slot) (see - * jsscript.h's UPVAR macros) and pn_dflags telling - * const-ness and static analysis results - * TOK_NAME name If pn_used, TOK_NAME uses the lexdef member instead - * of the expr member it overlays - * TOK_NUMBER dval pn_dval: double value of numeric literal - * TOK_PRIMARY nullary pn_op: JSOp bytecode - * - * - * TOK_DEFAULT name pn_atom: default XML namespace string literal - * TOK_FILTER binary pn_left: container expr, pn_right: filter expr - * TOK_DBLDOT binary pn_left: container expr, pn_right: selector expr - * TOK_ANYNAME nullary pn_op: JSOP_ANYNAME - * pn_atom: cx->runtime->atomState.starAtom - * TOK_AT unary pn_op: JSOP_TOATTRNAME; pn_kid attribute id/expr - * TOK_DBLCOLON binary pn_op: JSOP_QNAME - * pn_left: TOK_ANYNAME or TOK_NAME node - * pn_right: TOK_STRING "*" node, or expr within [] - * name pn_op: JSOP_QNAMECONST - * pn_expr: TOK_ANYNAME or TOK_NAME left operand - * pn_atom: name on right of :: - * TOK_XMLELEM list XML element node - * pn_head: start tag, content1, ... contentN, end tag - * pn_count: 2 + N where N is number of content nodes - * N may be > x.length() if {expr} embedded - * After constant folding, these contents may be - * concatenated into string nodes. - * TOK_XMLLIST list XML list node - * pn_head: content1, ... contentN - * TOK_XMLSTAGO, list XML start, end, and point tag contents - * TOK_XMLETAGO, pn_head: tag name or {expr}, ... XML attrs ... - * TOK_XMLPTAGC - * TOK_XMLNAME nullary pn_atom: XML name, with no {expr} embedded - * TOK_XMLNAME list pn_head: tag name or {expr}, ... name or {expr} - * TOK_XMLATTR, nullary pn_atom: attribute value string; pn_op: JSOP_STRING - * TOK_XMLCDATA, - * TOK_XMLCOMMENT - * TOK_XMLPI nullary pn_atom: XML processing instruction target - * pn_atom2: XML PI content, or null if no content - * TOK_XMLTEXT nullary pn_atom: marked-up text, or null if empty string - * TOK_LC unary {expr} in XML tag or content; pn_kid is expr - * - * So an XML tag with no {expr} and three attributes is a list with the form: - * - * (tagname attrname1 attrvalue1 attrname2 attrvalue2 attrname2 attrvalue3) - * - * An XML tag with embedded expressions like so: - * - * - * - * would have the form: - * - * ((name1 {expr1}) (name2 {expr2} name3) {expr3}) - * - * where () bracket a list with elements separated by spaces, and {expr} is a - * TOK_LC unary node with expr as its kid. - * - * Thus, the attribute name/value pairs occupy successive odd and even list - * locations, where pn_head is the TOK_XMLNAME node at list location 0. The - * parser builds the same sort of structures for elements: - * - * Hi there!How are you?{x + y} - * - * translates to: - * - * ((a x {x}) 'Hi there!' ((b y {y}) 'How are you?') ((answer) {x + y})) - * - * - * - * Label Variant Members - * ----- ------- ------- - * TOK_LEXICALSCOPE name pn_op: JSOP_LEAVEBLOCK or JSOP_LEAVEBLOCKEXPR - * pn_objbox: block object in JSObjectBox holder - * pn_expr: block body - * TOK_ARRAYCOMP list pn_count: 1 - * pn_head: list of 1 element, which is block - * enclosing for loop(s) and optionally - * if-guarded TOK_ARRAYPUSH - * TOK_ARRAYPUSH unary pn_op: JSOP_ARRAYCOMP - * pn_kid: array comprehension expression - */ -typedef enum JSParseNodeArity { - PN_NULLARY, /* 0 kids, only pn_atom/pn_dval/etc. */ - PN_UNARY, /* one kid, plus a couple of scalars */ - PN_BINARY, /* two kids, plus a couple of scalars */ - PN_TERNARY, /* three kids */ - PN_FUNC, /* function definition node */ - PN_LIST, /* generic singly linked list */ - PN_NAME, /* name use or definition node */ - PN_NAMESET /* JSAtomList + JSParseNode ptr */ -} JSParseNodeArity; - -struct JSDefinition; - -namespace js { - -struct GlobalScope { - GlobalScope(JSContext *cx, JSObject *globalObj, JSCodeGenerator *cg) - : globalObj(globalObj), cg(cg), defs(ContextAllocPolicy(cx)) - { } - - struct GlobalDef { - JSAtom *atom; // If non-NULL, specifies the property name to add. - JSFunctionBox *funbox; // If non-NULL, function value for the property. - // This value is only set/used if atom is non-NULL. - uint32 knownSlot; // If atom is NULL, this is the known shape slot. - - GlobalDef() { } - GlobalDef(uint32 knownSlot) - : atom(NULL), knownSlot(knownSlot) - { } - GlobalDef(JSAtom *atom, JSFunctionBox *box) : - atom(atom), funbox(box) - { } - }; - - JSObject *globalObj; - JSCodeGenerator *cg; - - /* - * This is the table of global names encountered during parsing. Each - * global name appears in the list only once, and the |names| table - * maps back into |defs| for fast lookup. - * - * A definition may either specify an existing global property, or a new - * one that must be added after compilation succeeds. - */ - Vector defs; - JSAtomList names; -}; - -} /* namespace js */ - -struct JSParseNode { - uint32 pn_type:16, /* TOK_* type, see jsscan.h */ - pn_op:8, /* see JSOp enum and jsopcode.tbl */ - pn_arity:5, /* see JSParseNodeArity enum */ - pn_parens:1, /* this expr was enclosed in parens */ - pn_used:1, /* name node is on a use-chain */ - pn_defn:1; /* this node is a JSDefinition */ - -#define PN_OP(pn) ((JSOp)(pn)->pn_op) -#define PN_TYPE(pn) ((js::TokenKind)(pn)->pn_type) - - js::TokenPos pn_pos; /* two 16-bit pairs here, for 64 bits */ - int32 pn_offset; /* first generated bytecode offset */ - JSParseNode *pn_next; /* intrinsic link in parent PN_LIST */ - JSParseNode *pn_link; /* def/use link (alignment freebie); - also links JSFunctionBox::methods - lists of would-be |this| methods */ - union { - struct { /* list of next-linked nodes */ - JSParseNode *head; /* first node in list */ - JSParseNode **tail; /* ptr to ptr to last node in list */ - uint32 count; /* number of nodes in list */ - uint32 xflags:12, /* extra flags, see below */ - blockid:20; /* see name variant below */ - } list; - struct { /* ternary: if, for(;;), ?: */ - JSParseNode *kid1; /* condition, discriminant, etc. */ - JSParseNode *kid2; /* then-part, case list, etc. */ - JSParseNode *kid3; /* else-part, default case, etc. */ - } ternary; - struct { /* two kids if binary */ - JSParseNode *left; - JSParseNode *right; - js::Value *pval; /* switch case value */ - uintN iflags; /* JSITER_* flags for TOK_FOR node */ - } binary; - struct { /* one kid if unary */ - JSParseNode *kid; - jsint num; /* -1 or sharp variable number */ - JSBool hidden; /* hidden genexp-induced JSOP_YIELD - or directive prologue member (as - pn_prologue) */ - } unary; - struct { /* name, labeled statement, etc. */ - union { - JSAtom *atom; /* lexical name or label atom */ - JSFunctionBox *funbox; /* function object */ - JSObjectBox *objbox; /* block or regexp object */ - }; - union { - JSParseNode *expr; /* function body, var initializer, or - base object of TOK_DOT */ - JSDefinition *lexdef; /* lexical definition for this use */ - }; - js::UpvarCookie cookie; /* upvar cookie with absolute frame - level (not relative skip), possibly - in current frame */ - uint32 dflags:12, /* definition/use flags, see below */ - blockid:20; /* block number, for subset dominance - computation */ - } name; - struct { /* lexical dependencies + sub-tree */ - JSAtomSet names; /* set of names with JSDefinitions */ - JSParseNode *tree; /* sub-tree containing name uses */ - } nameset; - struct { /* PN_NULLARY variant for E4X */ - JSAtom *atom; /* first atom in pair */ - JSAtom *atom2; /* second atom in pair or null */ - } apair; - jsdouble dval; /* aligned numeric literal value */ - } pn_u; - -#define pn_funbox pn_u.name.funbox -#define pn_body pn_u.name.expr -#define pn_cookie pn_u.name.cookie -#define pn_dflags pn_u.name.dflags -#define pn_blockid pn_u.name.blockid -#define pn_index pn_u.name.blockid /* reuse as object table index */ -#define pn_head pn_u.list.head -#define pn_tail pn_u.list.tail -#define pn_count pn_u.list.count -#define pn_xflags pn_u.list.xflags -#define pn_kid1 pn_u.ternary.kid1 -#define pn_kid2 pn_u.ternary.kid2 -#define pn_kid3 pn_u.ternary.kid3 -#define pn_left pn_u.binary.left -#define pn_right pn_u.binary.right -#define pn_pval pn_u.binary.pval -#define pn_iflags pn_u.binary.iflags -#define pn_kid pn_u.unary.kid -#define pn_num pn_u.unary.num -#define pn_hidden pn_u.unary.hidden -#define pn_prologue pn_u.unary.hidden -#define pn_atom pn_u.name.atom -#define pn_objbox pn_u.name.objbox -#define pn_expr pn_u.name.expr -#define pn_lexdef pn_u.name.lexdef -#define pn_names pn_u.nameset.names -#define pn_tree pn_u.nameset.tree -#define pn_dval pn_u.dval -#define pn_atom2 pn_u.apair.atom2 - -protected: - void inline init(js::TokenKind type, JSOp op, JSParseNodeArity arity) { - pn_type = type; - pn_op = op; - pn_arity = arity; - pn_parens = false; - JS_ASSERT(!pn_used); - JS_ASSERT(!pn_defn); - pn_next = pn_link = NULL; - } - - static JSParseNode *create(JSParseNodeArity arity, JSTreeContext *tc); - -public: - static JSParseNode *newBinaryOrAppend(js::TokenKind tt, JSOp op, JSParseNode *left, - JSParseNode *right, JSTreeContext *tc); - - /* - * The pn_expr and lexdef members are arms of an unsafe union. Unless you - * know exactly what you're doing, use only the following methods to access - * them. For less overhead and assertions for protection, use pn->expr() - * and pn->lexdef(). Otherwise, use pn->maybeExpr() and pn->maybeLexDef(). - */ - JSParseNode *expr() const { - JS_ASSERT(!pn_used); - JS_ASSERT(pn_arity == PN_NAME || pn_arity == PN_FUNC); - return pn_expr; - } - - JSDefinition *lexdef() const { - JS_ASSERT(pn_used || isDeoptimized()); - JS_ASSERT(pn_arity == PN_NAME); - return pn_lexdef; - } - - JSParseNode *maybeExpr() { return pn_used ? NULL : expr(); } - JSDefinition *maybeLexDef() { return pn_used ? lexdef() : NULL; } - -/* PN_FUNC and PN_NAME pn_dflags bits. */ -#define PND_LET 0x01 /* let (block-scoped) binding */ -#define PND_CONST 0x02 /* const binding (orthogonal to let) */ -#define PND_INITIALIZED 0x04 /* initialized declaration */ -#define PND_ASSIGNED 0x08 /* set if ever LHS of assignment */ -#define PND_TOPLEVEL 0x10 /* see isTopLevel() below */ -#define PND_BLOCKCHILD 0x20 /* use or def is direct block child */ -#define PND_GVAR 0x40 /* gvar binding, can't close over - because it could be deleted */ -#define PND_PLACEHOLDER 0x80 /* placeholder definition for lexdep */ -#define PND_FUNARG 0x100 /* downward or upward funarg usage */ -#define PND_BOUND 0x200 /* bound to a stack or global slot */ -#define PND_DEOPTIMIZED 0x400 /* former pn_used name node, pn_lexdef - still valid, but this use no longer - optimizable via an upvar opcode */ -#define PND_CLOSED 0x800 /* variable is closed over */ - -/* Flags to propagate from uses to definition. */ -#define PND_USE2DEF_FLAGS (PND_ASSIGNED | PND_FUNARG | PND_CLOSED) - -/* PN_LIST pn_xflags bits. */ -#define PNX_STRCAT 0x01 /* TOK_PLUS list has string term */ -#define PNX_CANTFOLD 0x02 /* TOK_PLUS list has unfoldable term */ -#define PNX_POPVAR 0x04 /* TOK_VAR last result needs popping */ -#define PNX_FORINVAR 0x08 /* TOK_VAR is left kid of TOK_IN node, - which is left kid of TOK_FOR */ -#define PNX_ENDCOMMA 0x10 /* array literal has comma at end */ -#define PNX_XMLROOT 0x20 /* top-most node in XML literal tree */ -#define PNX_GROUPINIT 0x40 /* var [a, b] = [c, d]; unit list */ -#define PNX_NEEDBRACES 0x80 /* braces necessary due to closure */ -#define PNX_FUNCDEFS 0x100 /* contains top-level function statements */ -#define PNX_SETCALL 0x100 /* call expression in lvalue context */ -#define PNX_DESTRUCT 0x200 /* destructuring special cases: - 1. shorthand syntax used, at present - object destructuring ({x,y}) only; - 2. code evaluating destructuring - arguments occurs before function - body */ -#define PNX_HOLEY 0x400 /* array initialiser has holes */ -#define PNX_NONCONST 0x800 /* initialiser has non-constants */ - - uintN frameLevel() const { - JS_ASSERT(pn_arity == PN_FUNC || pn_arity == PN_NAME); - return pn_cookie.level(); - } - - uintN frameSlot() const { - JS_ASSERT(pn_arity == PN_FUNC || pn_arity == PN_NAME); - return pn_cookie.slot(); - } - - inline bool test(uintN flag) const; - - bool isLet() const { return test(PND_LET); } - bool isConst() const { return test(PND_CONST); } - bool isInitialized() const { return test(PND_INITIALIZED); } - bool isBlockChild() const { return test(PND_BLOCKCHILD); } - bool isPlaceholder() const { return test(PND_PLACEHOLDER); } - bool isDeoptimized() const { return test(PND_DEOPTIMIZED); } - bool isAssigned() const { return test(PND_ASSIGNED); } - bool isFunArg() const { return test(PND_FUNARG); } - bool isClosed() const { return test(PND_CLOSED); } - - /* - * True iff this definition creates a top-level binding in the overall - * script being compiled -- that is, it affects the whole program's - * bindings, not bindings for a specific function (unless this definition - * is in the outermost scope in eval code, executed within a function) or - * the properties of a specific object (through the with statement). - * - * NB: Function sub-statements found in overall program code and not nested - * within other functions are not currently top level, even though (if - * executed) they do create top-level bindings; there is no particular - * rationale for this behavior. - */ - bool isTopLevel() const { return test(PND_TOPLEVEL); } - - /* Defined below, see after struct JSDefinition. */ - void setFunArg(); - - void become(JSParseNode *pn2); - void clear(); - - /* True if pn is a parsenode representing a literal constant. */ - bool isLiteral() const { - return PN_TYPE(this) == js::TOK_NUMBER || - PN_TYPE(this) == js::TOK_STRING || - (PN_TYPE(this) == js::TOK_PRIMARY && PN_OP(this) != JSOP_THIS); - } - - /* - * True if this statement node could be a member of a Directive Prologue: an - * expression statement consisting of a single string literal. - * - * This considers only the node and its children, not its context. After - * parsing, check the node's pn_prologue flag to see if it is indeed part of - * a directive prologue. - * - * Note that a Directive Prologue can contain statements that cannot - * themselves be directives (string literals that include escape sequences - * or escaped newlines, say). This member function returns true for such - * nodes; we use it to determine the extent of the prologue. - * isEscapeFreeStringLiteral, below, checks whether the node itself could be - * a directive. - */ - bool isStringExprStatement() const { - if (PN_TYPE(this) == js::TOK_SEMI) { - JS_ASSERT(pn_arity == PN_UNARY); - JSParseNode *kid = pn_kid; - return kid && PN_TYPE(kid) == js::TOK_STRING && !kid->pn_parens; - } - return false; - } - - /* - * Return true if this node, known to be a string literal, could be the - * string of a directive in a Directive Prologue. Directive strings never - * contain escape sequences or line continuations. - */ - bool isEscapeFreeStringLiteral() const { - JS_ASSERT(pn_type == js::TOK_STRING && !pn_parens); - JSString *str = ATOM_TO_STRING(pn_atom); - - /* - * If the string's length in the source code is its length as a value, - * accounting for the quotes, then it must not contain any escape - * sequences or line continuations. - */ - return (pn_pos.begin.lineno == pn_pos.end.lineno && - pn_pos.begin.index + str->length() + 2 == pn_pos.end.index); - } - - /* Return true if this node appears in a Directive Prologue. */ - bool isDirectivePrologueMember() const { return pn_prologue; } - -#ifdef JS_HAS_GENERATOR_EXPRS - /* - * True if this node is a desugared generator expression. - */ - bool isGeneratorExpr() const { - if (PN_TYPE(this) == js::TOK_LP) { - JSParseNode *callee = this->pn_head; - if (PN_TYPE(callee) == js::TOK_FUNCTION) { - JSParseNode *body = (PN_TYPE(callee->pn_body) == js::TOK_UPVARS) - ? callee->pn_body->pn_tree - : callee->pn_body; - if (PN_TYPE(body) == js::TOK_LEXICALSCOPE) - return true; - } - } - return false; - } - - JSParseNode *generatorExpr() const { - JS_ASSERT(isGeneratorExpr()); - JSParseNode *callee = this->pn_head; - JSParseNode *body = PN_TYPE(callee->pn_body) == js::TOK_UPVARS - ? callee->pn_body->pn_tree - : callee->pn_body; - JS_ASSERT(PN_TYPE(body) == js::TOK_LEXICALSCOPE); - return body->pn_expr; - } -#endif - - /* - * Compute a pointer to the last element in a singly-linked list. NB: list - * must be non-empty for correct PN_LAST usage -- this is asserted! - */ - JSParseNode *last() const { - JS_ASSERT(pn_arity == PN_LIST); - JS_ASSERT(pn_count != 0); - return (JSParseNode *)((char *)pn_tail - offsetof(JSParseNode, pn_next)); - } - - void makeEmpty() { - JS_ASSERT(pn_arity == PN_LIST); - pn_head = NULL; - pn_tail = &pn_head; - pn_count = 0; - pn_xflags = 0; - pn_blockid = 0; - } - - void initList(JSParseNode *pn) { - JS_ASSERT(pn_arity == PN_LIST); - pn_head = pn; - pn_tail = &pn->pn_next; - pn_count = 1; - pn_xflags = 0; - pn_blockid = 0; - } - - void append(JSParseNode *pn) { - JS_ASSERT(pn_arity == PN_LIST); - *pn_tail = pn; - pn_tail = &pn->pn_next; - pn_count++; - } - - bool getConstantValue(JSContext *cx, bool strictChecks, js::Value *vp); - inline bool isConstant(); -}; - -namespace js { - -struct NullaryNode : public JSParseNode { - static inline NullaryNode *create(JSTreeContext *tc) { - return (NullaryNode *)JSParseNode::create(PN_NULLARY, tc); - } -}; - -struct UnaryNode : public JSParseNode { - static inline UnaryNode *create(JSTreeContext *tc) { - return (UnaryNode *)JSParseNode::create(PN_UNARY, tc); - } -}; - -struct BinaryNode : public JSParseNode { - static inline BinaryNode *create(JSTreeContext *tc) { - return (BinaryNode *)JSParseNode::create(PN_BINARY, tc); - } -}; - -struct TernaryNode : public JSParseNode { - static inline TernaryNode *create(JSTreeContext *tc) { - return (TernaryNode *)JSParseNode::create(PN_TERNARY, tc); - } -}; - -struct ListNode : public JSParseNode { - static inline ListNode *create(JSTreeContext *tc) { - return (ListNode *)JSParseNode::create(PN_LIST, tc); - } -}; - -struct FunctionNode : public JSParseNode { - static inline FunctionNode *create(JSTreeContext *tc) { - return (FunctionNode *)JSParseNode::create(PN_FUNC, tc); - } -}; - -struct NameNode : public JSParseNode { - static NameNode *create(JSAtom *atom, JSTreeContext *tc); - - void inline initCommon(JSTreeContext *tc); -}; - -struct NameSetNode : public JSParseNode { - static inline NameSetNode *create(JSTreeContext *tc) { - return (NameSetNode *)JSParseNode::create(PN_NAMESET, tc); - } -}; - -struct LexicalScopeNode : public JSParseNode { - static inline LexicalScopeNode *create(JSTreeContext *tc) { - return (LexicalScopeNode *)JSParseNode::create(PN_NAME, tc); - } -}; - -} /* namespace js */ - -/* - * JSDefinition is a degenerate subtype of the PN_FUNC and PN_NAME variants of - * JSParseNode, allocated only for function, var, const, and let declarations - * that define truly lexical bindings. This means that a child of a TOK_VAR - * list may be a JSDefinition instead of a JSParseNode. The pn_defn bit is set - * for all JSDefinitions, clear otherwise. - * - * Note that not all var declarations are definitions: JS allows multiple var - * declarations in a function or script, but only the first creates the hoisted - * binding. JS programmers do redeclare variables for good refactoring reasons, - * for example: - * - * function foo() { - * ... - * for (var i ...) ...; - * ... - * for (var i ...) ...; - * ... - * } - * - * Not all definitions bind lexical variables, alas. In global and eval code - * var may re-declare a pre-existing property having any attributes, with or - * without JSPROP_PERMANENT. In eval code, indeed, ECMA-262 Editions 1 through - * 3 require function and var to bind deletable bindings. Global vars thus are - * properties of the global object, so they can be aliased even if they can't - * be deleted. - * - * Only bindings within function code may be treated as lexical, of course with - * the caveat that hoisting means use before initialization is allowed. We deal - * with use before declaration in one pass as follows (error checking elided): - * - * for (each use of unqualified name x in parse order) { - * if (this use of x is a declaration) { - * if (x in tc->decls) { // redeclaring - * pn = allocate a PN_NAME JSParseNode; - * } else { // defining - * dn = lookup x in tc->lexdeps; - * if (dn) // use before def - * remove x from tc->lexdeps; - * else // def before use - * dn = allocate a PN_NAME JSDefinition; - * map x to dn via tc->decls; - * pn = dn; - * } - * insert pn into its parent TOK_VAR list; - * } else { - * pn = allocate a JSParseNode for this reference to x; - * dn = lookup x in tc's lexical scope chain; - * if (!dn) { - * dn = lookup x in tc->lexdeps; - * if (!dn) { - * dn = pre-allocate a JSDefinition for x; - * map x to dn in tc->lexdeps; - * } - * } - * append pn to dn's use chain; - * } - * } - * - * See jsemit.h for JSTreeContext and its top*Stmt, decls, and lexdeps members. - * - * Notes: - * - * 0. To avoid bloating JSParseNode, we steal a bit from pn_arity for pn_defn - * and set it on a JSParseNode instead of allocating a JSDefinition. - * - * 1. Due to hoisting, a definition cannot be eliminated even if its "Variable - * statement" (ECMA-262 12.2) can be proven to be dead code. RecycleTree in - * jsparse.cpp will not recycle a node whose pn_defn bit is set. - * - * 2. "lookup x in tc's lexical scope chain" gives up on def/use chaining if a - * with statement is found along the the scope chain, which includes tc, - * tc->parent, etc. Thus we eagerly connect an inner function's use of an - * outer's var x if the var x was parsed before the inner function. - * - * 3. A use may be eliminated as dead by the constant folder, which therefore - * must remove the dead name node from its singly-linked use chain, which - * would mean hashing to find the definition node and searching to update - * the pn_link pointing at the use to be removed. This is costly, so as for - * dead definitions, we do not recycle dead pn_used nodes. - * - * At the end of parsing a function body or global or eval program, tc->lexdeps - * holds the lexical dependencies of the parsed unit. The name to def/use chain - * mappings are then merged into the parent tc->lexdeps. - * - * Thus if a later var x is parsed in the outer function satisfying an earlier - * inner function's use of x, we will remove dn from tc->lexdeps and re-use it - * as the new definition node in the outer function's parse tree. - * - * When the compiler unwinds from the outermost tc, tc->lexdeps contains the - * definition nodes with use chains for all free variables. These are either - * global variables or reference errors. - * - * We analyze whether a binding is initialized, whether the bound names is ever - * assigned apart from its initializer, and if the bound name definition or use - * is in a direct child of a block. These PND_* flags allow a subset dominance - * computation telling whether an initialized var dominates its uses. An inner - * function using only such outer vars (and formal parameters) can be optimized - * into a flat closure. See JSOP_{GET,CALL}DSLOT. - * - * Another important subset dominance relation: ... { var x = ...; ... x ... } - * where x is not assigned after initialization and not used outside the block. - * This style is common in the absence of 'let'. Even though the var x is not - * at top level, we can tell its initialization dominates all uses cheaply, - * because the above one-pass algorithm sees the definition before any uses, - * and because all uses are contained in the same block as the definition. - * - * We also analyze function uses to flag upward/downward funargs, optimizing - * those lambdas that post-dominate their upvars inevitable only assignments or - * initializations as flat closures (after Chez Scheme's display closures). - */ -#define dn_uses pn_link - -struct JSDefinition : public JSParseNode -{ - /* - * We store definition pointers in PN_NAMESET JSAtomLists in the AST, but - * due to redefinition these nodes may become uses of other definitions. - * This is unusual, so we simply chase the pn_lexdef link to find the final - * definition node. See methods called from Parser::analyzeFunctions. - * - * FIXME: MakeAssignment mutates for want of a parent link... - */ - JSDefinition *resolve() { - JSParseNode *pn = this; - while (!pn->pn_defn) { - if (pn->pn_type == js::TOK_ASSIGN) { - pn = pn->pn_left; - continue; - } - pn = pn->lexdef(); - } - return (JSDefinition *) pn; - } - - bool isFreeVar() const { - JS_ASSERT(pn_defn); - return pn_cookie.isFree() || test(PND_GVAR); - } - - bool isGlobal() const { - JS_ASSERT(pn_defn); - return test(PND_GVAR); - } - - // Grr, windows.h or something under it #defines CONST... -#ifdef CONST -# undef CONST -#endif - enum Kind { VAR, CONST, LET, FUNCTION, ARG, UNKNOWN }; - - bool isBindingForm() { return int(kind()) <= int(LET); } - - static const char *kindString(Kind kind); - - Kind kind() { - if (PN_TYPE(this) == js::TOK_FUNCTION) - return FUNCTION; - JS_ASSERT(PN_TYPE(this) == js::TOK_NAME); - if (PN_OP(this) == JSOP_NOP) - return UNKNOWN; - if (PN_OP(this) == JSOP_GETARG) - return ARG; - if (isConst()) - return CONST; - if (isLet()) - return LET; - return VAR; - } -}; - -inline bool -JSParseNode::test(uintN flag) const -{ - JS_ASSERT(pn_defn || pn_arity == PN_FUNC || pn_arity == PN_NAME); -#ifdef DEBUG - if ((flag & (PND_ASSIGNED | PND_FUNARG)) && pn_defn && !(pn_dflags & flag)) { - for (JSParseNode *pn = ((JSDefinition *) this)->dn_uses; pn; pn = pn->pn_link) { - JS_ASSERT(!pn->pn_defn); - JS_ASSERT(!(pn->pn_dflags & flag)); - } - } -#endif - return !!(pn_dflags & flag); -} - -inline void -JSParseNode::setFunArg() -{ - /* - * pn_defn NAND pn_used must be true, per this chart: - * - * pn_defn pn_used - * 0 0 anonymous function used implicitly, e.g. by - * hidden yield in a genexp - * 0 1 a use of a definition or placeholder - * 1 0 a definition or placeholder - * 1 1 error: this case must not be possible - */ - JS_ASSERT(!(pn_defn & pn_used)); - if (pn_used) - pn_lexdef->pn_dflags |= PND_FUNARG; - pn_dflags |= PND_FUNARG; -} - -struct JSObjectBox { - JSObjectBox *traceLink; - JSObjectBox *emitLink; - JSObject *object; - JSObjectBox *parent; - uintN index; - bool isFunctionBox; -}; - -#define JSFB_LEVEL_BITS 14 - -struct JSFunctionBox : public JSObjectBox -{ - JSParseNode *node; - JSFunctionBox *siblings; - JSFunctionBox *kids; - JSFunctionBox *parent; - JSParseNode *methods; /* would-be methods set on this; - these nodes are linked via - pn_link, since lambdas are - neither definitions nor uses - of a binding */ - js::Bindings bindings; /* bindings for this function */ - uint32 queued:1, - inLoop:1, /* in a loop in parent function */ - level:JSFB_LEVEL_BITS; - uint32 tcflags; - - bool joinable() const; - - /* - * True if this function is inside the scope of a with-statement, an E4X - * filter-expression, or a function that uses direct eval. - */ - bool inAnyDynamicScope() const; - - /* - * Unbrand an object being initialized or constructed if any method cannot - * be joined to one compiler-created null closure shared among N different - * closure environments. - * - * We despecialize from caching function objects, caching slots or shapes - * instead, because an unbranded object may still have joined methods (for - * which shape->isMethod), since PropertyCache::fill gives precedence to - * joined methods over branded methods. - */ - bool shouldUnbrand(uintN methods, uintN slowMethods) const; -}; - -struct JSFunctionBoxQueue { - JSFunctionBox **vector; - size_t head, tail; - size_t lengthMask; - - size_t count() { return head - tail; } - size_t length() { return lengthMask + 1; } - - JSFunctionBoxQueue() - : vector(NULL), head(0), tail(0), lengthMask(0) { } - - bool init(uint32 count) { - lengthMask = JS_BITMASK(JS_CeilingLog2(count)); - vector = js_array_new(length()); - return !!vector; - } - - ~JSFunctionBoxQueue() { js_array_delete(vector); } - - void push(JSFunctionBox *funbox) { - if (!funbox->queued) { - JS_ASSERT(count() < length()); - vector[head++ & lengthMask] = funbox; - funbox->queued = true; - } - } - - JSFunctionBox *pull() { - if (tail == head) - return NULL; - JS_ASSERT(tail < head); - JSFunctionBox *funbox = vector[tail++ & lengthMask]; - funbox->queued = false; - return funbox; - } -}; - -#define NUM_TEMP_FREELISTS 6U /* 32 to 2048 byte size classes (32 bit) */ - -typedef struct BindData BindData; - -namespace js { - -struct Parser : private js::AutoGCRooter -{ - JSContext * const context; /* FIXME Bug 551291: use AutoGCRooter::context? */ - JSAtomListElement *aleFreeList; - void *tempFreeList[NUM_TEMP_FREELISTS]; - TokenStream tokenStream; - void *tempPoolMark; /* initial JSContext.tempPool mark */ - JSPrincipals *principals; /* principals associated with source */ - JSStackFrame *const callerFrame; /* scripted caller frame for eval and dbgapi */ - JSObject *const callerVarObj; /* callerFrame's varObj */ - JSParseNode *nodeList; /* list of recyclable parse-node structs */ - uint32 functionCount; /* number of functions in current unit */ - JSObjectBox *traceListHead; /* list of parsed object for GC tracing */ - JSTreeContext *tc; /* innermost tree context (stack-allocated) */ - - /* Root atoms and objects allocated for the parsed tree. */ - js::AutoKeepAtoms keepAtoms; - - Parser(JSContext *cx, JSPrincipals *prin = NULL, JSStackFrame *cfp = NULL); - ~Parser(); - - friend void js::AutoGCRooter::trace(JSTracer *trc); - friend struct ::JSTreeContext; - friend struct Compiler; - - /* - * Initialize a parser. Parameters are passed on to init tokenStream. - * The compiler owns the arena pool "tops-of-stack" space above the current - * JSContext.tempPool mark. This means you cannot allocate from tempPool - * and save the pointer beyond the next Parser destructor invocation. - */ - bool init(const jschar *base, size_t length, const char *filename, uintN lineno, - JSVersion version); - - void setPrincipals(JSPrincipals *prin); - - const char *getFilename() const { return tokenStream.getFilename(); } - JSVersion versionWithFlags() const { return tokenStream.versionWithFlags(); } - JSVersion versionNumber() const { return tokenStream.versionNumber(); } - bool hasXML() const { return tokenStream.hasXML(); } - bool hasAnonFunFix() const { return tokenStream.hasAnonFunFix(); } - - /* - * Parse a top-level JS script. - */ - JSParseNode *parse(JSObject *chain); - -#if JS_HAS_XML_SUPPORT - JSParseNode *parseXMLText(JSObject *chain, bool allowList); -#endif - - /* - * Allocate a new parsed object or function container from cx->tempPool. - */ - JSObjectBox *newObjectBox(JSObject *obj); - - JSFunctionBox *newFunctionBox(JSObject *obj, JSParseNode *fn, JSTreeContext *tc); - - /* - * Create a new function object given tree context (tc), optional name - * (atom may be null) and lambda flag (JSFUN_LAMBDA or 0). - */ - JSFunction *newFunction(JSTreeContext *tc, JSAtom *atom, uintN lambda); - - /* - * Analyze the tree of functions nested within a single compilation unit, - * starting at funbox, recursively walking its kids, then following its - * siblings, their kids, etc. - */ - bool analyzeFunctions(JSTreeContext *tc); - void cleanFunctionList(JSFunctionBox **funbox); - bool markFunArgs(JSFunctionBox *funbox); - void setFunctionKinds(JSFunctionBox *funbox, uint32 *tcflags); - - void trace(JSTracer *trc); - - /* - * Report a parse (compile) error. - */ - inline bool reportErrorNumber(JSParseNode *pn, uintN flags, uintN errorNumber, ...); - -private: - /* - * JS parsers, from lowest to highest precedence. - * - * Each parser must be called during the dynamic scope of a JSTreeContext - * object, pointed to by this->tc. - * - * Each returns a parse node tree or null on error. - */ - JSParseNode *functionStmt(); - JSParseNode *functionExpr(); - JSParseNode *statements(); - JSParseNode *statement(); - JSParseNode *switchStatement(); - JSParseNode *forStatement(); - JSParseNode *tryStatement(); - JSParseNode *withStatement(); -#if JS_HAS_BLOCK_SCOPE - JSParseNode *letStatement(); -#endif - JSParseNode *expressionStatement(); - JSParseNode *variables(bool inLetHead); - JSParseNode *expr(); - JSParseNode *assignExpr(); - JSParseNode *condExpr(); - JSParseNode *orExpr(); - JSParseNode *andExpr(); - JSParseNode *bitOrExpr(); - JSParseNode *bitXorExpr(); - JSParseNode *bitAndExpr(); - JSParseNode *eqExpr(); - JSParseNode *relExpr(); - JSParseNode *shiftExpr(); - JSParseNode *addExpr(); - JSParseNode *mulExpr(); - JSParseNode *unaryExpr(); - JSParseNode *memberExpr(JSBool allowCallSyntax); - JSParseNode *primaryExpr(js::TokenKind tt, JSBool afterDot); - JSParseNode *parenExpr(JSBool *genexp = NULL); - - /* - * Additional JS parsers. - */ - bool recognizeDirectivePrologue(JSParseNode *pn, bool *isDirectivePrologueMember); - - enum FunctionType { GETTER, SETTER, GENERAL }; - bool functionArguments(JSTreeContext &funtc, JSFunctionBox *funbox, JSParseNode **list); - JSParseNode *functionBody(); - JSParseNode *functionDef(JSAtom *name, FunctionType type, uintN lambda); - - JSParseNode *condition(); - JSParseNode *comprehensionTail(JSParseNode *kid, uintN blockid, - js::TokenKind type = js::TOK_SEMI, JSOp op = JSOP_NOP); - JSParseNode *generatorExpr(JSParseNode *kid); - JSBool argumentList(JSParseNode *listNode); - JSParseNode *bracketedExpr(); - JSParseNode *letBlock(JSBool statement); - JSParseNode *returnOrYield(bool useAssignExpr); - JSParseNode *destructuringExpr(BindData *data, js::TokenKind tt); - -#if JS_HAS_XML_SUPPORT - JSParseNode *endBracketedExpr(); - - JSParseNode *propertySelector(); - JSParseNode *qualifiedSuffix(JSParseNode *pn); - JSParseNode *qualifiedIdentifier(); - JSParseNode *attributeIdentifier(); - JSParseNode *xmlExpr(JSBool inTag); - JSParseNode *xmlAtomNode(); - JSParseNode *xmlNameExpr(); - JSParseNode *xmlTagContent(js::TokenKind tagtype, JSAtom **namep); - JSBool xmlElementContent(JSParseNode *pn); - JSParseNode *xmlElementOrList(JSBool allowList); - JSParseNode *xmlElementOrListRoot(JSBool allowList); -#endif /* JS_HAS_XML_SUPPORT */ -}; - -inline bool -Parser::reportErrorNumber(JSParseNode *pn, uintN flags, uintN errorNumber, ...) -{ - va_list args; - va_start(args, errorNumber); - bool result = tokenStream.reportCompileErrorNumberVA(pn, flags, errorNumber, args); - va_end(args); - return result; -} - -struct Compiler -{ - Parser parser; - GlobalScope *globalScope; - - Compiler(JSContext *cx, JSPrincipals *prin = NULL, JSStackFrame *cfp = NULL); - - /* - * Initialize a compiler. Parameters are passed on to init parser. - */ - inline bool - init(const jschar *base, size_t length, const char *filename, uintN lineno, JSVersion version) - { - return parser.init(base, length, filename, lineno, version); - } - - static bool - compileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *principals, - js::Bindings *bindings, const jschar *chars, size_t length, - const char *filename, uintN lineno, JSVersion version); - - static JSScript * - compileScript(JSContext *cx, JSObject *scopeChain, JSStackFrame *callerFrame, - JSPrincipals *principals, uint32 tcflags, - const jschar *chars, size_t length, - const char *filename, uintN lineno, JSVersion version, - JSString *source = NULL, uintN staticLevel = 0); - - private: - static bool defineGlobals(JSContext *cx, GlobalScope &globalScope, JSScript *script); -}; - -} /* namespace js */ - -/* - * Convenience macro to access Parser.tokenStream as a pointer. - */ -#define TS(p) (&(p)->tokenStream) - -extern JSBool -js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc, - bool inCond = false); - -JS_END_EXTERN_C - -#endif /* jsparse_h___ */ diff --git a/x86/mozilla/include/jsperf.h b/x86/mozilla/include/jsperf.h deleted file mode 100644 index aed019a..0000000 --- a/x86/mozilla/include/jsperf.h +++ /dev/null @@ -1,163 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * the Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Zack Weinberg (original author) - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsperf_h___ -#define jsperf_h___ - -#include "jsapi.h" - -namespace JS { - -/* - * JS::PerfMeasurement is a generic way to access detailed performance - * measurement APIs provided by your operating system. The details of - * exactly how this works and what can be measured are highly - * system-specific, but this interface is (one hopes) implementable - * on top of all of them. - * - * To use this API, create a PerfMeasurement object, passing its - * constructor a bitmask indicating which events you are interested - * in. Thereafter, Start() zeroes all counters and starts timing; - * Stop() stops timing again; and the counters for the events you - * requested are available as data values after calling Stop(). The - * object may be reused for many measurements. - */ -class JS_FRIEND_API(PerfMeasurement) -{ - protected: - // Implementation-specific data, if any. - void* impl; - - public: - /* - * Events that may be measured. Taken directly from the list of - * "generalized hardware performance event types" in the Linux - * perf_event API, plus some of the "software events". - */ - enum EventMask { - CPU_CYCLES = 0x00000001, - INSTRUCTIONS = 0x00000002, - CACHE_REFERENCES = 0x00000004, - CACHE_MISSES = 0x00000008, - BRANCH_INSTRUCTIONS = 0x00000010, - BRANCH_MISSES = 0x00000020, - BUS_CYCLES = 0x00000040, - PAGE_FAULTS = 0x00000080, - MAJOR_PAGE_FAULTS = 0x00000100, - CONTEXT_SWITCHES = 0x00000200, - CPU_MIGRATIONS = 0x00000400, - - ALL = 0x000007ff, - NUM_MEASURABLE_EVENTS = 11 - }; - - /* - * Bitmask of events that will be measured when this object is - * active (between Start() and Stop()). This may differ from the - * bitmask passed to the constructor if the platform does not - * support measuring all of the requested events. - */ - const EventMask eventsMeasured; - - /* - * Counters for each measurable event. - * Immediately after one of these objects is created, all of the - * counters for enabled events will be zero, and all of the - * counters for disabled events will be uint64(-1). - */ - uint64 cpu_cycles; - uint64 instructions; - uint64 cache_references; - uint64 cache_misses; - uint64 branch_instructions; - uint64 branch_misses; - uint64 bus_cycles; - uint64 page_faults; - uint64 major_page_faults; - uint64 context_switches; - uint64 cpu_migrations; - - /* - * Prepare to measure the indicated set of events. If not all of - * the requested events can be measured on the current platform, - * then the eventsMeasured bitmask will only include the subset of - * |toMeasure| corresponding to the events that can be measured. - */ - PerfMeasurement(EventMask toMeasure); - - /* Done with this set of measurements, tear down OS-level state. */ - ~PerfMeasurement(); - - /* Start a measurement cycle. */ - void start(); - - /* - * End a measurement cycle, and for each enabled counter, add the - * number of measured events of that type to the appropriate - * visible variable. - */ - void stop(); - - /* Reset all enabled counters to zero. */ - void reset(); - - /* - * True if this platform supports measuring _something_, i.e. it's - * not using the stub implementation. - */ - static bool canMeasureSomething(); -}; - -/* Inject a Javascript wrapper around the above C++ class into the - * Javascript object passed as an argument (this will normally be a - * global object). The JS-visible API is identical to the C++ API. - */ -extern JS_FRIEND_API(JSObject*) - RegisterPerfMeasurement(JSContext *cx, JSObject *global); - -/* - * Given a jsval which contains an instance of the aforementioned - * wrapper class, extract the C++ object. Returns NULL if the - * jsval is not an instance of the wrapper. - */ -extern JS_FRIEND_API(PerfMeasurement*) - ExtractPerfMeasurement(jsval wrapper); - -} // namespace JS - -#endif // jsperf_h___ diff --git a/x86/mozilla/include/jsprf.h b/x86/mozilla/include/jsprf.h deleted file mode 100644 index 1f3200d..0000000 --- a/x86/mozilla/include/jsprf.h +++ /dev/null @@ -1,150 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsprf_h___ -#define jsprf_h___ - -/* -** API for PR printf like routines. Supports the following formats -** %d - decimal -** %u - unsigned decimal -** %x - unsigned hex -** %X - unsigned uppercase hex -** %o - unsigned octal -** %hd, %hu, %hx, %hX, %ho - 16-bit versions of above -** %ld, %lu, %lx, %lX, %lo - 32-bit versions of above -** %lld, %llu, %llx, %llX, %llo - 64 bit versions of above -** %s - string -** %hs - 16-bit version of above (only available if js_CStringsAreUTF8) -** %c - character -** %hc - 16-bit version of above (only available if js_CStringsAreUTF8) -** %p - pointer (deals with machine dependent pointer size) -** %f - float -** %g - float -*/ -#include "jstypes.h" -#include -#include - -JS_BEGIN_EXTERN_C - -/* -** sprintf into a fixed size buffer. Guarantees that a NUL is at the end -** of the buffer. Returns the length of the written output, NOT including -** the NUL, or (JSUint32)-1 if an error occurs. -*/ -extern JS_PUBLIC_API(JSUint32) JS_snprintf(char *out, JSUint32 outlen, const char *fmt, ...); - -/* -** sprintf into a malloc'd buffer. Return a pointer to the malloc'd -** buffer on success, NULL on failure. Call "JS_smprintf_free" to release -** the memory returned. -*/ -extern JS_PUBLIC_API(char*) JS_smprintf(const char *fmt, ...); - -/* -** Free the memory allocated, for the caller, by JS_smprintf -*/ -extern JS_PUBLIC_API(void) JS_smprintf_free(char *mem); - -/* -** "append" sprintf into a malloc'd buffer. "last" is the last value of -** the malloc'd buffer. sprintf will append data to the end of last, -** growing it as necessary using realloc. If last is NULL, JS_sprintf_append -** will allocate the initial string. The return value is the new value of -** last for subsequent calls, or NULL if there is a malloc failure. -*/ -extern JS_PUBLIC_API(char*) JS_sprintf_append(char *last, const char *fmt, ...); - -/* -** sprintf into a function. The function "f" is called with a string to -** place into the output. "arg" is an opaque pointer used by the stuff -** function to hold any state needed to do the storage of the output -** data. The return value is a count of the number of characters fed to -** the stuff function, or (JSUint32)-1 if an error occurs. -*/ -typedef JSIntn (*JSStuffFunc)(void *arg, const char *s, JSUint32 slen); - -extern JS_PUBLIC_API(JSUint32) JS_sxprintf(JSStuffFunc f, void *arg, const char *fmt, ...); - -/* -** va_list forms of the above. -*/ -extern JS_PUBLIC_API(JSUint32) JS_vsnprintf(char *out, JSUint32 outlen, const char *fmt, va_list ap); -extern JS_PUBLIC_API(char*) JS_vsmprintf(const char *fmt, va_list ap); -extern JS_PUBLIC_API(char*) JS_vsprintf_append(char *last, const char *fmt, va_list ap); -extern JS_PUBLIC_API(JSUint32) JS_vsxprintf(JSStuffFunc f, void *arg, const char *fmt, va_list ap); - -/* -*************************************************************************** -** FUNCTION: JS_sscanf -** DESCRIPTION: -** JS_sscanf() scans the input character string, performs data -** conversions, and stores the converted values in the data objects -** pointed to by its arguments according to the format control -** string. -** -** JS_sscanf() behaves the same way as the sscanf() function in the -** Standard C Library (stdio.h), with the following exceptions: -** - JS_sscanf() handles the NSPR integer and floating point types, -** such as JSInt16, JSInt32, JSInt64, and JSFloat64, whereas -** sscanf() handles the standard C types like short, int, long, -** and double. -** - JS_sscanf() has no multibyte character support, while sscanf() -** does. -** INPUTS: -** const char *buf -** a character string holding the input to scan -** const char *fmt -** the format control string for the conversions -** ... -** variable number of arguments, each of them is a pointer to -** a data object in which the converted value will be stored -** OUTPUTS: none -** RETURNS: JSInt32 -** The number of values converted and stored. -** RESTRICTIONS: -** Multibyte characters in 'buf' or 'fmt' are not allowed. -*************************************************************************** -*/ - -extern JS_PUBLIC_API(JSInt32) JS_sscanf(const char *buf, const char *fmt, ...); - -JS_END_EXTERN_C - -#endif /* jsprf_h___ */ diff --git a/x86/mozilla/include/jsprobes.h b/x86/mozilla/include/jsprobes.h deleted file mode 100644 index 69d3e1f..0000000 --- a/x86/mozilla/include/jsprobes.h +++ /dev/null @@ -1,257 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=80: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * Copyright (C) 2007 Sun Microsystems, Inc. All Rights Reserved. - * - * Contributor(s): - * Brendan Eich - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifdef INCLUDE_MOZILLA_DTRACE -#include "javascript-trace.h" -#endif -#include "jspubtd.h" -#include "jsprvtd.h" - -#ifndef _JSPROBES_H -#define _JSPROBES_H - -namespace js { - -class Probes { - static const char nullName[]; - - static const char *FunctionClassname(const JSFunction *fun); - static const char *ScriptFilename(JSScript *script); - static int FunctionLineNumber(JSContext *cx, const JSFunction *fun); - static const char *FunctionName(JSContext *cx, const JSFunction *fun, JSAutoByteString *bytes); - - static void enterJSFunImpl(JSContext *cx, JSFunction *fun, JSScript *script); - static void handleFunctionReturn(JSContext *cx, JSFunction *fun, JSScript *script); - static void finalizeObjectImpl(JSObject *obj); - public: - static bool callTrackingActive(JSContext *); - - static void enterJSFun(JSContext *, JSFunction *, JSScript *, int counter = 1); - static void exitJSFun(JSContext *, JSFunction *, JSScript *, int counter = 0); - - static void startExecution(JSContext *cx, JSScript *script); - static void stopExecution(JSContext *cx, JSScript *script); - - static void resizeHeap(JSCompartment *compartment, size_t oldSize, size_t newSize); - - /* |obj| must exist (its class and size are computed) */ - static void createObject(JSContext *cx, JSObject *obj); - - static void resizeObject(JSContext *cx, JSObject *obj, size_t oldSize, size_t newSize); - - /* |obj| must still exist (its class is accessed) */ - static void finalizeObject(JSObject *obj); - - /* - * |string| does not need to contain any content yet; only its - * pointer value is used. |length| is the length of the string and - * does not imply anything about the amount of storage consumed to - * store the string. (It may be a short string, an external - * string, or a rope, and the encoding is not taken into - * consideration.) - */ - static void createString(JSContext *cx, JSString *string, size_t length); - - /* - * |string| must still have a valid length. - */ - static void finalizeString(JSString *string); - - static void compileScriptBegin(JSContext *cx, const char *filename, int lineno); - static void compileScriptEnd(JSContext *cx, JSScript *script, const char *filename, int lineno); - - static void calloutBegin(JSContext *cx, JSFunction *fun); - static void calloutEnd(JSContext *cx, JSFunction *fun); - - static void acquireMemory(JSContext *cx, void *address, size_t nbytes); - static void releaseMemory(JSContext *cx, void *address, size_t nbytes); - - static void GCStart(JSCompartment *compartment); - static void GCEnd(JSCompartment *compartment); - static void GCStartMarkPhase(JSCompartment *compartment); - - static void GCEndMarkPhase(JSCompartment *compartment); - static void GCStartSweepPhase(JSCompartment *compartment); - static void GCEndSweepPhase(JSCompartment *compartment); - - static bool CustomMark(JSString *string); - static bool CustomMark(const char *string); - static bool CustomMark(int marker); - - static bool startProfiling(); - static void stopProfiling(); -}; - -inline bool -Probes::callTrackingActive(JSContext *cx) -{ -#ifdef INCLUDE_MOZILLA_DTRACE - if (JAVASCRIPT_FUNCTION_ENTRY_ENABLED() || JAVASCRIPT_FUNCTION_RETURN_ENABLED()) - return true; -#endif -#ifdef MOZ_TRACE_JSCALLS - if (cx->functionCallback) - return true; -#endif -#ifdef MOZ_ETW - if (ProfilingActive && MCGEN_ENABLE_CHECK(MozillaSpiderMonkey_Context, EvtFunctionEntry)) - return true; -#endif - return false; -} - -inline void -Probes::enterJSFun(JSContext *cx, JSFunction *fun, JSScript *script, int counter) -{ -#ifdef INCLUDE_MOZILLA_DTRACE - if (JAVASCRIPT_FUNCTION_ENTRY_ENABLED()) - enterJSFunImpl(cx, fun, script); -#endif -#ifdef MOZ_TRACE_JSCALLS - cx->doFunctionCallback(fun, script, counter); -#endif -} - -inline void -Probes::exitJSFun(JSContext *cx, JSFunction *fun, JSScript *script, int counter) -{ -#ifdef INCLUDE_MOZILLA_DTRACE - if (JAVASCRIPT_FUNCTION_RETURN_ENABLED()) - handleFunctionReturn(cx, fun, script); -#endif -#ifdef MOZ_TRACE_JSCALLS - if (counter > 0) - counter = -counter; - cx->doFunctionCallback(fun, script, counter); -#endif -} - -inline void -Probes::createObject(JSContext *cx, JSObject *obj) -{ -#ifdef INCLUDE_MOZILLA_DTRACE - if (JAVASCRIPT_OBJECT_CREATE_ENABLED()) { - Class *clasp = obj->getClass(); - JAVASCRIPT_OBJECT_CREATE((char *)clasp->name, (uintptr_t)obj); - } -#endif -} - -inline void -Probes::finalizeObject(JSObject *obj) -{ -#ifdef INCLUDE_MOZILLA_DTRACE - if (JAVASCRIPT_OBJECT_FINALIZE_ENABLED()) { - Class *clasp = obj->getClass(); - - /* the first arg is NULL - reserved for future use (filename?) */ - JAVASCRIPT_OBJECT_FINALIZE(NULL, (char *)clasp->name, (uintptr_t)obj); - } -#endif -} - -inline void -Probes::startExecution(JSContext *cx, JSScript *script) -{ -#ifdef INCLUDE_MOZILLA_DTRACE - if (JAVASCRIPT_EXECUTE_START_ENABLED()) - JAVASCRIPT_EXECUTE_START((script->filename ? (char *)script->filename : nullName), - script->lineno); -#endif -#ifdef MOZ_TRACE_JSCALLS - cx->doFunctionCallback(NULL, script, 1); -#endif -} - -inline void -Probes::stopExecution(JSContext *cx, JSScript *script) -{ -#ifdef INCLUDE_MOZILLA_DTRACE - if (JAVASCRIPT_EXECUTE_DONE_ENABLED()) - JAVASCRIPT_EXECUTE_DONE((script->filename ? (char *)script->filename : nullName), - script->lineno); -#endif -#ifdef MOZ_TRACE_JSCALLS - cx->doFunctionCallback(NULL, script, 0); -#endif -} - -/* - * New probes with no implementations, yet. Next patch will implement - * them. These are here just to make all intermediate patches compile - * and run. - */ -inline void Probes::resizeHeap(JSCompartment *compartment, size_t oldSize, size_t newSize) {} -inline void Probes::resizeObject(JSContext *cx, JSObject *obj, size_t oldSize, size_t newSize) {} -inline void Probes::createString(JSContext *cx, JSString *string, size_t length) {} -inline void Probes::finalizeString(JSString *string) {} -inline void Probes::compileScriptBegin(JSContext *cx, const char *filename, int lineno) {} -inline void Probes::compileScriptEnd(JSContext *cx, JSScript *script, const char *filename, int lineno) {} -inline void Probes::calloutBegin(JSContext *cx, JSFunction *fun) {} -inline void Probes::calloutEnd(JSContext *cx, JSFunction *fun) {} -inline void Probes::acquireMemory(JSContext *cx, void *address, size_t nbytes) {} -inline void Probes::releaseMemory(JSContext *cx, void *address, size_t nbytes) {} -inline void Probes::GCStart(JSCompartment *compartment) {} -inline void Probes::GCEnd(JSCompartment *compartment) {} -inline void Probes::GCStartMarkPhase(JSCompartment *compartment) {} -inline void Probes::GCEndMarkPhase(JSCompartment *compartment) {} -inline void Probes::GCStartSweepPhase(JSCompartment *compartment) {} -inline void Probes::GCEndSweepPhase(JSCompartment *compartment) {} -inline bool Probes::CustomMark(JSString *string) { return JS_TRUE; } -inline bool Probes::CustomMark(const char *string) { return JS_TRUE; } -inline bool Probes::CustomMark(int marker) { return JS_TRUE; } - -struct AutoFunctionCallProbe { - JSContext * const cx; - JSFunction *fun; - JSScript *script; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER - - AutoFunctionCallProbe(JSContext *cx, JSFunction *fun, JSScript *script - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : cx(cx), fun(fun), script(script) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - Probes::enterJSFun(cx, fun, script); - } - - ~AutoFunctionCallProbe() { - Probes::exitJSFun(cx, fun, script); - } -}; - -} /* namespace js */ - -#endif /* _JSPROBES_H */ diff --git a/x86/mozilla/include/jspropertycache.h b/x86/mozilla/include/jspropertycache.h deleted file mode 100644 index 71186c8..0000000 --- a/x86/mozilla/include/jspropertycache.h +++ /dev/null @@ -1,277 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=98: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jspropertycache_h___ -#define jspropertycache_h___ - -#include "jsapi.h" -#include "jsprvtd.h" -#include "jstypes.h" - -namespace js { - -/* - * Property cache with structurally typed capabilities for invalidation, for - * polymorphic callsite method/get/set speedups. For details, see - * . - */ - -/* Property cache value capabilities. */ -enum { - PCVCAP_PROTOBITS = 4, - PCVCAP_PROTOSIZE = JS_BIT(PCVCAP_PROTOBITS), - PCVCAP_PROTOMASK = JS_BITMASK(PCVCAP_PROTOBITS), - - PCVCAP_SCOPEBITS = 4, - PCVCAP_SCOPESIZE = JS_BIT(PCVCAP_SCOPEBITS), - PCVCAP_SCOPEMASK = JS_BITMASK(PCVCAP_SCOPEBITS), - - PCVCAP_TAGBITS = PCVCAP_PROTOBITS + PCVCAP_SCOPEBITS, - PCVCAP_TAGMASK = JS_BITMASK(PCVCAP_TAGBITS) -}; - -const uint32 SHAPE_OVERFLOW_BIT = JS_BIT(32 - PCVCAP_TAGBITS); - -/* - * Property cache value. This is simply a tagged union: - * PCVal = (JSObject * | uint32 | js::Shape *). - * It is the type of PropertyCacheEntry::vword and combines with the tag bits - * of PropertyCacheEntry::vcap to tell how to get or set the property, once a - * property cache hit is validated. - * - * PropertyCache::purge depends on the bit-pattern of a null PCVal being 0. - */ -class PCVal -{ - private: - enum { - OBJECT = 0, - SLOT = 1, - SHAPE = 2, - TAG = 3 - }; - - jsuword v; - - public: - bool isNull() const { return v == 0; } - void setNull() { v = 0; } - - bool isFunObj() const { return (v & TAG) == OBJECT; } - JSObject &toFunObj() const { - JS_ASSERT(isFunObj()); - return *reinterpret_cast(v); - } - void setFunObj(JSObject &obj) { - v = reinterpret_cast(&obj); - } - - bool isSlot() const { return v & SLOT; } - uint32 toSlot() const { JS_ASSERT(isSlot()); return uint32(v) >> 1; } - void setSlot(uint32 slot) { v = (jsuword(slot) << 1) | SLOT; } - - bool isShape() const { return (v & TAG) == SHAPE; } - const js::Shape *toShape() const { - JS_ASSERT(isShape()); - return reinterpret_cast(v & ~TAG); - } - void setShape(const js::Shape *shape) { - JS_ASSERT(shape); - v = reinterpret_cast(shape) | SHAPE; - } -}; - -struct PropertyCacheEntry -{ - jsbytecode *kpc; /* pc of cache-testing bytecode */ - jsuword kshape; /* shape of direct (key) object */ - jsuword vcap; /* value capability, see above */ - PCVal vword; /* value word, see PCVal above */ - - bool adding() const { return vcapTag() == 0 && kshape != vshape(); } - bool directHit() const { return vcapTag() == 0 && kshape == vshape(); } - - jsuword vcapTag() const { return vcap & PCVCAP_TAGMASK; } - uint32 vshape() const { return uint32(vcap >> PCVCAP_TAGBITS); } - jsuword scopeIndex() const { return (vcap >> PCVCAP_PROTOBITS) & PCVCAP_SCOPEMASK; } - jsuword protoIndex() const { return vcap & PCVCAP_PROTOMASK; } - - void assign(jsbytecode *kpc, jsuword kshape, jsuword vshape, - uintN scopeIndex, uintN protoIndex, PCVal vword) { - JS_ASSERT(kshape < SHAPE_OVERFLOW_BIT); - JS_ASSERT(vshape < SHAPE_OVERFLOW_BIT); - JS_ASSERT(scopeIndex <= PCVCAP_SCOPEMASK); - JS_ASSERT(protoIndex <= PCVCAP_PROTOMASK); - - this->kpc = kpc; - this->kshape = kshape; - this->vcap = (vshape << PCVCAP_TAGBITS) | (scopeIndex << PCVCAP_PROTOBITS) | protoIndex; - this->vword = vword; - } -}; - -/* - * Special value for functions returning PropertyCacheEntry * to distinguish - * between failure and no no-cache-fill cases. - */ -#define JS_NO_PROP_CACHE_FILL ((js::PropertyCacheEntry *) NULL + 1) - -#if defined DEBUG_brendan || defined DEBUG_brendaneich -#define JS_PROPERTY_CACHE_METERING 1 -#endif - -class PropertyCache -{ - private: - enum { - SIZE_LOG2 = 12, - SIZE = JS_BIT(SIZE_LOG2), - MASK = JS_BITMASK(SIZE_LOG2) - }; - - PropertyCacheEntry table[SIZE]; - JSBool empty; -#ifdef JS_PROPERTY_CACHE_METERING - public: - PropertyCacheEntry *pctestentry; /* entry of the last PC-based test */ - uint32 fills; /* number of cache entry fills */ - uint32 nofills; /* couldn't fill (e.g. default get) */ - uint32 rofills; /* set on read-only prop can't fill */ - uint32 disfills; /* fill attempts on disabled cache */ - uint32 oddfills; /* fill attempt after setter deleted */ - uint32 add2dictfills; /* fill attempt on dictionary object */ - uint32 modfills; /* fill that rehashed to a new entry */ - uint32 brandfills; /* scope brandings to type structural - method fills */ - uint32 noprotos; /* resolve-returned non-proto pobj */ - uint32 longchains; /* overlong scope and/or proto chain */ - uint32 recycles; /* cache entries recycled by fills */ - uint32 tests; /* cache probes */ - uint32 pchits; /* fast-path polymorphic op hits */ - uint32 protopchits; /* pchits hitting immediate prototype */ - uint32 initests; /* cache probes from JSOP_INITPROP */ - uint32 inipchits; /* init'ing next property pchit case */ - uint32 inipcmisses; /* init'ing next property pc misses */ - uint32 settests; /* cache probes from JOF_SET opcodes */ - uint32 addpchits; /* adding next property pchit case */ - uint32 setpchits; /* setting existing property pchit */ - uint32 setpcmisses; /* setting/adding property pc misses */ - uint32 setmisses; /* JSOP_SET{NAME,PROP} total misses */ - uint32 kpcmisses; /* slow-path key id == atom misses */ - uint32 kshapemisses; /* slow-path key object misses */ - uint32 vcapmisses; /* value capability misses */ - uint32 misses; /* cache misses */ - uint32 flushes; /* cache flushes */ - uint32 pcpurges; /* shadowing purges on proto chain */ - private: -# define PCMETER(x) x -#else -# define PCMETER(x) ((void)0) -#endif - - /* - * Add kshape rather than xor it to avoid collisions between nearby bytecode - * that are evolving an object by setting successive properties, incrementing - * the object's shape on each set. - */ - static inline jsuword - hash(jsbytecode *pc, jsuword kshape) - { - return ((((jsuword(pc) >> SIZE_LOG2) ^ jsuword(pc)) + kshape) & MASK); - } - - static inline bool matchShape(JSContext *cx, JSObject *obj, uint32 shape); - - JS_REQUIRES_STACK JSAtom *fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, - JSObject **pobjp, PropertyCacheEntry *entry); - -#ifdef DEBUG - void assertEmpty(); -#else - inline void assertEmpty() {} -#endif - - public: - JS_ALWAYS_INLINE JS_REQUIRES_STACK void test(JSContext *cx, jsbytecode *pc, - JSObject *&obj, JSObject *&pobj, - PropertyCacheEntry *&entry, JSAtom *&atom); - - /* - * Test for cached information about a property set on *objp at pc. - * - * On a hit, set *entryp to the entry and return true. - * - * On a miss, set *atomp to the name of the property being set and return false. - */ - JS_ALWAYS_INLINE bool testForSet(JSContext *cx, jsbytecode *pc, JSObject *obj, - PropertyCacheEntry **entryp, JSObject **obj2p, - JSAtom **atomp); - - /* - * Test for cached information about creating a new own data property on obj at pc. - * - * On a hit, set *shapep to an shape from the property tree describing the - * new property as well as all existing properties on obj and return - * true. Otherwise return false. - * - * Hit or miss, *entryp receives a pointer to the property cache entry. - */ - JS_ALWAYS_INLINE bool testForInit(JSRuntime *rt, jsbytecode *pc, JSObject *obj, - const js::Shape **shapep, PropertyCacheEntry **entryp); - - /* - * Fill property cache entry for key cx->fp->pc, optimized value word - * computed from obj and shape, and entry capability forged from 24-bit - * obj->shape(), 4-bit scopeIndex, and 4-bit protoIndex. - * - * Return the filled cache entry or JS_NO_PROP_CACHE_FILL if caching was - * not possible. - */ - JS_REQUIRES_STACK PropertyCacheEntry *fill(JSContext *cx, JSObject *obj, uintN scopeIndex, - uintN protoIndex, JSObject *pobj, - const js::Shape *shape, JSBool adding = false); - - void purge(JSContext *cx); - void purgeForScript(JSContext *cx, JSScript *script); -}; - -} /* namespace js */ - -#endif /* jspropertycache_h___ */ diff --git a/x86/mozilla/include/jspropertycacheinlines.h b/x86/mozilla/include/jspropertycacheinlines.h deleted file mode 100644 index 96aef0b..0000000 --- a/x86/mozilla/include/jspropertycacheinlines.h +++ /dev/null @@ -1,155 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Igor Bukanov - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jspropertycacheinlines_h___ -#define jspropertycacheinlines_h___ - -#include "jslock.h" -#include "jspropertycache.h" -#include "jsscope.h" - -using namespace js; - -/* static */ inline bool -PropertyCache::matchShape(JSContext *cx, JSObject *obj, uint32 shape) -{ - return obj->shape() == shape; -} - -/* - * This method is designed to inline the fast path in js_Interpret, so it makes - * "just-so" restrictions on parameters, e.g. pobj and obj should not be the - * same variable, since for JOF_PROP-mode opcodes, obj must not be changed - * because of a cache miss. - * - * On return, if atom is null then obj points to the scope chain element in - * which the property was found, pobj is locked, and entry is valid. If atom is - * non-null then no object is locked but entry is still set correctly for use, - * e.g., by PropertyCache::fill and atom should be used as the id to find. - * - * We must lock pobj on a hit in order to close races with threads that might - * be deleting a property from its scope, or otherwise invalidating property - * caches (on all threads) by re-generating JSObject::shape(). - */ -JS_ALWAYS_INLINE void -PropertyCache::test(JSContext *cx, jsbytecode *pc, JSObject *&obj, - JSObject *&pobj, PropertyCacheEntry *&entry, JSAtom *&atom) -{ - JS_ASSERT(this == &JS_PROPERTY_CACHE(cx)); - - uint32 kshape = obj->shape(); - entry = &table[hash(pc, kshape)]; - PCMETER(pctestentry = entry); - PCMETER(tests++); - JS_ASSERT(&obj != &pobj); - JS_ASSERT(entry->kshape < SHAPE_OVERFLOW_BIT); - if (entry->kpc == pc && entry->kshape == kshape) { - JSObject *tmp; - pobj = obj; - if (entry->vcapTag() == 1 && - (tmp = pobj->getProto()) != NULL) { - pobj = tmp; - } - - if (matchShape(cx, pobj, entry->vshape())) { - PCMETER(pchits++); - PCMETER(!entry->vcapTag() || protopchits++); - atom = NULL; - return; - } - } - atom = fullTest(cx, pc, &obj, &pobj, entry); - if (atom) - PCMETER(misses++); -} - -JS_ALWAYS_INLINE bool -PropertyCache::testForSet(JSContext *cx, jsbytecode *pc, JSObject *obj, - PropertyCacheEntry **entryp, JSObject **obj2p, JSAtom **atomp) -{ - uint32 shape = obj->shape(); - PropertyCacheEntry *entry = &table[hash(pc, shape)]; - *entryp = entry; - PCMETER(pctestentry = entry); - PCMETER(tests++); - PCMETER(settests++); - JS_ASSERT(entry->kshape < SHAPE_OVERFLOW_BIT); - if (entry->kpc == pc && entry->kshape == shape) - return true; - - JSAtom *atom = fullTest(cx, pc, &obj, obj2p, entry); - JS_ASSERT(atom); - - PCMETER(misses++); - PCMETER(setmisses++); - - *atomp = atom; - return false; -} - -JS_ALWAYS_INLINE bool -PropertyCache::testForInit(JSRuntime *rt, jsbytecode *pc, JSObject *obj, - const js::Shape **shapep, PropertyCacheEntry **entryp) -{ - JS_ASSERT(obj->slotSpan() >= JSSLOT_FREE(obj->getClass())); - JS_ASSERT(obj->isExtensible()); - uint32 kshape = obj->shape(); - PropertyCacheEntry *entry = &table[hash(pc, kshape)]; - *entryp = entry; - PCMETER(pctestentry = entry); - PCMETER(tests++); - PCMETER(initests++); - JS_ASSERT(entry->kshape < SHAPE_OVERFLOW_BIT); - - if (entry->kpc == pc && - entry->kshape == kshape && - entry->vshape() == rt->protoHazardShape) { - PCMETER(pchits++); - PCMETER(inipchits++); - JS_ASSERT(entry->vcapTag() == 0); - *shapep = entry->vword.toShape(); - JS_ASSERT((*shapep)->writable()); - return true; - } - return false; -} - -#endif /* jspropertycacheinlines_h___ */ diff --git a/x86/mozilla/include/jspropertytree.h b/x86/mozilla/include/jspropertytree.h deleted file mode 100644 index 3138151..0000000 --- a/x86/mozilla/include/jspropertytree.h +++ /dev/null @@ -1,141 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 4; tab-width: 40; indent-tabs-mode: nil -*- */ -/* vim: set ts=40 sw=4 et tw=99: */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Mozilla SpiderMonkey property tree implementation - * - * The Initial Developer of the Original Code is - * Mozilla Foundation - * Portions created by the Initial Developer are Copyright (C) 2002-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brendan Eich - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jspropertytree_h___ -#define jspropertytree_h___ - -#include "jsarena.h" -#include "jshashtable.h" -#include "jsprvtd.h" - -namespace js { - -struct ShapeHasher { - typedef js::Shape *Key; - typedef const js::Shape *Lookup; - - static inline HashNumber hash(const Lookup l); - static inline bool match(Key k, Lookup l); -}; - -typedef HashSet KidsHash; - -class KidsPointer { - private: - enum { - SHAPE = 0, - HASH = 1, - TAG = 1 - }; - - jsuword w; - - public: - bool isNull() const { return !w; } - void setNull() { w = 0; } - - bool isShape() const { return (w & TAG) == SHAPE && !isNull(); } - js::Shape *toShape() const { - JS_ASSERT(isShape()); - return reinterpret_cast(w & ~jsuword(TAG)); - } - void setShape(js::Shape *shape) { - JS_ASSERT(shape); - JS_ASSERT((reinterpret_cast(shape) & TAG) == 0); - w = reinterpret_cast(shape) | SHAPE; - } - - bool isHash() const { return (w & TAG) == HASH; } - KidsHash *toHash() const { - JS_ASSERT(isHash()); - return reinterpret_cast(w & ~jsuword(TAG)); - } - void setHash(KidsHash *hash) { - JS_ASSERT(hash); - JS_ASSERT((reinterpret_cast(hash) & TAG) == 0); - w = reinterpret_cast(hash) | HASH; - } - -#ifdef DEBUG - void checkConsistency(const js::Shape *aKid) const; -#endif -}; - -class PropertyTree -{ - friend struct ::JSFunction; - - JSCompartment *compartment; - JSArenaPool arenaPool; - js::Shape *freeList; - - bool insertChild(JSContext *cx, js::Shape *parent, js::Shape *child); - void removeChild(js::Shape *child); - - PropertyTree(); - - public: - enum { MAX_HEIGHT = 128 }; - - PropertyTree(JSCompartment *comp) - : compartment(comp), freeList(NULL) - { - PodZero(&arenaPool); - } - - bool init(); - void finish(); - - js::Shape *newShapeUnchecked(); - js::Shape *newShape(JSContext *cx); - js::Shape *getChild(JSContext *cx, js::Shape *parent, const js::Shape &child); - - void orphanChildren(js::Shape *shape); - void sweepShapes(JSContext *cx); - void unmarkShapes(JSContext *cx); - - static void dumpShapes(JSContext *cx); -#ifdef DEBUG - static void meter(JSBasicStats *bs, js::Shape *node); -#endif -}; - -} /* namespace js */ - -#endif /* jspropertytree_h___ */ diff --git a/x86/mozilla/include/jsproto.tbl b/x86/mozilla/include/jsproto.tbl deleted file mode 100644 index de7d027..0000000 --- a/x86/mozilla/include/jsproto.tbl +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set sw=4 ts=8 et tw=80 ft=c: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is SpiderMonkey 1.7 work in progress, released - * February 14, 2006. - * - * The Initial Developer of the Original Code is - * Brendan Eich - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "jsversion.h" - -#if JS_HAS_XML_SUPPORT -# define XML_INIT js_InitXMLClass -# define NAMESPACE_INIT js_InitNamespaceClass -# define QNAME_INIT js_InitQNameClass -# define XMLFILTER_INIT js_InitXMLFilterClass -#else -# define XML_INIT js_InitNullClass -# define NAMESPACE_INIT js_InitNullClass -# define QNAME_INIT js_InitNullClass -# define XMLFILTER_INIT js_InitNullClass -#endif - -#if JS_HAS_GENERATORS -# define GENERATOR_INIT js_InitIteratorClasses -#else -# define GENERATOR_INIT js_InitNullClass -#endif - -/* - * Enumerator codes in the second column must not change -- they are part of - * the JS XDR API. Client modules including jsproto.tbl should consider - * wrapping the inclusion with JS_BEGIN_EXTERN_C and JS_END_EXTERN_C. - */ -JS_PROTO(Null, 0, js_InitNullClass) -JS_PROTO(Object, 1, js_InitFunctionAndObjectClasses) -JS_PROTO(Function, 2, js_InitFunctionAndObjectClasses) -JS_PROTO(Array, 3, js_InitArrayClass) -JS_PROTO(Boolean, 4, js_InitBooleanClass) -JS_PROTO(JSON, 5, js_InitJSONClass) -JS_PROTO(Date, 6, js_InitDateClass) -JS_PROTO(Math, 7, js_InitMathClass) -JS_PROTO(Number, 8, js_InitNumberClass) -JS_PROTO(String, 9, js_InitStringClass) -JS_PROTO(RegExp, 10, js_InitRegExpClass) -JS_PROTO(XML, 11, XML_INIT) -JS_PROTO(Namespace, 12, NAMESPACE_INIT) -JS_PROTO(QName, 13, QNAME_INIT) -JS_PROTO(Reflect, 14, js_InitReflectClass) -JS_PROTO(ASTNode, 15, js_InitReflectClass) -JS_PROTO(Error, 16, js_InitExceptionClasses) -JS_PROTO(InternalError, 17, js_InitExceptionClasses) -JS_PROTO(EvalError, 18, js_InitExceptionClasses) -JS_PROTO(RangeError, 19, js_InitExceptionClasses) -JS_PROTO(ReferenceError, 20, js_InitExceptionClasses) -JS_PROTO(SyntaxError, 21, js_InitExceptionClasses) -JS_PROTO(TypeError, 22, js_InitExceptionClasses) -JS_PROTO(URIError, 23, js_InitExceptionClasses) -JS_PROTO(Generator, 24, GENERATOR_INIT) -JS_PROTO(Iterator, 25, js_InitIteratorClasses) -JS_PROTO(StopIteration, 26, js_InitIteratorClasses) -JS_PROTO(ArrayBuffer, 27, js_InitTypedArrayClasses) -JS_PROTO(Int8Array, 28, js_InitTypedArrayClasses) -JS_PROTO(Uint8Array, 29, js_InitTypedArrayClasses) -JS_PROTO(Int16Array, 30, js_InitTypedArrayClasses) -JS_PROTO(Uint16Array, 31, js_InitTypedArrayClasses) -JS_PROTO(Int32Array, 32, js_InitTypedArrayClasses) -JS_PROTO(Uint32Array, 33, js_InitTypedArrayClasses) -JS_PROTO(Float32Array, 34, js_InitTypedArrayClasses) -JS_PROTO(Float64Array, 35, js_InitTypedArrayClasses) -JS_PROTO(Uint8ClampedArray, 36, js_InitTypedArrayClasses) -JS_PROTO(Proxy, 37, js_InitProxyClass) -JS_PROTO(AnyName, 38, js_InitNullClass) - -#undef XML_INIT -#undef NAMESPACE_INIT -#undef QNAME_INIT -#undef GENERATOR_INIT diff --git a/x86/mozilla/include/jsproxy.h b/x86/mozilla/include/jsproxy.h deleted file mode 100644 index 398d56b..0000000 --- a/x86/mozilla/include/jsproxy.h +++ /dev/null @@ -1,225 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=4 sw=4 et tw=99: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released - * May 28, 2008. - * - * The Initial Developer of the Original Code is - * Mozilla Foundation - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Andreas Gal - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsproxy_h___ -#define jsproxy_h___ - -#include "jsapi.h" -#include "jscntxt.h" -#include "jsobj.h" - -namespace js { - -/* Base class for all C++ proxy handlers. */ -class JS_FRIEND_API(JSProxyHandler) { - void *mFamily; - public: - explicit JSProxyHandler(void *family); - virtual ~JSProxyHandler(); - - /* ES5 Harmony fundamental proxy traps. */ - virtual bool getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, - PropertyDescriptor *desc) = 0; - virtual bool getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, - PropertyDescriptor *desc) = 0; - virtual bool defineProperty(JSContext *cx, JSObject *proxy, jsid id, - PropertyDescriptor *desc) = 0; - virtual bool getOwnPropertyNames(JSContext *cx, JSObject *proxy, js::AutoIdVector &props) = 0; - virtual bool delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp) = 0; - virtual bool enumerate(JSContext *cx, JSObject *proxy, js::AutoIdVector &props) = 0; - virtual bool fix(JSContext *cx, JSObject *proxy, Value *vp) = 0; - - /* ES5 Harmony derived proxy traps. */ - virtual bool has(JSContext *cx, JSObject *proxy, jsid id, bool *bp); - virtual bool hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool *bp); - virtual bool get(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, js::Value *vp); - virtual bool set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, bool strict, - js::Value *vp); - virtual bool keys(JSContext *cx, JSObject *proxy, js::AutoIdVector &props); - virtual bool iterate(JSContext *cx, JSObject *proxy, uintN flags, js::Value *vp); - - /* Spidermonkey extensions. */ - virtual bool call(JSContext *cx, JSObject *proxy, uintN argc, js::Value *vp); - virtual bool construct(JSContext *cx, JSObject *proxy, - uintN argc, js::Value *argv, js::Value *rval); - virtual bool hasInstance(JSContext *cx, JSObject *proxy, const js::Value *vp, bool *bp); - virtual JSType typeOf(JSContext *cx, JSObject *proxy); - virtual JSString *obj_toString(JSContext *cx, JSObject *proxy); - virtual JSString *fun_toString(JSContext *cx, JSObject *proxy, uintN indent); - virtual void finalize(JSContext *cx, JSObject *proxy); - virtual void trace(JSTracer *trc, JSObject *proxy); - - virtual bool isOuterWindow() { - return false; - } - - inline void *family() { - return mFamily; - } -}; - -/* Dispatch point for handlers that executes the appropriate C++ or scripted traps. */ -class JSProxy { - public: - /* ES5 Harmony fundamental proxy traps. */ - static bool getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, - PropertyDescriptor *desc); - static bool getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, Value *vp); - static bool getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, - PropertyDescriptor *desc); - static bool getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, - Value *vp); - static bool defineProperty(JSContext *cx, JSObject *proxy, jsid id, PropertyDescriptor *desc); - static bool defineProperty(JSContext *cx, JSObject *proxy, jsid id, const Value &v); - static bool getOwnPropertyNames(JSContext *cx, JSObject *proxy, js::AutoIdVector &props); - static bool delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp); - static bool enumerate(JSContext *cx, JSObject *proxy, js::AutoIdVector &props); - static bool fix(JSContext *cx, JSObject *proxy, Value *vp); - - /* ES5 Harmony derived proxy traps. */ - static bool has(JSContext *cx, JSObject *proxy, jsid id, bool *bp); - static bool hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool *bp); - static bool get(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, Value *vp); - static bool set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, bool strict, - Value *vp); - static bool keys(JSContext *cx, JSObject *proxy, js::AutoIdVector &props); - static bool iterate(JSContext *cx, JSObject *proxy, uintN flags, Value *vp); - - /* Spidermonkey extensions. */ - static bool call(JSContext *cx, JSObject *proxy, uintN argc, js::Value *vp); - static bool construct(JSContext *cx, JSObject *proxy, uintN argc, js::Value *argv, js::Value *rval); - static bool hasInstance(JSContext *cx, JSObject *proxy, const js::Value *vp, bool *bp); - static JSType typeOf(JSContext *cx, JSObject *proxy); - static JSString *obj_toString(JSContext *cx, JSObject *proxy); - static JSString *fun_toString(JSContext *cx, JSObject *proxy, uintN indent); -}; - -/* Shared between object and function proxies. */ -const uint32 JSSLOT_PROXY_HANDLER = 0; -const uint32 JSSLOT_PROXY_PRIVATE = 1; -const uint32 JSSLOT_PROXY_EXTRA = 2; -/* Function proxies only. */ -const uint32 JSSLOT_PROXY_CALL = 3; -const uint32 JSSLOT_PROXY_CONSTRUCT = 4; - -extern JS_FRIEND_API(js::Class) ObjectProxyClass; -extern JS_FRIEND_API(js::Class) FunctionProxyClass; -extern JS_FRIEND_API(js::Class) OuterWindowProxyClass; -extern js::Class CallableObjectClass; - -} - -inline bool -JSObject::isObjectProxy() const -{ - return getClass() == &js::ObjectProxyClass || - getClass() == &js::OuterWindowProxyClass; -} - -inline bool -JSObject::isFunctionProxy() const -{ - return getClass() == &js::FunctionProxyClass; -} - -inline bool -JSObject::isProxy() const -{ - return isObjectProxy() || isFunctionProxy(); -} - -inline js::JSProxyHandler * -JSObject::getProxyHandler() const -{ - JS_ASSERT(isProxy()); - return (js::JSProxyHandler *) getSlot(js::JSSLOT_PROXY_HANDLER).toPrivate(); -} - -inline const js::Value & -JSObject::getProxyPrivate() const -{ - JS_ASSERT(isProxy()); - return getSlot(js::JSSLOT_PROXY_PRIVATE); -} - -inline void -JSObject::setProxyPrivate(const js::Value &priv) -{ - JS_ASSERT(isProxy()); - setSlot(js::JSSLOT_PROXY_PRIVATE, priv); -} - -inline const js::Value & -JSObject::getProxyExtra() const -{ - JS_ASSERT(isProxy()); - return getSlot(js::JSSLOT_PROXY_EXTRA); -} - -inline void -JSObject::setProxyExtra(const js::Value &extra) -{ - JS_ASSERT(isProxy()); - setSlot(js::JSSLOT_PROXY_EXTRA, extra); -} - -namespace js { - -JS_FRIEND_API(JSObject *) -NewProxyObject(JSContext *cx, JSProxyHandler *handler, const js::Value &priv, - JSObject *proto, JSObject *parent, - JSObject *call = NULL, JSObject *construct = NULL); - -JS_FRIEND_API(JSBool) -FixProxy(JSContext *cx, JSObject *proxy, JSBool *bp); - -} - -JS_BEGIN_EXTERN_C - -extern js::Class js_ProxyClass; - -extern JS_FRIEND_API(JSObject *) -js_InitProxyClass(JSContext *cx, JSObject *obj); - -JS_END_EXTERN_C - -#endif diff --git a/x86/mozilla/include/jsprvtd.h b/x86/mozilla/include/jsprvtd.h deleted file mode 100644 index e1adba3..0000000 --- a/x86/mozilla/include/jsprvtd.h +++ /dev/null @@ -1,344 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsprvtd_h___ -#define jsprvtd_h___ -/* - * JS private typename definitions. - * - * This header is included only in other .h files, for convenience and for - * simplicity of type naming. The alternative for structures is to use tags, - * which are named the same as their typedef names (legal in C/C++, and less - * noisy than suffixing the typedef name with "Struct" or "Str"). Instead, - * all .h files that include this file may use the same typedef name, whether - * declaring a pointer to struct type, or defining a member of struct type. - * - * A few fundamental scalar types are defined here too. Neither the scalar - * nor the struct typedefs should change much, therefore the nearly-global - * make dependency induced by this file should not prove painful. - */ - -#include "jspubtd.h" -#include "jsstaticcheck.h" -#include "jsutil.h" - -JS_BEGIN_EXTERN_C - -/* - * Convenience constants. - */ -#define JS_BITS_PER_UINT32_LOG2 5 -#define JS_BITS_PER_UINT32 32 - -/* The alignment required of objects stored in GC arenas. */ -static const uintN JS_GCTHING_ALIGN = 8; -static const uintN JS_GCTHING_ZEROBITS = 3; - -/* Scalar typedefs. */ -typedef uint8 jsbytecode; -typedef uint8 jssrcnote; -typedef uint32 jsatomid; - -/* Struct typedefs. */ -typedef struct JSArgumentFormatMap JSArgumentFormatMap; -typedef struct JSCodeGenerator JSCodeGenerator; -typedef struct JSGCThing JSGCThing; -typedef struct JSGenerator JSGenerator; -typedef struct JSNativeEnumerator JSNativeEnumerator; -typedef struct JSFunctionBox JSFunctionBox; -typedef struct JSObjectBox JSObjectBox; -typedef struct JSParseNode JSParseNode; -typedef struct JSProperty JSProperty; -typedef struct JSSharpObjectMap JSSharpObjectMap; -typedef struct JSThread JSThread; -typedef struct JSThreadData JSThreadData; -typedef struct JSTreeContext JSTreeContext; -typedef struct JSTryNote JSTryNote; - -/* Friend "Advanced API" typedefs. */ -typedef struct JSLinearString JSLinearString; -typedef struct JSAtom JSAtom; -typedef struct JSAtomList JSAtomList; -typedef struct JSAtomListElement JSAtomListElement; -typedef struct JSAtomMap JSAtomMap; -typedef struct JSAtomState JSAtomState; -typedef struct JSCodeSpec JSCodeSpec; -typedef struct JSPrinter JSPrinter; -typedef struct JSRegExpStatics JSRegExpStatics; -typedef struct JSStackHeader JSStackHeader; -typedef struct JSSubString JSSubString; -typedef struct JSNativeTraceInfo JSNativeTraceInfo; -typedef struct JSSpecializedNative JSSpecializedNative; -typedef struct JSXML JSXML; -typedef struct JSXMLArray JSXMLArray; -typedef struct JSXMLArrayCursor JSXMLArrayCursor; - -/* - * Template declarations. - * - * jsprvtd.h can be included in both C and C++ translation units. For C++, it - * may possibly be wrapped in an extern "C" block which does not agree with - * templates. - */ -#ifdef __cplusplus -extern "C++" { - -namespace js { - -struct ArgumentsData; - -class RegExp; -class RegExpStatics; -class AutoStringRooter; -class ExecuteArgsGuard; -class InvokeFrameGuard; -class InvokeArgsGuard; -class InvokeSessionGuard; -class TraceRecorder; -struct TraceMonitor; -class StackSpace; -class StackSegment; -class FrameRegsIter; -class StringBuffer; - -struct Compiler; -struct Parser; -class TokenStream; -struct Token; -struct TokenPos; -struct TokenPtr; - -class ContextAllocPolicy; -class SystemAllocPolicy; - -template -class Vector; - -template -struct DefaultHasher; - -template , - class AllocPolicy = ContextAllocPolicy> -class HashMap; - -template , - class AllocPolicy = ContextAllocPolicy> -class HashSet; - -class PropertyCache; -struct PropertyCacheEntry; - -struct Shape; -struct EmptyShape; - -} /* namespace js */ - -} /* export "C++" */ -#endif /* __cplusplus */ - -/* "Friend" types used by jscntxt.h and jsdbgapi.h. */ -typedef enum JSTrapStatus { - JSTRAP_ERROR, - JSTRAP_CONTINUE, - JSTRAP_RETURN, - JSTRAP_THROW, - JSTRAP_LIMIT -} JSTrapStatus; - -typedef JSTrapStatus -(* JSTrapHandler)(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, - jsval closure); - -typedef JSTrapStatus -(* JSInterruptHook)(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, - void *closure); - -typedef JSTrapStatus -(* JSDebuggerHandler)(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, - void *closure); - -typedef JSTrapStatus -(* JSThrowHook)(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, - void *closure); - -typedef JSBool -(* JSWatchPointHandler)(JSContext *cx, JSObject *obj, jsid id, jsval old, - jsval *newp, void *closure); - -/* called just after script creation */ -typedef void -(* JSNewScriptHook)(JSContext *cx, - const char *filename, /* URL of script */ - uintN lineno, /* first line */ - JSScript *script, - JSFunction *fun, - void *callerdata); - -/* called just before script destruction */ -typedef void -(* JSDestroyScriptHook)(JSContext *cx, - JSScript *script, - void *callerdata); - -typedef void -(* JSSourceHandler)(const char *filename, uintN lineno, jschar *str, - size_t length, void **listenerTSData, void *closure); - -/* - * This hook captures high level script execution and function calls (JS or - * native). It is used by JS_SetExecuteHook to hook top level scripts and by - * JS_SetCallHook to hook function calls. It will get called twice per script - * or function call: just before execution begins and just after it finishes. - * In both cases the 'current' frame is that of the executing code. - * - * The 'before' param is JS_TRUE for the hook invocation before the execution - * and JS_FALSE for the invocation after the code has run. - * - * The 'ok' param is significant only on the post execution invocation to - * signify whether or not the code completed 'normally'. - * - * The 'closure' param is as passed to JS_SetExecuteHook or JS_SetCallHook - * for the 'before'invocation, but is whatever value is returned from that - * invocation for the 'after' invocation. Thus, the hook implementor *could* - * allocate a structure in the 'before' invocation and return a pointer to that - * structure. The pointer would then be handed to the hook for the 'after' - * invocation. Alternately, the 'before' could just return the same value as - * in 'closure' to cause the 'after' invocation to be called with the same - * 'closure' value as the 'before'. - * - * Returning NULL in the 'before' hook will cause the 'after' hook *not* to - * be called. - */ -typedef void * -(* JSInterpreterHook)(JSContext *cx, JSStackFrame *fp, JSBool before, - JSBool *ok, void *closure); - -typedef JSBool -(* JSDebugErrorHook)(JSContext *cx, const char *message, JSErrorReport *report, - void *closure); - -typedef struct JSDebugHooks { - JSInterruptHook interruptHook; - void *interruptHookData; - JSNewScriptHook newScriptHook; - void *newScriptHookData; - JSDestroyScriptHook destroyScriptHook; - void *destroyScriptHookData; - JSDebuggerHandler debuggerHandler; - void *debuggerHandlerData; - JSSourceHandler sourceHandler; - void *sourceHandlerData; - JSInterpreterHook executeHook; - void *executeHookData; - JSInterpreterHook callHook; - void *callHookData; - JSThrowHook throwHook; - void *throwHookData; - JSDebugErrorHook debugErrorHook; - void *debugErrorHookData; -} JSDebugHooks; - -/* js::ObjectOps function pointer typedefs. */ - -/* - * Look for id in obj and its prototype chain, returning false on error or - * exception, true on success. On success, return null in *propp if id was - * not found. If id was found, return the first object searching from obj - * along its prototype chain in which id names a direct property in *objp, and - * return a non-null, opaque property pointer in *propp. - * - * If JSLookupPropOp succeeds and returns with *propp non-null, that pointer - * may be passed as the prop parameter to a JSAttributesOp, as a short-cut - * that bypasses id re-lookup. - * - * NB: successful return with non-null *propp means the implementation may - * have locked *objp and added a reference count associated with *propp, so - * callers should not risk deadlock by nesting or interleaving other lookups - * or any obj-bearing ops before dropping *propp. - */ -typedef JSBool -(* JSLookupPropOp)(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, - JSProperty **propp); - -/* - * Get or set attributes of the property obj[id]. Return false on error or - * exception, true with current attributes in *attrsp. - */ -typedef JSBool -(* JSAttributesOp)(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp); - -/* - * A generic type for functions mapping an object to another object, or null - * if an error or exception was thrown on cx. - */ -typedef JSObject * -(* JSObjectOp)(JSContext *cx, JSObject *obj); - -/* - * Hook that creates an iterator object for a given object. Returns the - * iterator object or null if an error or exception was thrown on cx. - */ -typedef JSObject * -(* JSIteratorOp)(JSContext *cx, JSObject *obj, JSBool keysonly); - -/* - * The following determines whether JS_EncodeCharacters and JS_DecodeBytes - * treat char[] as utf-8 or simply as bytes that need to be inflated/deflated. - */ -#ifdef JS_C_STRINGS_ARE_UTF8 -# define js_CStringsAreUTF8 JS_TRUE -#else -extern JSBool js_CStringsAreUTF8; -#endif - -/* - * Hack to expose obj->getOps()->outer to the C implementation of the debugger - * interface. - */ -extern JS_FRIEND_API(JSObject *) -js_ObjectToOuterObject(JSContext *cx, JSObject *obj); - -JS_END_EXTERN_C - -#endif /* jsprvtd_h___ */ diff --git a/x86/mozilla/include/jspubtd.h b/x86/mozilla/include/jspubtd.h deleted file mode 100644 index 249bedd..0000000 --- a/x86/mozilla/include/jspubtd.h +++ /dev/null @@ -1,626 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jspubtd_h___ -#define jspubtd_h___ -/* - * JS public API typedefs. - */ -#include "jstypes.h" -#include "jscompat.h" -#include "jsval.h" - -JS_BEGIN_EXTERN_C - -/* Scalar typedefs. */ -typedef JSInt32 jsint; -typedef JSUint32 jsuint; -typedef float64 jsdouble; -typedef JSInt32 jsrefcount; /* PRInt32 if JS_THREADSAFE, see jslock.h */ - -#ifdef WIN32 -typedef wchar_t jschar; -#else -typedef JSUint16 jschar; -#endif - - -/* - * Run-time version enumeration. See jsversion.h for compile-time counterparts - * to these values that may be selected by the JS_VERSION macro, and tested by - * #if expressions. - */ -typedef enum JSVersion { - JSVERSION_1_0 = 100, - JSVERSION_1_1 = 110, - JSVERSION_1_2 = 120, - JSVERSION_1_3 = 130, - JSVERSION_1_4 = 140, - JSVERSION_ECMA_3 = 148, - JSVERSION_1_5 = 150, - JSVERSION_1_6 = 160, - JSVERSION_1_7 = 170, - JSVERSION_1_8 = 180, - JSVERSION_ECMA_5 = 185, - JSVERSION_DEFAULT = 0, - JSVERSION_UNKNOWN = -1, - JSVERSION_LATEST = JSVERSION_ECMA_5 -} JSVersion; - -#define JSVERSION_IS_ECMA(version) \ - ((version) == JSVERSION_DEFAULT || (version) >= JSVERSION_1_3) - -/* Result of typeof operator enumeration. */ -typedef enum JSType { - JSTYPE_VOID, /* undefined */ - JSTYPE_OBJECT, /* object */ - JSTYPE_FUNCTION, /* function */ - JSTYPE_STRING, /* string */ - JSTYPE_NUMBER, /* number */ - JSTYPE_BOOLEAN, /* boolean */ - JSTYPE_NULL, /* null */ - JSTYPE_XML, /* xml object */ - JSTYPE_LIMIT -} JSType; - -/* Dense index into cached prototypes and class atoms for standard objects. */ -typedef enum JSProtoKey { -#define JS_PROTO(name,code,init) JSProto_##name = code, -#include "jsproto.tbl" -#undef JS_PROTO - JSProto_LIMIT -} JSProtoKey; - -/* js_CheckAccess mode enumeration. */ -typedef enum JSAccessMode { - JSACC_PROTO = 0, /* XXXbe redundant w.r.t. id */ - JSACC_PARENT = 1, /* XXXbe redundant w.r.t. id */ - - /* - * enum value #2 formerly called JSACC_IMPORT, - * gap preserved for ABI compatibility. - */ - - JSACC_WATCH = 3, /* a watchpoint on object foo for id 'bar' */ - JSACC_READ = 4, /* a "get" of foo.bar */ - JSACC_WRITE = 8, /* a "set" of foo.bar = baz */ - JSACC_LIMIT -} JSAccessMode; - -#define JSACC_TYPEMASK (JSACC_WRITE - 1) - -/* - * This enum type is used to control the behavior of a JSObject property - * iterator function that has type JSNewEnumerate. - */ -typedef enum JSIterateOp { - /* Create new iterator state over enumerable properties. */ - JSENUMERATE_INIT, - - /* Create new iterator state over all properties. */ - JSENUMERATE_INIT_ALL, - - /* Iterate once. */ - JSENUMERATE_NEXT, - - /* Destroy iterator state. */ - JSENUMERATE_DESTROY -} JSIterateOp; - -/* Struct typedefs. */ -typedef struct JSClass JSClass; -typedef struct JSConstDoubleSpec JSConstDoubleSpec; -typedef struct JSContext JSContext; -typedef struct JSErrorReport JSErrorReport; -typedef struct JSFunction JSFunction; -typedef struct JSFunctionSpec JSFunctionSpec; -typedef struct JSTracer JSTracer; -typedef struct JSIdArray JSIdArray; -typedef struct JSPropertyDescriptor JSPropertyDescriptor; -typedef struct JSPropertySpec JSPropertySpec; -typedef struct JSObjectMap JSObjectMap; -typedef struct JSRuntime JSRuntime; -typedef struct JSScript JSScript; -typedef struct JSStackFrame JSStackFrame; -typedef struct JSXDRState JSXDRState; -typedef struct JSExceptionState JSExceptionState; -typedef struct JSLocaleCallbacks JSLocaleCallbacks; -typedef struct JSSecurityCallbacks JSSecurityCallbacks; -typedef struct JSONParser JSONParser; -typedef struct JSCompartment JSCompartment; -typedef struct JSCrossCompartmentCall JSCrossCompartmentCall; -typedef struct JSStructuredCloneWriter JSStructuredCloneWriter; -typedef struct JSStructuredCloneReader JSStructuredCloneReader; -typedef struct JSStructuredCloneCallbacks JSStructuredCloneCallbacks; - -#ifdef __cplusplus -typedef class JSWrapper JSWrapper; -typedef class JSCrossCompartmentWrapper JSCrossCompartmentWrapper; -#endif - -/* JSClass (and js::ObjectOps where appropriate) function pointer typedefs. */ - -/* - * Add, delete, or get a property named by id in obj. Note the jsid id - * type -- id may be a string (Unicode property identifier) or an int (element - * index). The *vp out parameter, on success, is the new property value after - * an add or get. After a successful delete, *vp is JSVAL_FALSE iff - * obj[id] can't be deleted (because it's permanent). - */ -typedef JSBool -(* JSPropertyOp)(JSContext *cx, JSObject *obj, jsid id, jsval *vp); - -/* - * Set a property named by id in obj, treating the assignment as strict - * mode code if strict is true. Note the jsid id type -- id may be a string - * (Unicode property identifier) or an int (element index). The *vp out - * parameter, on success, is the new property value after the - * set. - */ -typedef JSBool -(* JSStrictPropertyOp)(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp); - -/* - * This function type is used for callbacks that enumerate the properties of - * a JSObject. The behavior depends on the value of enum_op: - * - * JSENUMERATE_INIT - * A new, opaque iterator state should be allocated and stored in *statep. - * (You can use PRIVATE_TO_JSVAL() to tag the pointer to be stored). - * - * The number of properties that will be enumerated should be returned as - * an integer jsval in *idp, if idp is non-null, and provided the number of - * enumerable properties is known. If idp is non-null and the number of - * enumerable properties can't be computed in advance, *idp should be set - * to JSVAL_ZERO. - * - * JSENUMERATE_INIT_ALL - * Used identically to JSENUMERATE_INIT, but exposes all properties of the - * object regardless of enumerability. - * - * JSENUMERATE_NEXT - * A previously allocated opaque iterator state is passed in via statep. - * Return the next jsid in the iteration using *idp. The opaque iterator - * state pointed at by statep is destroyed and *statep is set to JSVAL_NULL - * if there are no properties left to enumerate. - * - * JSENUMERATE_DESTROY - * Destroy the opaque iterator state previously allocated in *statep by a - * call to this function when enum_op was JSENUMERATE_INIT or - * JSENUMERATE_INIT_ALL. - * - * The return value is used to indicate success, with a value of JS_FALSE - * indicating failure. - */ -typedef JSBool -(* JSNewEnumerateOp)(JSContext *cx, JSObject *obj, JSIterateOp enum_op, - jsval *statep, jsid *idp); - -/* - * The old-style JSClass.enumerate op should define all lazy properties not - * yet reflected in obj. - */ -typedef JSBool -(* JSEnumerateOp)(JSContext *cx, JSObject *obj); - -/* - * Resolve a lazy property named by id in obj by defining it directly in obj. - * Lazy properties are those reflected from some peer native property space - * (e.g., the DOM attributes for a given node reflected as obj) on demand. - * - * JS looks for a property in an object, and if not found, tries to resolve - * the given id. If resolve succeeds, the engine looks again in case resolve - * defined obj[id]. If no such property exists directly in obj, the process - * is repeated with obj's prototype, etc. - * - * NB: JSNewResolveOp provides a cheaper way to resolve lazy properties. - */ -typedef JSBool -(* JSResolveOp)(JSContext *cx, JSObject *obj, jsid id); - -/* - * Like JSResolveOp, but flags provide contextual information as follows: - * - * JSRESOLVE_QUALIFIED a qualified property id: obj.id or obj[id], not id - * JSRESOLVE_ASSIGNING obj[id] is on the left-hand side of an assignment - * JSRESOLVE_DETECTING 'if (o.p)...' or similar detection opcode sequence - * JSRESOLVE_DECLARING var, const, or function prolog declaration opcode - * JSRESOLVE_CLASSNAME class name used when constructing - * - * The *objp out parameter, on success, should be null to indicate that id - * was not resolved; and non-null, referring to obj or one of its prototypes, - * if id was resolved. - * - * This hook instead of JSResolveOp is called via the JSClass.resolve member - * if JSCLASS_NEW_RESOLVE is set in JSClass.flags. - * - * Setting JSCLASS_NEW_RESOLVE and JSCLASS_NEW_RESOLVE_GETS_START further - * extends this hook by passing in the starting object on the prototype chain - * via *objp. Thus a resolve hook implementation may define the property id - * being resolved in the object in which the id was first sought, rather than - * in a prototype object whose class led to the resolve hook being called. - * - * When using JSCLASS_NEW_RESOLVE_GETS_START, the resolve hook must therefore - * null *objp to signify "not resolved". With only JSCLASS_NEW_RESOLVE and no - * JSCLASS_NEW_RESOLVE_GETS_START, the hook can assume *objp is null on entry. - * This is not good practice, but enough existing hook implementations count - * on it that we can't break compatibility by passing the starting object in - * *objp without a new JSClass flag. - */ -typedef JSBool -(* JSNewResolveOp)(JSContext *cx, JSObject *obj, jsid id, uintN flags, - JSObject **objp); - -/* - * Convert obj to the given type, returning true with the resulting value in - * *vp on success, and returning false on error or exception. - */ -typedef JSBool -(* JSConvertOp)(JSContext *cx, JSObject *obj, JSType type, jsval *vp); - -/* - * Delegate typeof to an object so it can cloak a primitive or another object. - */ -typedef JSType -(* JSTypeOfOp)(JSContext *cx, JSObject *obj); - -/* - * Finalize obj, which the garbage collector has determined to be unreachable - * from other live objects or from GC roots. Obviously, finalizers must never - * store a reference to obj. - */ -typedef void -(* JSFinalizeOp)(JSContext *cx, JSObject *obj); - -/* - * Used by JS_AddExternalStringFinalizer and JS_RemoveExternalStringFinalizer - * to extend and reduce the set of string types finalized by the GC. - */ -typedef void -(* JSStringFinalizeOp)(JSContext *cx, JSString *str); - -/* - * JSClass.checkAccess type: check whether obj[id] may be accessed per mode, - * returning false on error/exception, true on success with obj[id]'s last-got - * value in *vp, and its attributes in *attrsp. As for JSPropertyOp above, id - * is either a string or an int jsval. - */ -typedef JSBool -(* JSCheckAccessOp)(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, - jsval *vp); - -/* - * Encode or decode an object, given an XDR state record representing external - * data. See jsxdrapi.h. - */ -typedef JSBool -(* JSXDRObjectOp)(JSXDRState *xdr, JSObject **objp); - -/* - * Check whether v is an instance of obj. Return false on error or exception, - * true on success with JS_TRUE in *bp if v is an instance of obj, JS_FALSE in - * *bp otherwise. - */ -typedef JSBool -(* JSHasInstanceOp)(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp); - -/* - * Deprecated function type for JSClass.mark. All new code should define - * JSTraceOp instead to ensure the traversal of traceable things stored in - * the native structures. - */ -typedef uint32 -(* JSMarkOp)(JSContext *cx, JSObject *obj, void *arg); - -/* - * Function type for trace operation of the class called to enumerate all - * traceable things reachable from obj's private data structure. For each such - * thing, a trace implementation must call - * - * JS_CallTracer(trc, thing, kind); - * - * or one of its convenience macros as described in jsapi.h. - * - * JSTraceOp implementation can assume that no other threads mutates object - * state. It must not change state of the object or corresponding native - * structures. The only exception for this rule is the case when the embedding - * needs a tight integration with GC. In that case the embedding can check if - * the traversal is a part of the marking phase through calling - * JS_IsGCMarkingTracer and apply a special code like emptying caches or - * marking its native structures. - * - * To define the tracer for a JSClass, the implementation must add - * JSCLASS_MARK_IS_TRACE to class flags and use JS_CLASS_TRACE(method) - * macro below to convert JSTraceOp to JSMarkOp when initializing or - * assigning JSClass.mark field. - */ -typedef void -(* JSTraceOp)(JSTracer *trc, JSObject *obj); - -#if defined __GNUC__ && __GNUC__ >= 4 && !defined __cplusplus -# define JS_CLASS_TRACE(method) \ - (__builtin_types_compatible_p(JSTraceOp, __typeof(&(method))) \ - ? (JSMarkOp)(method) \ - : js_WrongTypeForClassTracer) - -extern JSMarkOp js_WrongTypeForClassTracer; - -#else -# define JS_CLASS_TRACE(method) ((JSMarkOp)(method)) -#endif - -/* - * Tracer callback, called for each traceable thing directly referenced by a - * particular object or runtime structure. It is the callback responsibility - * to ensure the traversal of the full object graph via calling eventually - * JS_TraceChildren on the passed thing. In this case the callback must be - * prepared to deal with cycles in the traversal graph. - * - * kind argument is one of JSTRACE_OBJECT, JSTRACE_STRING or a tag denoting - * internal implementation-specific traversal kind. In the latter case the only - * operations on thing that the callback can do is to call JS_TraceChildren or - * DEBUG-only JS_PrintTraceThingInfo. - */ -typedef void -(* JSTraceCallback)(JSTracer *trc, void *thing, uint32 kind); - -/* - * DEBUG only callback that JSTraceOp implementation can provide to return - * a string describing the reference traced with JS_CallTracer. - */ -typedef void -(* JSTraceNamePrinter)(JSTracer *trc, char *buf, size_t bufsize); - -typedef JSBool -(* JSEqualityOp)(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp); - -/* - * Typedef for native functions called by the JS VM. - * - * See jsapi.h, the JS_CALLEE, JS_THIS, etc. macros. - */ - -typedef JSBool -(* JSNative)(JSContext *cx, uintN argc, jsval *vp); - -/* Callbacks and their arguments. */ - -typedef enum JSContextOp { - JSCONTEXT_NEW, - JSCONTEXT_DESTROY -} JSContextOp; - -/* - * The possible values for contextOp when the runtime calls the callback are: - * JSCONTEXT_NEW JS_NewContext successfully created a new JSContext - * instance. The callback can initialize the instance as - * required. If the callback returns false, the instance - * will be destroyed and JS_NewContext returns null. In - * this case the callback is not called again. - * JSCONTEXT_DESTROY One of JS_DestroyContext* methods is called. The - * callback may perform its own cleanup and must always - * return true. - * Any other value For future compatibility the callback must do nothing - * and return true in this case. - */ -typedef JSBool -(* JSContextCallback)(JSContext *cx, uintN contextOp); - -#ifndef JS_THREADSAFE -typedef void -(* JSHeartbeatCallback)(JSRuntime *rt); -#endif - -typedef enum JSGCStatus { - JSGC_BEGIN, - JSGC_END, - JSGC_MARK_END, - JSGC_FINALIZE_END -} JSGCStatus; - -typedef JSBool -(* JSGCCallback)(JSContext *cx, JSGCStatus status); - -/* - * Generic trace operation that calls JS_CallTracer on each traceable thing - * stored in data. - */ -typedef void -(* JSTraceDataOp)(JSTracer *trc, void *data); - -typedef JSBool -(* JSOperationCallback)(JSContext *cx); - -/* - * Deprecated form of JSOperationCallback. - */ -typedef JSBool -(* JSBranchCallback)(JSContext *cx, JSScript *script); - -typedef void -(* JSErrorReporter)(JSContext *cx, const char *message, JSErrorReport *report); - -/* - * Possible exception types. These types are part of a JSErrorFormatString - * structure. They define which error to throw in case of a runtime error. - * JSEXN_NONE marks an unthrowable error. - */ -typedef enum JSExnType { - JSEXN_NONE = -1, - JSEXN_ERR, - JSEXN_INTERNALERR, - JSEXN_EVALERR, - JSEXN_RANGEERR, - JSEXN_REFERENCEERR, - JSEXN_SYNTAXERR, - JSEXN_TYPEERR, - JSEXN_URIERR, - JSEXN_LIMIT -} JSExnType; - -typedef struct JSErrorFormatString { - /* The error format string (UTF-8 if js_CStringsAreUTF8). */ - const char *format; - - /* The number of arguments to expand in the formatted error message. */ - uint16 argCount; - - /* One of the JSExnType constants above. */ - int16 exnType; -} JSErrorFormatString; - -typedef const JSErrorFormatString * -(* JSErrorCallback)(void *userRef, const char *locale, - const uintN errorNumber); - -#ifdef va_start -#define JS_ARGUMENT_FORMATTER_DEFINED 1 - -typedef JSBool -(* JSArgumentFormatter)(JSContext *cx, const char *format, JSBool fromJS, - jsval **vpp, va_list *app); -#endif - -typedef JSBool -(* JSLocaleToUpperCase)(JSContext *cx, JSString *src, jsval *rval); - -typedef JSBool -(* JSLocaleToLowerCase)(JSContext *cx, JSString *src, jsval *rval); - -typedef JSBool -(* JSLocaleCompare)(JSContext *cx, JSString *src1, JSString *src2, - jsval *rval); - -typedef JSBool -(* JSLocaleToUnicode)(JSContext *cx, const char *src, jsval *rval); - -/* - * Security protocol types. - */ -typedef struct JSPrincipals JSPrincipals; - -/* - * XDR-encode or -decode a principals instance, based on whether xdr->mode is - * JSXDR_ENCODE, in which case *principalsp should be encoded; or JSXDR_DECODE, - * in which case implementations must return a held (via JSPRINCIPALS_HOLD), - * non-null *principalsp out parameter. Return true on success, false on any - * error, which the implementation must have reported. - */ -typedef JSBool -(* JSPrincipalsTranscoder)(JSXDRState *xdr, JSPrincipals **principalsp); - -/* - * Return a weak reference to the principals associated with obj, possibly via - * the immutable parent chain leading from obj to a top-level container (e.g., - * a window object in the DOM level 0). If there are no principals associated - * with obj, return null. Therefore null does not mean an error was reported; - * in no event should an error be reported or an exception be thrown by this - * callback's implementation. - */ -typedef JSPrincipals * -(* JSObjectPrincipalsFinder)(JSContext *cx, JSObject *obj); - -/* - * Used to check if a CSP instance wants to disable eval() and friends. - * See js_CheckCSPPermitsJSAction() in jsobj. - */ -typedef JSBool -(* JSCSPEvalChecker)(JSContext *cx); - -/* - * Callback used to ask the embedding for the cross compartment wrapper handler - * that implements the desired prolicy for this kind of object in the - * destination compartment. - */ -typedef JSObject * -(* JSWrapObjectCallback)(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent, - uintN flags); - -/* - * Callback used by the wrap hook to ask the embedding to prepare an object - * for wrapping in a context. This might include unwrapping other wrappers - * or even finding a more suitable object for the new compartment. - */ -typedef JSObject * -(* JSPreWrapCallback)(JSContext *cx, JSObject *scope, JSObject *obj, uintN flags); - -typedef enum { - JSCOMPARTMENT_NEW, /* XXX Does it make sense to have a NEW? */ - JSCOMPARTMENT_DESTROY -} JSCompartmentOp; - -typedef JSBool -(* JSCompartmentCallback)(JSContext *cx, JSCompartment *compartment, uintN compartmentOp); - -/* - * Read structured data from the reader r. This hook is used to read a value - * previously serialized by a call to the WriteStructuredCloneOp hook. - * - * tag and data are the pair of uint32 values from the header. The callback may - * use the JS_Read* APIs to read any other relevant parts of the object from - * the reader r. closure is any value passed to the JS_ReadStructuredClone - * function. Return the new object on success, NULL on error/exception. - */ -typedef JSObject *(*ReadStructuredCloneOp)(JSContext *cx, JSStructuredCloneReader *r, - uint32 tag, uint32 data, void *closure); - -/* - * Structured data serialization hook. The engine can write primitive values, - * Objects, Arrays, Dates, RegExps, TypedArrays, and ArrayBuffers. Any other - * type of object requires application support. This callback must first use - * the JS_WriteUint32Pair API to write an object header, passing a value - * greater than JS_SCTAG_USER to the tag parameter. Then it can use the - * JS_Write* APIs to write any other relevant parts of the value v to the - * writer w. closure is any value passed to the JS_WriteStructuredCLone function. - * - * Return true on success, false on error/exception. - */ -typedef JSBool (*WriteStructuredCloneOp)(JSContext *cx, JSStructuredCloneWriter *w, - JSObject *obj, void *closure); - -/* - * This is called when JS_WriteStructuredClone finds that the object to be - * written is recursive. To follow HTML5, the application must throw a - * DATA_CLONE_ERR DOMException. errorid is always JS_SCERR_RECURSION. - */ -typedef void (*StructuredCloneErrorOp)(JSContext *cx, uint32 errorid); - -JS_END_EXTERN_C - -#endif /* jspubtd_h___ */ diff --git a/x86/mozilla/include/jsreflect.h b/x86/mozilla/include/jsreflect.h deleted file mode 100644 index bad975f..0000000 --- a/x86/mozilla/include/jsreflect.h +++ /dev/null @@ -1,139 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99 ft=cpp: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released - * June 12, 2009. - * - * The Initial Developer of the Original Code is - * the Mozilla Corporation. - * - * Contributor(s): - * Dave Herman - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * JS reflection package. - */ -#ifndef jsreflect_h___ -#define jsreflect_h___ - -#include -#include "jspubtd.h" - -namespace js { - -enum ASTType { - AST_ERROR = -1, -#define ASTDEF(ast, str, method) ast, -#include "jsast.tbl" -#undef ASTDEF - AST_LIMIT -}; - -enum AssignmentOperator { - AOP_ERR = -1, - - /* assign */ - AOP_ASSIGN = 0, - /* operator-assign */ - AOP_PLUS, AOP_MINUS, AOP_STAR, AOP_DIV, AOP_MOD, - /* shift-assign */ - AOP_LSH, AOP_RSH, AOP_URSH, - /* binary */ - AOP_BITOR, AOP_BITXOR, AOP_BITAND, - - AOP_LIMIT -}; - -enum BinaryOperator { - BINOP_ERR = -1, - - /* eq */ - BINOP_EQ = 0, BINOP_NE, BINOP_STRICTEQ, BINOP_STRICTNE, - /* rel */ - BINOP_LT, BINOP_LE, BINOP_GT, BINOP_GE, - /* shift */ - BINOP_LSH, BINOP_RSH, BINOP_URSH, - /* arithmetic */ - BINOP_PLUS, BINOP_MINUS, BINOP_STAR, BINOP_DIV, BINOP_MOD, - /* binary */ - BINOP_BITOR, BINOP_BITXOR, BINOP_BITAND, - /* misc */ - BINOP_IN, BINOP_INSTANCEOF, - /* xml */ - BINOP_DBLDOT, - - BINOP_LIMIT -}; - -enum UnaryOperator { - UNOP_ERR = -1, - - UNOP_DELETE = 0, - UNOP_NEG, - UNOP_POS, - UNOP_NOT, - UNOP_BITNOT, - UNOP_TYPEOF, - UNOP_VOID, - - UNOP_LIMIT -}; - -enum VarDeclKind { - VARDECL_ERR = -1, - VARDECL_VAR = 0, - VARDECL_CONST, - VARDECL_LET, - VARDECL_LET_HEAD, - VARDECL_LIMIT -}; - -enum PropKind { - PROP_ERR = -1, - PROP_INIT = 0, - PROP_GETTER, - PROP_SETTER, - PROP_LIMIT -}; - -extern char const *aopNames[]; -extern char const *binopNames[]; -extern char const *unopNames[]; -extern char const *nodeTypeNames[]; - -} /* namespace js */ - -extern js::Class js_ReflectClass; - -extern JSObject * -js_InitReflectClass(JSContext *cx, JSObject *obj); - - -#endif /* jsreflect_h___ */ diff --git a/x86/mozilla/include/jsregexp.h b/x86/mozilla/include/jsregexp.h deleted file mode 100644 index 1c1d061..0000000 --- a/x86/mozilla/include/jsregexp.h +++ /dev/null @@ -1,401 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsregexp_h___ -#define jsregexp_h___ -/* - * JS regular expression interface. - */ -#include -#include "jsprvtd.h" -#include "jsstr.h" -#include "jscntxt.h" -#include "jsvector.h" - -#ifdef JS_THREADSAFE -#include "jsdhash.h" -#endif - -extern js::Class js_RegExpClass; - -namespace js { - -class RegExpStatics -{ - typedef Vector MatchPairs; - MatchPairs matchPairs; - /* The input that was used to produce matchPairs. */ - JSLinearString *matchPairsInput; - /* The input last set on the statics. */ - JSString *pendingInput; - uintN flags; - RegExpStatics *bufferLink; - bool copied; - - bool createDependent(JSContext *cx, size_t start, size_t end, Value *out) const; - - void copyTo(RegExpStatics &dst) { - dst.matchPairs.clear(); - /* 'save' has already reserved space in matchPairs */ - JS_ALWAYS_TRUE(dst.matchPairs.append(matchPairs)); - dst.matchPairsInput = matchPairsInput; - dst.pendingInput = pendingInput; - dst.flags = flags; - } - - void aboutToWrite() { - if (bufferLink && !bufferLink->copied) { - copyTo(*bufferLink); - bufferLink->copied = true; - } - } - - bool save(JSContext *cx, RegExpStatics *buffer) { - JS_ASSERT(!buffer->copied && !buffer->bufferLink); - buffer->bufferLink = bufferLink; - bufferLink = buffer; - if (!buffer->matchPairs.reserve(matchPairs.length())) { - js_ReportOutOfMemory(cx); - return false; - } - return true; - } - - void restore() { - if (bufferLink->copied) - bufferLink->copyTo(*this); - bufferLink = bufferLink->bufferLink; - } - - void checkInvariants() { -#if DEBUG - if (pairCount() == 0) { - JS_ASSERT(!matchPairsInput); - return; - } - - /* Pair count is non-zero, so there must be match pairs input. */ - JS_ASSERT(matchPairsInput); - size_t mpiLen = matchPairsInput->length(); - - /* Both members of the first pair must be non-negative. */ - JS_ASSERT(pairIsPresent(0)); - JS_ASSERT(get(0, 1) >= 0); - - /* Present pairs must be valid. */ - for (size_t i = 0; i < pairCount(); ++i) { - if (!pairIsPresent(i)) - continue; - int start = get(i, 0); - int limit = get(i, 1); - JS_ASSERT(mpiLen >= size_t(limit) && limit >= start && start >= 0); - } -#endif - } - - /* - * Since the first pair indicates the whole match, the paren pair numbers have to be in the - * range [1, pairCount). - */ - void checkParenNum(size_t pairNum) const { - JS_ASSERT(1 <= pairNum); - JS_ASSERT(pairNum < pairCount()); - } - - bool pairIsPresent(size_t pairNum) const { - return get(pairNum, 0) >= 0; - } - - /* Precondition: paren is present. */ - size_t getParenLength(size_t pairNum) const { - checkParenNum(pairNum); - JS_ASSERT(pairIsPresent(pairNum)); - return get(pairNum, 1) - get(pairNum, 0); - } - - int get(size_t pairNum, bool which) const { - JS_ASSERT(pairNum < pairCount()); - return matchPairs[2 * pairNum + which]; - } - - /* - * Check whether the index at |checkValidIndex| is valid (>= 0). - * If so, construct a string for it and place it in |*out|. - * If not, place undefined in |*out|. - */ - bool makeMatch(JSContext *cx, size_t checkValidIndex, size_t pairNum, Value *out) const; - - static const uintN allFlags = JSREG_FOLD | JSREG_GLOB | JSREG_STICKY | JSREG_MULTILINE; - - struct InitBuffer {}; - explicit RegExpStatics(InitBuffer) : bufferLink(NULL), copied(false) {} - - friend class PreserveRegExpStatics; - - public: - RegExpStatics() : bufferLink(NULL), copied(false) { clear(); } - - static RegExpStatics *extractFrom(JSObject *global); - - /* Mutators. */ - - bool updateFromMatch(JSContext *cx, JSLinearString *input, int *buf, size_t matchItemCount) { - aboutToWrite(); - pendingInput = input; - - if (!matchPairs.resizeUninitialized(matchItemCount)) { - js_ReportOutOfMemory(cx); - return false; - } - - for (size_t i = 0; i < matchItemCount; ++i) - matchPairs[i] = buf[i]; - - matchPairsInput = input; - return true; - } - - void setMultiline(bool enabled) { - aboutToWrite(); - if (enabled) - flags = flags | JSREG_MULTILINE; - else - flags = flags & ~JSREG_MULTILINE; - } - - void clear() { - aboutToWrite(); - flags = 0; - pendingInput = NULL; - matchPairsInput = NULL; - matchPairs.clear(); - } - - /* Corresponds to JSAPI functionality to set the pending RegExp input. */ - void reset(JSString *newInput, bool newMultiline) { - aboutToWrite(); - clear(); - pendingInput = newInput; - setMultiline(newMultiline); - checkInvariants(); - } - - void setPendingInput(JSString *newInput) { - aboutToWrite(); - pendingInput = newInput; - } - - /* Accessors. */ - - /* - * When there is a match present, the pairCount is at least 1 for the whole - * match. There is one additional pair per parenthesis. - * - * Getting a parenCount requires there to be a match result as a precondition. - */ - - private: - size_t pairCount() const { - JS_ASSERT(matchPairs.length() % 2 == 0); - return matchPairs.length() / 2; - } - - public: - size_t parenCount() const { - size_t pc = pairCount(); - JS_ASSERT(pc); - return pc - 1; - } - - JSString *getPendingInput() const { return pendingInput; } - uintN getFlags() const { return flags; } - bool multiline() const { return flags & JSREG_MULTILINE; } - - size_t matchStart() const { - int start = get(0, 0); - JS_ASSERT(start >= 0); - return size_t(start); - } - - size_t matchLimit() const { - int limit = get(0, 1); - JS_ASSERT(size_t(limit) >= matchStart() && limit >= 0); - return size_t(limit); - } - - /* Returns whether results for a non-empty match are present. */ - bool matched() const { - JS_ASSERT(pairCount() > 0); - JS_ASSERT_IF(get(0, 1) == -1, get(1, 1) == -1); - return get(0, 1) - get(0, 0) > 0; - } - - void mark(JSTracer *trc) const { - if (pendingInput) - JS_CALL_STRING_TRACER(trc, pendingInput, "res->pendingInput"); - if (matchPairsInput) - JS_CALL_STRING_TRACER(trc, matchPairsInput, "res->matchPairsInput"); - } - - /* Value creators. */ - - bool createPendingInput(JSContext *cx, Value *out) const; - bool createLastMatch(JSContext *cx, Value *out) const { return makeMatch(cx, 0, 0, out); } - bool createLastParen(JSContext *cx, Value *out) const; - bool createLeftContext(JSContext *cx, Value *out) const; - bool createRightContext(JSContext *cx, Value *out) const; - - /* @param pairNum Any number >= 1. */ - bool createParen(JSContext *cx, size_t pairNum, Value *out) const { - JS_ASSERT(pairNum >= 1); - if (pairNum >= pairCount()) { - out->setString(cx->runtime->emptyString); - return true; - } - return makeMatch(cx, pairNum * 2, pairNum, out); - } - - /* Substring creators. */ - - void getParen(size_t pairNum, JSSubString *out) const; - void getLastMatch(JSSubString *out) const; - void getLastParen(JSSubString *out) const; - void getLeftContext(JSSubString *out) const; - void getRightContext(JSSubString *out) const; -}; - -class PreserveRegExpStatics -{ - RegExpStatics *const original; - RegExpStatics buffer; - - public: - explicit PreserveRegExpStatics(RegExpStatics *original) - : original(original), - buffer(RegExpStatics::InitBuffer()) - {} - - bool init(JSContext *cx) { - return original->save(cx, &buffer); - } - - ~PreserveRegExpStatics() { - original->restore(); - } -}; - -} - -static inline bool -VALUE_IS_REGEXP(JSContext *cx, js::Value v) -{ - return !v.isPrimitive() && v.toObject().isRegExp(); -} - -inline const js::Value & -JSObject::getRegExpLastIndex() const -{ - JS_ASSERT(isRegExp()); - return getSlot(JSSLOT_REGEXP_LAST_INDEX); -} - -inline void -JSObject::setRegExpLastIndex(const js::Value &v) -{ - JS_ASSERT(isRegExp()); - setSlot(JSSLOT_REGEXP_LAST_INDEX, v); -} - -inline void -JSObject::setRegExpLastIndex(jsdouble d) -{ - JS_ASSERT(isRegExp()); - setSlot(JSSLOT_REGEXP_LAST_INDEX, js::NumberValue(d)); -} - -inline void -JSObject::zeroRegExpLastIndex() -{ - JS_ASSERT(isRegExp()); - getSlotRef(JSSLOT_REGEXP_LAST_INDEX).setInt32(0); -} - -namespace js { class AutoStringRooter; } - -inline bool -JSObject::isRegExp() const -{ - return getClass() == &js_RegExpClass; -} - -extern JS_FRIEND_API(JSBool) -js_ObjectIsRegExp(JSObject *obj); - -extern JSObject * -js_InitRegExpClass(JSContext *cx, JSObject *obj); - -/* - * Export js_regexp_toString to the decompiler. - */ -extern JSBool -js_regexp_toString(JSContext *cx, JSObject *obj, js::Value *vp); - -extern JS_FRIEND_API(JSObject *) JS_FASTCALL -js_CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *proto); - -/* - * Move data from |cx|'s regexp statics to |statics| and root the input string in |tvr| if it's - * available. - */ -extern JS_FRIEND_API(void) -js_SaveAndClearRegExpStatics(JSContext *cx, js::RegExpStatics *res, js::AutoStringRooter *tvr); - -/* Move the data from |statics| into |cx|. */ -extern JS_FRIEND_API(void) -js_RestoreRegExpStatics(JSContext *cx, js::RegExpStatics *res); - -extern JSBool -js_XDRRegExpObject(JSXDRState *xdr, JSObject **objp); - -extern JSBool -js_regexp_exec(JSContext *cx, uintN argc, js::Value *vp); -extern JSBool -js_regexp_test(JSContext *cx, uintN argc, js::Value *vp); - -#endif /* jsregexp_h___ */ diff --git a/x86/mozilla/include/jsscan.h b/x86/mozilla/include/jsscan.h deleted file mode 100644 index b65219e..0000000 --- a/x86/mozilla/include/jsscan.h +++ /dev/null @@ -1,603 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsscan_h___ -#define jsscan_h___ -/* - * JS lexical scanner interface. - */ -#include -#include -#include -#include "jsversion.h" -#include "jsopcode.h" -#include "jsprvtd.h" -#include "jspubtd.h" -#include "jsvector.h" - -#define JS_KEYWORD(keyword, type, op, version) \ - extern const char js_##keyword##_str[]; -#include "jskeyword.tbl" -#undef JS_KEYWORD - -namespace js { - -enum TokenKind { - TOK_ERROR = -1, /* well-known as the only code < EOF */ - TOK_EOF = 0, /* end of file */ - TOK_EOL = 1, /* end of line */ - TOK_SEMI = 2, /* semicolon */ - TOK_COMMA = 3, /* comma operator */ - TOK_ASSIGN = 4, /* assignment ops (= += -= etc.) */ - TOK_HOOK = 5, TOK_COLON = 6, /* conditional (?:) */ - TOK_OR = 7, /* logical or (||) */ - TOK_AND = 8, /* logical and (&&) */ - TOK_BITOR = 9, /* bitwise-or (|) */ - TOK_BITXOR = 10, /* bitwise-xor (^) */ - TOK_BITAND = 11, /* bitwise-and (&) */ - TOK_EQOP = 12, /* equality ops (== !=) */ - TOK_RELOP = 13, /* relational ops (< <= > >=) */ - TOK_SHOP = 14, /* shift ops (<< >> >>>) */ - TOK_PLUS = 15, /* plus */ - TOK_MINUS = 16, /* minus */ - TOK_STAR = 17, TOK_DIVOP = 18, /* multiply/divide ops (* / %) */ - TOK_UNARYOP = 19, /* unary prefix operator */ - TOK_INC = 20, TOK_DEC = 21, /* increment/decrement (++ --) */ - TOK_DOT = 22, /* member operator (.) */ - TOK_LB = 23, TOK_RB = 24, /* left and right brackets */ - TOK_LC = 25, TOK_RC = 26, /* left and right curlies (braces) */ - TOK_LP = 27, TOK_RP = 28, /* left and right parentheses */ - TOK_NAME = 29, /* identifier */ - TOK_NUMBER = 30, /* numeric constant */ - TOK_STRING = 31, /* string constant */ - TOK_REGEXP = 32, /* RegExp constant */ - TOK_PRIMARY = 33, /* true, false, null, this, super */ - TOK_FUNCTION = 34, /* function keyword */ - TOK_IF = 35, /* if keyword */ - TOK_ELSE = 36, /* else keyword */ - TOK_SWITCH = 37, /* switch keyword */ - TOK_CASE = 38, /* case keyword */ - TOK_DEFAULT = 39, /* default keyword */ - TOK_WHILE = 40, /* while keyword */ - TOK_DO = 41, /* do keyword */ - TOK_FOR = 42, /* for keyword */ - TOK_BREAK = 43, /* break keyword */ - TOK_CONTINUE = 44, /* continue keyword */ - TOK_IN = 45, /* in keyword */ - TOK_VAR = 46, /* var keyword */ - TOK_WITH = 47, /* with keyword */ - TOK_RETURN = 48, /* return keyword */ - TOK_NEW = 49, /* new keyword */ - TOK_DELETE = 50, /* delete keyword */ - TOK_DEFSHARP = 51, /* #n= for object/array initializers */ - TOK_USESHARP = 52, /* #n# for object/array initializers */ - TOK_TRY = 53, /* try keyword */ - TOK_CATCH = 54, /* catch keyword */ - TOK_FINALLY = 55, /* finally keyword */ - TOK_THROW = 56, /* throw keyword */ - TOK_INSTANCEOF = 57, /* instanceof keyword */ - TOK_DEBUGGER = 58, /* debugger keyword */ - TOK_XMLSTAGO = 59, /* XML start tag open (<) */ - TOK_XMLETAGO = 60, /* XML end tag open () */ - TOK_XMLTAGC = 62, /* XML start or end tag close (>) */ - TOK_XMLNAME = 63, /* XML start-tag non-final fragment */ - TOK_XMLATTR = 64, /* XML quoted attribute value */ - TOK_XMLSPACE = 65, /* XML whitespace */ - TOK_XMLTEXT = 66, /* XML text */ - TOK_XMLCOMMENT = 67, /* XML comment */ - TOK_XMLCDATA = 68, /* XML CDATA section */ - TOK_XMLPI = 69, /* XML processing instruction */ - TOK_AT = 70, /* XML attribute op (@) */ - TOK_DBLCOLON = 71, /* namespace qualified name op (::) */ - TOK_ANYNAME = 72, /* XML AnyName singleton (*) */ - TOK_DBLDOT = 73, /* XML descendant op (..) */ - TOK_FILTER = 74, /* XML filtering predicate op (.()) */ - TOK_XMLELEM = 75, /* XML element node type (no token) */ - TOK_XMLLIST = 76, /* XML list node type (no token) */ - TOK_YIELD = 77, /* yield from generator function */ - TOK_ARRAYCOMP = 78, /* array comprehension initialiser */ - TOK_ARRAYPUSH = 79, /* array push within comprehension */ - TOK_LEXICALSCOPE = 80, /* block scope AST node label */ - TOK_LET = 81, /* let keyword */ - TOK_SEQ = 82, /* synthetic sequence of statements, - not a block */ - TOK_FORHEAD = 83, /* head of for(;;)-style loop */ - TOK_ARGSBODY = 84, /* formal args in list + body at end */ - TOK_UPVARS = 85, /* lexical dependencies as JSAtomList - of definitions paired with a parse - tree full of uses of those names */ - TOK_RESERVED, /* reserved keywords */ - TOK_STRICT_RESERVED, /* reserved keywords in strict mode */ - TOK_LIMIT /* domain size */ -}; - -static inline bool -TokenKindIsXML(TokenKind tt) -{ - return tt == TOK_AT || tt == TOK_DBLCOLON || tt == TOK_ANYNAME; -} - -static inline bool -TreeTypeIsXML(TokenKind tt) -{ - return tt == TOK_XMLCOMMENT || tt == TOK_XMLCDATA || tt == TOK_XMLPI || - tt == TOK_XMLELEM || tt == TOK_XMLLIST; -} - -static inline bool -TokenKindIsDecl(TokenKind tt) -{ -#if JS_HAS_BLOCK_SCOPE - return tt == TOK_VAR || tt == TOK_LET; -#else - return tt == TOK_VAR; -#endif -} - -struct TokenPtr { - uint32 index; /* index of char in physical line */ - uint32 lineno; /* physical line number */ - - bool operator==(const TokenPtr& bptr) { - return index == bptr.index && lineno == bptr.lineno; - } - - bool operator!=(const TokenPtr& bptr) { - return index != bptr.index || lineno != bptr.lineno; - } - - bool operator <(const TokenPtr& bptr) { - return lineno < bptr.lineno || - (lineno == bptr.lineno && index < bptr.index); - } - - bool operator <=(const TokenPtr& bptr) { - return lineno < bptr.lineno || - (lineno == bptr.lineno && index <= bptr.index); - } - - bool operator >(const TokenPtr& bptr) { - return !(*this <= bptr); - } - - bool operator >=(const TokenPtr& bptr) { - return !(*this < bptr); - } -}; - -struct TokenPos { - TokenPtr begin; /* first character and line of token */ - TokenPtr end; /* index 1 past last char, last line */ - - bool operator==(const TokenPos& bpos) { - return begin == bpos.begin && end == bpos.end; - } - - bool operator!=(const TokenPos& bpos) { - return begin != bpos.begin || end != bpos.end; - } - - bool operator <(const TokenPos& bpos) { - return begin < bpos.begin; - } - - bool operator <=(const TokenPos& bpos) { - return begin <= bpos.begin; - } - - bool operator >(const TokenPos& bpos) { - return !(*this <= bpos); - } - - bool operator >=(const TokenPos& bpos) { - return !(*this < bpos); - } -}; - -struct Token { - TokenKind type; /* char value or above enumerator */ - TokenPos pos; /* token position in file */ - jschar *ptr; /* beginning of token in line buffer */ - union { - struct { /* name or string literal */ - JSOp op; /* operator, for minimal parser */ - JSAtom *atom; /* atom table entry */ - } s; - uintN reflags; /* regexp flags, use tokenbuf to access - regexp chars */ - struct { /* atom pair, for XML PIs */ - JSAtom *atom2; /* auxiliary atom table entry */ - JSAtom *atom; /* main atom table entry */ - } p; - jsdouble dval; /* floating point number */ - } u; -}; - -enum TokenStreamFlags -{ - TSF_ERROR = 0x01, /* fatal error while compiling */ - TSF_EOF = 0x02, /* hit end of file */ - TSF_NEWLINES = 0x04, /* tokenize newlines */ - TSF_OPERAND = 0x08, /* looking for operand, not operator */ - TSF_UNEXPECTED_EOF = 0x10, /* unexpected end of input, i.e. TOK_EOF not at top-level. */ - TSF_KEYWORD_IS_NAME = 0x20, /* Ignore keywords and return TOK_NAME instead to the parser. */ - TSF_STRICT_MODE_CODE = 0x40,/* Tokenize as appropriate for strict mode code. */ - TSF_DIRTYLINE = 0x80, /* non-whitespace since start of line */ - TSF_OWNFILENAME = 0x100, /* ts->filename is malloc'd */ - TSF_XMLTAGMODE = 0x200, /* scanning within an XML tag in E4X */ - TSF_XMLTEXTMODE = 0x400, /* scanning XMLText terminal from E4X */ - TSF_XMLONLYMODE = 0x800, /* don't scan {expr} within text/tag */ - TSF_OCTAL_CHAR = 0x1000, /* observed a octal character escape */ - - /* - * To handle the hard case of contiguous HTML comments, we want to clear the - * TSF_DIRTYINPUT flag at the end of each such comment. But we'd rather not - * scan for --> within every //-style comment unless we have to. So we set - * TSF_IN_HTML_COMMENT when a either on a clean line, or - * only if (ts->flags & TSF_IN_HTML_COMMENT), in a //-style comment. - * - * This still works as before given a malformed comment hiding hack such as: - * - * - * - * It does not cope with malformed comment hiding hacks where --> is hidden - * by C-style comments, or on a dirty line. Such cases are already broken. - */ - TSF_IN_HTML_COMMENT = 0x2000 -}; - -#define t_op u.s.op -#define t_reflags u.reflags -#define t_atom u.s.atom -#define t_atom2 u.p.atom2 -#define t_dval u.dval - -class TokenStream -{ - static const size_t ntokens = 4; /* 1 current + 2 lookahead, rounded - to power of 2 to avoid divmod by 3 */ - static const uintN ntokensMask = ntokens - 1; - - public: - typedef Vector CharBuffer; - - /* - * To construct a TokenStream, first call the constructor, which is - * infallible, then call |init|, which can fail. To destroy a TokenStream, - * first call |close| then call the destructor. If |init| fails, do not call - * |close|. - * - * This class uses JSContext.tempPool to allocate internal buffers. The - * caller should JS_ARENA_MARK before calling |init| and JS_ARENA_RELEASE - * after calling |close|. - */ - TokenStream(JSContext *); - - /* - * Create a new token stream from an input buffer. - * Return false on memory-allocation failure. - */ - bool init(const jschar *base, size_t length, const char *filename, uintN lineno, - JSVersion version); - void close(); - ~TokenStream() {} - - /* Accessors. */ - JSContext *getContext() const { return cx; } - bool onCurrentLine(const TokenPos &pos) const { return lineno == pos.end.lineno; } - const Token ¤tToken() const { return tokens[cursor]; } - const CharBuffer &getTokenbuf() const { return tokenbuf; } - const char *getFilename() const { return filename; } - uintN getLineno() const { return lineno; } - /* Note that the version and hasXML can get out of sync via setXML. */ - JSVersion versionNumber() const { return VersionNumber(version); } - JSVersion versionWithFlags() const { return version; } - bool hasAnonFunFix() const { return VersionHasAnonFunFix(version); } - bool hasXML() const { return xml || VersionShouldParseXML(versionNumber()); } - void setXML(bool enabled) { xml = enabled; } - - /* Flag methods. */ - void setStrictMode(bool enabled = true) { setFlag(enabled, TSF_STRICT_MODE_CODE); } - void setXMLTagMode(bool enabled = true) { setFlag(enabled, TSF_XMLTAGMODE); } - void setXMLOnlyMode(bool enabled = true) { setFlag(enabled, TSF_XMLONLYMODE); } - void setUnexpectedEOF(bool enabled = true) { setFlag(enabled, TSF_UNEXPECTED_EOF); } - void setOctalCharacterEscape(bool enabled = true) { setFlag(enabled, TSF_OCTAL_CHAR); } - - bool isStrictMode() { return !!(flags & TSF_STRICT_MODE_CODE); } - bool isXMLTagMode() { return !!(flags & TSF_XMLTAGMODE); } - bool isXMLOnlyMode() { return !!(flags & TSF_XMLONLYMODE); } - bool isUnexpectedEOF() { return !!(flags & TSF_UNEXPECTED_EOF); } - bool isEOF() const { return !!(flags & TSF_EOF); } - bool isError() const { return !!(flags & TSF_ERROR); } - bool hasOctalCharacterEscape() const { return flags & TSF_OCTAL_CHAR; } - - /* Mutators. */ - bool reportCompileErrorNumberVA(JSParseNode *pn, uintN flags, uintN errorNumber, va_list ap); - void mungeCurrentToken(TokenKind newKind) { tokens[cursor].type = newKind; } - void mungeCurrentToken(JSOp newOp) { tokens[cursor].t_op = newOp; } - void mungeCurrentToken(TokenKind newKind, JSOp newOp) { - mungeCurrentToken(newKind); - mungeCurrentToken(newOp); - } - - private: - static JSAtom *atomize(JSContext *cx, CharBuffer &cb); - - /* - * Enables flags in the associated tokenstream for the object lifetime. - * Useful for lexically-scoped flag toggles. - */ - class Flagger { - TokenStream * const parent; - uintN flags; - public: - Flagger(TokenStream *parent, uintN withFlags) : parent(parent), flags(withFlags) { - parent->flags |= flags; - } - - ~Flagger() { parent->flags &= ~flags; } - }; - friend class Flagger; - - void setFlag(bool enabled, TokenStreamFlags flag) { - if (enabled) - flags |= flag; - else - flags &= ~flag; - } - - public: - /* - * Get the next token from the stream, make it the current token, and - * return its kind. - */ - TokenKind getToken() { - /* Check for a pushed-back token resulting from mismatching lookahead. */ - while (lookahead != 0) { - JS_ASSERT(!(flags & TSF_XMLTEXTMODE)); - lookahead--; - cursor = (cursor + 1) & ntokensMask; - TokenKind tt = currentToken().type; - JS_ASSERT(!(flags & TSF_NEWLINES)); - if (tt != TOK_EOL) - return tt; - } - - /* If there was a fatal error, keep returning TOK_ERROR. */ - if (flags & TSF_ERROR) - return TOK_ERROR; - - return getTokenInternal(); - } - - /* Similar, but also sets flags. */ - TokenKind getToken(uintN withFlags) { - Flagger flagger(this, withFlags); - return getToken(); - } - - /* - * Push the last scanned token back into the stream. - */ - void ungetToken() { - JS_ASSERT(lookahead < ntokensMask); - lookahead++; - cursor = (cursor - 1) & ntokensMask; - } - - TokenKind peekToken(uintN withFlags = 0) { - Flagger flagger(this, withFlags); - if (lookahead != 0) { - JS_ASSERT(lookahead == 1); - return tokens[(cursor + lookahead) & ntokensMask].type; - } - TokenKind tt = getToken(); - ungetToken(); - return tt; - } - - TokenKind peekTokenSameLine(uintN withFlags = 0) { - Flagger flagger(this, withFlags); - if (!onCurrentLine(currentToken().pos)) - return TOK_EOL; - TokenKind tt = peekToken(TSF_NEWLINES); - return tt; - } - - /* - * Get the next token from the stream if its kind is |tt|. - */ - JSBool matchToken(TokenKind tt, uintN withFlags = 0) { - Flagger flagger(this, withFlags); - if (getToken() == tt) - return JS_TRUE; - ungetToken(); - return JS_FALSE; - } - - private: - typedef struct TokenBuf { - jschar *base; /* base of line or stream buffer */ - jschar *limit; /* limit for quick bounds check */ - jschar *ptr; /* next char to get, or slot to use */ - } TokenBuf; - - TokenKind getTokenInternal(); /* doesn't check for pushback or error flag. */ - - int32 getChar(); - int32 getCharIgnoreEOL(); - void ungetChar(int32 c); - void ungetCharIgnoreEOL(int32 c); - Token *newToken(ptrdiff_t adjust); - bool peekUnicodeEscape(int32 *c); - bool matchUnicodeEscapeIdStart(int32 *c); - bool matchUnicodeEscapeIdent(int32 *c); - JSBool peekChars(intN n, jschar *cp); - JSBool getXMLEntity(); - jschar *findEOL(); - - JSBool matchChar(int32 expect) { - int32 c = getChar(); - if (c == expect) - return JS_TRUE; - ungetChar(c); - return JS_FALSE; - } - - int32 peekChar() { - int32 c = getChar(); - ungetChar(c); - return c; - } - - void skipChars(intN n) { - while (--n >= 0) - getChar(); - } - - JSContext * const cx; - Token tokens[ntokens];/* circular token buffer */ - uintN cursor; /* index of last parsed token */ - uintN lookahead; /* count of lookahead tokens */ - uintN lineno; /* current line number */ - uintN flags; /* flags -- see above */ - jschar *linebase; /* start of current line; points into userbuf */ - jschar *prevLinebase; /* start of previous line; NULL if on the first line */ - TokenBuf userbuf; /* user input buffer */ - const char *filename; /* input filename or null */ - JSSourceHandler listener; /* callback for source; eg debugger */ - void *listenerData; /* listener 'this' data */ - void *listenerTSData;/* listener data for this TokenStream */ - CharBuffer tokenbuf; /* current token string buffer */ - bool maybeEOL[256]; /* probabilistic EOL lookup table */ - bool maybeStrSpecial[256];/* speeds up string scanning */ - JSVersion version; /* (i.e. to identify keywords) */ - bool xml; /* see JSOPTION_XML */ -}; - -} /* namespace js */ - -/* Unicode separators that are treated as line terminators, in addition to \n, \r */ -#define LINE_SEPARATOR 0x2028 -#define PARA_SEPARATOR 0x2029 - -extern void -js_CloseTokenStream(JSContext *cx, js::TokenStream *ts); - -extern JS_FRIEND_API(int) -js_fgets(char *buf, int size, FILE *file); - -namespace js { - -struct KeywordInfo { - const char *chars; /* C string with keyword text */ - TokenKind tokentype; - JSOp op; /* JSOp */ - JSVersion version; /* JSVersion */ -}; - -/* - * Returns a KeywordInfo for the specified characters, or NULL if the string is - * not a keyword. - */ -extern const KeywordInfo * -FindKeyword(const jschar *s, size_t length); - -} // namespace js - -/* - * Friend-exported API entry point to call a mapping function on each reserved - * identifier in the scanner's keyword table. - */ -typedef void (*JSMapKeywordFun)(const char *); - -/* - * Check that str forms a valid JS identifier name. The function does not - * check if str is a JS keyword. - */ -extern JSBool -js_IsIdentifier(JSLinearString *str); - -/* - * Steal one JSREPORT_* bit (see jsapi.h) to tell that arguments to the error - * message have const jschar* type, not const char*. - */ -#define JSREPORT_UC 0x100 - -namespace js { - -/* - * Report a compile-time error by its number. Return true for a warning, false - * for an error. When pn is not null, use it to report error's location. - * Otherwise use ts, which must not be null. - */ -bool -ReportCompileErrorNumber(JSContext *cx, TokenStream *ts, JSParseNode *pn, uintN flags, - uintN errorNumber, ...); - -/* - * Report a condition that should elicit a warning with JSOPTION_STRICT, - * or an error if ts or tc is handling strict mode code. This function - * defers to ReportCompileErrorNumber to do the real work. Either tc - * or ts may be NULL, if there is no tree context or token stream state - * whose strictness should affect the report. - * - * One could have ReportCompileErrorNumber recognize the - * JSREPORT_STRICT_MODE_ERROR flag instead of having a separate function - * like this one. However, the strict mode code flag we need to test is - * in the JSTreeContext structure for that code; we would have to change - * the ~120 ReportCompileErrorNumber calls to pass the additional - * argument, even though many of those sites would never use it. Using - * ts's TSF_STRICT_MODE_CODE flag instead of tc's would be brittle: at some - * points ts's flags don't correspond to those of the tc relevant to the - * error. - */ -bool -ReportStrictModeError(JSContext *cx, TokenStream *ts, JSTreeContext *tc, JSParseNode *pn, - uintN errorNumber, ...); - -} /* namespace js */ - -#endif /* jsscan_h___ */ diff --git a/x86/mozilla/include/jsscope.h b/x86/mozilla/include/jsscope.h deleted file mode 100644 index 99aefa1..0000000 --- a/x86/mozilla/include/jsscope.h +++ /dev/null @@ -1,924 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsscope_h___ -#define jsscope_h___ -/* - * JS symbol tables. - */ -#include -#ifdef DEBUG -#include -#endif - -#include "jstypes.h" -#include "jscntxt.h" -#include "jscompartment.h" -#include "jshashtable.h" -#include "jsobj.h" -#include "jsprvtd.h" -#include "jspubtd.h" -#include "jspropertytree.h" -#include "jsstrinlines.h" - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4800) -#pragma warning(push) -#pragma warning(disable:4100) /* Silence unreferenced formal parameter warnings */ -#endif - -/* - * Given P independent, non-unique properties each of size S words mapped by - * all scopes in a runtime, construct a property tree of N nodes each of size - * S+L words (L for tree linkage). A nominal L value is 2 for leftmost-child - * and right-sibling links. We hope that the N < P by enough that the space - * overhead of L, and the overhead of scope entries pointing at property tree - * nodes, is worth it. - * - * The tree construction goes as follows. If any empty scope in the runtime - * has a property X added to it, find or create a node under the tree root - * labeled X, and set obj->lastProp to point at that node. If any non-empty - * scope whose most recently added property is labeled Y has another property - * labeled Z added, find or create a node for Z under the node that was added - * for Y, and set obj->lastProp to point at that node. - * - * A property is labeled by its members' values: id, getter, setter, slot, - * attributes, tiny or short id, and a field telling for..in order. Note that - * labels are not unique in the tree, but they are unique among a node's kids - * (barring rare and benign multi-threaded race condition outcomes, see below) - * and along any ancestor line from the tree root to a given leaf node (except - * for the hard case of duplicate formal parameters to a function). - * - * Thus the root of the tree represents all empty scopes, and the first ply - * of the tree represents all scopes containing one property, etc. Each node - * in the tree can stand for any number of scopes having the same ordered set - * of properties, where that node was the last added to the scope. (We need - * not store the root of the tree as a node, and do not -- all we need are - * links to its kids.) - * - * Sidebar on for..in loop order: ECMA requires no particular order, but this - * implementation has promised and delivered property definition order, and - * compatibility is king. We could use an order number per property, which - * would require a sort in js_Enumerate, and an entry order generation number - * per scope. An order number beats a list, which should be doubly-linked for - * O(1) delete. An even better scheme is to use a parent link in the property - * tree, so that the ancestor line can be iterated from obj->lastProp when - * filling in a JSIdArray from back to front. This parent link also helps the - * GC to sweep properties iteratively. - * - * What if a property Y is deleted from a scope? If Y is the last property in - * the scope, we simply adjust the scope's lastProp member after we remove the - * scope's hash-table entry pointing at that property node. The parent link - * mentioned in the for..in sidebar above makes this adjustment O(1). But if - * Y comes between X and Z in the scope, then we might have to "fork" the tree - * at X, leaving X->Y->Z in case other scopes have those properties added in - * that order; and to finish the fork, we'd add a node labeled Z with the path - * X->Z, if it doesn't exist. This could lead to lots of extra nodes, and to - * O(n^2) growth when deleting lots of properties. - * - * Rather, for O(1) growth all around, we should share the path X->Y->Z among - * scopes having those three properties added in that order, and among scopes - * having only X->Z where Y was deleted. All such scopes have a lastProp that - * points to the Z child of Y. But a scope in which Y was deleted does not - * have a table entry for Y, and when iterating that scope by traversing the - * ancestor line from Z, we will have to test for a table entry for each node, - * skipping nodes that lack entries. - * - * What if we add Y again? X->Y->Z->Y is wrong and we'll enumerate Y twice. - * Therefore we must fork in such a case if not earlier, or do something else. - * We used to fork on the theory that set after delete is rare, but the Web is - * a harsh mistress, and we now convert the scope to a "dictionary" on first - * delete, to avoid O(n^2) growth in the property tree. - * - * What about thread safety? If the property tree operations done by requests - * are find-node and insert-node, then the only hazard is duplicate insertion. - * This is harmless except for minor bloat. When all requests have ended or - * been suspended, the GC is free to sweep the tree after marking all nodes - * reachable from scopes, performing remove-node operations as needed. - * - * Is the property tree worth it compared to property storage in each table's - * entries? To decide, we must find the relation <> between the words used - * with a property tree and the words required without a tree. - * - * Model all scopes as one super-scope of capacity T entries (T a power of 2). - * Let alpha be the load factor of this double hash-table. With the property - * tree, each entry in the table is a word-sized pointer to a node that can be - * shared by many scopes. But all such pointers are overhead compared to the - * situation without the property tree, where the table stores property nodes - * directly, as entries each of size S words. With the property tree, we need - * L=2 extra words per node for siblings and kids pointers. Without the tree, - * (1-alpha)*S*T words are wasted on free or removed sentinel-entries required - * by double hashing. - * - * Therefore, - * - * (property tree) <> (no property tree) - * N*(S+L) + T <> S*T - * N*(S+L) + T <> P*S + (1-alpha)*S*T - * N*(S+L) + alpha*T + (1-alpha)*T <> P*S + (1-alpha)*S*T - * - * Note that P is alpha*T by definition, so - * - * N*(S+L) + P + (1-alpha)*T <> P*S + (1-alpha)*S*T - * N*(S+L) <> P*S - P + (1-alpha)*S*T - (1-alpha)*T - * N*(S+L) <> (P + (1-alpha)*T) * (S-1) - * N*(S+L) <> (P + (1-alpha)*P/alpha) * (S-1) - * N*(S+L) <> P * (1/alpha) * (S-1) - * - * Let N = P*beta for a compression ratio beta, beta <= 1: - * - * P*beta*(S+L) <> P * (1/alpha) * (S-1) - * beta*(S+L) <> (S-1)/alpha - * beta <> (S-1)/((S+L)*alpha) - * - * For S = 6 (32-bit architectures) and L = 2, the property tree wins iff - * - * beta < 5/(8*alpha) - * - * We ensure that alpha <= .75, so the property tree wins if beta < .83_. An - * average beta from recent Mozilla browser startups was around .6. - * - * Can we reduce L? Observe that the property tree degenerates into a list of - * lists if at most one property Y follows X in all scopes. In or near such a - * case, we waste a word on the right-sibling link outside of the root ply of - * the tree. Note also that the root ply tends to be large, so O(n^2) growth - * searching it is likely, indicating the need for hashing (but with increased - * thread safety costs). - * - * If only K out of N nodes in the property tree have more than one child, we - * could eliminate the sibling link and overlay a children list or hash-table - * pointer on the leftmost-child link (which would then be either null or an - * only-child link; the overlay could be tagged in the low bit of the pointer, - * or flagged elsewhere in the property tree node, although such a flag must - * not be considered when comparing node labels during tree search). - * - * For such a system, L = 1 + (K * averageChildrenTableSize) / N instead of 2. - * If K << N, L approaches 1 and the property tree wins if beta < .95. - * - * We observe that fan-out below the root ply of the property tree appears to - * have extremely low degree (see the MeterPropertyTree code that histograms - * child-counts in jsscope.c), so instead of a hash-table we use a linked list - * of child node pointer arrays ("kid chunks"). The details are isolated in - * jspropertytree.h/.cpp; others must treat js::Shape.kids as opaque. - * - * One final twist (can you stand it?): the vast majority (~95% or more) of - * scopes are looked up fewer than three times; in these cases, initializing - * scope->table isn't worth it. So instead of always allocating scope->table, - * we leave it null while initializing all the other scope members as if it - * were non-null and minimal-length. Until a scope is searched - * MAX_LINEAR_SEARCHES times, we use linear search from obj->lastProp to find a - * given id, and save on the time and space overhead of creating a hash table. - */ - -#define SHAPE_INVALID_SLOT 0xffffffff - -namespace js { - -/* - * Shapes use multiplicative hashing, _a la_ jsdhash.[ch], but specialized to - * minimize footprint. But if a Shape lineage has been searched fewer than - * MAX_LINEAR_SEARCHES times, we use linear search and avoid allocating - * scope->table. - */ -struct PropertyTable { - static const uint32 MAX_LINEAR_SEARCHES = 7; - static const uint32 MIN_SIZE_LOG2 = 4; - static const uint32 MIN_SIZE = JS_BIT(MIN_SIZE_LOG2); - - int hashShift; /* multiplicative hash shift */ - - uint32 entryCount; /* number of entries in table */ - uint32 removedCount; /* removed entry sentinels in table */ - uint32 freelist; /* SHAPE_INVALID_SLOT or head of slot - freelist in owning dictionary-mode - object */ - js::Shape **entries; /* table of ptrs to shared tree nodes */ - - PropertyTable(uint32 nentries) - : hashShift(JS_DHASH_BITS - MIN_SIZE_LOG2), - entryCount(nentries), - removedCount(0), - freelist(SHAPE_INVALID_SLOT) - { - /* NB: entries is set by init, which must be called. */ - } - - ~PropertyTable() { - js_free(entries); - } - - /* By definition, hashShift = JS_DHASH_BITS - log2(capacity). */ - uint32 capacity() const { return JS_BIT(JS_DHASH_BITS - hashShift); } - - /* Whether we need to grow. We want to do this if the load factor is >= 0.75 */ - bool needsToGrow() const { - uint32 size = capacity(); - return entryCount + removedCount >= size - (size >> 2); - } - - /* - * Try to grow the table. On failure, reports out of memory on cx - * and returns false. This will make any extant pointers into the - * table invalid. Don't call this unless needsToGrow() is true. - */ - bool grow(JSContext *cx); - - /* - * NB: init and change are fallible but do not report OOM, so callers can - * cope or ignore. They do however use JSRuntime's calloc method in order - * to update the malloc counter on success. - */ - bool init(JSRuntime *rt, js::Shape *lastProp); - bool change(int log2Delta, JSContext *cx); - js::Shape **search(jsid id, bool adding); -}; - -} /* namespace js */ - -struct JSObject; - -namespace js { - -class PropertyTree; - -static inline PropertyOp -CastAsPropertyOp(js::Class *clasp) -{ - return JS_DATA_TO_FUNC_PTR(PropertyOp, clasp); -} - -/* - * Reuse the API-only JSPROP_INDEX attribute to mean shadowability. - */ -#define JSPROP_SHADOWABLE JSPROP_INDEX - -struct Shape : public JSObjectMap -{ - friend struct ::JSObject; - friend struct ::JSFunction; - friend class js::PropertyTree; - friend class js::Bindings; - friend bool IsShapeAboutToBeFinalized(JSContext *cx, const js::Shape *shape); - - /* - * numLinearSearches starts at zero and is incremented initially on each - * search() call. Once numLinearSearches reaches MAX_LINEAR_SEARCHES - * (which is a small integer), the table is created on the next search() - * call, and the table pointer will be easily distinguishable from a small - * integer. The table can also be created when hashifying for dictionary - * mode. - */ - union { - mutable size_t numLinearSearches; - mutable js::PropertyTable *table; - }; - - public: - inline void freeTable(JSContext *cx); - - static bool initEmptyShapes(JSCompartment *comp); - static void finishEmptyShapes(JSCompartment *comp); - - jsid id; - -#ifdef DEBUG - JSCompartment *compartment; -#endif - - protected: - union { - js::PropertyOp rawGetter; /* getter and setter hooks or objects */ - JSObject *getterObj; /* user-defined callable "get" object or - null if shape->hasGetterValue(); or - joined function object if METHOD flag - is set. */ - js::Class *clasp; /* prototype class for empty scope */ - }; - - union { - js::StrictPropertyOp rawSetter;/* getter is JSObject* and setter is 0 - if shape->isMethod() */ - JSObject *setterObj; /* user-defined callable "set" object or - null if shape->hasSetterValue() */ - }; - - public: - uint32 slot; /* abstract index in object slots */ - private: - uint8 attrs; /* attributes, see jsapi.h JSPROP_* */ - mutable uint8 flags; /* flags, see below for defines */ - public: - int16 shortid; /* tinyid, or local arg/var index */ - - protected: - mutable js::Shape *parent; /* parent node, reverse for..in order */ - union { - mutable js::KidsPointer kids; /* null, single child, or a tagged ptr - to many-kids data structure */ - mutable js::Shape **listp; /* dictionary list starting at lastProp - has a double-indirect back pointer, - either to shape->parent if not last, - else to obj->lastProp */ - }; - - static inline js::Shape **search(JSRuntime *rt, js::Shape **startp, jsid id, - bool adding = false); - static js::Shape *newDictionaryShape(JSContext *cx, const js::Shape &child, js::Shape **listp); - static js::Shape *newDictionaryList(JSContext *cx, js::Shape **listp); - - inline void removeFromDictionary(JSObject *obj) const; - inline void insertIntoDictionary(js::Shape **dictp); - - js::Shape *getChild(JSContext *cx, const js::Shape &child, js::Shape **listp); - - bool hashify(JSRuntime *rt); - - bool hasTable() const { - /* A valid pointer should be much bigger than MAX_LINEAR_SEARCHES. */ - return numLinearSearches > PropertyTable::MAX_LINEAR_SEARCHES; - } - - js::PropertyTable *getTable() const { - JS_ASSERT(hasTable()); - return table; - } - - void setTable(js::PropertyTable *t) const { - JS_ASSERT_IF(t && t->freelist != SHAPE_INVALID_SLOT, t->freelist < slotSpan); - table = t; - } - - /* - * Setter for parent. The challenge is to maintain JSObjectMap::slotSpan in - * the face of arbitrary slot order. - * - * By induction, an empty shape has a slotSpan member correctly computed as - * JSCLASS_FREE(clasp) -- see EmptyShape's constructor in jsscopeinlines.h. - * This is the basis case, where p is null. - * - * Any child shape, whether in a shape tree or in a dictionary list, must - * have a slotSpan either one greater than its slot value (if the child's - * slot is SHAPE_INVALID_SLOT, this will yield 0; the static assertion - * below enforces this), or equal to its parent p's slotSpan, whichever is - * greater. This is the inductive step. - * - * If we maintained shape paths such that parent slot was always one less - * than child slot, possibly with an exception for SHAPE_INVALID_SLOT slot - * values where we would use another way of computing slotSpan based on the - * PropertyTable (as JSC does), then we would not need to store slotSpan in - * Shape (to be precise, in its base struct, JSobjectMap). - * - * But we currently scramble slots along shape paths due to resolve-based - * creation of shapes mapping reserved slots, and we do not have the needed - * PropertyTable machinery to use as an alternative when parent slot is not - * one less than child slot. This machinery is neither simple nor free, as - * it must involve creating a table for any slot-less transition and then - * pinning the table to its shape. - * - * Use of 'delete' can scramble slots along the shape lineage too, although - * it always switches the target object to dictionary mode, so the cost of - * a pinned table is less onerous. - * - * Note that allocating a uint32 slotSpan member in JSObjectMap takes no - * net extra space on 64-bit targets (it packs with shape). And on 32-bit - * targets, adding slotSpan to JSObjectMap takes no gross extra space, - * because Shape rounds up to an even number of 32-bit words (required for - * GC-thing and js::Value allocation in any event) on 32-bit targets. - * - * So in terms of space, we can afford to maintain both slotSpan and slot, - * but it might be better if we eliminated slotSpan using slot combined - * with an auxiliary mechanism based on table. - */ - void setParent(js::Shape *p) { - JS_STATIC_ASSERT(uint32(SHAPE_INVALID_SLOT) == ~uint32(0)); - if (p) - slotSpan = JS_MAX(p->slotSpan, slot + 1); - JS_ASSERT(slotSpan < JSObject::NSLOTS_LIMIT); - parent = p; - } - - void insertFree(js::Shape **freep) { -#ifdef DEBUG - memset(this, JS_FREE_PATTERN, sizeof *this); -#endif - id = JSID_VOID; - parent = *freep; - if (parent) - parent->listp = &parent; - listp = freep; - *freep = this; - } - - void removeFree() { - JS_ASSERT(JSID_IS_VOID(id)); - *listp = parent; - if (parent) - parent->listp = listp; - } - - public: - const js::Shape *previous() const { - return parent; - } - - class Range { - protected: - friend struct Shape; - - const Shape *cursor; - const Shape *end; - - public: - Range(const Shape *shape) : cursor(shape) { } - - bool empty() const { - JS_ASSERT_IF(!cursor->parent, JSID_IS_EMPTY(cursor->id)); - return !cursor->parent; - } - - const Shape &front() const { - JS_ASSERT(!empty()); - return *cursor; - } - - void popFront() { - JS_ASSERT(!empty()); - cursor = cursor->parent; - } - }; - - Range all() const { - return Range(this); - } - - protected: - /* - * Implementation-private bits stored in shape->flags. See public: enum {} - * flags further below, which were allocated FCFS over time, so interleave - * with these bits. - */ - enum { - /* GC mark flag. */ - MARK = 0x01, - - SHARED_EMPTY = 0x02, - - /* - * Set during a shape-regenerating GC if the shape has already been - * regenerated. - */ - SHAPE_REGEN = 0x04, - - /* Property stored in per-object dictionary, not shared property tree. */ - IN_DICTIONARY = 0x08, - - /* Prevent unwanted mutation of shared Bindings::lastBinding nodes. */ - FROZEN = 0x10 - }; - - Shape(jsid id, js::PropertyOp getter, js::StrictPropertyOp setter, uint32 slot, uintN attrs, - uintN flags, intN shortid, uint32 shape = INVALID_SHAPE, uint32 slotSpan = 0); - - /* Used by EmptyShape (see jsscopeinlines.h). */ - Shape(JSCompartment *comp, Class *aclasp); - - bool marked() const { return (flags & MARK) != 0; } - void mark() const { flags |= MARK; } - void clearMark() { flags &= ~MARK; } - - bool hasRegenFlag() const { return (flags & SHAPE_REGEN) != 0; } - void setRegenFlag() { flags |= SHAPE_REGEN; } - void clearRegenFlag() { flags &= ~SHAPE_REGEN; } - - bool inDictionary() const { return (flags & IN_DICTIONARY) != 0; } - bool frozen() const { return (flags & FROZEN) != 0; } - void setFrozen() { flags |= FROZEN; } - - bool isEmptyShape() const { JS_ASSERT_IF(!parent, JSID_IS_EMPTY(id)); return !parent; } - - public: - /* Public bits stored in shape->flags. */ - enum { - ALIAS = 0x20, - HAS_SHORTID = 0x40, - METHOD = 0x80, - PUBLIC_FLAGS = ALIAS | HAS_SHORTID | METHOD - }; - - uintN getFlags() const { return flags & PUBLIC_FLAGS; } - bool isAlias() const { return (flags & ALIAS) != 0; } - bool hasShortID() const { return (flags & HAS_SHORTID) != 0; } - bool isMethod() const { return (flags & METHOD) != 0; } - - JSObject &methodObject() const { JS_ASSERT(isMethod()); return *getterObj; } - - js::PropertyOp getter() const { return rawGetter; } - bool hasDefaultGetter() const { return !rawGetter; } - js::PropertyOp getterOp() const { JS_ASSERT(!hasGetterValue()); return rawGetter; } - JSObject *getterObject() const { JS_ASSERT(hasGetterValue()); return getterObj; } - - // Per ES5, decode null getterObj as the undefined value, which encodes as null. - js::Value getterValue() const { - JS_ASSERT(hasGetterValue()); - return getterObj ? js::ObjectValue(*getterObj) : js::UndefinedValue(); - } - - js::Value getterOrUndefined() const { - return hasGetterValue() && getterObj ? js::ObjectValue(*getterObj) : js::UndefinedValue(); - } - - js::StrictPropertyOp setter() const { return rawSetter; } - bool hasDefaultSetter() const { return !rawSetter; } - js::StrictPropertyOp setterOp() const { JS_ASSERT(!hasSetterValue()); return rawSetter; } - JSObject *setterObject() const { JS_ASSERT(hasSetterValue()); return setterObj; } - - // Per ES5, decode null setterObj as the undefined value, which encodes as null. - js::Value setterValue() const { - JS_ASSERT(hasSetterValue()); - return setterObj ? js::ObjectValue(*setterObj) : js::UndefinedValue(); - } - - js::Value setterOrUndefined() const { - return hasSetterValue() && setterObj ? js::ObjectValue(*setterObj) : js::UndefinedValue(); - } - - inline JSDHashNumber hash() const; - inline bool matches(const js::Shape *p) const; - inline bool matchesParamsAfterId(js::PropertyOp agetter, js::StrictPropertyOp asetter, - uint32 aslot, uintN aattrs, uintN aflags, - intN ashortid) const; - - bool get(JSContext* cx, JSObject *receiver, JSObject *obj, JSObject *pobj, js::Value* vp) const; - bool set(JSContext* cx, JSObject *obj, bool strict, js::Value* vp) const; - - inline bool isSharedPermanent() const; - - void trace(JSTracer *trc) const; - - bool hasSlot() const { return (attrs & JSPROP_SHARED) == 0; } - - uint8 attributes() const { return attrs; } - bool configurable() const { return (attrs & JSPROP_PERMANENT) == 0; } - bool enumerable() const { return (attrs & JSPROP_ENUMERATE) != 0; } - bool writable() const { - // JS_ASSERT(isDataDescriptor()); - return (attrs & JSPROP_READONLY) == 0; - } - bool hasGetterValue() const { return attrs & JSPROP_GETTER; } - bool hasSetterValue() const { return attrs & JSPROP_SETTER; } - - bool hasDefaultGetterOrIsMethod() const { - return hasDefaultGetter() || isMethod(); - } - - bool isDataDescriptor() const { - return (attrs & (JSPROP_SETTER | JSPROP_GETTER)) == 0; - } - bool isAccessorDescriptor() const { - return (attrs & (JSPROP_SETTER | JSPROP_GETTER)) != 0; - } - - /* - * For ES5 compatibility, we allow properties with JSPropertyOp-flavored - * setters to be shadowed when set. The "own" property thereby created in - * the directly referenced object will have the same getter and setter as - * the prototype property. See bug 552432. - */ - bool shadowable() const { - JS_ASSERT_IF(isDataDescriptor(), writable()); - return hasSlot() || (attrs & JSPROP_SHADOWABLE); - } - - uint32 entryCount() const { - if (hasTable()) - return getTable()->entryCount; - - const js::Shape *shape = this; - uint32 count = 0; - for (js::Shape::Range r = shape->all(); !r.empty(); r.popFront()) - ++count; - return count; - } - -#ifdef DEBUG - void dump(JSContext *cx, FILE *fp) const; - void dumpSubtree(JSContext *cx, int level, FILE *fp) const; -#endif -}; - -struct EmptyShape : public js::Shape -{ - EmptyShape(JSCompartment *comp, js::Class *aclasp); - - js::Class *getClass() const { return clasp; }; - - static EmptyShape *create(JSCompartment *comp, js::Class *clasp) { - js::Shape *eprop = comp->propertyTree.newShapeUnchecked(); - if (!eprop) - return NULL; - return new (eprop) EmptyShape(comp, clasp); - } - - static EmptyShape *create(JSContext *cx, js::Class *clasp) { - js::Shape *eprop = JS_PROPERTY_TREE(cx).newShape(cx); - if (!eprop) - return NULL; - return new (eprop) EmptyShape(cx->compartment, clasp); - } -}; - -} /* namespace js */ - -/* js::Shape pointer tag bit indicating a collision. */ -#define SHAPE_COLLISION (jsuword(1)) -#define SHAPE_REMOVED ((js::Shape *) SHAPE_COLLISION) - -/* Macros to get and set shape pointer values and collision flags. */ -#define SHAPE_IS_FREE(shape) ((shape) == NULL) -#define SHAPE_IS_REMOVED(shape) ((shape) == SHAPE_REMOVED) -#define SHAPE_IS_LIVE(shape) ((shape) > SHAPE_REMOVED) -#define SHAPE_FLAG_COLLISION(spp,shape) (*(spp) = (js::Shape *) \ - (jsuword(shape) | SHAPE_COLLISION)) -#define SHAPE_HAD_COLLISION(shape) (jsuword(shape) & SHAPE_COLLISION) -#define SHAPE_FETCH(spp) SHAPE_CLEAR_COLLISION(*(spp)) - -#define SHAPE_CLEAR_COLLISION(shape) \ - ((js::Shape *) (jsuword(shape) & ~SHAPE_COLLISION)) - -#define SHAPE_STORE_PRESERVING_COLLISION(spp, shape) \ - (*(spp) = (js::Shape *) (jsuword(shape) | SHAPE_HAD_COLLISION(*(spp)))) - -inline js::Shape ** -JSObject::nativeSearch(jsid id, bool adding) -{ - return js::Shape::search(compartment()->rt, &lastProp, id, adding); -} - -inline const js::Shape * -JSObject::nativeLookup(jsid id) -{ - JS_ASSERT(isNative()); - return SHAPE_FETCH(nativeSearch(id)); -} - -inline bool -JSObject::nativeContains(jsid id) -{ - return nativeLookup(id) != NULL; -} - -inline bool -JSObject::nativeContains(const js::Shape &shape) -{ - return nativeLookup(shape.id) == &shape; -} - -inline const js::Shape * -JSObject::lastProperty() const -{ - JS_ASSERT(isNative()); - JS_ASSERT(!JSID_IS_VOID(lastProp->id)); - return lastProp; -} - -inline bool -JSObject::nativeEmpty() const -{ - return lastProperty()->isEmptyShape(); -} - -inline bool -JSObject::inDictionaryMode() const -{ - return lastProperty()->inDictionary(); -} - -inline uint32 -JSObject::propertyCount() const -{ - return lastProperty()->entryCount(); -} - -inline bool -JSObject::hasPropertyTable() const -{ - return lastProperty()->hasTable(); -} - -/* - * FIXME: shape must not be null, should use a reference here and other places. - */ -inline void -JSObject::setLastProperty(const js::Shape *shape) -{ - JS_ASSERT(!inDictionaryMode()); - JS_ASSERT(!JSID_IS_VOID(shape->id)); - JS_ASSERT_IF(lastProp, !JSID_IS_VOID(lastProp->id)); - JS_ASSERT(shape->compartment == compartment()); - - lastProp = const_cast(shape); -} - -inline void -JSObject::removeLastProperty() -{ - JS_ASSERT(!inDictionaryMode()); - JS_ASSERT(!JSID_IS_VOID(lastProp->parent->id)); - - lastProp = lastProp->parent; -} - -namespace js { - -inline void -Shape::removeFromDictionary(JSObject *obj) const -{ - JS_ASSERT(!frozen()); - JS_ASSERT(inDictionary()); - JS_ASSERT(obj->inDictionaryMode()); - JS_ASSERT(listp); - JS_ASSERT(!JSID_IS_VOID(id)); - - JS_ASSERT(obj->lastProp->inDictionary()); - JS_ASSERT(obj->lastProp->listp == &obj->lastProp); - JS_ASSERT_IF(obj->lastProp != this, !JSID_IS_VOID(obj->lastProp->id)); - JS_ASSERT_IF(obj->lastProp->parent, !JSID_IS_VOID(obj->lastProp->parent->id)); - - if (parent) - parent->listp = listp; - *listp = parent; - listp = NULL; -} - -inline void -Shape::insertIntoDictionary(js::Shape **dictp) -{ - /* - * Don't assert inDictionaryMode() here because we may be called from - * JSObject::toDictionaryMode via JSObject::newDictionaryShape. - */ - JS_ASSERT(inDictionary()); - JS_ASSERT(!listp); - JS_ASSERT(!JSID_IS_VOID(id)); - - JS_ASSERT_IF(*dictp, !(*dictp)->frozen()); - JS_ASSERT_IF(*dictp, (*dictp)->inDictionary()); - JS_ASSERT_IF(*dictp, (*dictp)->listp == dictp); - JS_ASSERT_IF(*dictp, !JSID_IS_VOID((*dictp)->id)); - - setParent(*dictp); - if (parent) - parent->listp = &parent; - listp = dictp; - *dictp = this; -} - -} /* namespace js */ - -/* - * If SHORTID is set in shape->flags, we use shape->shortid rather - * than id when calling shape's getter or setter. - */ -#define SHAPE_USERID(shape) \ - ((shape)->hasShortID() ? INT_TO_JSID((shape)->shortid) \ - : (shape)->id) - -extern uint32 -js_GenerateShape(JSRuntime *rt); - -extern uint32 -js_GenerateShape(JSContext *cx); - -#ifdef DEBUG -struct JSScopeStats { - jsrefcount searches; - jsrefcount hits; - jsrefcount misses; - jsrefcount hashes; - jsrefcount hashHits; - jsrefcount hashMisses; - jsrefcount steps; - jsrefcount stepHits; - jsrefcount stepMisses; - jsrefcount initSearches; - jsrefcount changeSearches; - jsrefcount tableAllocFails; - jsrefcount toDictFails; - jsrefcount wrapWatchFails; - jsrefcount adds; - jsrefcount addFails; - jsrefcount puts; - jsrefcount redundantPuts; - jsrefcount putFails; - jsrefcount changes; - jsrefcount changePuts; - jsrefcount changeFails; - jsrefcount compresses; - jsrefcount grows; - jsrefcount removes; - jsrefcount removeFrees; - jsrefcount uselessRemoves; - jsrefcount shrinks; -}; - -extern JS_FRIEND_DATA(JSScopeStats) js_scope_stats; - -# define METER(x) JS_ATOMIC_INCREMENT(&js_scope_stats.x) -#else -# define METER(x) /* nothing */ -#endif - -namespace js { - -JS_ALWAYS_INLINE js::Shape ** -Shape::search(JSRuntime *rt, js::Shape **startp, jsid id, bool adding) -{ - js::Shape *start = *startp; - METER(searches); - - if (start->hasTable()) - return start->getTable()->search(id, adding); - - if (start->numLinearSearches == PropertyTable::MAX_LINEAR_SEARCHES) { - if (start->hashify(rt)) - return start->getTable()->search(id, adding); - /* OOM! Don't increment numLinearSearches, to keep hasTable() false. */ - JS_ASSERT(!start->hasTable()); - } else { - JS_ASSERT(start->numLinearSearches < PropertyTable::MAX_LINEAR_SEARCHES); - start->numLinearSearches++; - } - - /* - * Not enough searches done so far to justify hashing: search linearly - * from *startp. - * - * We don't use a Range here, or stop at null parent (the empty shape - * at the end), to avoid an extra load per iteration just to save a - * load and id test at the end (when missing). - */ - js::Shape **spp; - for (spp = startp; js::Shape *shape = *spp; spp = &shape->parent) { - if (shape->id == id) { - METER(hits); - return spp; - } - } - METER(misses); - return spp; -} - -#undef METER - -inline bool -Shape::isSharedPermanent() const -{ - return (~attrs & (JSPROP_SHARED | JSPROP_PERMANENT)) == 0; -} - -} // namespace js - -#ifdef _MSC_VER -#pragma warning(pop) -#pragma warning(pop) -#endif - -#endif /* jsscope_h___ */ diff --git a/x86/mozilla/include/jsscript.h b/x86/mozilla/include/jsscript.h deleted file mode 100644 index 7394abe..0000000 --- a/x86/mozilla/include/jsscript.h +++ /dev/null @@ -1,737 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=4 sw=4 et tw=79 ft=cpp: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsscript_h___ -#define jsscript_h___ -/* - * JS script descriptor. - */ -#include "jsatom.h" -#include "jsprvtd.h" -#include "jsdbgapi.h" -#include "jsclist.h" - -/* - * Type of try note associated with each catch or finally block, and also with - * for-in loops. - */ -typedef enum JSTryNoteKind { - JSTRY_CATCH, - JSTRY_FINALLY, - JSTRY_ITER -} JSTryNoteKind; - -namespace js { - -/* - * Indicates a location in the stack that an upvar value can be retrieved from - * as a two tuple of (level, slot). - * - * Some existing client code uses the level value as a delta, or level "skip" - * quantity. We could probably document that through use of more types at some - * point in the future. - * - * Existing XDR code wants this to be backed by a 32b integer for serialization, - * so we oblige. - * - * TODO: consider giving more bits to the slot value and takings ome from the level. - */ -class UpvarCookie -{ - uint32 value; - - static const uint32 FREE_VALUE = 0xfffffffful; - - void checkInvariants() { - JS_STATIC_ASSERT(sizeof(UpvarCookie) == sizeof(uint32)); - JS_STATIC_ASSERT(UPVAR_LEVEL_LIMIT < FREE_LEVEL); - } - - public: - /* - * All levels above-and-including FREE_LEVEL are reserved so that - * FREE_VALUE can be used as a special value. - */ - static const uint16 FREE_LEVEL = 0x3fff; - - /* - * If a function has a higher static level than this limit, we will not - * optimize it using UPVAR opcodes. - */ - static const uint16 UPVAR_LEVEL_LIMIT = 16; - static const uint16 CALLEE_SLOT = 0xffff; - static bool isLevelReserved(uint16 level) { return level >= FREE_LEVEL; } - - bool isFree() const { return value == FREE_VALUE; } - uint32 asInteger() const { return value; } - /* isFree check should be performed before using these accessors. */ - uint16 level() const { JS_ASSERT(!isFree()); return uint16(value >> 16); } - uint16 slot() const { JS_ASSERT(!isFree()); return uint16(value); } - - void set(const UpvarCookie &other) { set(other.level(), other.slot()); } - void set(uint16 newLevel, uint16 newSlot) { value = (uint32(newLevel) << 16) | newSlot; } - void makeFree() { set(0xffff, 0xffff); JS_ASSERT(isFree()); } - void fromInteger(uint32 u32) { value = u32; } -}; - -} - -/* - * Exception handling record. - */ -struct JSTryNote { - uint8 kind; /* one of JSTryNoteKind */ - uint8 padding; /* explicit padding on uint16 boundary */ - uint16 stackDepth; /* stack depth upon exception handler entry */ - uint32 start; /* start of the try statement or for-in loop - relative to script->main */ - uint32 length; /* length of the try statement or for-in loop */ -}; - -typedef struct JSTryNoteArray { - JSTryNote *vector; /* array of indexed try notes */ - uint32 length; /* count of indexed try notes */ -} JSTryNoteArray; - -typedef struct JSObjectArray { - JSObject **vector; /* array of indexed objects */ - uint32 length; /* count of indexed objects */ -} JSObjectArray; - -typedef struct JSUpvarArray { - js::UpvarCookie *vector; /* array of indexed upvar cookies */ - uint32 length; /* count of indexed upvar cookies */ -} JSUpvarArray; - -typedef struct JSConstArray { - js::Value *vector; /* array of indexed constant values */ - uint32 length; -} JSConstArray; - -struct JSArenaPool; - -namespace js { - -struct GlobalSlotArray { - struct Entry { - uint32 atomIndex; /* index into atom table */ - uint32 slot; /* global obj slot number */ - }; - Entry *vector; - uint32 length; -}; - -struct Shape; - -enum BindingKind { NONE, ARGUMENT, VARIABLE, CONSTANT, UPVAR }; - -/* - * Formal parameters, local variables, and upvars are stored in a shape tree - * path encapsulated within this class. This class represents bindings for - * both function and top-level scripts (the latter is needed to track names in - * strict mode eval code, to give such code its own lexical environment). - */ -class Bindings { - js::Shape *lastBinding; - uint16 nargs; - uint16 nvars; - uint16 nupvars; - - public: - inline Bindings(JSContext *cx); - - /* - * Transfers ownership of bindings data from bindings into this fresh - * Bindings instance. Once such a transfer occurs, the old bindings must - * not be used again. - */ - inline void transfer(JSContext *cx, Bindings *bindings); - - /* - * Clones bindings data from bindings, which must be immutable, into this - * fresh Bindings instance. A Bindings instance may be cloned multiple - * times. - */ - inline void clone(JSContext *cx, Bindings *bindings); - - uint16 countArgs() const { return nargs; } - uint16 countVars() const { return nvars; } - uint16 countUpvars() const { return nupvars; } - - uintN countArgsAndVars() const { return nargs + nvars; } - - uintN countLocalNames() const { return nargs + nvars + nupvars; } - - bool hasUpvars() const { return nupvars > 0; } - bool hasLocalNames() const { return countLocalNames() > 0; } - - /* Returns the shape lineage generated for these bindings. */ - inline const js::Shape *lastShape() const; - - enum { - /* - * A script may have no more than this many arguments, variables, or - * upvars. - */ - BINDING_COUNT_LIMIT = 0xFFFF - }; - - /* - * Add a local binding for the given name, of the given type, for the code - * being compiled. If fun is non-null, this binding set is being created - * for that function, so adjust corresponding metadata in that function - * while adding. Otherwise this set must correspond to a top-level script. - * - * A binding may be added twice with different kinds; the last one for a - * given name prevails. (We preserve both bindings for the decompiler, - * which must deal with such cases.) Pass null for name when indicating a - * destructuring argument. Return true on success. - * - * The parser builds shape paths for functions, usable by Call objects at - * runtime, by calling an "add" method. All ARGUMENT bindings must be added - * before before any VARIABLE or CONSTANT bindings, which themselves must - * be added before all UPVAR bindings. - */ - bool add(JSContext *cx, JSAtom *name, BindingKind kind); - - /* Convenience specializations. */ - bool addVariable(JSContext *cx, JSAtom *name) { - return add(cx, name, VARIABLE); - } - bool addConstant(JSContext *cx, JSAtom *name) { - return add(cx, name, CONSTANT); - } - bool addUpvar(JSContext *cx, JSAtom *name) { - return add(cx, name, UPVAR); - } - bool addArgument(JSContext *cx, JSAtom *name, uint16 *slotp) { - JS_ASSERT(name != NULL); /* not destructuring */ - *slotp = nargs; - return add(cx, name, ARGUMENT); - } - bool addDestructuring(JSContext *cx, uint16 *slotp) { - *slotp = nargs; - return add(cx, NULL, ARGUMENT); - } - - /* - * Look up an argument or variable name, returning its kind when found or - * NONE when no such name exists. When indexp is not null and the name - * exists, *indexp will receive the index of the corresponding argument or - * variable. - */ - BindingKind lookup(JSContext *cx, JSAtom *name, uintN *indexp) const; - - /* Convenience method to check for any binding for a name. */ - bool hasBinding(JSContext *cx, JSAtom *name) const { - return lookup(cx, name, NULL) != NONE; - } - - /* - * Function and macros to work with local names as an array of words. - * getLocalNameArray returns the array, or null if we are out of memory. - * This function must be called only when hasLocalNames(). - * - * The supplied pool is used to allocate the returned array, so the caller - * is obligated to mark and release to free it. - * - * The elements of the array with index less than nargs correspond to the - * the names of arguments. An index >= nargs addresses a var binding. Use - * JS_LOCAL_NAME_TO_ATOM to convert array's element to an atom pointer. - * This pointer can be null when the element is for an argument - * corresponding to a destructuring pattern. - * - * If nameWord does not name an argument, use JS_LOCAL_NAME_IS_CONST to - * check if nameWord corresponds to the const declaration. - */ - jsuword * - getLocalNameArray(JSContext *cx, JSArenaPool *pool); - - /* - * Returns the slot where the sharp array is stored, or a value < 0 if no - * sharps are present or in case of failure. - */ - int sharpSlotBase(JSContext *cx); - - /* - * Protect stored bindings from mutation. Subsequent attempts to add - * bindings will copy the existing bindings before adding to them, allowing - * the original bindings to be safely shared. - */ - void makeImmutable(); - - /* - * These methods provide direct access to the shape path normally - * encapsulated by js::Bindings. These methods may be used to make a - * Shape::Range for iterating over the relevant shapes from youngest to - * oldest (i.e., last or right-most to first or left-most in source order). - * - * Sometimes iteration order must be from oldest to youngest, however. For - * such cases, use js::Bindings::getLocalNameArray. The RAII class - * js::AutoLocalNameArray, defined in jscntxt.h, should be used where - * possible instead of direct calls to getLocalNameArray. - */ - const js::Shape *lastArgument() const; - const js::Shape *lastVariable() const; - const js::Shape *lastUpvar() const; - - void trace(JSTracer *trc); -}; - -} /* namespace js */ - -#define JS_OBJECT_ARRAY_SIZE(length) \ - (offsetof(JSObjectArray, vector) + sizeof(JSObject *) * (length)) - -#if defined DEBUG && defined JS_THREADSAFE -# define CHECK_SCRIPT_OWNER 1 -#endif - -#ifdef JS_METHODJIT -namespace JSC { - class ExecutablePool; -} - -#define JS_UNJITTABLE_SCRIPT (reinterpret_cast(1)) - -enum JITScriptStatus { - JITScript_None, - JITScript_Invalid, - JITScript_Valid -}; - -namespace js { -namespace mjit { - -struct JITScript; - -} -} -#endif - -struct JSScript { - /* - * Two successively less primitive ways to make a new JSScript. The first - * does *not* call a non-null cx->runtime->newScriptHook -- only the second, - * NewScriptFromCG, calls this optional debugger hook. - * - * The NewScript function can't know whether the script it creates belongs - * to a function, or is top-level or eval code, but the debugger wants access - * to the newly made script's function, if any -- so callers of NewScript - * are responsible for notifying the debugger after successfully creating any - * kind (function or other) of new JSScript. - */ - static JSScript *NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natoms, - uint32 nobjects, uint32 nupvars, uint32 nregexps, - uint32 ntrynotes, uint32 nconsts, uint32 nglobals, - uint16 nClosedArgs, uint16 nClosedVars, JSVersion version); - - static JSScript *NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg); - - /* FIXME: bug 586181 */ - JSCList links; /* Links for compartment script list */ - jsbytecode *code; /* bytecodes and their immediate operands */ - uint32 length; /* length of code vector */ - - private: - uint16 version; /* JS version under which script was compiled */ - - size_t callCount_; /* Number of times the script has been called. */ - - public: - uint16 nfixed; /* number of slots besides stack operands in - slot array */ - - /* - * Offsets to various array structures from the end of this script, or - * JSScript::INVALID_OFFSET if the array has length 0. - */ - uint8 objectsOffset; /* offset to the array of nested function, - block, scope, xml and one-time regexps - objects */ - uint8 upvarsOffset; /* offset of the array of display ("up") - closure vars */ - uint8 regexpsOffset; /* offset to the array of to-be-cloned - regexps */ - uint8 trynotesOffset; /* offset to the array of try notes */ - uint8 globalsOffset; /* offset to the array of global slots */ - uint8 constOffset; /* offset to the array of constants */ - - bool noScriptRval:1; /* no need for result value of last - expression statement */ - bool savedCallerFun:1; /* object 0 is caller function */ - bool hasSharps:1; /* script uses sharp variables */ - bool strictModeCode:1; /* code is in strict mode */ - bool compileAndGo:1; /* script was compiled with TCF_COMPILE_N_GO */ - bool usesEval:1; /* script uses eval() */ - bool usesArguments:1; /* script uses arguments */ - bool warnedAboutTwoArgumentEval:1; /* have warned about use of - obsolete eval(s, o) in - this script */ - bool hasSingletons:1; /* script has singleton objects */ -#ifdef JS_METHODJIT - bool debugMode:1; /* script was compiled in debug mode */ - bool singleStepMode:1; /* compile script in single-step mode */ -#endif - - jsbytecode *main; /* main entry point, after predef'ing prolog */ - JSAtomMap atomMap; /* maps immediate index to literal struct */ - JSCompartment *compartment; /* compartment the script was compiled for */ - const char *filename; /* source filename or null */ - uint32 lineno; /* base line number of script */ - uint16 nslots; /* vars plus maximum stack depth */ - uint16 staticLevel;/* static level for display maintenance */ - uint16 nClosedArgs; /* number of args which are closed over. */ - uint16 nClosedVars; /* number of vars which are closed over. */ - js::Bindings bindings; /* names of top-level variables in this script - (and arguments if this is a function script) */ - JSPrincipals *principals;/* principals for this script */ - union { - /* - * A script object of class js_ScriptClass, to ensure the script is GC'd. - * - All scripts returned by JSAPI functions (JS_CompileScript, - * JS_CompileFile, etc.) have these objects. - * - Function scripts never have script objects; such scripts are owned - * by their function objects. - * - Temporary scripts created by obj_eval, JS_EvaluateScript, and - * similar functions never have these objects; such scripts are - * explicitly destroyed by the code that created them. - * Debugging API functions (JSDebugHooks::newScriptHook; - * JS_GetFunctionScript) may reveal sans-script-object Function and - * temporary scripts to clients, but clients must never call - * JS_NewScriptObject on such scripts: doing so would double-free them, - * once from the explicit call to js_DestroyScript, and once when the - * script object is garbage collected. - */ - JSObject *object; - JSScript *nextToGC; /* next to GC in rt->scriptsToGC list */ - } u; - -#ifdef CHECK_SCRIPT_OWNER - JSThread *owner; /* for thread-safe life-cycle assertions */ -#endif - - uint32 *closedSlots; /* vector of closed slots; args first, then vars. */ - - public: -#ifdef JS_METHODJIT - // Fast-cached pointers to make calls faster. These are also used to - // quickly test whether there is JIT code; a NULL value means no - // compilation has been attempted. A JS_UNJITTABLE_SCRIPT value means - // compilation failed. Any value is the arity-check entry point. - void *jitArityCheckNormal; - void *jitArityCheckCtor; - - js::mjit::JITScript *jitNormal; /* Extra JIT info for normal scripts */ - js::mjit::JITScript *jitCtor; /* Extra JIT info for constructors */ - - bool hasJITCode() { - return jitNormal || jitCtor; - } - - // These methods are implemented in MethodJIT.h. - inline void **nativeMap(bool constructing); - inline void *maybeNativeCodeForPC(bool constructing, jsbytecode *pc); - inline void *nativeCodeForPC(bool constructing, jsbytecode *pc); - - js::mjit::JITScript *getJIT(bool constructing) { - return constructing ? jitCtor : jitNormal; - } - - size_t callCount() const { return callCount_; } - size_t incCallCount() { return ++callCount_; } - - JITScriptStatus getJITStatus(bool constructing) { - void *addr = constructing ? jitArityCheckCtor : jitArityCheckNormal; - if (addr == NULL) - return JITScript_None; - if (addr == JS_UNJITTABLE_SCRIPT) - return JITScript_Invalid; - return JITScript_Valid; - } -#endif - - /* Script notes are allocated right after the code. */ - jssrcnote *notes() { return (jssrcnote *)(code + length); } - - static const uint8 INVALID_OFFSET = 0xFF; - static bool isValidOffset(uint8 offset) { return offset != INVALID_OFFSET; } - - JSObjectArray *objects() { - JS_ASSERT(isValidOffset(objectsOffset)); - return (JSObjectArray *)((uint8 *) (this + 1) + objectsOffset); - } - - JSUpvarArray *upvars() { - JS_ASSERT(isValidOffset(upvarsOffset)); - return (JSUpvarArray *) ((uint8 *) (this + 1) + upvarsOffset); - } - - JSObjectArray *regexps() { - JS_ASSERT(isValidOffset(regexpsOffset)); - return (JSObjectArray *) ((uint8 *) (this + 1) + regexpsOffset); - } - - JSTryNoteArray *trynotes() { - JS_ASSERT(isValidOffset(trynotesOffset)); - return (JSTryNoteArray *) ((uint8 *) (this + 1) + trynotesOffset); - } - - js::GlobalSlotArray *globals() { - JS_ASSERT(isValidOffset(globalsOffset)); - return (js::GlobalSlotArray *) ((uint8 *) (this + 1) + globalsOffset); - } - - JSConstArray *consts() { - JS_ASSERT(isValidOffset(constOffset)); - return (JSConstArray *) ((uint8 *) (this + 1) + constOffset); - } - - JSAtom *getAtom(size_t index) { - JS_ASSERT(index < atomMap.length); - return atomMap.vector[index]; - } - - JSObject *getObject(size_t index) { - JSObjectArray *arr = objects(); - JS_ASSERT(index < arr->length); - return arr->vector[index]; - } - - uint32 getGlobalSlot(size_t index) { - js::GlobalSlotArray *arr = globals(); - JS_ASSERT(index < arr->length); - return arr->vector[index].slot; - } - - JSAtom *getGlobalAtom(size_t index) { - js::GlobalSlotArray *arr = globals(); - JS_ASSERT(index < arr->length); - return getAtom(arr->vector[index].atomIndex); - } - - JSVersion getVersion() const { - return JSVersion(version); - } - - inline JSFunction *getFunction(size_t index); - - inline JSObject *getRegExp(size_t index); - - const js::Value &getConst(size_t index) { - JSConstArray *arr = consts(); - JS_ASSERT(index < arr->length); - return arr->vector[index]; - } - - /* - * The isEmpty method tells whether this script has code that computes any - * result (not return value, result AKA normal completion value) other than - * JSVAL_VOID, or any other effects. - */ - inline bool isEmpty() const; - - uint32 getClosedArg(uint32 index) { - JS_ASSERT(index < nClosedArgs); - return closedSlots[index]; - } - - uint32 getClosedVar(uint32 index) { - JS_ASSERT(index < nClosedVars); - return closedSlots[nClosedArgs + index]; - } - - void copyClosedSlotsTo(JSScript *other); -}; - -#define SHARP_NSLOTS 2 /* [#array, #depth] slots if the script - uses sharp variables */ - -static JS_INLINE uintN -StackDepth(JSScript *script) -{ - return script->nslots - script->nfixed; -} - -/* - * If pc_ does not point within script_'s bytecode, then it must point into an - * imacro body, so we use cx->runtime common atoms instead of script_'s atoms. - * This macro uses cx from its callers' environments in the pc-in-imacro case. - */ -#define JS_GET_SCRIPT_ATOM(script_, pc_, index, atom) \ - JS_BEGIN_MACRO \ - if ((pc_) < (script_)->code || \ - (script_)->code + (script_)->length <= (pc_)) { \ - JS_ASSERT((size_t)(index) < js_common_atom_count); \ - (atom) = COMMON_ATOMS_START(&cx->runtime->atomState)[index]; \ - } else { \ - (atom) = script_->getAtom(index); \ - } \ - JS_END_MACRO - -extern JS_FRIEND_DATA(js::Class) js_ScriptClass; - -extern JSObject * -js_InitScriptClass(JSContext *cx, JSObject *obj); - -/* - * On first new context in rt, initialize script runtime state, specifically - * the script filename table and its lock. - */ -extern JSBool -js_InitRuntimeScriptState(JSRuntime *rt); - -/* - * On JS_DestroyRuntime(rt), forcibly free script filename prefixes and any - * script filename table entries that have not been GC'd. - * - * This allows script filename prefixes to outlive any context in rt. - */ -extern void -js_FreeRuntimeScriptState(JSRuntime *rt); - -extern const char * -js_SaveScriptFilename(JSContext *cx, const char *filename); - -extern const char * -js_SaveScriptFilenameRT(JSRuntime *rt, const char *filename, uint32 flags); - -extern uint32 -js_GetScriptFilenameFlags(const char *filename); - -extern void -js_MarkScriptFilename(const char *filename); - -extern void -js_MarkScriptFilenames(JSRuntime *rt); - -extern void -js_SweepScriptFilenames(JSRuntime *rt); - -/* - * New-script-hook calling is factored from js_NewScriptFromCG so that it - * and callers of js_XDRScript can share this code. In the case of callers - * of js_XDRScript, the hook should be invoked only after successful decode - * of any owning function (the fun parameter) or script object (null fun). - */ -extern JS_FRIEND_API(void) -js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun); - -extern void -js_CallDestroyScriptHook(JSContext *cx, JSScript *script); - -/* - * The function must be used only outside the GC for a script that was run - * only on the current thread. - */ -extern void -js_DestroyScript(JSContext *cx, JSScript *script); - -extern void -js_DestroyScriptFromGC(JSContext *cx, JSScript *script); - -/* - * Script objects may be cached and reused, in which case their JSD-visible - * lifetimes may be shorter than their actual lifetimes. Destroy one such - * script for real as part of a GC pass. From JSD's point of view, the script - * is already dead. - */ -extern void -js_DestroyCachedScript(JSContext *cx, JSScript *script); - -extern void -js_TraceScript(JSTracer *trc, JSScript *script); - -extern JSBool -js_NewScriptObject(JSContext *cx, JSScript *script); - -/* - * To perturb as little code as possible, we introduce a js_GetSrcNote lookup - * cache without adding an explicit cx parameter. Thus js_GetSrcNote becomes - * a macro that uses cx from its calls' lexical environments. - */ -#define js_GetSrcNote(script,pc) js_GetSrcNoteCached(cx, script, pc) - -extern jssrcnote * -js_GetSrcNoteCached(JSContext *cx, JSScript *script, jsbytecode *pc); - -/* - * NOTE: use js_FramePCToLineNumber(cx, fp) when you have an active fp, in - * preference to js_PCToLineNumber (cx, fp->script fp->regs->pc), because - * fp->imacpc may be non-null, indicating an active imacro. - */ -extern uintN -js_FramePCToLineNumber(JSContext *cx, JSStackFrame *fp); - -extern uintN -js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc); - -extern jsbytecode * -js_LineNumberToPC(JSScript *script, uintN lineno); - -extern JS_FRIEND_API(uintN) -js_GetScriptLineExtent(JSScript *script); - -static JS_INLINE JSOp -js_GetOpcode(JSContext *cx, JSScript *script, jsbytecode *pc) -{ - JSOp op = (JSOp) *pc; - if (op == JSOP_TRAP) - op = JS_GetTrapOpcode(cx, script, pc); - return op; -} - -extern JSScript * -js_CloneScript(JSContext *cx, JSScript *script); - -/* - * If magic is non-null, js_XDRScript succeeds on magic number mismatch but - * returns false in *magic; it reflects a match via a true *magic out param. - * If magic is null, js_XDRScript returns false on bad magic number errors, - * which it reports. - * - * NB: after a successful JSXDR_DECODE, js_XDRScript callers must do any - * required subsequent set-up of owning function or script object and then call - * js_CallNewScriptHook. - */ -extern JSBool -js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *hasMagic); - -#endif /* jsscript_h___ */ diff --git a/x86/mozilla/include/jsscriptinlines.h b/x86/mozilla/include/jsscriptinlines.h deleted file mode 100644 index fb99164..0000000 --- a/x86/mozilla/include/jsscriptinlines.h +++ /dev/null @@ -1,131 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=79 ft=cpp: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is SpiderMonkey JavaScript engine. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Jason Orendorff - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsscriptinlines_h___ -#define jsscriptinlines_h___ - -#include "jscntxt.h" -#include "jsfun.h" -#include "jsopcode.h" -#include "jsregexp.h" -#include "jsscript.h" -#include "jsscope.h" - -namespace js { - -inline -Bindings::Bindings(JSContext *cx) - : lastBinding(cx->compartment->emptyCallShape), nargs(0), nvars(0), nupvars(0) -{ -} - -inline void -Bindings::transfer(JSContext *cx, Bindings *bindings) -{ - JS_ASSERT(lastBinding == cx->compartment->emptyCallShape); - - *this = *bindings; -#ifdef DEBUG - bindings->lastBinding = NULL; -#endif - - /* Preserve back-pointer invariants across the lastBinding transfer. */ - if (lastBinding->inDictionary()) - lastBinding->listp = &this->lastBinding; -} - -inline void -Bindings::clone(JSContext *cx, Bindings *bindings) -{ - JS_ASSERT(lastBinding == cx->compartment->emptyCallShape); - - /* - * Non-dictionary bindings are fine to share, as are dictionary bindings if - * they're copy-on-modification. - */ - JS_ASSERT(!bindings->lastBinding->inDictionary() || bindings->lastBinding->frozen()); - - *this = *bindings; -} - -const Shape * -Bindings::lastShape() const -{ - JS_ASSERT(lastBinding); - JS_ASSERT_IF(lastBinding->inDictionary(), lastBinding->frozen()); - return lastBinding; -} - -} // namespace js - -inline JSFunction * -JSScript::getFunction(size_t index) -{ - JSObject *funobj = getObject(index); - JS_ASSERT(funobj->isFunction()); - JS_ASSERT(funobj == (JSObject *) funobj->getPrivate()); - JSFunction *fun = (JSFunction *) funobj; - JS_ASSERT(FUN_INTERPRETED(fun)); - return fun; -} - -inline JSObject * -JSScript::getRegExp(size_t index) -{ - JSObjectArray *arr = regexps(); - JS_ASSERT((uint32) index < arr->length); - JSObject *obj = arr->vector[index]; - JS_ASSERT(obj->getClass() == &js_RegExpClass); - return obj; -} - -inline bool -JSScript::isEmpty() const -{ - if (length > 3) - return false; - - jsbytecode *pc = code; - if (noScriptRval && JSOp(*pc) == JSOP_FALSE) - ++pc; - return JSOp(*pc) == JSOP_STOP; -} - -#endif /* jsscriptinlines_h___ */ diff --git a/x86/mozilla/include/jsstaticcheck.h b/x86/mozilla/include/jsstaticcheck.h deleted file mode 100644 index c605d2f..0000000 --- a/x86/mozilla/include/jsstaticcheck.h +++ /dev/null @@ -1,125 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsstaticcheck_h___ -#define jsstaticcheck_h___ - -#ifdef NS_STATIC_CHECKING -/* - * Trigger a control flow check to make sure that code flows through label - */ -inline __attribute__ ((unused)) void MUST_FLOW_THROUGH(const char *label) { -} - -/* avoid unused goto-label warnings */ -#define MUST_FLOW_LABEL(label) goto label; label: - -inline JS_FORCES_STACK void VOUCH_DOES_NOT_REQUIRE_STACK() {} - -inline JS_FORCES_STACK void -JS_ASSERT_NOT_ON_TRACE(JSContext *cx) -{ - JS_ASSERT(!JS_ON_TRACE(cx)); -} - -#else -#define MUST_FLOW_THROUGH(label) ((void) 0) -#define MUST_FLOW_LABEL(label) -#define VOUCH_DOES_NOT_REQUIRE_STACK() ((void) 0) -#define JS_ASSERT_NOT_ON_TRACE(cx) JS_ASSERT(!JS_ON_TRACE(cx)) -#endif -#define VOUCH_HAVE_STACK VOUCH_DOES_NOT_REQUIRE_STACK - -/* sixgill annotation defines */ - -/* Avoid name collision if included with other headers defining annotations. */ -#ifndef HAVE_STATIC_ANNOTATIONS -#define HAVE_STATIC_ANNOTATIONS - -#ifdef XGILL_PLUGIN - -#define STATIC_PRECONDITION(COND) __attribute__((precondition(#COND))) -#define STATIC_PRECONDITION_ASSUME(COND) __attribute__((precondition_assume(#COND))) -#define STATIC_POSTCONDITION(COND) __attribute__((postcondition(#COND))) -#define STATIC_POSTCONDITION_ASSUME(COND) __attribute__((postcondition_assume(#COND))) -#define STATIC_INVARIANT(COND) __attribute__((invariant(#COND))) -#define STATIC_INVARIANT_ASSUME(COND) __attribute__((invariant_assume(#COND))) - -/* Used to make identifiers for assert/assume annotations in a function. */ -#define STATIC_PASTE2(X,Y) X ## Y -#define STATIC_PASTE1(X,Y) STATIC_PASTE2(X,Y) - -#define STATIC_ASSERT(COND) \ - JS_BEGIN_MACRO \ - __attribute__((assert_static(#COND), unused)) \ - int STATIC_PASTE1(assert_static_, __COUNTER__); \ - JS_END_MACRO - -#define STATIC_ASSUME(COND) \ - JS_BEGIN_MACRO \ - __attribute__((assume_static(#COND), unused)) \ - int STATIC_PASTE1(assume_static_, __COUNTER__); \ - JS_END_MACRO - -#define STATIC_ASSERT_RUNTIME(COND) \ - JS_BEGIN_MACRO \ - __attribute__((assert_static_runtime(#COND), unused)) \ - int STATIC_PASTE1(assert_static_runtime_, __COUNTER__); \ - JS_END_MACRO - -#else /* XGILL_PLUGIN */ - -#define STATIC_PRECONDITION(COND) /* nothing */ -#define STATIC_PRECONDITION_ASSUME(COND) /* nothing */ -#define STATIC_POSTCONDITION(COND) /* nothing */ -#define STATIC_POSTCONDITION_ASSUME(COND) /* nothing */ -#define STATIC_INVARIANT(COND) /* nothing */ -#define STATIC_INVARIANT_ASSUME(COND) /* nothing */ - -#define STATIC_ASSERT(COND) JS_BEGIN_MACRO /* nothing */ JS_END_MACRO -#define STATIC_ASSUME(COND) JS_BEGIN_MACRO /* nothing */ JS_END_MACRO -#define STATIC_ASSERT_RUNTIME(COND) JS_BEGIN_MACRO /* nothing */ JS_END_MACRO - -#endif /* XGILL_PLUGIN */ - -#define STATIC_SKIP_INFERENCE STATIC_INVARIANT(skip_inference()) - -#endif /* HAVE_STATIC_ANNOTATIONS */ - -#endif /* jsstaticcheck_h___ */ diff --git a/x86/mozilla/include/jsstdint.h b/x86/mozilla/include/jsstdint.h deleted file mode 100644 index 446a873..0000000 --- a/x86/mozilla/include/jsstdint.h +++ /dev/null @@ -1,122 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=78: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Jim Blandy - * Portions created by the Initial Developer are Copyright (C) 2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * This header provides definitions for the types we use, - * even on systems that lack . - * - * NOTE: This header should only be included in private SpiderMonkey - * code; public headers should use only the JS{Int,Uint}N types; see - * the comment for them in "jsinttypes.h". - * - * At the moment, these types are not widely used within SpiderMonkey; - * this file is meant to make existing uses portable, and to allow us - * to transition portably to using them more, if desired. - */ - -#ifndef jsstdint_h___ -#define jsstdint_h___ - -#include "jsinttypes.h" - -/* If we have a working stdint.h, then jsinttypes.h has already - defined the standard integer types. Otherwise, define the standard - names in terms of the 'JS' types. */ -#if ! defined(JS_HAVE_STDINT_H) && \ - ! defined(JS_SYS_TYPES_H_DEFINES_EXACT_SIZE_TYPES) - -typedef JSInt8 int8_t; -typedef JSInt16 int16_t; -typedef JSInt32 int32_t; -typedef JSInt64 int64_t; - -typedef JSUint8 uint8_t; -typedef JSUint16 uint16_t; -typedef JSUint32 uint32_t; -typedef JSUint64 uint64_t; - -/* Suppress other, conflicting attempts to define stdint-bits. */ -#define _STDINT_H - -/* If JS_STDDEF_H_HAS_INTPTR_T or JS_CRTDEFS_H_HAS_INTPTR_T are - defined, then jsinttypes.h included the given header, which - introduced definitions for intptr_t and uintptr_t. Otherwise, - define the standard names in terms of the 'JS' types. */ -#if !defined(JS_STDDEF_H_HAS_INTPTR_T) && !defined(JS_CRTDEFS_H_HAS_INTPTR_T) -typedef JSIntPtr intptr_t; -typedef JSUintPtr uintptr_t; -#endif - -#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) - -#define INT8_MAX 127 -#define INT8_MIN (-INT8_MAX - 1) -#define INT16_MAX 32767 -#define INT16_MIN (-INT16_MAX - 1) -#define INT32_MAX 2147483647 -#define INT32_MIN (-INT32_MAX - 1) -#define INT64_MAX 9223372036854775807LL -#define INT64_MIN (-INT64_MAX - 1) - -#define UINT8_MAX 255 -#define UINT16_MAX 65535 -#define UINT32_MAX 4294967295U -#define UINT64_MAX 18446744073709551615ULL - -/* - * These are technically wrong as they can't be used in the preprocessor, but - * we would require compiler assistance, and at the moment we don't need - * preprocessor-correctness. - */ -#ifdef _MSC_VER -#undef SIZE_MAX -#endif - -#define INTPTR_MAX ((intptr_t) (UINTPTR_MAX >> 1)) -#define INTPTR_MIN (intptr_t(uintptr_t(INTPTR_MAX) + uintptr_t(1))) -#define UINTPTR_MAX ((uintptr_t) -1) -#define SIZE_MAX UINTPTR_MAX -#define PTRDIFF_MAX INTPTR_MAX -#define PTRDIFF_MIN INTPTR_MIN - -#endif /* !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) */ - -#endif /* JS_HAVE_STDINT_H */ - -#endif /* jsstdint_h___ */ diff --git a/x86/mozilla/include/jsstr.h b/x86/mozilla/include/jsstr.h deleted file mode 100644 index 275f989..0000000 --- a/x86/mozilla/include/jsstr.h +++ /dev/null @@ -1,1077 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsstr_h___ -#define jsstr_h___ -/* - * JS string type implementation. - * - * A JS string is a counted array of unicode characters. To support handoff - * of API client memory, the chars are allocated separately from the length, - * necessitating a pointer after the count, to form a separately allocated - * string descriptor. String descriptors are GC'ed, while their chars are - * allocated from the malloc heap. - */ -#include -#include "jsapi.h" -#include "jsprvtd.h" -#include "jshashtable.h" -#include "jslock.h" -#include "jsobj.h" -#include "jsvalue.h" -#include "jscell.h" - -enum { - UNIT_STRING_LIMIT = 256U, - SMALL_CHAR_LIMIT = 128U, /* Bigger chars cannot be in a length-2 string. */ - NUM_SMALL_CHARS = 64U, - INT_STRING_LIMIT = 256U, - NUM_HUNDRED_STRINGS = 156U -}; - -extern jschar * -js_GetDependentStringChars(JSString *str); - -extern JSString * JS_FASTCALL -js_ConcatStrings(JSContext *cx, JSString *left, JSString *right); - -JS_STATIC_ASSERT(JS_BITS_PER_WORD >= 32); - -struct JSRopeBufferInfo { - /* Number of jschars we can hold, not including null terminator. */ - size_t capacity; -}; - -/* Forward declaration for friending. */ -namespace js { namespace mjit { - class Compiler; -}} - -struct JSLinearString; - -/* - * The GC-thing "string" type. - * - * In FLAT strings, the mChars field points to a flat character array owned by - * its GC-thing descriptor. The array is terminated at index length by a zero - * character and the size of the array in bytes is - * (length + 1) * sizeof(jschar). The terminator is purely a backstop, in case - * the chars pointer flows out to native code that requires \u0000 termination. - * - * A flat string with the ATOMIZED flag means that the string is hashed as - * an atom. This flag is used to avoid re-hashing the already-atomized string. - * - * A flat string with the EXTENSIBLE flag means that the string may change into - * a dependent string as part of an optimization with js_ConcatStrings: - * extending |str1 = "abc"| with the character |str2 = str1 + "d"| will place - * "d" in the extra capacity from |str1|, make that the buffer for |str2|, and - * turn |str1| into a dependent string of |str2|. - * - * Flat strings without the EXTENSIBLE flag can be safely accessed by multiple - * threads. - * - * When the string is DEPENDENT, the string depends on characters of another - * string strongly referenced by the base field. The base member may point to - * another dependent string if chars() has not been called yet. - * - * When a string is a ROPE, it represents the lazy concatenation of other - * strings. In general, the nodes reachable from any rope form a dag. - * - * To allow static type-based checking that a given JSString* always points - * to a flat or non-rope string, the JSFlatString and JSLinearString types may - * be used. Instead of casting, callers should use ensureX() and assertIsX(). - */ -struct JSString -{ - friend class js::TraceRecorder; - friend class js::mjit::Compiler; - - friend JSAtom *js_AtomizeString(JSContext *cx, JSString *str, uintN flags); - - /* - * Not private because we want to be able to use static initializers for - * them. Don't use these directly! FIXME bug 614459. - */ - size_t lengthAndFlags; /* in all strings */ - union { - const jschar *chars; /* in non-rope strings */ - JSString *left; /* in rope strings */ - } u; - union { - jschar inlineStorage[4]; /* in short strings */ - struct { - union { - JSString *right; /* in rope strings */ - JSString *base; /* in dependent strings */ - size_t capacity; /* in extensible flat strings */ - }; - union { - JSString *parent; /* temporarily used during flatten */ - size_t reserved; /* may use for bug 615290 */ - }; - } s; - size_t externalStringType; /* in external strings */ - }; - - /* - * The lengthAndFlags field in string headers has data arranged in the - * following way: - * - * [ length (bits 4-31) ][ flags (bits 2-3) ][ type (bits 0-1) ] - * - * The length is packed in lengthAndFlags, even in string types that don't - * need 3 other fields, to make the length check simpler. - * - * When the string type is FLAT, the flags can contain ATOMIZED or - * EXTENSIBLE. - */ - static const size_t TYPE_FLAGS_MASK = JS_BITMASK(4); - static const size_t LENGTH_SHIFT = 4; - - static const size_t TYPE_MASK = JS_BITMASK(2); - static const size_t FLAT = 0x0; - static const size_t DEPENDENT = 0x1; - static const size_t ROPE = 0x2; - - /* Allow checking 1 bit for dependent/rope strings. */ - static const size_t DEPENDENT_BIT = JS_BIT(0); - static const size_t ROPE_BIT = JS_BIT(1); - - static const size_t ATOMIZED = JS_BIT(2); - static const size_t EXTENSIBLE = JS_BIT(3); - - - size_t buildLengthAndFlags(size_t length, size_t flags) { - return (length << LENGTH_SHIFT) | flags; - } - - inline js::gc::Cell *asCell() { - return reinterpret_cast(this); - } - - inline js::gc::FreeCell *asFreeCell() { - return reinterpret_cast(this); - } - - /* - * Generous but sane length bound; the "-1" is there for comptibility with - * OOM tests. - */ - static const size_t MAX_LENGTH = (1 << 28) - 1; - - JS_ALWAYS_INLINE bool isDependent() const { - return lengthAndFlags & DEPENDENT_BIT; - } - - JS_ALWAYS_INLINE bool isFlat() const { - return (lengthAndFlags & TYPE_MASK) == FLAT; - } - - JS_ALWAYS_INLINE bool isExtensible() const { - JS_ASSERT_IF(lengthAndFlags & EXTENSIBLE, isFlat()); - return lengthAndFlags & EXTENSIBLE; - } - - JS_ALWAYS_INLINE bool isAtomized() const { - JS_ASSERT_IF(lengthAndFlags & ATOMIZED, isFlat()); - return lengthAndFlags & ATOMIZED; - } - - JS_ALWAYS_INLINE bool isRope() const { - return lengthAndFlags & ROPE_BIT; - } - - JS_ALWAYS_INLINE size_t length() const { - return lengthAndFlags >> LENGTH_SHIFT; - } - - JS_ALWAYS_INLINE bool empty() const { - return lengthAndFlags <= TYPE_FLAGS_MASK; - } - - /* This can fail by returning null and reporting an error on cx. */ - JS_ALWAYS_INLINE const jschar *getChars(JSContext *cx) { - if (isRope()) - return flatten(cx); - return nonRopeChars(); - } - - /* This can fail by returning null and reporting an error on cx. */ - JS_ALWAYS_INLINE const jschar *getCharsZ(JSContext *cx) { - if (!isFlat()) - return undepend(cx); - return flatChars(); - } - - JS_ALWAYS_INLINE void initFlatNotTerminated(jschar *chars, size_t length) { - JS_ASSERT(length <= MAX_LENGTH); - JS_ASSERT(!isStatic(this)); - lengthAndFlags = buildLengthAndFlags(length, FLAT); - u.chars = chars; - } - - /* Specific flat string initializer and accessor methods. */ - JS_ALWAYS_INLINE void initFlat(jschar *chars, size_t length) { - initFlatNotTerminated(chars, length); - JS_ASSERT(chars[length] == jschar(0)); - } - - JS_ALWAYS_INLINE void initShortString(const jschar *chars, size_t length) { - JS_ASSERT(length <= MAX_LENGTH); - JS_ASSERT(chars >= inlineStorage && chars < (jschar *)(this + 2)); - JS_ASSERT(!isStatic(this)); - lengthAndFlags = buildLengthAndFlags(length, FLAT); - u.chars = chars; - } - - JS_ALWAYS_INLINE void initFlatExtensible(jschar *chars, size_t length, size_t cap) { - JS_ASSERT(length <= MAX_LENGTH); - JS_ASSERT(chars[length] == jschar(0)); - JS_ASSERT(!isStatic(this)); - lengthAndFlags = buildLengthAndFlags(length, FLAT | EXTENSIBLE); - u.chars = chars; - s.capacity = cap; - } - - JS_ALWAYS_INLINE JSFlatString *assertIsFlat() { - JS_ASSERT(isFlat()); - return reinterpret_cast(this); - } - - JS_ALWAYS_INLINE const jschar *flatChars() const { - JS_ASSERT(isFlat()); - return u.chars; - } - - JS_ALWAYS_INLINE size_t flatLength() const { - JS_ASSERT(isFlat()); - return length(); - } - - inline void flatSetAtomized() { - JS_ASSERT(isFlat()); - JS_ASSERT(!isStatic(this)); - lengthAndFlags |= ATOMIZED; - } - - inline void flatClearExtensible() { - /* - * N.B. This may be called on static strings, which may be in read-only - * memory, so we cannot unconditionally apply the mask. - */ - JS_ASSERT(isFlat()); - if (lengthAndFlags & EXTENSIBLE) - lengthAndFlags &= ~EXTENSIBLE; - } - - /* - * The chars pointer should point somewhere inside the buffer owned by base. - * The caller still needs to pass base for GC purposes. - */ - inline void initDependent(JSString *base, const jschar *chars, size_t length) { - JS_ASSERT(!isStatic(this)); - JS_ASSERT(base->isFlat()); - JS_ASSERT(chars >= base->flatChars() && chars < base->flatChars() + base->length()); - JS_ASSERT(length <= base->length() - (chars - base->flatChars())); - lengthAndFlags = buildLengthAndFlags(length, DEPENDENT); - u.chars = chars; - s.base = base; - } - - inline JSLinearString *dependentBase() const { - JS_ASSERT(isDependent()); - return s.base->assertIsLinear(); - } - - JS_ALWAYS_INLINE const jschar *dependentChars() { - JS_ASSERT(isDependent()); - return u.chars; - } - - inline size_t dependentLength() const { - JS_ASSERT(isDependent()); - return length(); - } - - const jschar *undepend(JSContext *cx); - - const jschar *nonRopeChars() const { - JS_ASSERT(!isRope()); - return u.chars; - } - - /* Rope-related initializers and accessors. */ - inline void initRopeNode(JSString *left, JSString *right, size_t length) { - JS_ASSERT(left->length() + right->length() == length); - lengthAndFlags = buildLengthAndFlags(length, ROPE); - u.left = left; - s.right = right; - } - - inline JSString *ropeLeft() const { - JS_ASSERT(isRope()); - return u.left; - } - - inline JSString *ropeRight() const { - JS_ASSERT(isRope()); - return s.right; - } - - inline void finishTraversalConversion(JSString *base, const jschar *baseBegin, const jschar *end) { - JS_ASSERT(baseBegin <= u.chars && u.chars <= end); - lengthAndFlags = buildLengthAndFlags(end - u.chars, DEPENDENT); - s.base = base; - } - - const jschar *flatten(JSContext *maybecx); - - JSLinearString *ensureLinear(JSContext *cx) { - if (isRope() && !flatten(cx)) - return NULL; - return reinterpret_cast(this); - } - - bool isLinear() const { - return !isRope(); - } - - JSLinearString *assertIsLinear() { - JS_ASSERT(isLinear()); - return reinterpret_cast(this); - } - - typedef uint8 SmallChar; - - static inline bool fitsInSmallChar(jschar c) { - return c < SMALL_CHAR_LIMIT && toSmallChar[c] != INVALID_SMALL_CHAR; - } - - static inline bool isUnitString(void *ptr) { - jsuword delta = reinterpret_cast(ptr) - - reinterpret_cast(unitStringTable); - if (delta >= UNIT_STRING_LIMIT * sizeof(JSString)) - return false; - - /* If ptr points inside the static array, it must be well-aligned. */ - JS_ASSERT(delta % sizeof(JSString) == 0); - return true; - } - - static inline bool isLength2String(void *ptr) { - jsuword delta = reinterpret_cast(ptr) - - reinterpret_cast(length2StringTable); - if (delta >= NUM_SMALL_CHARS * NUM_SMALL_CHARS * sizeof(JSString)) - return false; - - /* If ptr points inside the static array, it must be well-aligned. */ - JS_ASSERT(delta % sizeof(JSString) == 0); - return true; - } - - static inline bool isHundredString(void *ptr) { - jsuword delta = reinterpret_cast(ptr) - - reinterpret_cast(hundredStringTable); - if (delta >= NUM_HUNDRED_STRINGS * sizeof(JSString)) - return false; - - /* If ptr points inside the static array, it must be well-aligned. */ - JS_ASSERT(delta % sizeof(JSString) == 0); - return true; - } - - static inline bool isStatic(void *ptr) { - return isUnitString(ptr) || isLength2String(ptr) || isHundredString(ptr); - } - -#ifdef __SUNPRO_CC -#pragma align 8 (__1cIJSStringPunitStringTable_, __1cIJSStringSlength2StringTable_, __1cIJSStringShundredStringTable_) -#endif - - static const SmallChar INVALID_SMALL_CHAR = -1; - - static const jschar fromSmallChar[]; - static const SmallChar toSmallChar[]; - static const JSString unitStringTable[]; - static const JSString length2StringTable[]; - static const JSString hundredStringTable[]; - /* - * Since int strings can be unit strings, length-2 strings, or hundred - * strings, we keep a table to map from integer to the correct string. - */ - static const JSString *const intStringTable[]; - - static JSFlatString *unitString(jschar c); - static JSLinearString *getUnitString(JSContext *cx, JSString *str, size_t index); - static JSFlatString *length2String(jschar c1, jschar c2); - static JSFlatString *length2String(uint32 i); - static JSFlatString *intString(jsint i); - - static JSFlatString *lookupStaticString(const jschar *chars, size_t length); - - JS_ALWAYS_INLINE void finalize(JSContext *cx); - - static size_t offsetOfLengthAndFlags() { - return offsetof(JSString, lengthAndFlags); - } - - static size_t offsetOfChars() { - return offsetof(JSString, u.chars); - } - - static void staticAsserts() { - JS_STATIC_ASSERT(((JSString::MAX_LENGTH << JSString::LENGTH_SHIFT) >> - JSString::LENGTH_SHIFT) == JSString::MAX_LENGTH); - } -}; - -/* - * A "linear" string may or may not be null-terminated, but it provides - * infallible access to a linear array of characters. Namely, this means the - * string is not a rope. - */ -struct JSLinearString : JSString -{ - const jschar *chars() const { return JSString::nonRopeChars(); } -}; - -JS_STATIC_ASSERT(sizeof(JSLinearString) == sizeof(JSString)); - -/* - * A linear string where, additionally, chars()[length()] == '\0'. Namely, this - * means the string is not a dependent string or rope. - */ -struct JSFlatString : JSLinearString -{ - const jschar *charsZ() const { return chars(); } -}; - -JS_STATIC_ASSERT(sizeof(JSFlatString) == sizeof(JSString)); - -/* - * A flat string which has been "atomized", i.e., that is a unique string among - * other atomized strings and therefore allows equality via pointer comparison. - */ -struct JSAtom : JSFlatString -{ -}; - -struct JSExternalString : JSString -{ - static const uintN TYPE_LIMIT = 8; - static JSStringFinalizeOp str_finalizers[TYPE_LIMIT]; - - static intN changeFinalizer(JSStringFinalizeOp oldop, - JSStringFinalizeOp newop) { - for (uintN i = 0; i != JS_ARRAY_LENGTH(str_finalizers); i++) { - if (str_finalizers[i] == oldop) { - str_finalizers[i] = newop; - return intN(i); - } - } - return -1; - } - - void finalize(JSContext *cx); - void finalize(); -}; - -JS_STATIC_ASSERT(sizeof(JSString) == sizeof(JSExternalString)); - -/* - * Short strings should be created in cases where it's worthwhile to avoid - * mallocing the string buffer for a small string. We keep 2 string headers' - * worth of space in short strings so that more strings can be stored this way. - */ -class JSShortString : public js::gc::Cell -{ - JSString mHeader; - JSString mDummy; - - public: - /* - * Set the length of the string, and return a buffer for the caller to write - * to. This buffer must be written immediately, and should not be modified - * afterward. - */ - inline jschar *init(size_t length) { - JS_ASSERT(length <= MAX_SHORT_STRING_LENGTH); - mHeader.initShortString(mHeader.inlineStorage, length); - return mHeader.inlineStorage; - } - - inline jschar *getInlineStorageBeforeInit() { - return mHeader.inlineStorage; - } - - inline void initAtOffsetInBuffer(jschar *p, size_t length) { - JS_ASSERT(p >= mHeader.inlineStorage && p < mHeader.inlineStorage + MAX_SHORT_STRING_LENGTH); - mHeader.initShortString(p, length); - } - - inline void resetLength(size_t length) { - mHeader.initShortString(mHeader.flatChars(), length); - } - - inline JSString *header() { - return &mHeader; - } - - static const size_t FREE_STRING_WORDS = 2; - - static const size_t MAX_SHORT_STRING_LENGTH = - ((sizeof(JSString) + FREE_STRING_WORDS * sizeof(size_t)) / sizeof(jschar)) - 1; - - static inline bool fitsIntoShortString(size_t length) { - return length <= MAX_SHORT_STRING_LENGTH; - } - - JS_ALWAYS_INLINE void finalize(JSContext *cx); - - static void staticAsserts() { - JS_STATIC_ASSERT(offsetof(JSString, inlineStorage) == - sizeof(JSString) - JSShortString::FREE_STRING_WORDS * sizeof(void *)); - JS_STATIC_ASSERT(offsetof(JSShortString, mDummy) == sizeof(JSString)); - JS_STATIC_ASSERT(offsetof(JSString, inlineStorage) + - sizeof(jschar) * (JSShortString::MAX_SHORT_STRING_LENGTH + 1) == - sizeof(JSShortString)); - } -}; - -namespace js { - -class StringBuffer; - -/* - * When an algorithm does not need a string represented as a single linear - * array of characters, this range utility may be used to traverse the string a - * sequence of linear arrays of characters. This avoids flattening ropes. - * - * Implemented in jsstrinlines.h. - */ -class StringSegmentRange; -class MutatingRopeSegmentRange; - -/* - * Utility for building a rope (lazy concatenation) of strings. - */ -class RopeBuilder; - -} /* namespace js */ - -extern const jschar * -js_GetStringChars(JSContext *cx, JSString *str); - -extern const jschar * -js_UndependString(JSContext *cx, JSString *str); - -extern JSBool -js_MakeStringImmutable(JSContext *cx, JSString *str); - -extern JSString * JS_FASTCALL -js_toLowerCase(JSContext *cx, JSString *str); - -extern JSString * JS_FASTCALL -js_toUpperCase(JSContext *cx, JSString *str); - -struct JSSubString { - size_t length; - const jschar *chars; -}; - -extern jschar js_empty_ucstr[]; -extern JSSubString js_EmptySubString; - -/* Unicode character attribute lookup tables. */ -extern const uint8 js_X[]; -extern const uint8 js_Y[]; -extern const uint32 js_A[]; - -/* Enumerated Unicode general category types. */ -typedef enum JSCharType { - JSCT_UNASSIGNED = 0, - JSCT_UPPERCASE_LETTER = 1, - JSCT_LOWERCASE_LETTER = 2, - JSCT_TITLECASE_LETTER = 3, - JSCT_MODIFIER_LETTER = 4, - JSCT_OTHER_LETTER = 5, - JSCT_NON_SPACING_MARK = 6, - JSCT_ENCLOSING_MARK = 7, - JSCT_COMBINING_SPACING_MARK = 8, - JSCT_DECIMAL_DIGIT_NUMBER = 9, - JSCT_LETTER_NUMBER = 10, - JSCT_OTHER_NUMBER = 11, - JSCT_SPACE_SEPARATOR = 12, - JSCT_LINE_SEPARATOR = 13, - JSCT_PARAGRAPH_SEPARATOR = 14, - JSCT_CONTROL = 15, - JSCT_FORMAT = 16, - JSCT_PRIVATE_USE = 18, - JSCT_SURROGATE = 19, - JSCT_DASH_PUNCTUATION = 20, - JSCT_START_PUNCTUATION = 21, - JSCT_END_PUNCTUATION = 22, - JSCT_CONNECTOR_PUNCTUATION = 23, - JSCT_OTHER_PUNCTUATION = 24, - JSCT_MATH_SYMBOL = 25, - JSCT_CURRENCY_SYMBOL = 26, - JSCT_MODIFIER_SYMBOL = 27, - JSCT_OTHER_SYMBOL = 28 -} JSCharType; - -/* Character classifying and mapping macros, based on java.lang.Character. */ -#define JS_CCODE(c) (js_A[js_Y[(js_X[(uint16)(c)>>6]<<6)|((c)&0x3F)]]) -#define JS_CTYPE(c) (JS_CCODE(c) & 0x1F) - -#define JS_ISALPHA(c) ((((1 << JSCT_UPPERCASE_LETTER) | \ - (1 << JSCT_LOWERCASE_LETTER) | \ - (1 << JSCT_TITLECASE_LETTER) | \ - (1 << JSCT_MODIFIER_LETTER) | \ - (1 << JSCT_OTHER_LETTER)) \ - >> JS_CTYPE(c)) & 1) - -#define JS_ISALNUM(c) ((((1 << JSCT_UPPERCASE_LETTER) | \ - (1 << JSCT_LOWERCASE_LETTER) | \ - (1 << JSCT_TITLECASE_LETTER) | \ - (1 << JSCT_MODIFIER_LETTER) | \ - (1 << JSCT_OTHER_LETTER) | \ - (1 << JSCT_DECIMAL_DIGIT_NUMBER)) \ - >> JS_CTYPE(c)) & 1) - -/* A unicode letter, suitable for use in an identifier. */ -#define JS_ISLETTER(c) ((((1 << JSCT_UPPERCASE_LETTER) | \ - (1 << JSCT_LOWERCASE_LETTER) | \ - (1 << JSCT_TITLECASE_LETTER) | \ - (1 << JSCT_MODIFIER_LETTER) | \ - (1 << JSCT_OTHER_LETTER) | \ - (1 << JSCT_LETTER_NUMBER)) \ - >> JS_CTYPE(c)) & 1) - -/* - * 'IdentifierPart' from ECMA grammar, is Unicode letter or combining mark or - * digit or connector punctuation. - */ -#define JS_ISIDPART(c) ((((1 << JSCT_UPPERCASE_LETTER) | \ - (1 << JSCT_LOWERCASE_LETTER) | \ - (1 << JSCT_TITLECASE_LETTER) | \ - (1 << JSCT_MODIFIER_LETTER) | \ - (1 << JSCT_OTHER_LETTER) | \ - (1 << JSCT_LETTER_NUMBER) | \ - (1 << JSCT_NON_SPACING_MARK) | \ - (1 << JSCT_COMBINING_SPACING_MARK) | \ - (1 << JSCT_DECIMAL_DIGIT_NUMBER) | \ - (1 << JSCT_CONNECTOR_PUNCTUATION)) \ - >> JS_CTYPE(c)) & 1) - -/* Unicode control-format characters, ignored in input */ -#define JS_ISFORMAT(c) (((1 << JSCT_FORMAT) >> JS_CTYPE(c)) & 1) - -/* - * This table is used in JS_ISWORD. The definition has external linkage to - * allow the raw table data to be used in the regular expression compiler. - */ -extern const bool js_alnum[]; - -/* - * This macro performs testing for the regular expression word class \w, which - * is defined by ECMA-262 15.10.2.6 to be [0-9A-Z_a-z]. If we want a - * Unicode-friendlier definition of "word", we should rename this macro to - * something regexp-y. - */ -#define JS_ISWORD(c) ((c) < 128 && js_alnum[(c)]) - -#define JS_ISIDSTART(c) (JS_ISLETTER(c) || (c) == '_' || (c) == '$') -#define JS_ISIDENT(c) (JS_ISIDPART(c) || (c) == '_' || (c) == '$') - -#define JS_ISXMLSPACE(c) ((c) == ' ' || (c) == '\t' || (c) == '\r' || \ - (c) == '\n') -#define JS_ISXMLNSSTART(c) ((JS_CCODE(c) & 0x00000100) || (c) == '_') -#define JS_ISXMLNS(c) ((JS_CCODE(c) & 0x00000080) || (c) == '.' || \ - (c) == '-' || (c) == '_') -#define JS_ISXMLNAMESTART(c) (JS_ISXMLNSSTART(c) || (c) == ':') -#define JS_ISXMLNAME(c) (JS_ISXMLNS(c) || (c) == ':') - -#define JS_ISDIGIT(c) (JS_CTYPE(c) == JSCT_DECIMAL_DIGIT_NUMBER) - -const jschar BYTE_ORDER_MARK = 0xFEFF; -const jschar NO_BREAK_SPACE = 0x00A0; - -static inline bool -JS_ISSPACE(jschar c) -{ - unsigned w = c; - - if (w < 256) - return (w <= ' ' && (w == ' ' || (9 <= w && w <= 0xD))) || w == NO_BREAK_SPACE; - - return w == BYTE_ORDER_MARK || (JS_CCODE(w) & 0x00070000) == 0x00040000; -} - -#define JS_ISPRINT(c) ((c) < 128 && isprint(c)) - -#define JS_ISUPPER(c) (JS_CTYPE(c) == JSCT_UPPERCASE_LETTER) -#define JS_ISLOWER(c) (JS_CTYPE(c) == JSCT_LOWERCASE_LETTER) - -#define JS_TOUPPER(c) ((jschar) ((JS_CCODE(c) & 0x00100000) \ - ? (c) - ((int32)JS_CCODE(c) >> 22) \ - : (c))) -#define JS_TOLOWER(c) ((jschar) ((JS_CCODE(c) & 0x00200000) \ - ? (c) + ((int32)JS_CCODE(c) >> 22) \ - : (c))) - -/* - * Shorthands for ASCII (7-bit) decimal and hex conversion. - * Manually inline isdigit for performance; MSVC doesn't do this for us. - */ -#define JS7_ISDEC(c) ((((unsigned)(c)) - '0') <= 9) -#define JS7_UNDEC(c) ((c) - '0') -#define JS7_ISHEX(c) ((c) < 128 && isxdigit(c)) -#define JS7_UNHEX(c) (uintN)(JS7_ISDEC(c) ? (c) - '0' : 10 + tolower(c) - 'a') -#define JS7_ISLET(c) ((c) < 128 && isalpha(c)) - -/* Initialize the String class, returning its prototype object. */ -extern js::Class js_StringClass; - -inline bool -JSObject::isString() const -{ - return getClass() == &js_StringClass; -} - -extern JSObject * -js_InitStringClass(JSContext *cx, JSObject *obj); - -extern const char js_escape_str[]; -extern const char js_unescape_str[]; -extern const char js_uneval_str[]; -extern const char js_decodeURI_str[]; -extern const char js_encodeURI_str[]; -extern const char js_decodeURIComponent_str[]; -extern const char js_encodeURIComponent_str[]; - -/* GC-allocate a string descriptor for the given malloc-allocated chars. */ -extern JSFlatString * -js_NewString(JSContext *cx, jschar *chars, size_t length); - -extern JSLinearString * -js_NewDependentString(JSContext *cx, JSString *base, size_t start, - size_t length); - -/* Copy a counted string and GC-allocate a descriptor for it. */ -extern JSFlatString * -js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n); - -extern JSFlatString * -js_NewStringCopyN(JSContext *cx, const char *s, size_t n); - -/* Copy a C string and GC-allocate a descriptor for it. */ -extern JSFlatString * -js_NewStringCopyZ(JSContext *cx, const jschar *s); - -extern JSFlatString * -js_NewStringCopyZ(JSContext *cx, const char *s); - -/* - * Convert a value to a printable C string. - */ -extern const char * -js_ValueToPrintable(JSContext *cx, const js::Value &, - JSAutoByteString *bytes, bool asSource = false); - -/* - * Convert a value to a string, returning null after reporting an error, - * otherwise returning a new string reference. - */ -extern JSString * -js_ValueToString(JSContext *cx, const js::Value &v); - -namespace js { - -/* - * Most code that calls js_ValueToString knows the value is (probably) not a - * string, so it does not make sense to put this inline fast path into - * js_ValueToString. - */ -static JS_ALWAYS_INLINE JSString * -ValueToString_TestForStringInline(JSContext *cx, const Value &v) -{ - if (v.isString()) - return v.toString(); - return js_ValueToString(cx, v); -} - -/* - * This function implements E-262-3 section 9.8, toString. Convert the given - * value to a string of jschars appended to the given buffer. On error, the - * passed buffer may have partial results appended. - */ -extern bool -ValueToStringBuffer(JSContext *cx, const Value &v, StringBuffer &sb); - -} /* namespace js */ - -/* - * Convert a value to its source expression, returning null after reporting - * an error, otherwise returning a new string reference. - */ -extern JS_FRIEND_API(JSString *) -js_ValueToSource(JSContext *cx, const js::Value &v); - -/* - * Compute a hash function from str. The caller can call this function even if - * str is not a GC-allocated thing. - */ -inline uint32 -js_HashString(JSLinearString *str) -{ - const jschar *s = str->chars(); - size_t n = str->length(); - uint32 h; - for (h = 0; n; s++, n--) - h = JS_ROTATE_LEFT32(h, 4) ^ *s; - return h; -} - -namespace js { - -/* - * Test if strings are equal. The caller can call the function even if str1 - * or str2 are not GC-allocated things. - */ -extern bool -EqualStrings(JSContext *cx, JSString *str1, JSString *str2, JSBool *result); - -/* EqualStrings is infallible on linear strings. */ -extern bool -EqualStrings(JSLinearString *str1, JSLinearString *str2); - -/* - * Return less than, equal to, or greater than zero depending on whether - * str1 is less than, equal to, or greater than str2. - */ -extern bool -CompareStrings(JSContext *cx, JSString *str1, JSString *str2, int32 *result); - -/* - * Return true if the string matches the given sequence of ASCII bytes. - */ -extern bool -StringEqualsAscii(JSLinearString *str, const char *asciiBytes); - -} /* namespacejs */ - -/* - * Boyer-Moore-Horspool superlinear search for pat:patlen in text:textlen. - * The patlen argument must be positive and no greater than sBMHPatLenMax. - * - * Return the index of pat in text, or -1 if not found. - */ -static const jsuint sBMHCharSetSize = 256; /* ISO-Latin-1 */ -static const jsuint sBMHPatLenMax = 255; /* skip table element is uint8 */ -static const jsint sBMHBadPattern = -2; /* return value if pat is not ISO-Latin-1 */ - -extern jsint -js_BoyerMooreHorspool(const jschar *text, jsuint textlen, - const jschar *pat, jsuint patlen); - -extern size_t -js_strlen(const jschar *s); - -extern jschar * -js_strchr(const jschar *s, jschar c); - -extern jschar * -js_strchr_limit(const jschar *s, jschar c, const jschar *limit); - -#define js_strncpy(t, s, n) memcpy((t), (s), (n) * sizeof(jschar)) - -inline void -js_short_strncpy(jschar *dest, const jschar *src, size_t num) -{ - /* - * It isn't strictly necessary here for |num| to be small, but this function - * is currently only called on buffers for short strings. - */ - JS_ASSERT(JSShortString::fitsIntoShortString(num)); - for (size_t i = 0; i < num; i++) - dest[i] = src[i]; -} - -/* - * Return s advanced past any Unicode white space characters. - */ -static inline const jschar * -js_SkipWhiteSpace(const jschar *s, const jschar *end) -{ - JS_ASSERT(s <= end); - while (s != end && JS_ISSPACE(*s)) - s++; - return s; -} - -/* - * Inflate bytes to JS chars and vice versa. Report out of memory via cx and - * return null on error, otherwise return the jschar or byte vector that was - * JS_malloc'ed. length is updated to the length of the new string in jschars. - */ -extern jschar * -js_InflateString(JSContext *cx, const char *bytes, size_t *length); - -extern char * -js_DeflateString(JSContext *cx, const jschar *chars, size_t length); - -/* - * Inflate bytes to JS chars into a buffer. 'chars' must be large enough for - * 'length' jschars. The buffer is NOT null-terminated. The destination length - * must be be initialized with the buffer size and will contain on return the - * number of copied chars. Conversion behavior depends on js_CStringsAreUTF8. - */ -extern JSBool -js_InflateStringToBuffer(JSContext *cx, const char *bytes, size_t length, - jschar *chars, size_t *charsLength); - -/* - * Same as js_InflateStringToBuffer, but always treats 'bytes' as UTF-8. - */ -extern JSBool -js_InflateUTF8StringToBuffer(JSContext *cx, const char *bytes, size_t length, - jschar *chars, size_t *charsLength); - -/* - * Get number of bytes in the deflated sequence of characters. Behavior depends - * on js_CStringsAreUTF8. - */ -extern size_t -js_GetDeflatedStringLength(JSContext *cx, const jschar *chars, - size_t charsLength); - -/* - * Same as js_GetDeflatedStringLength, but always treats the result as UTF-8. - */ -extern size_t -js_GetDeflatedUTF8StringLength(JSContext *cx, const jschar *chars, - size_t charsLength); - -/* - * Deflate JS chars to bytes into a buffer. 'bytes' must be large enough for - * 'length chars. The buffer is NOT null-terminated. The destination length - * must to be initialized with the buffer size and will contain on return the - * number of copied bytes. Conversion behavior depends on js_CStringsAreUTF8. - */ -extern JSBool -js_DeflateStringToBuffer(JSContext *cx, const jschar *chars, - size_t charsLength, char *bytes, size_t *length); - -/* - * Same as js_DeflateStringToBuffer, but always treats 'bytes' as UTF-8. - */ -extern JSBool -js_DeflateStringToUTF8Buffer(JSContext *cx, const jschar *chars, - size_t charsLength, char *bytes, size_t *length); - -/* Export a few natives and a helper to other files in SpiderMonkey. */ -extern JSBool -js_str_escape(JSContext *cx, uintN argc, js::Value *argv, js::Value *rval); - -/* - * The String.prototype.replace fast-native entry point is exported for joined - * function optimization in js{interp,tracer}.cpp. - */ -namespace js { -extern JSBool -str_replace(JSContext *cx, uintN argc, js::Value *vp); -} - -extern JSBool -js_str_toString(JSContext *cx, uintN argc, js::Value *vp); - -extern JSBool -js_str_charAt(JSContext *cx, uintN argc, js::Value *vp); - -extern JSBool -js_str_charCodeAt(JSContext *cx, uintN argc, js::Value *vp); - -/* - * Convert one UCS-4 char and write it into a UTF-8 buffer, which must be at - * least 6 bytes long. Return the number of UTF-8 bytes of data written. - */ -extern int -js_OneUcs4ToUtf8Char(uint8 *utf8Buffer, uint32 ucs4Char); - -namespace js { - -extern size_t -PutEscapedStringImpl(char *buffer, size_t size, FILE *fp, JSLinearString *str, uint32 quote); - -/* - * Write str into buffer escaping any non-printable or non-ASCII character - * using \escapes for JS string literals. - * Guarantees that a NUL is at the end of the buffer unless size is 0. Returns - * the length of the written output, NOT including the NUL. Thus, a return - * value of size or more means that the output was truncated. If buffer - * is null, just returns the length of the output. If quote is not 0, it must - * be a single or double quote character that will quote the output. -*/ -inline size_t -PutEscapedString(char *buffer, size_t size, JSLinearString *str, uint32 quote) -{ - size_t n = PutEscapedStringImpl(buffer, size, NULL, str, quote); - - /* PutEscapedStringImpl can only fail with a file. */ - JS_ASSERT(n != size_t(-1)); - return n; -} - -/* - * Write str into file escaping any non-printable or non-ASCII character. - * If quote is not 0, it must be a single or double quote character that - * will quote the output. -*/ -inline bool -FileEscapedString(FILE *fp, JSLinearString *str, uint32 quote) -{ - return PutEscapedStringImpl(NULL, 0, fp, str, quote) != size_t(-1); -} - -} /* namespace js */ - -extern JSBool -js_String(JSContext *cx, uintN argc, js::Value *vp); - -#endif /* jsstr_h___ */ diff --git a/x86/mozilla/include/jstl.h b/x86/mozilla/include/jstl.h deleted file mode 100644 index 36e90f1..0000000 --- a/x86/mozilla/include/jstl.h +++ /dev/null @@ -1,495 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99 ft=cpp: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released - * July 16, 2009. - * - * The Initial Developer of the Original Code is - * the Mozilla Corporation. - * - * Contributor(s): - * Luke Wagner - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jstl_h_ -#define jstl_h_ - -#include "jsbit.h" -#include "jsstaticcheck.h" - -#include -#include - -/* Gross special case for Gecko, which defines malloc/calloc/free. */ -#ifdef mozilla_mozalloc_macro_wrappers_h -# define JSSTL_UNDEFD_MOZALLOC_WRAPPERS -/* The "anti-header" */ -# include "mozilla/mozalloc_undef_macro_wrappers.h" -#endif - -namespace js { - -/* JavaScript Template Library. */ -namespace tl { - -/* Compute min/max/clamp. */ -template struct Min { - static const size_t result = i < j ? i : j; -}; -template struct Max { - static const size_t result = i > j ? i : j; -}; -template struct Clamp { - static const size_t result = i < min ? min : (i > max ? max : i); -}; - -/* Compute x^y. */ -template struct Pow { - static const size_t result = x * Pow::result; -}; -template struct Pow { - static const size_t result = 1; -}; - -/* Compute floor(log2(i)). */ -template struct FloorLog2 { - static const size_t result = 1 + FloorLog2::result; -}; -template <> struct FloorLog2<0> { /* Error */ }; -template <> struct FloorLog2<1> { static const size_t result = 0; }; - -/* Compute ceiling(log2(i)). */ -template struct CeilingLog2 { - static const size_t result = FloorLog2<2 * i - 1>::result; -}; - -/* Round up to the nearest power of 2. */ -template struct RoundUpPow2 { - static const size_t result = 1u << CeilingLog2::result; -}; -template <> struct RoundUpPow2<0> { - static const size_t result = 1; -}; - -/* Compute the number of bits in the given unsigned type. */ -template struct BitSize { - static const size_t result = sizeof(T) * JS_BITS_PER_BYTE; -}; - -/* Allow Assertions by only including the 'result' typedef if 'true'. */ -template struct StaticAssert {}; -template <> struct StaticAssert { typedef int result; }; - -/* Boolean test for whether two types are the same. */ -template struct IsSameType { - static const bool result = false; -}; -template struct IsSameType { - static const bool result = true; -}; - -/* - * Produce an N-bit mask, where N <= BitSize::result. Handle the - * language-undefined edge case when N = BitSize::result. - */ -template struct NBitMask { - typedef typename StaticAssert::result>::result _; - static const size_t result = (size_t(1) << N) - 1; -}; -template <> struct NBitMask::result> { - static const size_t result = size_t(-1); -}; - -/* - * For the unsigned integral type size_t, compute a mask M for N such that - * for all X, !(X & M) implies X * N will not overflow (w.r.t size_t) - */ -template struct MulOverflowMask { - static const size_t result = - ~NBitMask::result - CeilingLog2::result>::result; -}; -template <> struct MulOverflowMask<0> { /* Error */ }; -template <> struct MulOverflowMask<1> { static const size_t result = 0; }; - -/* - * Generate a mask for T such that if (X & sUnsafeRangeSizeMask), an X-sized - * array of T's is big enough to cause a ptrdiff_t overflow when subtracting - * a pointer to the end of the array from the beginning. - */ -template struct UnsafeRangeSizeMask { - /* - * The '2' factor means the top bit is clear, sizeof(T) converts from - * units of elements to bytes. - */ - static const size_t result = MulOverflowMask<2 * sizeof(T)>::result; -}; - -/* Return T stripped of any const-ness. */ -template struct StripConst { typedef T result; }; -template struct StripConst { typedef T result; }; - -/* - * Traits class for identifying POD types. Until C++0x, there is no automatic - * way to detect PODs, so for the moment it is done manually. - */ -template struct IsPodType { static const bool result = false; }; -template <> struct IsPodType { static const bool result = true; }; -template <> struct IsPodType { static const bool result = true; }; -template <> struct IsPodType { static const bool result = true; }; -template <> struct IsPodType { static const bool result = true; }; -template <> struct IsPodType { static const bool result = true; }; -template <> struct IsPodType { static const bool result = true; }; -template <> struct IsPodType { static const bool result = true; }; -template <> struct IsPodType { static const bool result = true; }; -template <> struct IsPodType { static const bool result = true; }; -template <> struct IsPodType { static const bool result = true; }; -template <> struct IsPodType { static const bool result = true; }; - -/* Return the size/end of an array without using macros. */ -template inline T *ArraySize(T (&)[N]) { return N; } -template inline T *ArrayEnd(T (&arr)[N]) { return arr + N; } - -} /* namespace tl */ - -/* Useful for implementing containers that assert non-reentrancy */ -class ReentrancyGuard -{ - /* ReentrancyGuard is not copyable. */ - ReentrancyGuard(const ReentrancyGuard &); - void operator=(const ReentrancyGuard &); - -#ifdef DEBUG - bool &entered; -#endif - public: - template -#ifdef DEBUG - ReentrancyGuard(T &obj) - : entered(obj.entered) -#else - ReentrancyGuard(T &/*obj*/) -#endif - { -#ifdef DEBUG - JS_ASSERT(!entered); - entered = true; -#endif - } - ~ReentrancyGuard() - { -#ifdef DEBUG - entered = false; -#endif - } -}; - -/* - * Round x up to the nearest power of 2. This function assumes that the most - * significant bit of x is not set, which would lead to overflow. - */ -STATIC_POSTCONDITION_ASSUME(return >= x) -JS_ALWAYS_INLINE size_t -RoundUpPow2(size_t x) -{ - size_t log2 = JS_CEILING_LOG2W(x); - JS_ASSERT(log2 < tl::BitSize::result); - size_t result = size_t(1) << log2; - return result; -} - -/* - * Safely subtract two pointers when it is known that end > begin. This avoids - * the common compiler bug that if (size_t(end) - size_t(begin)) has the MSB - * set, the unsigned subtraction followed by right shift will produce -1, or - * size_t(-1), instead of the real difference. - */ -template -JS_ALWAYS_INLINE size_t -PointerRangeSize(T *begin, T *end) -{ - return (size_t(end) - size_t(begin)) / sizeof(T); -} - -/* - * Allocation policies. These model the concept: - * - public copy constructor, assignment, destructor - * - void *malloc(size_t) - * Responsible for OOM reporting on NULL return value. - * - void *realloc(size_t) - * Responsible for OOM reporting on NULL return value. - * - void free(void *) - * - reportAllocOverflow() - * Called on overflow before the container returns NULL. - */ - -/* Policy for using system memory functions and doing no error reporting. */ -class SystemAllocPolicy -{ - public: - void *malloc(size_t bytes) { return js_malloc(bytes); } - void *realloc(void *p, size_t bytes) { return js_realloc(p, bytes); } - void free(void *p) { js_free(p); } - void reportAllocOverflow() const {} -}; - -/* - * This utility pales in comparison to Boost's aligned_storage. The utility - * simply assumes that JSUint64 is enough alignment for anyone. This may need - * to be extended one day... - * - * As an important side effect, pulling the storage into this template is - * enough obfuscation to confuse gcc's strict-aliasing analysis into not giving - * false negatives when we cast from the char buffer to whatever type we've - * constructed using the bytes. - */ -template -struct AlignedStorage -{ - union U { - char bytes[nbytes]; - uint64 _; - } u; - - const void *addr() const { return u.bytes; } - void *addr() { return u.bytes; } -}; - -template -struct AlignedStorage2 -{ - union U { - char bytes[sizeof(T)]; - uint64 _; - } u; - - const T *addr() const { return (const T *)u.bytes; } - T *addr() { return (T *)u.bytes; } -}; - -/* - * Small utility for lazily constructing objects without using dynamic storage. - * When a LazilyConstructed is constructed, it is |empty()|, i.e., no value - * of T has been constructed and no T destructor will be called when the - * LazilyConstructed is destroyed. Upon calling |construct|, a T object will - * be constructed with the given arguments and that object will be destroyed - * when the owning LazilyConstructed is destroyed. - * - * N.B. GCC seems to miss some optimizations with LazilyConstructed and may - * generate extra branches/loads/stores. Use with caution on hot paths. - */ -template -class LazilyConstructed -{ - AlignedStorage2 storage; - bool constructed; - - T &asT() { return *storage.addr(); } - - public: - LazilyConstructed() { constructed = false; } - ~LazilyConstructed() { if (constructed) asT().~T(); } - - bool empty() const { return !constructed; } - - void construct() { - JS_ASSERT(!constructed); - new(storage.addr()) T(); - constructed = true; - } - - template - void construct(const T1 &t1) { - JS_ASSERT(!constructed); - new(storage.addr()) T(t1); - constructed = true; - } - - template - void construct(const T1 &t1, const T2 &t2) { - JS_ASSERT(!constructed); - new(storage.addr()) T(t1, t2); - constructed = true; - } - - template - void construct(const T1 &t1, const T2 &t2, const T3 &t3) { - JS_ASSERT(!constructed); - new(storage.addr()) T(t1, t2, t3); - constructed = true; - } - - template - void construct(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4) { - JS_ASSERT(!constructed); - new(storage.addr()) T(t1, t2, t3, t4); - constructed = true; - } - - T *addr() { - JS_ASSERT(constructed); - return &asT(); - } - - T &ref() { - JS_ASSERT(constructed); - return asT(); - } - - void destroy() { - ref().~T(); - constructed = false; - } -}; - - -/* - * N.B. GCC seems to miss some optimizations with Conditionally and may - * generate extra branches/loads/stores. Use with caution on hot paths. - */ -template -class Conditionally { - LazilyConstructed t; - - public: - Conditionally(bool b) { if (b) t.construct(); } - - template - Conditionally(bool b, const T1 &t1) { if (b) t.construct(t1); } - - template - Conditionally(bool b, const T1 &t1, const T2 &t2) { if (b) t.construct(t1, t2); } -}; - -template -class AlignedPtrAndFlag -{ - uintptr_t bits; - - public: - AlignedPtrAndFlag(T *t, bool flag) { - JS_ASSERT((uintptr_t(t) & 1) == 0); - bits = uintptr_t(t) | uintptr_t(flag); - } - - T *ptr() const { - return (T *)(bits & ~uintptr_t(1)); - } - - bool flag() const { - return (bits & 1) != 0; - } - - void setPtr(T *t) { - JS_ASSERT((uintptr_t(t) & 1) == 0); - bits = uintptr_t(t) | uintptr_t(flag()); - } - - void setFlag() { - bits |= 1; - } - - void unsetFlag() { - bits &= ~uintptr_t(1); - } - - void set(T *t, bool flag) { - JS_ASSERT((uintptr_t(t) & 1) == 0); - bits = uintptr_t(t) | flag; - } -}; - -template -static inline void -Reverse(T *beg, T *end) -{ - while (beg != end) { - if (--end == beg) - return; - T tmp = *beg; - *beg = *end; - *end = tmp; - ++beg; - } -} - -template -static inline T * -Find(T *beg, T *end, const T &v) -{ - for (T *p = beg; p != end; ++p) { - if (*p == v) - return p; - } - return end; -} - -template -static inline typename Container::ElementType * -Find(Container &c, const typename Container::ElementType &v) -{ - return Find(c.begin(), c.end(), v); -} - -template -void -ForEach(InputIterT begin, InputIterT end, CallableT f) -{ - for (; begin != end; ++begin) - f(*begin); -} - -template -static inline T -Min(T t1, T t2) -{ - return t1 < t2 ? t1 : t2; -} - -template -static inline T -Max(T t1, T t2) -{ - return t1 > t2 ? t1 : t2; -} - -/* Allows a const variable to be initialized after its declaration. */ -template -static T& -InitConst(const T &t) -{ - return const_cast(t); -} - -} /* namespace js */ - -#ifdef JSSTL_UNDEFD_MOZALLOC_WRAPPERS -# include "mozilla/mozalloc_macro_wrappers.h" -#endif - -#endif /* jstl_h_ */ diff --git a/x86/mozilla/include/jstracer.h b/x86/mozilla/include/jstracer.h deleted file mode 100644 index 76921cc..0000000 --- a/x86/mozilla/include/jstracer.h +++ /dev/null @@ -1,1895 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=4 sw=4 et tw=99 ft=cpp: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released - * May 28, 2008. - * - * The Initial Developer of the Original Code is - * Brendan Eich - * - * Contributor(s): - * Andreas Gal - * Mike Shaver - * David Anderson - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jstracer_h___ -#define jstracer_h___ - -#ifdef JS_TRACER - -#include "jstypes.h" -#include "jsbuiltins.h" -#include "jscntxt.h" -#include "jsdhash.h" -#include "jsinterp.h" -#include "jslock.h" -#include "jsnum.h" -#include "jsvector.h" -#include "jscompartment.h" -#include "Writer.h" - -namespace js { - -template -class Queue { - T* _data; - unsigned _len; - unsigned _max; - nanojit::Allocator* alloc; - -public: - void ensure(unsigned size) { - if (_max > size) - return; - if (!_max) - _max = 8; - _max = JS_MAX(_max * 2, size); - if (alloc) { - T* tmp = new (*alloc) T[_max]; - memcpy(tmp, _data, _len * sizeof(T)); - _data = tmp; - } else { - _data = (T*)js_realloc(_data, _max * sizeof(T)); - } -#if defined(DEBUG) - memset(&_data[_len], 0xcd, _max - _len); -#endif - } - - Queue(nanojit::Allocator* alloc) - : alloc(alloc) - { - this->_max = - this->_len = 0; - this->_data = NULL; - } - - ~Queue() { - if (!alloc) - js_free(_data); - } - - bool contains(T a) { - for (unsigned n = 0; n < _len; ++n) { - if (_data[n] == a) - return true; - } - return false; - } - - void add(T a) { - ensure(_len + 1); - JS_ASSERT(_len <= _max); - _data[_len++] = a; - } - - void add(T* chunk, unsigned size) { - ensure(_len + size); - JS_ASSERT(_len <= _max); - memcpy(&_data[_len], chunk, size * sizeof(T)); - _len += size; - } - - void addUnique(T a) { - if (!contains(a)) - add(a); - } - - void setLength(unsigned len) { - ensure(len + 1); - _len = len; - } - - void clear() { - _len = 0; - } - - T & get(unsigned i) { - JS_ASSERT(i < length()); - return _data[i]; - } - - const T & get(unsigned i) const { - JS_ASSERT(i < length()); - return _data[i]; - } - - T & operator [](unsigned i) { - return get(i); - } - - const T & operator [](unsigned i) const { - return get(i); - } - - unsigned length() const { - return _len; - } - - T* data() const { - return _data; - } - - int offsetOf(T slot) { - T* p = _data; - unsigned n = 0; - for (n = 0; n < _len; ++n) - if (*p++ == slot) - return n; - return -1; - } - -}; - -/* - * Tracker is used to keep track of values being manipulated by the interpreter - * during trace recording. It maps opaque, 4-byte aligned address to LIns pointers. - * pointers. To do this efficiently, we observe that the addresses of jsvals - * living in the interpreter tend to be aggregated close to each other - - * usually on the same page (where a tracker page doesn't have to be the same - * size as the OS page size, but it's typically similar). The Tracker - * consists of a linked-list of structures representing a memory page, which - * are created on-demand as memory locations are used. - * - * For every address, first we split it into two parts: upper bits which - * represent the "base", and lower bits which represent an offset against the - * base. For the offset, we then right-shift it by two because the bottom two - * bits of a 4-byte aligned address are always zero. The mapping then - * becomes: - * - * page = page in pagelist such that Base(address) == page->base, - * page->map[Offset(address)] - */ -class Tracker { - #define TRACKER_PAGE_SZB 4096 - #define TRACKER_PAGE_ENTRIES (TRACKER_PAGE_SZB >> 2) // each slot is 4 bytes - #define TRACKER_PAGE_MASK jsuword(TRACKER_PAGE_SZB - 1) - - struct TrackerPage { - struct TrackerPage* next; - jsuword base; - nanojit::LIns* map[TRACKER_PAGE_ENTRIES]; - }; - struct TrackerPage* pagelist; - - jsuword getTrackerPageBase(const void* v) const; - jsuword getTrackerPageOffset(const void* v) const; - struct TrackerPage* findTrackerPage(const void* v) const; - struct TrackerPage* addTrackerPage(const void* v); -public: - Tracker(); - ~Tracker(); - - bool has(const void* v) const; - nanojit::LIns* get(const void* v) const; - void set(const void* v, nanojit::LIns* ins); - void clear(); -}; - -class VMFragment : public nanojit::Fragment { -public: - VMFragment(const void* _ip verbose_only(, uint32_t profFragID)) - : Fragment(_ip verbose_only(, profFragID)) - {} - - /* - * If this is anchored off a TreeFragment, this points to that tree fragment. - * Otherwise, it is |this|. - */ - TreeFragment* root; - - TreeFragment* toTreeFragment(); -}; - -#ifdef NJ_NO_VARIADIC_MACROS - -#define debug_only_stmt(action) /* */ -static void debug_only_printf(int mask, const char *fmt, ...) JS_BEGIN_MACRO JS_END_MACRO -#define debug_only_print0(mask, str) JS_BEGIN_MACRO JS_END_MACRO - -#elif defined(JS_JIT_SPEW) - -// Top level logging controller object. -extern nanojit::LogControl LogController; - -// Top level profiling hook, needed to harvest profile info from Fragments -// whose logical lifetime is about to finish -extern void FragProfiling_FragFinalizer(nanojit::Fragment* f, TraceMonitor*); - -#define debug_only_stmt(stmt) \ - stmt - -#define debug_only_printf(mask, fmt, ...) \ - JS_BEGIN_MACRO \ - if ((LogController.lcbits & (mask)) > 0) { \ - LogController.printf(fmt, __VA_ARGS__); \ - fflush(stdout); \ - } \ - JS_END_MACRO - -#define debug_only_print0(mask, str) \ - JS_BEGIN_MACRO \ - if ((LogController.lcbits & (mask)) > 0) { \ - LogController.printf("%s", str); \ - fflush(stdout); \ - } \ - JS_END_MACRO - -#else - -#define debug_only_stmt(action) /* */ -#define debug_only_printf(mask, fmt, ...) JS_BEGIN_MACRO JS_END_MACRO -#define debug_only_print0(mask, str) JS_BEGIN_MACRO JS_END_MACRO - -#endif - -/* - * The oracle keeps track of hit counts for program counter locations, as - * well as slots that should not be demoted to int because we know them to - * overflow or they result in type-unstable traces. We are using simple - * hash tables. Collisions lead to loss of optimization (demotable slots - * are not demoted, etc.) but have no correctness implications. - */ -#define ORACLE_SIZE 4096 - -class Oracle { - avmplus::BitSet _stackDontDemote; - avmplus::BitSet _globalDontDemote; - avmplus::BitSet _pcDontDemote; - avmplus::BitSet _pcSlowZeroTest; -public: - Oracle(); - - JS_REQUIRES_STACK void markGlobalSlotUndemotable(JSContext* cx, unsigned slot); - JS_REQUIRES_STACK bool isGlobalSlotUndemotable(JSContext* cx, unsigned slot) const; - JS_REQUIRES_STACK void markStackSlotUndemotable(JSContext* cx, unsigned slot); - JS_REQUIRES_STACK void markStackSlotUndemotable(JSContext* cx, unsigned slot, const void* pc); - JS_REQUIRES_STACK bool isStackSlotUndemotable(JSContext* cx, unsigned slot) const; - JS_REQUIRES_STACK bool isStackSlotUndemotable(JSContext* cx, unsigned slot, const void* pc) const; - void markInstructionUndemotable(jsbytecode* pc); - bool isInstructionUndemotable(jsbytecode* pc) const; - void markInstructionSlowZeroTest(jsbytecode* pc); - bool isInstructionSlowZeroTest(jsbytecode* pc) const; - - void clearDemotability(); - void clear() { - clearDemotability(); - } -}; - -typedef Queue SlotList; - -class TypeMap : public Queue { - Oracle *oracle; -public: - TypeMap(nanojit::Allocator* alloc, Oracle *oracle) - : Queue(alloc), - oracle(oracle) - {} - void set(unsigned stackSlots, unsigned ngslots, - const JSValueType* stackTypeMap, const JSValueType* globalTypeMap); - JS_REQUIRES_STACK void captureTypes(JSContext* cx, JSObject* globalObj, SlotList& slots, unsigned callDepth, - bool speculate); - JS_REQUIRES_STACK void captureMissingGlobalTypes(JSContext* cx, JSObject* globalObj, SlotList& slots, - unsigned stackSlots, bool speculate); - bool matches(TypeMap& other) const; - void fromRaw(JSValueType* other, unsigned numSlots); -}; - -#define JS_TM_EXITCODES(_) \ - /* \ - * An exit at a possible branch-point in the trace at which to attach a \ - * future secondary trace. Therefore the recorder must generate different \ - * code to handle the other outcome of the branch condition from the \ - * primary trace's outcome. \ - */ \ - _(BRANCH) \ - /* \ - * Exit at a tableswitch via a numbered case. \ - */ \ - _(CASE) \ - /* \ - * Exit at a tableswitch via the default case. \ - */ \ - _(DEFAULT) \ - _(LOOP) \ - _(NESTED) \ - /* \ - * An exit from a trace because a condition relied upon at recording time \ - * no longer holds, where the alternate path of execution is so rare or \ - * difficult to address in native code that it is not traced at all, e.g. \ - * negative array index accesses, which differ from positive indexes in \ - * that they require a string-based property lookup rather than a simple \ - * memory access. \ - */ \ - _(MISMATCH) \ - /* \ - * A specialization of MISMATCH_EXIT to handle allocation failures. \ - */ \ - _(OOM) \ - _(OVERFLOW) \ - _(MUL_ZERO) \ - _(UNSTABLE_LOOP) \ - _(TIMEOUT) \ - _(DEEP_BAIL) \ - _(STATUS) - -enum ExitType { - #define MAKE_EXIT_CODE(x) x##_EXIT, - JS_TM_EXITCODES(MAKE_EXIT_CODE) - #undef MAKE_EXIT_CODE - TOTAL_EXIT_TYPES -}; - -struct FrameInfo; - -struct VMSideExit : public nanojit::SideExit -{ - jsbytecode* pc; - jsbytecode* imacpc; - intptr_t sp_adj; - intptr_t rp_adj; - int32_t calldepth; - uint32 numGlobalSlots; - uint32 numStackSlots; - uint32 numStackSlotsBelowCurrentFrame; - ExitType exitType; - uintN lookupFlags; - unsigned hitcount; - - inline JSValueType* stackTypeMap() { - return (JSValueType*)(this + 1); - } - - inline JSValueType& stackType(unsigned i) { - JS_ASSERT(i < numStackSlots); - return stackTypeMap()[i]; - } - - inline JSValueType* globalTypeMap() { - return (JSValueType*)(this + 1) + this->numStackSlots; - } - - inline JSValueType* fullTypeMap() { - return stackTypeMap(); - } - - inline VMFragment* fromFrag() { - return (VMFragment*)from; - } - - inline TreeFragment* root() { - return fromFrag()->root; - } -}; - -class VMAllocator : public nanojit::Allocator -{ - -public: - VMAllocator(char* reserve, size_t reserveSize) - : mOutOfMemory(false), mSize(0), mReserve(reserve), - mReserveCurr(uintptr_t(reserve)), mReserveLimit(uintptr_t(reserve + reserveSize)) - {} - - ~VMAllocator() { - js_free(mReserve); - } - - size_t size() { - return mSize; - } - - bool outOfMemory() { - return mOutOfMemory; - } - - struct Mark - { - VMAllocator& vma; - bool committed; - nanojit::Allocator::Chunk* saved_chunk; - char* saved_top; - char* saved_limit; - size_t saved_size; - - Mark(VMAllocator& vma) : - vma(vma), - committed(false), - saved_chunk(vma.current_chunk), - saved_top(vma.current_top), - saved_limit(vma.current_limit), - saved_size(vma.mSize) - {} - - ~Mark() - { - if (!committed) - vma.rewind(*this); - } - - void commit() { committed = true; } - }; - - void rewind(const Mark& m) { - while (current_chunk != m.saved_chunk) { - Chunk *prev = current_chunk->prev; - freeChunk(current_chunk); - current_chunk = prev; - } - current_top = m.saved_top; - current_limit = m.saved_limit; - mSize = m.saved_size; - memset(current_top, 0, current_limit - current_top); - } - - bool mOutOfMemory; - size_t mSize; - - /* See nanojit::Allocator::allocChunk() for details on these. */ - char* mReserve; - uintptr_t mReserveCurr; - uintptr_t mReserveLimit; -}; - -struct FrameInfo { - JSObject* block; // caller block chain head - jsbytecode* pc; // caller fp->regs->pc - jsbytecode* imacpc; // caller fp->imacpc - uint32 spdist; // distance from fp->slots to fp->regs->sp at JSOP_CALL - - /* - * Bit 15 (0x8000) is a flag that is set if constructing (called through new). - * Bits 0-14 are the actual argument count. This may be less than fun->nargs. - * NB: This is argc for the callee, not the caller. - */ - uint32 argc; - - /* - * Number of stack slots in the caller, not counting slots pushed when - * invoking the callee. That is, slots after JSOP_CALL completes but - * without the return value. This is also equal to the number of slots - * between fp->prev->argv[-2] (calleR fp->callee) and fp->argv[-2] - * (calleE fp->callee). - */ - uint32 callerHeight; - - /* argc of the caller */ - uint32 callerArgc; - - // Safer accessors for argc. - enum { CONSTRUCTING_FLAG = 0x10000 }; - void set_argc(uint16 argc, bool constructing) { - this->argc = uint32(argc) | (constructing ? CONSTRUCTING_FLAG: 0); - } - uint16 get_argc() const { return uint16(argc & ~CONSTRUCTING_FLAG); } - bool is_constructing() const { return (argc & CONSTRUCTING_FLAG) != 0; } - - // The typemap just before the callee is called. - JSValueType* get_typemap() { return (JSValueType*) (this+1); } - const JSValueType* get_typemap() const { return (JSValueType*) (this+1); } -}; - -struct UnstableExit -{ - VMFragment* fragment; - VMSideExit* exit; - UnstableExit* next; -}; - -struct LinkableFragment : public VMFragment -{ - LinkableFragment(const void* _ip, nanojit::Allocator* alloc, Oracle *oracle - verbose_only(, uint32_t profFragID)) - : VMFragment(_ip verbose_only(, profFragID)), typeMap(alloc, oracle), nStackTypes(0) - { } - - uint32 branchCount; - TypeMap typeMap; - unsigned nStackTypes; - unsigned spOffsetAtEntry; - SlotList* globalSlots; -}; - -/* - * argc is cx->fp->argc at the trace loop header, i.e., the number of arguments - * pushed for the innermost JS frame. This is required as part of the fragment - * key because the fragment will write those arguments back to the interpreter - * stack when it exits, using its typemap, which implicitly incorporates a - * given value of argc. Without this feature, a fragment could be called as an - * inner tree with two different values of argc, and entry type checking or - * exit frame synthesis could crash. - */ -struct TreeFragment : public LinkableFragment -{ - TreeFragment(const void* _ip, nanojit::Allocator* alloc, Oracle *oracle, JSObject* _globalObj, - uint32 _globalShape, uint32 _argc verbose_only(, uint32_t profFragID)): - LinkableFragment(_ip, alloc, oracle verbose_only(, profFragID)), - first(NULL), - next(NULL), - peer(NULL), - globalObj(_globalObj), - globalShape(_globalShape), - argc(_argc), - dependentTrees(alloc), - linkedTrees(alloc), - sideExits(alloc), - gcthings(alloc), - shapes(alloc) - { } - - TreeFragment* first; - TreeFragment* next; - TreeFragment* peer; - JSObject* globalObj; - uint32 globalShape; - uint32 argc; - /* Dependent trees must be trashed if this tree dies, and updated on missing global types */ - Queue dependentTrees; - /* Linked trees must be updated on missing global types, but are not dependent */ - Queue linkedTrees; -#ifdef DEBUG - const char* treeFileName; - uintN treeLineNumber; - uintN treePCOffset; -#endif - JSScript* script; - UnstableExit* unstableExits; - Queue sideExits; - ptrdiff_t nativeStackBase; - unsigned maxCallDepth; - /* All embedded GC things are registered here so the GC can scan them. */ - Queue gcthings; - Queue shapes; - unsigned maxNativeStackSlots; - /* Gives the number of times we have entered this trace. */ - uintN execs; - /* Gives the total number of iterations executed by the trace (up to a limit). */ - uintN iters; - - inline unsigned nGlobalTypes() { - return typeMap.length() - nStackTypes; - } - inline JSValueType* globalTypeMap() { - return typeMap.data() + nStackTypes; - } - inline JSValueType* stackTypeMap() { - return typeMap.data(); - } - - JS_REQUIRES_STACK void initialize(JSContext* cx, SlotList *globalSlots, bool speculate); - UnstableExit* removeUnstableExit(VMSideExit* exit); -}; - -inline TreeFragment* -VMFragment::toTreeFragment() -{ - JS_ASSERT(root == this); - return static_cast(this); -} - -enum MonitorResult { - MONITOR_RECORDING, - MONITOR_NOT_RECORDING, - MONITOR_ERROR -}; - -const uintN PROFILE_MAX_INNER_LOOPS = 8; -const uintN PROFILE_MAX_STACK = 6; - -/* - * A loop profile keeps track of the instruction mix of a hot loop. We use this - * information to predict whether tracing would be beneficial for the loop. - */ -class LoopProfile -{ -public: - /* Instructions are divided into a few categories. */ - enum OpKind { - OP_FLOAT, // Floating point arithmetic - OP_INT, // Integer arithmetic - OP_BIT, // Bit operations - OP_EQ, // == and != - OP_EVAL, // Calls to eval() - OP_CALL, // JSOP_CALL instructions - OP_FWDJUMP, // Jumps with positive delta - OP_NEW, // JSOP_NEW instructions - OP_RECURSIVE, // Recursive calls - OP_ARRAY_READ, // Reads from dense arrays - OP_TYPED_ARRAY, // Accesses to typed arrays - OP_LIMIT - }; - - /* The TraceMonitor for which we're profiling. */ - TraceMonitor *traceMonitor; - - /* The script in which the loop header lives. */ - JSScript *entryScript; - - /* The stack frame where we started profiling. Only valid while profiling! */ - JSStackFrame *entryfp; - - /* The bytecode locations of the loop header and the back edge. */ - jsbytecode *top, *bottom; - - /* Number of times we have seen this loop executed; used to decide when to profile. */ - uintN hits; - - /* Whether we have run a complete profile of the loop. */ - bool profiled; - - /* Sometimes we can't decide in one profile run whether to trace, so we set undecided. */ - bool undecided; - - /* If we have profiled the loop, this saves the decision of whether to trace it. */ - bool traceOK; - - /* Memoized value of isCompilationUnprofitable. */ - bool unprofitable; - - /* - * Sometimes loops are not good tracing opportunities, but they are nested inside - * loops that we want to trace. In that case, we set their traceOK flag to true, - * but we set execOK to false. That way, the loop is traced so that it can be - * integrated into the outer trace. But we never execute the trace on its only. - */ - bool execOK; - - /* Instruction mix for the loop and total number of instructions. */ - uintN allOps[OP_LIMIT]; - uintN numAllOps; - - /* Instruction mix and total for the loop, excluding nested inner loops. */ - uintN selfOps[OP_LIMIT]; - uintN numSelfOps; - - /* - * A prediction of the number of instructions we would have to compile - * for the loop. This takes into account the fact that a branch may cause us to - * compile every instruction after it twice. Polymorphic calls are - * treated as n-way branches. - */ - double numSelfOpsMult; - - /* - * This keeps track of the number of times that every succeeding instruction - * in the trace will have to be compiled. Every time we hit a branch, we - * double this number. Polymorphic calls multiply it by n (for n-way - * polymorphism). - */ - double branchMultiplier; - - /* Set to true if the loop is short (i.e., has fewer than 8 iterations). */ - bool shortLoop; - - /* Set to true if the loop may be short (has few iterations at profiling time). */ - bool maybeShortLoop; - - /* - * When we hit a nested loop while profiling, we record where it occurs - * and how many iterations we execute it. - */ - struct InnerLoop { - JSStackFrame *entryfp; - jsbytecode *top, *bottom; - uintN iters; - - InnerLoop() {} - InnerLoop(JSStackFrame *entryfp, jsbytecode *top, jsbytecode *bottom) - : entryfp(entryfp), top(top), bottom(bottom), iters(0) {} - }; - - /* These two variables track all the inner loops seen while profiling (up to a limit). */ - InnerLoop innerLoops[PROFILE_MAX_INNER_LOOPS]; - uintN numInnerLoops; - - /* - * These two variables track the loops that we are currently nested - * inside while profiling. Loops get popped off here when they exit. - */ - InnerLoop loopStack[PROFILE_MAX_INNER_LOOPS]; - uintN loopStackDepth; - - /* - * These fields keep track of values on the JS stack. If the stack grows larger - * than PROFILE_MAX_STACK, we continue to track sp, but we return conservative results - * for stackTop(). - */ - struct StackValue { - bool isConst; - bool hasValue; - int value; - - StackValue() : isConst(false), hasValue(false) {} - StackValue(bool isConst) : isConst(isConst), hasValue(false) {} - StackValue(bool isConst, int value) : isConst(isConst), hasValue(true), value(value) {} - }; - StackValue stack[PROFILE_MAX_STACK]; - uintN sp; - - inline void stackClear() { sp = 0; } - - inline void stackPush(const StackValue &v) { - if (sp < PROFILE_MAX_STACK) - stack[sp++] = v; - else - stackClear(); - } - - inline void stackPop() { if (sp > 0) sp--; } - - inline StackValue stackAt(int pos) { - pos += sp; - if (pos >= 0 && uintN(pos) < PROFILE_MAX_STACK) - return stack[pos]; - else - return StackValue(false); - } - - LoopProfile(TraceMonitor *tm, JSStackFrame *entryfp, jsbytecode *top, jsbytecode *bottom); - - void reset(); - - enum ProfileAction { - ProfContinue, - ProfComplete - }; - - /* These two functions track the instruction mix. */ - inline void increment(OpKind kind) - { - allOps[kind]++; - if (loopStackDepth == 0) - selfOps[kind]++; - } - - inline uintN count(OpKind kind) { return allOps[kind]; } - - /* Called for every back edge being profiled. */ - MonitorResult profileLoopEdge(JSContext* cx, uintN& inlineCallCount); - - /* Called for every instruction being profiled. */ - ProfileAction profileOperation(JSContext *cx, JSOp op); - - /* Once a loop's profile is done, these decide whether it should be traced. */ - bool isCompilationExpensive(JSContext *cx, uintN depth); - bool isCompilationUnprofitable(JSContext *cx, uintN goodOps); - void decide(JSContext *cx); - - void stopProfiling(JSContext *cx); -}; - -/* - * BUILTIN_NO_FIXUP_NEEDED indicates that after the initial LeaveTree of a deep - * bail, the builtin call needs no further fixup when the trace exits and calls - * LeaveTree the second time. - */ -typedef enum BuiltinStatus { - BUILTIN_BAILED = 1, - BUILTIN_ERROR = 2 -} BuiltinStatus; - -static JS_INLINE void -SetBuiltinError(TraceMonitor *tm) -{ - tm->tracerState->builtinStatus |= BUILTIN_ERROR; -} - -static JS_INLINE bool -WasBuiltinSuccessful(TraceMonitor *tm) -{ - return tm->tracerState->builtinStatus == 0; -} - -#ifdef DEBUG_RECORDING_STATUS_NOT_BOOL -/* #define DEBUG_RECORDING_STATUS_NOT_BOOL to detect misuses of RecordingStatus */ -struct RecordingStatus { - int code; - bool operator==(RecordingStatus &s) { return this->code == s.code; }; - bool operator!=(RecordingStatus &s) { return this->code != s.code; }; -}; -enum RecordingStatusCodes { - RECORD_ERROR_code = 0, - RECORD_STOP_code = 1, - - RECORD_CONTINUE_code = 3, - RECORD_IMACRO_code = 4 -}; -RecordingStatus RECORD_CONTINUE = { RECORD_CONTINUE_code }; -RecordingStatus RECORD_STOP = { RECORD_STOP_code }; -RecordingStatus RECORD_IMACRO = { RECORD_IMACRO_code }; -RecordingStatus RECORD_ERROR = { RECORD_ERROR_code }; - -struct AbortableRecordingStatus { - int code; - bool operator==(AbortableRecordingStatus &s) { return this->code == s.code; }; - bool operator!=(AbortableRecordingStatus &s) { return this->code != s.code; }; -}; -enum AbortableRecordingStatusCodes { - ARECORD_ERROR_code = 0, - ARECORD_STOP_code = 1, - ARECORD_ABORTED_code = 2, - ARECORD_CONTINUE_code = 3, - ARECORD_IMACRO_code = 4, - ARECORD_IMACRO_ABORTED_code = 5, - ARECORD_COMPLETED_code = 6 -}; -AbortableRecordingStatus ARECORD_ERROR = { ARECORD_ERROR_code }; -AbortableRecordingStatus ARECORD_STOP = { ARECORD_STOP_code }; -AbortableRecordingStatus ARECORD_CONTINUE = { ARECORD_CONTINUE_code }; -AbortableRecordingStatus ARECORD_IMACRO = { ARECORD_IMACRO_code }; -AbortableRecordingStatus ARECORD_IMACRO_ABORTED = { ARECORD_IMACRO_ABORTED_code }; -AbortableRecordingStatus ARECORD_ABORTED = { ARECORD_ABORTED_code }; -AbortableRecordingStatus ARECORD_COMPLETED = { ARECORD_COMPLETED_code }; - -static inline AbortableRecordingStatus -InjectStatus(RecordingStatus rs) -{ - AbortableRecordingStatus ars = { rs.code }; - return ars; -} -static inline AbortableRecordingStatus -InjectStatus(AbortableRecordingStatus ars) -{ - return ars; -} - -static inline bool -StatusAbortsRecorderIfActive(AbortableRecordingStatus ars) -{ - return ars == ARECORD_ERROR || ars == ARECORD_STOP; -} -#else - -/* - * Normally, during recording, when the recorder cannot continue, it returns - * ARECORD_STOP to indicate that recording should be aborted by the top-level - * recording function. However, if the recorder reenters the interpreter (e.g., - * when executing an inner loop), there will be an immediate abort. This - * condition must be carefully detected and propagated out of all nested - * recorder calls lest the now-invalid TraceRecorder object be accessed - * accidentally. This condition is indicated by the ARECORD_ABORTED value. - * - * The AbortableRecordingStatus enumeration represents the general set of - * possible results of calling a recorder function. Functions that cannot - * possibly return ARECORD_ABORTED may statically guarantee this to the caller - * using the RecordingStatus enumeration. Ideally, C++ would allow subtyping - * of enumerations, but it doesn't. To simulate subtype conversion manually, - * code should call InjectStatus to inject a value of the restricted set into a - * value of the general set. - */ - -enum RecordingStatus { - RECORD_STOP = 0, // Recording should be aborted at the top-level - // call to the recorder. - RECORD_ERROR = 1, // Recording should be aborted at the top-level - // call to the recorder and the interpreter should - // goto error - RECORD_CONTINUE = 2, // Continue recording. - RECORD_IMACRO = 3 // Entered imacro; continue recording. - // Only JSOP_IS_IMACOP opcodes may return this. -}; - -enum AbortableRecordingStatus { - ARECORD_STOP = 0, // see RECORD_STOP - ARECORD_ERROR = 1, // Recording may or may not have been aborted. - // Recording should be aborted at the top-level - // if it has not already been and the interpreter - // should goto error - ARECORD_CONTINUE = 2, // see RECORD_CONTINUE - ARECORD_IMACRO = 3, // see RECORD_IMACRO - ARECORD_IMACRO_ABORTED = 4, // see comment in TR::monitorRecording. - ARECORD_ABORTED = 5, // Recording has already been aborted; the - // interpreter should continue executing - ARECORD_COMPLETED = 6 // Recording completed successfully, the - // trace recorder has been deleted -}; - -static JS_ALWAYS_INLINE AbortableRecordingStatus -InjectStatus(RecordingStatus rs) -{ - return static_cast(rs); -} - -static JS_ALWAYS_INLINE AbortableRecordingStatus -InjectStatus(AbortableRecordingStatus ars) -{ - return ars; -} - -/* - * Return whether the recording status requires the current recording session - * to be deleted. ERROR means the recording session should be deleted if it - * hasn't already. ABORTED and COMPLETED indicate the recording session is - * already deleted, so they return 'false'. - */ -static JS_ALWAYS_INLINE bool -StatusAbortsRecorderIfActive(AbortableRecordingStatus ars) -{ - return ars <= ARECORD_ERROR; -} -#endif - -class SlotMap; -class SlurpInfo; - -/* Results of trying to compare two typemaps together */ -enum TypeConsensus -{ - TypeConsensus_Okay, /* Two typemaps are compatible */ - TypeConsensus_Undemotes, /* Not compatible now, but would be with pending undemotes. */ - TypeConsensus_Bad /* Typemaps are not compatible */ -}; - -enum TracePointAction { - TPA_Nothing, - TPA_RanStuff, - TPA_Recorded, - TPA_Error -}; - -typedef HashMap GuardedShapeTable; - -#ifdef DEBUG -# define AbortRecording(cx, reason) AbortRecordingImpl(cx, reason) -#else -# define AbortRecording(cx, reason) AbortRecordingImpl(cx) -#endif - -void -AbortProfiling(JSContext *cx); - -class TraceRecorder -{ - /*************************************************************** Recording session constants */ - - /* The context in which recording started. */ - JSContext* const cx; - - /* Cached value of JS_TRACE_MONITOR(cx). */ - TraceMonitor* const traceMonitor; - - /* Cached oracle keeps track of hit counts for program counter locations */ - Oracle* oracle; - - /* The Fragment being recorded by this recording session. */ - VMFragment* const fragment; - - /* The root fragment representing the tree. */ - TreeFragment* const tree; - - /* The global object from the start of recording until now. */ - JSObject* const globalObj; - - /* If non-null, the script of outer loop aborted to start recording this loop. */ - JSScript* const outerScript; - - /* If non-null, the pc of the outer loop aborted to start recording this loop. */ - jsbytecode* const outerPC; - - /* If |outerPC|, the argc to use when looking up |outerPC| in the fragments table. */ - uint32 const outerArgc; - - /* If non-null, the side exit from which we are growing. */ - VMSideExit* const anchor; - - /* Instructions yielding the corresponding trace-const members of TracerState. */ - nanojit::LIns* const cx_ins; - nanojit::LIns* const eos_ins; - nanojit::LIns* const eor_ins; - nanojit::LIns* const loopLabel; - - /* Lazy slot import state. */ - unsigned importStackSlots; - unsigned importGlobalSlots; - TypeMap importTypeMap; - - /* - * The LirBuffer used to supply memory to our LirWriter pipeline. Also contains the most recent - * instruction for {sp, rp, state}. Also contains names for debug JIT spew. Should be split. - */ - nanojit::LirBuffer* const lirbuf; - - /* - * Remembers traceAlloc state before recording started; automatically rewinds when mark is - * destroyed on a failed compilation. - */ - VMAllocator::Mark mark; - - /* Remembers the number of sideExits in treeInfo before recording started. */ - const unsigned numSideExitsBefore; - - /*********************************************************** Recording session mutable state */ - - /* Maps interpreter stack values to the instruction generating that value. */ - Tracker tracker; - - /* Maps interpreter stack values to the instruction writing back to the native stack. */ - Tracker nativeFrameTracker; - - /* The start of the global object's slots we assume for the trackers. */ - Value* global_slots; - - /* The number of interpreted calls entered (and not yet left) since recording began. */ - unsigned callDepth; - - /* The current atom table, mirroring the interpreter loop's variable of the same name. */ - JSAtom** atoms; - Value* consts; - - /* An instruction yielding the current script's strict mode code flag. */ - nanojit::LIns* strictModeCode_ins; - - /* FIXME: Dead, but soon to be used for something or other. */ - Queue cfgMerges; - - /* Indicates whether the current tree should be trashed when the recording session ends. */ - bool trashSelf; - - /* A list of trees to trash at the end of the recording session. */ - Queue whichTreesToTrash; - - /* The set of objects whose shapes already have been guarded. */ - GuardedShapeTable guardedShapeTable; - - /* Current initializer depth, and whether any of the initializers are unoptimized NEWINIT. */ - int initDepth; - bool hadNewInit; - -#ifdef DEBUG - /* - * If we are expecting a record_AddProperty callback for this instruction, - * the shape of the object before adding the data property. Else NULL. - */ - const js::Shape* addPropShapeBefore; -#endif - - /***************************************** Temporal state hoisted into the recording session */ - - /* Carry the return value from a STOP/RETURN to the subsequent record_LeaveFrame. */ - nanojit::LIns* rval_ins; - - /* Carry the return value from a native call to the record_NativeCallComplete. */ - nanojit::LIns* native_rval_ins; - - /* Carry the return value of js_CreateThis to record_NativeCallComplete. */ - nanojit::LIns* newobj_ins; - - /* Carry the JSSpecializedNative used to generate a call to record_NativeCallComplete. */ - JSSpecializedNative* pendingSpecializedNative; - - /* Carry whether this is a jsval on the native stack from finishGetProp to monitorRecording. */ - Value* pendingUnboxSlot; - - /* Carry a guard condition to the beginning of the next monitorRecording. */ - nanojit::LIns* pendingGuardCondition; - - /* See AbortRecordingIfUnexpectedGlobalWrite. */ - js::Vector pendingGlobalSlotsToSet; - - /* Carry whether we have an always-exit from emitIf to checkTraceEnd. */ - bool pendingLoop; - - /* Temporary JSSpecializedNative used to describe non-specialized fast natives. */ - JSSpecializedNative generatedSpecializedNative; - - /* Temporary JSValueType array used to construct temporary typemaps. */ - js::Vector tempTypeMap; - - /* Used to generate LIR. Has a short name because it's used a lot. */ - tjit::Writer w; - - /************************************************************* 10 bajillion member functions */ - - /* - * These would be in Writer if they didn't modify TraceRecorder state. - * They are invoked the via macros below that make them look like they are - * part of Writer (hence the "w_" prefix, which looks like "w."). - */ - nanojit::LIns* w_immpObjGC(JSObject* obj); - nanojit::LIns* w_immpFunGC(JSFunction* fun); - nanojit::LIns* w_immpStrGC(JSString* str); - nanojit::LIns* w_immpShapeGC(const js::Shape* shape); - nanojit::LIns* w_immpIdGC(jsid id); - - #define immpObjGC(obj) name(w_immpObjGC(obj), #obj) - #define immpFunGC(fun) name(w_immpFunGC(fun), #fun) - #define immpStrGC(str) name(w_immpStrGC(str), #str) - #define immpAtomGC(atom) name(w_immpStrGC(ATOM_TO_STRING(atom)), "ATOM_TO_STRING(" #atom ")") - #define immpShapeGC(shape) name(w_immpShapeGC(shape), #shape) - #define immpIdGC(id) name(w_immpIdGC(id), #id) - - /* - * Examines current interpreter state to record information suitable for returning to the - * interpreter through a side exit of the given type. - */ - JS_REQUIRES_STACK VMSideExit* snapshot(ExitType exitType); - - /* - * Creates a separate but identical copy of the given side exit, allowing the guards associated - * with each to be entirely separate even after subsequent patching. - */ - JS_REQUIRES_STACK VMSideExit* copy(VMSideExit* exit); - - /* - * Creates an instruction whose payload is a GuardRecord for the given exit. The instruction - * is suitable for use as the final argument of a single call to LirBuffer::insGuard; do not - * reuse the returned value. - */ - JS_REQUIRES_STACK nanojit::GuardRecord* createGuardRecord(VMSideExit* exit); - - JS_REQUIRES_STACK JS_INLINE void markSlotUndemotable(LinkableFragment* f, unsigned slot); - - JS_REQUIRES_STACK JS_INLINE void markSlotUndemotable(LinkableFragment* f, unsigned slot, const void* pc); - - JS_REQUIRES_STACK unsigned findUndemotesInTypemaps(const TypeMap& typeMap, LinkableFragment* f, - Queue& undemotes); - - JS_REQUIRES_STACK void assertDownFrameIsConsistent(VMSideExit* anchor, FrameInfo* fi); - - JS_REQUIRES_STACK void captureStackTypes(unsigned callDepth, JSValueType* typeMap); - - bool isVoidPtrGlobal(const void* p) const; - bool isGlobal(const Value* p) const; - ptrdiff_t nativeGlobalSlot(const Value *p) const; - ptrdiff_t nativeGlobalOffset(const Value* p) const; - JS_REQUIRES_STACK ptrdiff_t nativeStackOffsetImpl(const void* p) const; - JS_REQUIRES_STACK ptrdiff_t nativeStackOffset(const Value* p) const; - JS_REQUIRES_STACK ptrdiff_t nativeStackSlotImpl(const void* p) const; - JS_REQUIRES_STACK ptrdiff_t nativeStackSlot(const Value* p) const; - JS_REQUIRES_STACK ptrdiff_t nativespOffsetImpl(const void* p) const; - JS_REQUIRES_STACK ptrdiff_t nativespOffset(const Value* p) const; - JS_REQUIRES_STACK void importImpl(tjit::Address addr, const void* p, JSValueType t, - const char *prefix, uintN index, JSStackFrame *fp); - JS_REQUIRES_STACK void import(tjit::Address addr, const Value* p, JSValueType t, - const char *prefix, uintN index, JSStackFrame *fp); - JS_REQUIRES_STACK void import(TreeFragment* tree, nanojit::LIns* sp, unsigned stackSlots, - unsigned callDepth, unsigned ngslots, JSValueType* typeMap); - void trackNativeStackUse(unsigned slots); - - JS_REQUIRES_STACK bool isValidSlot(JSObject *obj, const js::Shape* shape); - JS_REQUIRES_STACK bool lazilyImportGlobalSlot(unsigned slot); - JS_REQUIRES_STACK void importGlobalSlot(unsigned slot); - - void ensureCond(nanojit::LIns** ins, bool* cond); - - JS_REQUIRES_STACK RecordingStatus guard(bool expected, nanojit::LIns* cond, ExitType exitType, - bool abortIfAlwaysExits = false); - JS_REQUIRES_STACK RecordingStatus guard(bool expected, nanojit::LIns* cond, VMSideExit* exit, - bool abortIfAlwaysExits = false); - JS_REQUIRES_STACK nanojit::LIns* guard_xov(nanojit::LOpcode op, nanojit::LIns* d0, - nanojit::LIns* d1, VMSideExit* exit); - - nanojit::LIns* writeBack(nanojit::LIns* i, nanojit::LIns* base, ptrdiff_t offset, - bool shouldDemoteToInt32); - -#ifdef DEBUG - bool isValidFrameObjPtr(void *obj); -#endif - void assertInsideLoop(); - - JS_REQUIRES_STACK void setImpl(void* p, nanojit::LIns* l, bool shouldDemoteToInt32 = true); - JS_REQUIRES_STACK void set(Value* p, nanojit::LIns* l, bool shouldDemoteToInt32 = true); - JS_REQUIRES_STACK void setFrameObjPtr(void* p, nanojit::LIns* l, - bool shouldDemoteToInt32 = true); - nanojit::LIns* getFromTrackerImpl(const void *p); - nanojit::LIns* getFromTracker(const Value* p); - JS_REQUIRES_STACK nanojit::LIns* getImpl(const void* p); - JS_REQUIRES_STACK nanojit::LIns* get(const Value* p); - JS_REQUIRES_STACK nanojit::LIns* getFrameObjPtr(void* p); - JS_REQUIRES_STACK nanojit::LIns* attemptImport(const Value* p); - JS_REQUIRES_STACK nanojit::LIns* addr(Value* p); - - JS_REQUIRES_STACK bool knownImpl(const void* p); - JS_REQUIRES_STACK bool known(const Value* p); - JS_REQUIRES_STACK bool known(JSObject** p); - /* - * The slots of the global object are sometimes reallocated by the - * interpreter. This function checks for that condition and re-maps the - * entries of the tracker accordingly. - */ - JS_REQUIRES_STACK void checkForGlobalObjectReallocation() { - if (global_slots != globalObj->getSlots()) - checkForGlobalObjectReallocationHelper(); - } - JS_REQUIRES_STACK void checkForGlobalObjectReallocationHelper(); - - JS_REQUIRES_STACK TypeConsensus selfTypeStability(SlotMap& smap); - JS_REQUIRES_STACK TypeConsensus peerTypeStability(SlotMap& smap, const void* ip, - TreeFragment** peer); - - JS_REQUIRES_STACK Value& argval(unsigned n) const; - JS_REQUIRES_STACK Value& varval(unsigned n) const; - JS_REQUIRES_STACK Value& stackval(int n) const; - - JS_REQUIRES_STACK void updateAtoms(); - JS_REQUIRES_STACK void updateAtoms(JSScript *script); - - struct NameResult { - // |tracked| is true iff the result of the name lookup is a variable that - // is already in the tracker. The rest of the fields are set only if - // |tracked| is false. - bool tracked; - Value v; // current property value - JSObject *obj; // Call object where name was found - nanojit::LIns *obj_ins; // LIR value for obj - js::Shape *shape; // shape name was resolved to - }; - - JS_REQUIRES_STACK nanojit::LIns* scopeChain(); - JS_REQUIRES_STACK nanojit::LIns* entryScopeChain() const; - JS_REQUIRES_STACK nanojit::LIns* entryFrameIns() const; - JS_REQUIRES_STACK JSStackFrame* frameIfInRange(JSObject* obj, unsigned* depthp = NULL) const; - JS_REQUIRES_STACK RecordingStatus traverseScopeChain(JSObject *obj, nanojit::LIns *obj_ins, JSObject *obj2, nanojit::LIns *&obj2_ins); - JS_REQUIRES_STACK AbortableRecordingStatus scopeChainProp(JSObject* obj, Value*& vp, nanojit::LIns*& ins, NameResult& nr, JSObject **scopeObjp = NULL); - JS_REQUIRES_STACK RecordingStatus callProp(JSObject* obj, JSProperty* shape, jsid id, Value*& vp, nanojit::LIns*& ins, NameResult& nr); - - JS_REQUIRES_STACK nanojit::LIns* arg(unsigned n); - JS_REQUIRES_STACK void arg(unsigned n, nanojit::LIns* i); - JS_REQUIRES_STACK nanojit::LIns* var(unsigned n); - JS_REQUIRES_STACK void var(unsigned n, nanojit::LIns* i); - JS_REQUIRES_STACK nanojit::LIns* upvar(JSScript* script, JSUpvarArray* uva, uintN index, Value& v); - nanojit::LIns* stackLoad(tjit::Address addr, uint8 type); - JS_REQUIRES_STACK nanojit::LIns* stack(int n); - JS_REQUIRES_STACK void stack(int n, nanojit::LIns* i); - - JS_REQUIRES_STACK void guardNonNeg(nanojit::LIns* d0, nanojit::LIns* d1, VMSideExit* exit); - JS_REQUIRES_STACK nanojit::LIns* alu(nanojit::LOpcode op, jsdouble v0, jsdouble v1, - nanojit::LIns* s0, nanojit::LIns* s1); - - nanojit::LIns* d2i(nanojit::LIns* f, bool resultCanBeImpreciseIfFractional = false); - nanojit::LIns* d2u(nanojit::LIns* d); - JS_REQUIRES_STACK RecordingStatus makeNumberInt32(nanojit::LIns* d, nanojit::LIns** num_ins); - JS_REQUIRES_STACK RecordingStatus makeNumberUint32(nanojit::LIns* d, nanojit::LIns** num_ins); - JS_REQUIRES_STACK nanojit::LIns* stringify(const Value& v); - - JS_REQUIRES_STACK nanojit::LIns* newArguments(nanojit::LIns* callee_ins); - - JS_REQUIRES_STACK bool canCallImacro() const; - JS_REQUIRES_STACK RecordingStatus callImacro(jsbytecode* imacro); - JS_REQUIRES_STACK RecordingStatus callImacroInfallibly(jsbytecode* imacro); - - JS_REQUIRES_STACK AbortableRecordingStatus ifop(); - JS_REQUIRES_STACK RecordingStatus switchop(); -#ifdef NANOJIT_IA32 - JS_REQUIRES_STACK AbortableRecordingStatus tableswitch(); -#endif - JS_REQUIRES_STACK RecordingStatus inc(Value& v, jsint incr, bool pre = true); - JS_REQUIRES_STACK RecordingStatus inc(const Value &v, nanojit::LIns*& v_ins, - Value &v_out, jsint incr, - bool pre = true); - JS_REQUIRES_STACK RecordingStatus incHelper(const Value &v, nanojit::LIns*& v_ins, - Value &v_after, - nanojit::LIns*& v_ins_after, - jsint incr); - JS_REQUIRES_STACK AbortableRecordingStatus incProp(jsint incr, bool pre = true); - JS_REQUIRES_STACK RecordingStatus incElem(jsint incr, bool pre = true); - JS_REQUIRES_STACK AbortableRecordingStatus incName(jsint incr, bool pre = true); - - JS_REQUIRES_STACK RecordingStatus strictEquality(bool equal, bool cmpCase); - JS_REQUIRES_STACK AbortableRecordingStatus equality(bool negate, bool tryBranchAfterCond); - JS_REQUIRES_STACK AbortableRecordingStatus equalityHelper(Value& l, Value& r, - nanojit::LIns* l_ins, nanojit::LIns* r_ins, - bool negate, bool tryBranchAfterCond, - Value& rval); - JS_REQUIRES_STACK AbortableRecordingStatus relational(nanojit::LOpcode op, bool tryBranchAfterCond); - - JS_REQUIRES_STACK RecordingStatus unary(nanojit::LOpcode op); - JS_REQUIRES_STACK RecordingStatus binary(nanojit::LOpcode op); - - JS_REQUIRES_STACK RecordingStatus guardShape(nanojit::LIns* obj_ins, JSObject* obj, - uint32 shape, const char* name, VMSideExit* exit); - -#if defined DEBUG_notme && defined XP_UNIX - void dumpGuardedShapes(const char* prefix); -#endif - - void forgetGuardedShapes(); - - JS_REQUIRES_STACK AbortableRecordingStatus test_property_cache(JSObject* obj, nanojit::LIns* obj_ins, - JSObject*& obj2, PCVal& pcval); - JS_REQUIRES_STACK RecordingStatus guardPropertyCacheHit(nanojit::LIns* obj_ins, - JSObject* aobj, - JSObject* obj2, - PropertyCacheEntry* entry, - PCVal& pcval); - - void stobj_set_fslot(nanojit::LIns *obj_ins, unsigned slot, const Value &v, - nanojit::LIns* v_ins); - void stobj_set_dslot(nanojit::LIns *obj_ins, unsigned slot, - nanojit::LIns*& slots_ins, const Value &v, nanojit::LIns* v_ins); - void stobj_set_slot(JSObject *obj, nanojit::LIns* obj_ins, unsigned slot, - nanojit::LIns*& slots_ins, const Value &v, nanojit::LIns* v_ins); - - nanojit::LIns* unbox_slot(JSObject *obj, nanojit::LIns *obj_ins, uint32 slot, - VMSideExit *exit); - - JS_REQUIRES_STACK AbortableRecordingStatus name(Value*& vp, nanojit::LIns*& ins, NameResult& nr); - JS_REQUIRES_STACK AbortableRecordingStatus prop(JSObject* obj, nanojit::LIns* obj_ins, - uint32 *slotp, nanojit::LIns** v_insp, - Value* outp); - JS_REQUIRES_STACK RecordingStatus propTail(JSObject* obj, nanojit::LIns* obj_ins, - JSObject* obj2, PCVal pcval, - uint32 *slotp, nanojit::LIns** v_insp, - Value* outp); - JS_REQUIRES_STACK RecordingStatus denseArrayElement(Value& oval, Value& idx, Value*& vp, - nanojit::LIns*& v_ins, - nanojit::LIns*& addr_ins, - VMSideExit* exit); - JS_REQUIRES_STACK nanojit::LIns *canonicalizeNaNs(nanojit::LIns *dval_ins); - JS_REQUIRES_STACK AbortableRecordingStatus typedArrayElement(Value& oval, Value& idx, Value*& vp, - nanojit::LIns*& v_ins); - JS_REQUIRES_STACK AbortableRecordingStatus getProp(JSObject* obj, nanojit::LIns* obj_ins); - JS_REQUIRES_STACK AbortableRecordingStatus getProp(Value& v); - JS_REQUIRES_STACK RecordingStatus getThis(nanojit::LIns*& this_ins); - - JS_REQUIRES_STACK void storeMagic(JSWhyMagic why, tjit::Address addr); - JS_REQUIRES_STACK AbortableRecordingStatus unboxNextValue(nanojit::LIns* &v_ins); - - JS_REQUIRES_STACK VMSideExit* enterDeepBailCall(); - JS_REQUIRES_STACK void leaveDeepBailCall(); - - JS_REQUIRES_STACK RecordingStatus primitiveToStringInPlace(Value* vp); - JS_REQUIRES_STACK void finishGetProp(nanojit::LIns* obj_ins, nanojit::LIns* vp_ins, - nanojit::LIns* ok_ins, Value* outp); - JS_REQUIRES_STACK RecordingStatus getPropertyByName(nanojit::LIns* obj_ins, Value* idvalp, - Value* outp); - JS_REQUIRES_STACK RecordingStatus getPropertyByIndex(nanojit::LIns* obj_ins, - nanojit::LIns* index_ins, Value* outp); - JS_REQUIRES_STACK RecordingStatus getPropertyById(nanojit::LIns* obj_ins, Value* outp); - JS_REQUIRES_STACK RecordingStatus getPropertyWithNativeGetter(nanojit::LIns* obj_ins, - const js::Shape* shape, - Value* outp); - JS_REQUIRES_STACK RecordingStatus getPropertyWithScriptGetter(JSObject *obj, - nanojit::LIns* obj_ins, - const js::Shape* shape); - - JS_REQUIRES_STACK RecordingStatus getCharCodeAt(JSString *str, - nanojit::LIns* str_ins, nanojit::LIns* idx_ins, - nanojit::LIns** out_ins); - JS_REQUIRES_STACK nanojit::LIns* getUnitString(nanojit::LIns* str_ins, nanojit::LIns* idx_ins); - JS_REQUIRES_STACK RecordingStatus getCharAt(JSString *str, - nanojit::LIns* str_ins, nanojit::LIns* idx_ins, - JSOp mode, nanojit::LIns** out_ins); - - JS_REQUIRES_STACK RecordingStatus initOrSetPropertyByName(nanojit::LIns* obj_ins, - Value* idvalp, Value* rvalp, - bool init); - JS_REQUIRES_STACK RecordingStatus initOrSetPropertyByIndex(nanojit::LIns* obj_ins, - nanojit::LIns* index_ins, - Value* rvalp, bool init); - JS_REQUIRES_STACK AbortableRecordingStatus setElem(int lval_spindex, int idx_spindex, - int v_spindex); - - JS_REQUIRES_STACK RecordingStatus lookupForSetPropertyOp(JSObject* obj, nanojit::LIns* obj_ins, - jsid id, bool* safep, - JSObject** pobjp, - const js::Shape** shapep); - JS_REQUIRES_STACK RecordingStatus nativeSet(JSObject* obj, nanojit::LIns* obj_ins, - const js::Shape* shape, - const Value& v, nanojit::LIns* v_ins); - JS_REQUIRES_STACK RecordingStatus addDataProperty(JSObject* obj); - JS_REQUIRES_STACK RecordingStatus setCallProp(JSObject* callobj, nanojit::LIns* callobj_ins, - const js::Shape* shape, nanojit::LIns* v_ins, - const Value& v); - JS_REQUIRES_STACK RecordingStatus setProperty(JSObject* obj, nanojit::LIns* obj_ins, - const Value& v, nanojit::LIns* v_ins, - bool* deferredp); - JS_REQUIRES_STACK RecordingStatus recordSetPropertyOp(); - JS_REQUIRES_STACK RecordingStatus recordInitPropertyOp(jsbytecode op); - - void box_undefined_into(tjit::Address addr); -#if JS_BITS_PER_WORD == 32 - void box_null_into(tjit::Address addr); - nanojit::LIns* unbox_number_as_double(tjit::Address addr, nanojit::LIns* tag_ins, - VMSideExit* exit); - nanojit::LIns* unbox_object(tjit::Address addr, nanojit::LIns* tag_ins, JSValueType type, - VMSideExit* exit); - nanojit::LIns* unbox_non_double_object(tjit::Address addr, nanojit::LIns* tag_ins, - JSValueType type, VMSideExit* exit); -#elif JS_BITS_PER_WORD == 64 - nanojit::LIns* non_double_object_value_has_type(nanojit::LIns* v_ins, JSValueType type); - nanojit::LIns* unpack_ptr(nanojit::LIns* v_ins); - nanojit::LIns* unbox_number_as_double(nanojit::LIns* v_ins, VMSideExit* exit); - nanojit::LIns* unbox_object(nanojit::LIns* v_ins, JSValueType type, VMSideExit* exit); - nanojit::LIns* unbox_non_double_object(nanojit::LIns* v_ins, JSValueType type, VMSideExit* exit); -#endif - - nanojit::LIns* unbox_value(const Value& v, tjit::Address addr, VMSideExit* exit, - bool force_double=false); - void unbox_any_object(tjit::Address addr, nanojit::LIns** obj_ins, nanojit::LIns** is_obj_ins); - nanojit::LIns* is_boxed_true(tjit::Address addr); - nanojit::LIns* is_boxed_magic(tjit::Address addr, JSWhyMagic why); - - nanojit::LIns* is_string_id(nanojit::LIns* id_ins); - nanojit::LIns* unbox_string_id(nanojit::LIns* id_ins); - nanojit::LIns* unbox_int_id(nanojit::LIns* id_ins); - - /* Box a slot on trace into the given address at the given offset. */ - void box_value_into(const Value& v, nanojit::LIns* v_ins, tjit::Address addr); - - /* - * Box a slot so that it may be passed with value semantics to a native. On - * 32-bit, this currently means boxing the value into insAlloc'd memory and - * returning the address which is passed as a Value*. On 64-bit, this - * currently means returning the boxed value which is passed as a jsval. - */ - nanojit::LIns* box_value_for_native_call(const Value& v, nanojit::LIns* v_ins); - - /* Box a slot into insAlloc'd memory. */ - nanojit::LIns* box_value_into_alloc(const Value& v, nanojit::LIns* v_ins); - - JS_REQUIRES_STACK void guardClassHelper(bool cond, nanojit::LIns* obj_ins, Class* clasp, - VMSideExit* exit, nanojit::LoadQual loadQual); - JS_REQUIRES_STACK void guardClass(nanojit::LIns* obj_ins, Class* clasp, - VMSideExit* exit, nanojit::LoadQual loadQual); - JS_REQUIRES_STACK void guardNotClass(nanojit::LIns* obj_ins, Class* clasp, - VMSideExit* exit, nanojit::LoadQual loadQual); - JS_REQUIRES_STACK void guardDenseArray(nanojit::LIns* obj_ins, ExitType exitType); - JS_REQUIRES_STACK void guardDenseArray(nanojit::LIns* obj_ins, VMSideExit* exit); - JS_REQUIRES_STACK bool guardHasPrototype(JSObject* obj, nanojit::LIns* obj_ins, - JSObject** pobj, nanojit::LIns** pobj_ins, - VMSideExit* exit); - JS_REQUIRES_STACK RecordingStatus guardPrototypeHasNoIndexedProperties(JSObject* obj, - nanojit::LIns* obj_ins, - VMSideExit* exit); - JS_REQUIRES_STACK RecordingStatus guardNativeConversion(Value& v); - JS_REQUIRES_STACK void clearReturningFrameFromNativeTracker(); - JS_REQUIRES_STACK AbortableRecordingStatus putActivationObjects(); - JS_REQUIRES_STACK RecordingStatus createThis(JSObject& ctor, nanojit::LIns* ctor_ins, - nanojit::LIns** thisobj_insp); - JS_REQUIRES_STACK RecordingStatus guardCallee(Value& callee); - JS_REQUIRES_STACK JSStackFrame *guardArguments(JSObject *obj, nanojit::LIns* obj_ins, - unsigned *depthp); - JS_REQUIRES_STACK nanojit::LIns* guardArgsLengthNotAssigned(nanojit::LIns* argsobj_ins); - JS_REQUIRES_STACK void guardNotHole(nanojit::LIns* argsobj_ins, nanojit::LIns* ids_ins); - JS_REQUIRES_STACK RecordingStatus getClassPrototype(JSObject* ctor, - nanojit::LIns*& proto_ins); - JS_REQUIRES_STACK RecordingStatus getClassPrototype(JSProtoKey key, - nanojit::LIns*& proto_ins); - JS_REQUIRES_STACK RecordingStatus newArray(JSObject* ctor, uint32 argc, Value* argv, - Value* rval); - JS_REQUIRES_STACK RecordingStatus newString(JSObject* ctor, uint32 argc, Value* argv, - Value* rval); - JS_REQUIRES_STACK RecordingStatus interpretedFunctionCall(Value& fval, JSFunction* fun, - uintN argc, bool constructing); - JS_REQUIRES_STACK void propagateFailureToBuiltinStatus(nanojit::LIns *ok_ins, - nanojit::LIns *&status_ins); - JS_REQUIRES_STACK RecordingStatus emitNativeCall(JSSpecializedNative* sn, uintN argc, - nanojit::LIns* args[], bool rooted); - JS_REQUIRES_STACK void emitNativePropertyOp(const js::Shape* shape, - nanojit::LIns* obj_ins, - bool setflag, - nanojit::LIns* addr_boxed_val_ins); - JS_REQUIRES_STACK RecordingStatus callSpecializedNative(JSNativeTraceInfo* trcinfo, uintN argc, - bool constructing); - JS_REQUIRES_STACK RecordingStatus callNative(uintN argc, JSOp mode); - JS_REQUIRES_STACK RecordingStatus callFloatReturningInt(uintN argc, - const nanojit::CallInfo *ci); - JS_REQUIRES_STACK RecordingStatus functionCall(uintN argc, JSOp mode); - - JS_REQUIRES_STACK void trackCfgMerges(jsbytecode* pc); - JS_REQUIRES_STACK void emitIf(jsbytecode* pc, bool cond, nanojit::LIns* x); - JS_REQUIRES_STACK void fuseIf(jsbytecode* pc, bool cond, nanojit::LIns* x); - JS_REQUIRES_STACK AbortableRecordingStatus checkTraceEnd(jsbytecode* pc); - - AbortableRecordingStatus hasMethod(JSObject* obj, jsid id, bool& found); - JS_REQUIRES_STACK AbortableRecordingStatus hasIteratorMethod(JSObject* obj, bool& found); - - JS_REQUIRES_STACK jsatomid getFullIndex(ptrdiff_t pcoff = 0); - - JS_REQUIRES_STACK JSValueType determineSlotType(Value* vp); - - JS_REQUIRES_STACK RecordingStatus setUpwardTrackedVar(Value* stackVp, const Value& v, - nanojit::LIns* v_ins); - - JS_REQUIRES_STACK AbortableRecordingStatus compile(); - JS_REQUIRES_STACK AbortableRecordingStatus closeLoop(); - JS_REQUIRES_STACK AbortableRecordingStatus endLoop(); - JS_REQUIRES_STACK AbortableRecordingStatus endLoop(VMSideExit* exit); - JS_REQUIRES_STACK void joinEdgesToEntry(TreeFragment* peer_root); - JS_REQUIRES_STACK void adjustCallerTypes(TreeFragment* f); - JS_REQUIRES_STACK void prepareTreeCall(TreeFragment* inner); - JS_REQUIRES_STACK void emitTreeCall(TreeFragment* inner, VMSideExit* exit); - JS_REQUIRES_STACK void determineGlobalTypes(JSValueType* typeMap); - JS_REQUIRES_STACK VMSideExit* downSnapshot(FrameInfo* downFrame); - JS_REQUIRES_STACK TreeFragment* findNestedCompatiblePeer(TreeFragment* f); - JS_REQUIRES_STACK AbortableRecordingStatus attemptTreeCall(TreeFragment* inner, - uintN& inlineCallCount); - - static JS_REQUIRES_STACK MonitorResult recordLoopEdge(JSContext* cx, TraceRecorder* r, - uintN& inlineCallCount); - - /* Allocators associated with this recording session. */ - VMAllocator& tempAlloc() const { return *traceMonitor->tempAlloc; } - VMAllocator& traceAlloc() const { return *traceMonitor->traceAlloc; } - VMAllocator& dataAlloc() const { return *traceMonitor->dataAlloc; } - - /* Member declarations for each opcode, to be called before interpreting the opcode. */ -#define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format) \ - JS_REQUIRES_STACK AbortableRecordingStatus record_##op(); -# include "jsopcode.tbl" -#undef OPDEF - - JS_REQUIRES_STACK - TraceRecorder(JSContext* cx, TraceMonitor *tm, VMSideExit*, VMFragment*, - unsigned stackSlots, unsigned ngslots, JSValueType* typeMap, - VMSideExit* expectedInnerExit, JSScript* outerScript, jsbytecode* outerPC, - uint32 outerArgc, bool speculate); - - /* The destructor should only be called through finish*, not directly. */ - ~TraceRecorder(); - JS_REQUIRES_STACK AbortableRecordingStatus finishSuccessfully(); - - enum AbortResult { NORMAL_ABORT, JIT_RESET }; - JS_REQUIRES_STACK AbortResult finishAbort(const char* reason); - - friend class ImportBoxedStackSlotVisitor; - friend class ImportUnboxedStackSlotVisitor; - friend class ImportGlobalSlotVisitor; - friend class AdjustCallerGlobalTypesVisitor; - friend class AdjustCallerStackTypesVisitor; - friend class TypeCompatibilityVisitor; - friend class ImportFrameSlotsVisitor; - friend class SlotMap; - friend class DefaultSlotMap; - friend class DetermineTypesVisitor; - friend class RecursiveSlotMap; - friend class UpRecursiveSlotMap; - friend MonitorResult RecordLoopEdge(JSContext*, TraceMonitor*, uintN&); - friend TracePointAction RecordTracePoint(JSContext*, TraceMonitor*, uintN &inlineCallCount, - bool *blacklist); - friend AbortResult AbortRecording(JSContext*, const char*); - friend class BoxArg; - friend void TraceMonitor::sweep(JSContext *cx); - - public: - static bool JS_REQUIRES_STACK - startRecorder(JSContext*, TraceMonitor *, VMSideExit*, VMFragment*, - unsigned stackSlots, unsigned ngslots, JSValueType* typeMap, - VMSideExit* expectedInnerExit, JSScript* outerScript, jsbytecode* outerPC, - uint32 outerArgc, bool speculate); - - /* Accessors. */ - VMFragment* getFragment() const { return fragment; } - TreeFragment* getTree() const { return tree; } - bool outOfMemory() const { return traceMonitor->outOfMemory(); } - Oracle* getOracle() const { return oracle; } - JSObject* getGlobal() const { return globalObj; } - - /* Entry points / callbacks from the interpreter. */ - JS_REQUIRES_STACK AbortableRecordingStatus monitorRecording(JSOp op); - JS_REQUIRES_STACK AbortableRecordingStatus record_EnterFrame(); - JS_REQUIRES_STACK AbortableRecordingStatus record_LeaveFrame(); - JS_REQUIRES_STACK AbortableRecordingStatus record_AddProperty(JSObject *obj); - JS_REQUIRES_STACK AbortableRecordingStatus record_DefLocalFunSetSlot(uint32 slot, - JSObject* obj); - JS_REQUIRES_STACK AbortableRecordingStatus record_NativeCallComplete(); - void forgetGuardedShapesForObject(JSObject* obj); - - bool globalSetExpected(unsigned slot) { - unsigned *pi = Find(pendingGlobalSlotsToSet, slot); - if (pi == pendingGlobalSlotsToSet.end()) { - /* - * Do slot arithmetic manually to avoid getSlotRef assertions which - * do not need to be satisfied for this purpose. - */ - Value *vp = globalObj->getSlots() + slot; - - /* If this global is definitely being tracked, then the write is unexpected. */ - if (tracker.has(vp)) - return false; - - /* - * Otherwise, only abort if the global is not present in the - * import typemap. Just deep aborting false here is not acceptable, - * because the recorder does not guard on every operation that - * could lazily resolve. Since resolving adds properties to - * reserved slots, the tracer will never have imported them. - */ - return tree->globalSlots->offsetOf((uint16)nativeGlobalSlot(vp)) == -1; - } - pendingGlobalSlotsToSet.erase(pi); - return true; - } - -#ifdef DEBUG - /* Debug printing functionality to emit printf() on trace. */ - JS_REQUIRES_STACK void tprint(const char *format, int count, nanojit::LIns *insa[]); - JS_REQUIRES_STACK void tprint(const char *format); - JS_REQUIRES_STACK void tprint(const char *format, nanojit::LIns *ins); - JS_REQUIRES_STACK void tprint(const char *format, nanojit::LIns *ins1, - nanojit::LIns *ins2); - JS_REQUIRES_STACK void tprint(const char *format, nanojit::LIns *ins1, - nanojit::LIns *ins2, nanojit::LIns *ins3); - JS_REQUIRES_STACK void tprint(const char *format, nanojit::LIns *ins1, - nanojit::LIns *ins2, nanojit::LIns *ins3, - nanojit::LIns *ins4); - JS_REQUIRES_STACK void tprint(const char *format, nanojit::LIns *ins1, - nanojit::LIns *ins2, nanojit::LIns *ins3, - nanojit::LIns *ins4, nanojit::LIns *ins5); - JS_REQUIRES_STACK void tprint(const char *format, nanojit::LIns *ins1, - nanojit::LIns *ins2, nanojit::LIns *ins3, - nanojit::LIns *ins4, nanojit::LIns *ins5, - nanojit::LIns *ins6); -#endif -}; - -#define TRACING_ENABLED(cx) ((cx)->traceJitEnabled) -#define REGEX_JIT_ENABLED(cx) ((cx)->traceJitEnabled || (cx)->methodJitEnabled) - -#define JSOP_IN_RANGE(op,lo,hi) (uintN((op) - (lo)) <= uintN((hi) - (lo))) -#define JSOP_IS_BINARY(op) JSOP_IN_RANGE(op, JSOP_BITOR, JSOP_MOD) -#define JSOP_IS_UNARY(op) JSOP_IN_RANGE(op, JSOP_NEG, JSOP_POS) -#define JSOP_IS_EQUALITY(op) JSOP_IN_RANGE(op, JSOP_EQ, JSOP_NE) - -#define TRACE_ARGS_(x,args) \ - JS_BEGIN_MACRO \ - if (TraceRecorder* tr_ = TRACE_RECORDER(cx)) { \ - AbortableRecordingStatus status = tr_->record_##x args; \ - if (StatusAbortsRecorderIfActive(status)) { \ - if (TRACE_RECORDER(cx)) { \ - JS_ASSERT(TRACE_RECORDER(cx) == tr_); \ - AbortRecording(cx, #x); \ - } \ - if (status == ARECORD_ERROR) \ - goto error; \ - } \ - JS_ASSERT(status != ARECORD_IMACRO); \ - } \ - JS_END_MACRO - -#define TRACE_ARGS(x,args) TRACE_ARGS_(x, args) -#define TRACE_0(x) TRACE_ARGS(x, ()) -#define TRACE_1(x,a) TRACE_ARGS(x, (a)) -#define TRACE_2(x,a,b) TRACE_ARGS(x, (a, b)) - -extern JS_REQUIRES_STACK MonitorResult -MonitorLoopEdge(JSContext* cx, uintN& inlineCallCount, JSInterpMode interpMode); - -extern JS_REQUIRES_STACK TracePointAction -RecordTracePoint(JSContext*, uintN& inlineCallCount, bool* blacklist); - -extern JS_REQUIRES_STACK TracePointAction -MonitorTracePoint(JSContext*, uintN& inlineCallCount, bool* blacklist, - void** traceData, uintN *traceEpoch, uint32 *loopCounter, uint32 hits); - -extern JS_REQUIRES_STACK TraceRecorder::AbortResult -AbortRecording(JSContext* cx, const char* reason); - -extern bool -InitJIT(TraceMonitor *tm); - -extern void -FinishJIT(TraceMonitor *tm); - -extern void -PurgeScriptFragments(TraceMonitor* tm, JSScript* script); - -extern bool -OverfullJITCache(JSContext *cx, TraceMonitor* tm); - -extern void -FlushJITCache(JSContext* cx, TraceMonitor* tm); - -extern JSObject * -GetBuiltinFunction(JSContext *cx, uintN index); - -extern void -SetMaxCodeCacheBytes(JSContext* cx, uint32 bytes); - -extern void -ExternNativeToValue(JSContext* cx, Value& v, JSValueType type, double* slot); - -#ifdef MOZ_TRACEVIS - -extern JS_FRIEND_API(bool) -StartTraceVis(const char* filename); - -extern JS_FRIEND_API(JSBool) -StartTraceVisNative(JSContext *cx, uintN argc, jsval *vp); - -extern JS_FRIEND_API(bool) -StopTraceVis(); - -extern JS_FRIEND_API(JSBool) -StopTraceVisNative(JSContext *cx, uintN argc, jsval *vp); - -/* Must contain no more than 16 items. */ -enum TraceVisState { - // Special: means we returned from current activity to last - S_EXITLAST, - // Activities - S_INTERP, - S_MONITOR, - S_RECORD, - S_COMPILE, - S_EXECUTE, - S_NATIVE, - // Events: these all have (bit 3) == 1. - S_RESET = 8 -}; - -/* Reason for an exit to the interpreter. */ -enum TraceVisExitReason { - R_NONE, - R_ABORT, - /* Reasons in MonitorLoopEdge */ - R_INNER_SIDE_EXIT, - R_DOUBLES, - R_CALLBACK_PENDING, - R_OOM_GETANCHOR, - R_BACKED_OFF, - R_COLD, - R_FAIL_RECORD_TREE, - R_MAX_PEERS, - R_FAIL_EXECUTE_TREE, - R_FAIL_STABILIZE, - R_FAIL_EXTEND_FLUSH, - R_FAIL_EXTEND_MAX_BRANCHES, - R_FAIL_EXTEND_START, - R_FAIL_EXTEND_COLD, - R_FAIL_SCOPE_CHAIN_CHECK, - R_NO_EXTEND_OUTER, - R_MISMATCH_EXIT, - R_OOM_EXIT, - R_TIMEOUT_EXIT, - R_DEEP_BAIL_EXIT, - R_STATUS_EXIT, - R_OTHER_EXIT -}; - -enum TraceVisFlushReason { - FR_DEEP_BAIL, - FR_OOM, - FR_GLOBAL_SHAPE_MISMATCH, - FR_GLOBALS_FULL -}; - -const unsigned long long MS64_MASK = 0xfull << 60; -const unsigned long long MR64_MASK = 0x1full << 55; -const unsigned long long MT64_MASK = ~(MS64_MASK | MR64_MASK); - -extern FILE* traceVisLogFile; -extern JSHashTable *traceVisScriptTable; - -extern JS_FRIEND_API(void) -StoreTraceVisState(JSContext *cx, TraceVisState s, TraceVisExitReason r); - -static inline void -LogTraceVisState(JSContext *cx, TraceVisState s, TraceVisExitReason r) -{ - if (traceVisLogFile) { - unsigned long long sllu = s; - unsigned long long rllu = r; - unsigned long long d = (sllu << 60) | (rllu << 55) | (rdtsc() & MT64_MASK); - fwrite(&d, sizeof(d), 1, traceVisLogFile); - } - if (traceVisScriptTable) { - StoreTraceVisState(cx, s, r); - } -} - -/* - * Although this runs the same code as LogTraceVisState, it is a separate - * function because the meaning of the log entry is different. Also, the entry - * formats may diverge someday. - */ -static inline void -LogTraceVisEvent(JSContext *cx, TraceVisState s, TraceVisFlushReason r) -{ - LogTraceVisState(cx, s, (TraceVisExitReason) r); -} - -static inline void -EnterTraceVisState(JSContext *cx, TraceVisState s, TraceVisExitReason r) -{ - LogTraceVisState(cx, s, r); -} - -static inline void -ExitTraceVisState(JSContext *cx, TraceVisExitReason r) -{ - LogTraceVisState(cx, S_EXITLAST, r); -} - -struct TraceVisStateObj { - TraceVisExitReason r; - JSContext *mCx; - - inline TraceVisStateObj(JSContext *cx, TraceVisState s) : r(R_NONE) - { - EnterTraceVisState(cx, s, R_NONE); - mCx = cx; - } - inline ~TraceVisStateObj() - { - ExitTraceVisState(mCx, r); - } -}; - -#endif /* MOZ_TRACEVIS */ - -} /* namespace js */ - -#else /* !JS_TRACER */ - -#define TRACE_0(x) ((void)0) -#define TRACE_1(x,a) ((void)0) -#define TRACE_2(x,a,b) ((void)0) - -#endif /* !JS_TRACER */ - -namespace js { - -/* - * While recording, the slots of the global object may change payload or type. - * This is fine as long as the recorder expects this change (and therefore has - * generated the corresponding LIR, snapshots, etc). The recorder indicates - * that it expects a write to a global slot by setting pendingGlobalSlotsToSet - * in the recorder, before the write is made by the interpreter, and clearing - * pendingGlobalSlotsToSet before recording the next op. Any global slot write - * that has not been whitelisted in this manner is therefore unexpected and, if - * the global slot is actually being tracked, recording must be aborted. - */ -static JS_INLINE void -AbortRecordingIfUnexpectedGlobalWrite(JSContext *cx, JSObject *obj, unsigned slot) -{ -#ifdef JS_TRACER - if (TraceRecorder *tr = TRACE_RECORDER(cx)) { - if (obj == tr->getGlobal() && !tr->globalSetExpected(slot)) - AbortRecording(cx, "Global slot written outside tracer supervision"); - } -#endif -} - -} /* namespace js */ - -#endif /* jstracer_h___ */ diff --git a/x86/mozilla/include/jstypedarray.h b/x86/mozilla/include/jstypedarray.h deleted file mode 100644 index 953914d..0000000 --- a/x86/mozilla/include/jstypedarray.h +++ /dev/null @@ -1,237 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 4; tab-width: 40; indent-tabs-mode: nil -*- */ -/* vim: set ts=40 sw=4 et tw=99: */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla WebGL impl - * - * The Initial Developer of the Original Code is - * Mozilla Foundation - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Vladimir Vukicevic - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jstypedarray_h -#define jstypedarray_h - -#include "jsapi.h" -#include "jsvalue.h" - -typedef struct JSProperty JSProperty; - -namespace js { - -/* - * ArrayBuffer - * - * This class holds the underlying raw buffer that the TypedArray - * subclasses access. It can be created explicitly and passed to a - * TypedArray subclass, or can be created implicitly by constructing a - * TypedArray with a size. - */ -struct JS_FRIEND_API(ArrayBuffer) { - static Class jsclass; - static JSPropertySpec jsprops[]; - - static JSBool prop_getByteLength(JSContext *cx, JSObject *obj, jsid id, Value *vp); - static void class_finalize(JSContext *cx, JSObject *obj); - - static JSBool class_constructor(JSContext *cx, uintN argc, Value *vp); - - static JSObject *create(JSContext *cx, int32 nbytes); - - static ArrayBuffer *fromJSObject(JSObject *obj); - - ArrayBuffer() - : data(0), byteLength() - { - } - - ~ArrayBuffer(); - - bool allocateStorage(JSContext *cx, uint32 bytes); - void freeStorage(JSContext *cx); - - void *offsetData(uint32 offs) { - return (void*) (((intptr_t)data) + offs); - } - - void *data; - uint32 byteLength; -}; - -/* - * TypedArray - * - * The non-templated base class for the specific typed implementations. - * This class holds all the member variables that are used by - * the subclasses. - */ - -struct JS_FRIEND_API(TypedArray) { - enum { - TYPE_INT8 = 0, - TYPE_UINT8, - TYPE_INT16, - TYPE_UINT16, - TYPE_INT32, - TYPE_UINT32, - TYPE_FLOAT32, - TYPE_FLOAT64, - - /* - * Special type that's a uint8, but assignments are clamped to 0 .. 255. - * Treat the raw data type as a uint8. - */ - TYPE_UINT8_CLAMPED, - - TYPE_MAX - }; - - // and MUST NOT be used to construct new objects. - static Class fastClasses[TYPE_MAX]; - - // These are the slow/original classes, used - // fo constructing new objects - static Class slowClasses[TYPE_MAX]; - - static JSPropertySpec jsprops[]; - - static TypedArray *fromJSObject(JSObject *obj); - - static JSBool prop_getBuffer(JSContext *cx, JSObject *obj, jsid id, Value *vp); - static JSBool prop_getByteOffset(JSContext *cx, JSObject *obj, jsid id, Value *vp); - static JSBool prop_getByteLength(JSContext *cx, JSObject *obj, jsid id, Value *vp); - static JSBool prop_getLength(JSContext *cx, JSObject *obj, jsid id, Value *vp); - - static JSBool obj_lookupProperty(JSContext *cx, JSObject *obj, jsid id, - JSObject **objp, JSProperty **propp); - - static void obj_trace(JSTracer *trc, JSObject *obj); - - static JSBool obj_getAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp); - - static JSBool obj_setAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp); - - static int32 lengthOffset() { return offsetof(TypedArray, length); } - static int32 dataOffset() { return offsetof(TypedArray, data); } - static int32 typeOffset() { return offsetof(TypedArray, type); } - - public: - TypedArray() : buffer(0) { } - - bool isArrayIndex(JSContext *cx, jsid id, jsuint *ip = NULL); - bool valid() { return buffer != 0; } - - ArrayBuffer *buffer; - JSObject *bufferJS; - uint32 byteOffset; - uint32 byteLength; - uint32 length; - uint32 type; - - void *data; - - inline int slotWidth() const { - switch (type) { - case js::TypedArray::TYPE_INT8: - case js::TypedArray::TYPE_UINT8: - case js::TypedArray::TYPE_UINT8_CLAMPED: - return 1; - case js::TypedArray::TYPE_INT16: - case js::TypedArray::TYPE_UINT16: - return 2; - case js::TypedArray::TYPE_INT32: - case js::TypedArray::TYPE_UINT32: - case js::TypedArray::TYPE_FLOAT32: - return 4; - case js::TypedArray::TYPE_FLOAT64: - return 8; - default: - JS_NOT_REACHED("invalid typed array"); - return 0; - } - } -}; - -} // namespace js - -/* Friend API methods */ - -JS_FRIEND_API(JSObject *) -js_InitTypedArrayClasses(JSContext *cx, JSObject *obj); - -JS_FRIEND_API(JSBool) -js_IsTypedArray(JSObject *obj); - -JS_FRIEND_API(JSBool) -js_IsArrayBuffer(JSObject *obj); - -JS_FRIEND_API(JSObject *) -js_CreateArrayBuffer(JSContext *cx, jsuint nbytes); - -/* - * Create a new typed array of type atype (one of the TypedArray - * enumerant values above), with nelements elements. - */ -JS_FRIEND_API(JSObject *) -js_CreateTypedArray(JSContext *cx, jsint atype, jsuint nelements); - -/* - * Create a new typed array of type atype (one of the TypedArray - * enumerant values above), and copy in values from the given JSObject, - * which must either be a typed array or an array-like object. - */ -JS_FRIEND_API(JSObject *) -js_CreateTypedArrayWithArray(JSContext *cx, jsint atype, JSObject *arrayArg); - -/* - * Create a new typed array of type atype (one of the TypedArray - * enumerant values above), using a given ArrayBuffer for storage. - * The byteoffset and length values are optional; if -1 is passed, an - * offset of 0 and enough elements to use up the remainder of the byte - * array are used as the default values. - */ -JS_FRIEND_API(JSObject *) -js_CreateTypedArrayWithBuffer(JSContext *cx, jsint atype, JSObject *bufArg, - jsint byteoffset, jsint length); - -/* - * Reparent a typed array to a new scope. This should only be used to reparent - * a typed array that does not share its underlying ArrayBuffer with another - * typed array to avoid having a parent mismatch with the other typed array and - * its ArrayBuffer. - */ -JS_FRIEND_API(JSBool) -js_ReparentTypedArrayToScope(JSContext *cx, JSObject *obj, JSObject *scope); - -extern int32 JS_FASTCALL -js_TypedArray_uint8_clamp_double(const double x); - -#endif /* jstypedarray_h */ diff --git a/x86/mozilla/include/jstypes.h b/x86/mozilla/include/jstypes.h deleted file mode 100644 index c2103d8..0000000 --- a/x86/mozilla/include/jstypes.h +++ /dev/null @@ -1,507 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * IBM Corp. - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* -** File: jstypes.h -** Description: Definitions of NSPR's basic types -** -** Prototypes and macros used to make up for deficiencies in ANSI environments -** that we have found. -** -** Since we do not wrap and all the other standard headers, authors -** of portable code will not know in general that they need these definitions. -** Instead of requiring these authors to find the dependent uses in their code -** and take the following steps only in those C files, we take steps once here -** for all C files. -**/ - -#ifndef jstypes_h___ -#define jstypes_h___ - -#include -#include "js-config.h" - -/*********************************************************************** -** MACROS: JS_EXTERN_API -** JS_EXPORT_API -** DESCRIPTION: -** These are only for externally visible routines and globals. For -** internal routines, just use "extern" for type checking and that -** will not export internal cross-file or forward-declared symbols. -** Define a macro for declaring procedures return types. We use this to -** deal with windoze specific type hackery for DLL definitions. Use -** JS_EXTERN_API when the prototype for the method is declared. Use -** JS_EXPORT_API for the implementation of the method. -** -** Example: -** in dowhim.h -** JS_EXTERN_API( void ) DoWhatIMean( void ); -** in dowhim.c -** JS_EXPORT_API( void ) DoWhatIMean( void ) { return; } -** -** -***********************************************************************/ - -#define DEFINE_LOCAL_CLASS_OF_STATIC_FUNCTION(Name) class Name - -#if defined(WIN32) || defined(XP_OS2) - -/* These also work for __MWERKS__ */ -# define JS_EXTERN_API(__type) extern __declspec(dllexport) __type -# define JS_EXPORT_API(__type) __declspec(dllexport) __type -# define JS_EXTERN_DATA(__type) extern __declspec(dllexport) __type -# define JS_EXPORT_DATA(__type) __declspec(dllexport) __type - -#elif defined(__SYMBIAN32__) - -# define JS_EXTERN_API(__type) extern EXPORT_C __type -# define JS_EXPORT_API(__type) EXPORT_C __type -# define JS_EXTERN_DATA(__type) extern EXPORT_C __type -# define JS_EXPORT_DATA(__type) EXPORT_C __type - -#else /* Unix */ - -# ifdef HAVE_VISIBILITY_ATTRIBUTE -# define JS_EXTERNAL_VIS __attribute__((visibility ("default"))) -# if defined(__GNUC__) && __GNUC__ <= 4 && __GNUC_MINOR__ < 5 - /* - * GCC wrongly produces a warning when a type with hidden visibility - * (e.g. js::Value) is a member of a local class of a static function. - * This is apparently fixed with GCC 4.5 and above. See: - * - * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40145. - */ -# undef DEFINE_LOCAL_CLASS_OF_STATIC_FUNCTION -# define DEFINE_LOCAL_CLASS_OF_STATIC_FUNCTION(Name) class __attribute__((visibility ("hidden"))) Name -# endif -# elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) -# define JS_EXTERNAL_VIS __global -# else -# define JS_EXTERNAL_VIS -# endif - -# define JS_EXTERN_API(__type) extern JS_EXTERNAL_VIS __type -# define JS_EXPORT_API(__type) JS_EXTERNAL_VIS __type -# define JS_EXTERN_DATA(__type) extern JS_EXTERNAL_VIS __type -# define JS_EXPORT_DATA(__type) JS_EXTERNAL_VIS __type - -#endif - -#ifdef _WIN32 -# if defined(__MWERKS__) || defined(__GNUC__) -# define JS_IMPORT_API(__x) __x -# else -# define JS_IMPORT_API(__x) __declspec(dllimport) __x -# endif -#elif defined(XP_OS2) -# define JS_IMPORT_API(__x) __declspec(dllimport) __x -#elif defined(__SYMBIAN32__) -# define JS_IMPORT_API(__x) IMPORT_C __x -#else -# define JS_IMPORT_API(__x) JS_EXPORT_API (__x) -#endif - -#if defined(_WIN32) && !defined(__MWERKS__) -# define JS_IMPORT_DATA(__x) __declspec(dllimport) __x -#elif defined(XP_OS2) -# define JS_IMPORT_DATA(__x) __declspec(dllimport) __x -#elif defined(__SYMBIAN32__) -# if defined(__CW32__) -# define JS_IMPORT_DATA(__x) __declspec(dllimport) __x -# else -# define JS_IMPORT_DATA(__x) IMPORT_C __x -# endif -#else -# define JS_IMPORT_DATA(__x) JS_EXPORT_DATA (__x) -#endif - -/* - * The linkage of JS API functions differs depending on whether the file is - * used within the JS library or not. Any source file within the JS - * interpreter should define EXPORT_JS_API whereas any client of the library - * should not. STATIC_JS_API is used to build JS as a static library. - */ -#if defined(STATIC_JS_API) - -# define JS_PUBLIC_API(t) t -# define JS_PUBLIC_DATA(t) t - -#elif defined(EXPORT_JS_API) || defined(STATIC_EXPORTABLE_JS_API) - -# define JS_PUBLIC_API(t) JS_EXPORT_API(t) -# define JS_PUBLIC_DATA(t) JS_EXPORT_DATA(t) - -#else - -# define JS_PUBLIC_API(t) JS_IMPORT_API(t) -# define JS_PUBLIC_DATA(t) JS_IMPORT_DATA(t) - -#endif - -#define JS_FRIEND_API(t) JS_PUBLIC_API(t) -#define JS_FRIEND_DATA(t) JS_PUBLIC_DATA(t) - -#if defined(_MSC_VER) && defined(_M_IX86) -#define JS_FASTCALL __fastcall -#elif defined(__GNUC__) && defined(__i386__) && \ - ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -#define JS_FASTCALL __attribute__((fastcall)) -#else -#define JS_FASTCALL -#define JS_NO_FASTCALL -#endif - -#ifndef JS_INLINE -# if defined __cplusplus -# define JS_INLINE inline -# elif defined _MSC_VER -# define JS_INLINE __inline -# elif defined __GNUC__ -# define JS_INLINE __inline__ -# else -# define JS_INLINE inline -# endif -#endif - -#ifndef JS_ALWAYS_INLINE -# if defined DEBUG -# define JS_ALWAYS_INLINE JS_INLINE -# elif defined _MSC_VER -# define JS_ALWAYS_INLINE __forceinline -# elif defined __GNUC__ -# define JS_ALWAYS_INLINE __attribute__((always_inline)) JS_INLINE -# else -# define JS_ALWAYS_INLINE JS_INLINE -# endif -#endif - -#ifndef JS_NEVER_INLINE -# if defined _MSC_VER -# define JS_NEVER_INLINE __declspec(noinline) -# elif defined __GNUC__ -# define JS_NEVER_INLINE __attribute__((noinline)) -# else -# define JS_NEVER_INLINE -# endif -#endif - -#ifndef JS_WARN_UNUSED_RESULT -# if defined __GNUC__ -# define JS_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -# else -# define JS_WARN_UNUSED_RESULT -# endif -#endif - -#ifdef NS_STATIC_CHECKING -/* - * Attributes for static analysis. Functions declared with JS_REQUIRES_STACK - * always have a valid cx->fp and can access it freely. Other functions can - * access cx->fp only after calling a function that "forces" the stack - * (i.e. lazily instantiates it as needed). - */ -# define JS_REQUIRES_STACK __attribute__((user("JS_REQUIRES_STACK"))) -# define JS_FORCES_STACK __attribute__((user("JS_FORCES_STACK"))) -/* - * Skip the JS_REQUIRES_STACK analysis within functions with this annotation. - */ -# define JS_IGNORE_STACK __attribute__((user("JS_IGNORE_STACK"))) -#else -# define JS_REQUIRES_STACK -# define JS_FORCES_STACK -# define JS_IGNORE_STACK -#endif - -/*********************************************************************** -** MACROS: JS_BEGIN_MACRO -** JS_END_MACRO -** DESCRIPTION: -** Macro body brackets so that macros with compound statement definitions -** behave syntactically more like functions when called. -***********************************************************************/ -#define JS_BEGIN_MACRO do { - -#if defined(_MSC_VER) && _MSC_VER >= 1400 -# define JS_END_MACRO \ - } __pragma(warning(push)) __pragma(warning(disable:4127)) \ - while (0) __pragma(warning(pop)) -#else -# define JS_END_MACRO } while (0) -#endif - -/*********************************************************************** -** MACROS: JS_BEGIN_EXTERN_C -** JS_END_EXTERN_C -** DESCRIPTION: -** Macro shorthands for conditional C++ extern block delimiters. -***********************************************************************/ -#ifdef __cplusplus - -# define JS_BEGIN_EXTERN_C extern "C" { -# define JS_END_EXTERN_C } - -#else - -# define JS_BEGIN_EXTERN_C -# define JS_END_EXTERN_C - -#endif - -/*********************************************************************** -** MACROS: JS_BIT -** JS_BITMASK -** DESCRIPTION: -** Bit masking macros. XXX n must be <= 31 to be portable -***********************************************************************/ -#define JS_BIT(n) ((JSUint32)1 << (n)) -#define JS_BITMASK(n) (JS_BIT(n) - 1) - -/*********************************************************************** -** MACROS: JS_HOWMANY -** JS_ROUNDUP -** JS_MIN -** JS_MAX -** DESCRIPTION: -** Commonly used macros for operations on compatible types. -***********************************************************************/ -#define JS_HOWMANY(x,y) (((x)+(y)-1)/(y)) -#define JS_ROUNDUP(x,y) (JS_HOWMANY(x,y)*(y)) -#define JS_MIN(x,y) ((x)<(y)?(x):(y)) -#define JS_MAX(x,y) ((x)>(y)?(x):(y)) - -#ifdef _MSC_VER -# include "jscpucfg.h" /* We can't auto-detect MSVC configuration */ -# if _MSC_VER < 1400 -# define NJ_NO_VARIADIC_MACROS -# endif -#else -# include "jsautocfg.h" /* Use auto-detected configuration */ -#endif - -/* - * Define JS_64BIT iff we are building in an environment with 64-bit - * addresses. - */ -#ifdef _MSC_VER -# if defined(_M_X64) || defined(_M_AMD64) -# define JS_64BIT -# endif -#elif defined(__GNUC__) -# ifdef __x86_64__ -# define JS_64BIT -# endif -#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) -# ifdef __x86_64 -# define JS_64BIT -# endif -#else -# error "Implement me" -#endif - - -#include "jsinttypes.h" - -JS_BEGIN_EXTERN_C - -/************************************************************************ -** TYPES: JSUintn -** JSIntn -** DESCRIPTION: -** The JSIntn types are most appropriate for automatic variables. They are -** guaranteed to be at least 16 bits, though various architectures may -** define them to be wider (e.g., 32 or even 64 bits). These types are -** never valid for fields of a structure. -************************************************************************/ - -typedef int JSIntn; -typedef unsigned int JSUintn; - -/************************************************************************ -** TYPES: JSFloat64 -** DESCRIPTION: -** NSPR's floating point type is always 64 bits. -************************************************************************/ -typedef double JSFloat64; - -/************************************************************************ -** TYPES: JSSize -** DESCRIPTION: -** A type for representing the size of objects. -************************************************************************/ -typedef size_t JSSize; - -/************************************************************************ -** TYPES: JSPtrDiff -** DESCRIPTION: -** A type for pointer difference. Variables of this type are suitable -** for storing a pointer or pointer sutraction. -************************************************************************/ -typedef ptrdiff_t JSPtrdiff; - -/************************************************************************ -** TYPES: JSUptrdiff -** DESCRIPTION: -** A type for pointer difference. Variables of this type are suitable -** for storing a pointer or pointer sutraction. -************************************************************************/ -typedef JSUintPtr JSUptrdiff; - -/************************************************************************ -** TYPES: JSBool -** DESCRIPTION: -** Use JSBool for variables and parameter types. Use JS_FALSE and JS_TRUE -** for clarity of target type in assignments and actual arguments. Use -** 'if (bool)', 'while (!bool)', '(bool) ? x : y' etc., to test booleans -** just as you would C int-valued conditions. -************************************************************************/ -typedef JSIntn JSBool; -#define JS_TRUE (JSIntn)1 -#define JS_FALSE (JSIntn)0 -/* -** Special: JS_NEITHER is used by the tracer to have tri-state booleans. -** This should not be used in new code. -*/ -#define JS_NEITHER (JSIntn)2 - -/************************************************************************ -** TYPES: JSPackedBool -** DESCRIPTION: -** Use JSPackedBool within structs where bitfields are not desireable -** but minimum and consistent overhead matters. -************************************************************************/ -typedef JSUint8 JSPackedBool; - -/* -** A JSWord is an integer that is the same size as a void* -*/ -typedef JSIntPtr JSWord; -typedef JSUintPtr JSUword; - -#include "jsotypes.h" - -/*********************************************************************** -** MACROS: JS_LIKELY -** JS_UNLIKELY -** DESCRIPTION: -** These macros allow you to give a hint to the compiler about branch -** probability so that it can better optimize. Use them like this: -** -** if (JS_LIKELY(v == 1)) { -** ... expected code path ... -** } -** -** if (JS_UNLIKELY(v == 0)) { -** ... non-expected code path ... -** } -** -***********************************************************************/ -#if defined(__GNUC__) && (__GNUC__ > 2) - -# define JS_LIKELY(x) (__builtin_expect((x), 1)) -# define JS_UNLIKELY(x) (__builtin_expect((x), 0)) - -#else - -# define JS_LIKELY(x) (x) -# define JS_UNLIKELY(x) (x) - -#endif - -/*********************************************************************** -** MACROS: JS_ARRAY_LENGTH -** JS_ARRAY_END -** DESCRIPTION: -** Macros to get the number of elements and the pointer to one past the -** last element of a C array. Use them like this: -** -** jschar buf[10], *s; -** JSString *str; -** ... -** for (s = buf; s != JS_ARRAY_END(buf); ++s) *s = ...; -** ... -** str = JS_NewStringCopyN(cx, buf, JS_ARRAY_LENGTH(buf)); -** ... -** -***********************************************************************/ - -#define JS_ARRAY_LENGTH(array) (sizeof (array) / sizeof (array)[0]) -#define JS_ARRAY_END(array) ((array) + JS_ARRAY_LENGTH(array)) - -#define JS_BITS_PER_BYTE 8 -#define JS_BITS_PER_BYTE_LOG2 3 - -#define JS_BITS_PER_WORD (JS_BITS_PER_BYTE * JS_BYTES_PER_WORD) -#define JS_BITS_PER_DOUBLE (JS_BITS_PER_BYTE * JS_BYTES_PER_DOUBLE) - -/*********************************************************************** -** MACROS: JS_FUNC_TO_DATA_PTR -** JS_DATA_TO_FUNC_PTR -** DESCRIPTION: -** Macros to convert between function and data pointers assuming that -** they have the same size. Use them like this: -** -** JSPropertyOp nativeGetter; -** JSObject *scriptedGetter; -** ... -** scriptedGetter = JS_FUNC_TO_DATA_PTR(JSObject *, nativeGetter); -** ... -** nativeGetter = JS_DATA_TO_FUNC_PTR(JSPropertyOp, scriptedGetter); -** -***********************************************************************/ - -#ifdef __GNUC__ -# define JS_FUNC_TO_DATA_PTR(type, fun) (__extension__ (type) (size_t) (fun)) -# define JS_DATA_TO_FUNC_PTR(type, ptr) (__extension__ (type) (size_t) (ptr)) -#else -/* Use an extra (void *) cast for MSVC. */ -# define JS_FUNC_TO_DATA_PTR(type, fun) ((type) (void *) (fun)) -# define JS_DATA_TO_FUNC_PTR(type, ptr) ((type) (void *) (ptr)) -#endif - -#ifdef __GNUC__ -# define JS_EXTENSION __extension__ -# define JS_EXTENSION_(s) __extension__ ({ s; }) -#else -# define JS_EXTENSION -# define JS_EXTENSION_(s) s -#endif - -JS_END_EXTERN_C - -#endif /* jstypes_h___ */ diff --git a/x86/mozilla/include/jsutil.h b/x86/mozilla/include/jsutil.h deleted file mode 100644 index 9da2674..0000000 --- a/x86/mozilla/include/jsutil.h +++ /dev/null @@ -1,469 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * PR assertion checker. - */ - -#ifndef jsutil_h___ -#define jsutil_h___ - -#include "jstypes.h" -#include -#include - -JS_BEGIN_EXTERN_C - -/* - * JS_Assert is present even in release builds, for the benefit of applications - * that build DEBUG and link against a non-DEBUG SpiderMonkey library. - */ -extern JS_PUBLIC_API(void) -JS_Assert(const char *s, const char *file, JSIntn ln); - -#define JS_CRASH_UNLESS(__cond) \ - JS_BEGIN_MACRO \ - if (!(__cond)) { \ - *(int *)(uintptr_t)0xccadbeef = 0; \ - ((void(*)())0)(); /* More reliable, but doesn't say CCADBEEF */ \ - } \ - JS_END_MACRO - -#ifdef DEBUG - -#define JS_ASSERT(expr) \ - ((expr) ? (void)0 : JS_Assert(#expr, __FILE__, __LINE__)) - -#define JS_ASSERT_IF(cond, expr) \ - ((!(cond) || (expr)) ? (void)0 : JS_Assert(#expr, __FILE__, __LINE__)) - -#define JS_NOT_REACHED(reason) \ - JS_Assert(reason, __FILE__, __LINE__) - -#define JS_ALWAYS_TRUE(expr) JS_ASSERT(expr) - -#define JS_ALWAYS_FALSE(expr) JS_ASSERT(!(expr)) - -# ifdef JS_THREADSAFE -# define JS_THREADSAFE_ASSERT(expr) JS_ASSERT(expr) -# else -# define JS_THREADSAFE_ASSERT(expr) ((void) 0) -# endif - -#else - -#define JS_ASSERT(expr) ((void) 0) -#define JS_ASSERT_IF(cond,expr) ((void) 0) -#define JS_NOT_REACHED(reason) -#define JS_ALWAYS_TRUE(expr) ((void) (expr)) -#define JS_ALWAYS_FALSE(expr) ((void) (expr)) -#define JS_THREADSAFE_ASSERT(expr) ((void) 0) - -#endif /* defined(DEBUG) */ - -/* - * Compile-time assert. "cond" must be a constant expression. - * The macro can be used only in places where an "extern" declaration is - * allowed. - */ - -#ifdef __SUNPRO_CC -/* - * Sun Studio C++ compiler has a bug - * "sizeof expression not accepted as size of array parameter" - * It happens when js_static_assert() function is declared inside functions. - * The bug number is 6688515. It is not public yet. - * Therefore, for Sun Studio, declare js_static_assert as an array instead. - */ -#define JS_STATIC_ASSERT(cond) extern char js_static_assert[(cond) ? 1 : -1] -#else -#ifdef __COUNTER__ - #define JS_STATIC_ASSERT_GLUE1(x,y) x##y - #define JS_STATIC_ASSERT_GLUE(x,y) JS_STATIC_ASSERT_GLUE1(x,y) - #define JS_STATIC_ASSERT(cond) \ - typedef int JS_STATIC_ASSERT_GLUE(js_static_assert, __COUNTER__)[(cond) ? 1 : -1] -#else - #define JS_STATIC_ASSERT(cond) extern void js_static_assert(int arg[(cond) ? 1 : -1]) -#endif -#endif - -#define JS_STATIC_ASSERT_IF(cond, expr) JS_STATIC_ASSERT(!(cond) || (expr)) - -/* - * Abort the process in a non-graceful manner. This will cause a core file, - * call to the debugger or other moral equivalent as well as causing the - * entire process to stop. - */ -extern JS_PUBLIC_API(void) JS_Abort(void); - -#ifdef DEBUG -# define JS_BASIC_STATS 1 -#endif - -#ifdef DEBUG_brendan -# define JS_SCOPE_DEPTH_METER 1 -#endif - -#ifdef JS_BASIC_STATS - -#include - -typedef struct JSBasicStats { - uint32 num; - uint32 max; - double sum; - double sqsum; - uint32 logscale; /* logarithmic scale: 0 (linear), 2, 10 */ - uint32 hist[11]; -} JSBasicStats; - -#define JS_INIT_STATIC_BASIC_STATS {0,0,0,0,0,{0,0,0,0,0,0,0,0,0,0,0}} -#define JS_BASIC_STATS_INIT(bs) memset((bs), 0, sizeof(JSBasicStats)) - -#define JS_BASIC_STATS_ACCUM(bs,val) \ - JS_BasicStatsAccum(bs, val) - -#define JS_MeanAndStdDevBS(bs,sigma) \ - JS_MeanAndStdDev((bs)->num, (bs)->sum, (bs)->sqsum, sigma) - -extern void -JS_BasicStatsAccum(JSBasicStats *bs, uint32 val); - -extern double -JS_MeanAndStdDev(uint32 num, double sum, double sqsum, double *sigma); - -extern void -JS_DumpBasicStats(JSBasicStats *bs, const char *title, FILE *fp); - -extern void -JS_DumpHistogram(JSBasicStats *bs, FILE *fp); - -#else - -#define JS_BASIC_STATS_ACCUM(bs,val) /* nothing */ - -#endif /* JS_BASIC_STATS */ - - -#if defined(DEBUG_notme) && defined(XP_UNIX) - -typedef struct JSCallsite JSCallsite; - -struct JSCallsite { - uint32 pc; - char *name; - const char *library; - int offset; - JSCallsite *parent; - JSCallsite *siblings; - JSCallsite *kids; - void *handy; -}; - -extern JS_FRIEND_API(JSCallsite *) -JS_Backtrace(int skip); - -extern JS_FRIEND_API(void) -JS_DumpBacktrace(JSCallsite *trace); -#endif - -#if defined JS_USE_CUSTOM_ALLOCATOR - -#include "jscustomallocator.h" - -#else - -static JS_INLINE void* js_malloc(size_t bytes) { - return malloc(bytes); -} - -static JS_INLINE void* js_calloc(size_t bytes) { - return calloc(bytes, 1); -} - -static JS_INLINE void* js_realloc(void* p, size_t bytes) { - return realloc(p, bytes); -} - -static JS_INLINE void js_free(void* p) { - free(p); -} -#endif/* JS_USE_CUSTOM_ALLOCATOR */ - -JS_END_EXTERN_C - -#ifdef __cplusplus - -/* - * Using vanilla new/new[] is unsafe in SpiderMonkey because they throw on - * failure instead of returning NULL, which is what SpiderMonkey expects. - * js_new()/js_array_new() should be used instead, and memory allocated with - * them should be deallocated with js_delete()/js_array_delete(). - * - * If you have a class with a private constructor or destructor, you can - * make js_new/js_delete a friend. This can be fiddly, and the interaction of - * template functions, friend functions and namespaces can overwhelm even - * modern compilers. Manual inlining is probably easier. - * - * (If you're wondering why we can't just use the 'nothrow' variant of - * new/new[], it's because we want to mediate *all* allocations within - * SpiderMonkey, to satisfy any embedders using JS_USE_CUSTOM_ALLOCATOR.) - */ - -#define JS_NEW_BODY(t, parms) \ - void *memory = js_malloc(sizeof(t)); \ - return memory ? new(memory) t parms : NULL; - -template -JS_ALWAYS_INLINE T *js_new() { - JS_NEW_BODY(T, ()) -} - -template -JS_ALWAYS_INLINE T *js_new(const P1 &p1) { - JS_NEW_BODY(T, (p1)) -} - -template -JS_ALWAYS_INLINE T *js_new(const P1 &p1, const P2 &p2) { - JS_NEW_BODY(T, (p1, p2)) -} - -template -JS_ALWAYS_INLINE T *js_new(const P1 &p1, const P2 &p2, const P3 &p3) { - JS_NEW_BODY(T, (p1, p2, p3)) -} - -template -JS_ALWAYS_INLINE T *js_new(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4) { - JS_NEW_BODY(T, (p1, p2, p3, p4)) -} - -/* ...add additional js_new()s as necessary... */ - -#undef JS_NEW_BODY - -template -JS_ALWAYS_INLINE void js_delete(T *p) { - if (p) { - p->~T(); - js_free(p); - } -} - -static const int JSMinAlignment = 8; - -template -JS_ALWAYS_INLINE T *js_array_new(size_t n) { - /* The length is stored just before the vector memory. */ - uint64 numBytes64 = uint64(JSMinAlignment) + uint64(sizeof(T)) * uint64(n); - size_t numBytes = size_t(numBytes64); - if (numBytes64 != numBytes) { - JS_ASSERT(0); /* we want to know if this happens in debug builds */ - return NULL; - } - void *memory = js_malloc(numBytes); - if (!memory) - return NULL; - *(size_t *)memory = n; - memory = (void*)(uintptr_t(memory) + JSMinAlignment); - return new(memory) T[n]; -} - -template -JS_ALWAYS_INLINE void js_array_delete(T *p) { - if (p) { - void* p0 = (void *)(uintptr_t(p) - JSMinAlignment); - size_t n = *(size_t *)p0; - for (size_t i = 0; i < n; i++) - (p + i)->~T(); - js_free(p0); - } -} - -/** - * The following classes are designed to cause assertions to detect - * inadvertent use of guard objects as temporaries. In other words, - * when we have a guard object whose only purpose is its constructor and - * destructor (and is never otherwise referenced), the intended use - * might be: - * JSAutoTempValueRooter tvr(cx, 1, &val); - * but is is easy to accidentally write: - * JSAutoTempValueRooter(cx, 1, &val); - * which compiles just fine, but runs the destructor well before the - * intended time. - * - * They work by adding (#ifdef DEBUG) an additional parameter to the - * guard object's constructor, with a default value, so that users of - * the guard object's API do not need to do anything. The default value - * of this parameter is a temporary object. C++ (ISO/IEC 14882:1998), - * section 12.2 [class.temporary], clauses 4 and 5 seem to assume a - * guarantee that temporaries are destroyed in the reverse of their - * construction order, but I actually can't find a statement that that - * is true in the general case (beyond the two specific cases mentioned - * there). However, it seems to be true. - * - * These classes are intended to be used only via the macros immediately - * below them: - * JS_DECL_USE_GUARD_OBJECT_NOTIFIER declares (ifdef DEBUG) a member - * variable, and should be put where a declaration of a private - * member variable would be placed. - * JS_GUARD_OBJECT_NOTIFIER_PARAM should be placed at the end of the - * parameters to each constructor of the guard object; it declares - * (ifdef DEBUG) an additional parameter. - * JS_GUARD_OBJECT_NOTIFIER_INIT is a statement that belongs in each - * constructor. It uses the parameter declared by - * JS_GUARD_OBJECT_NOTIFIER_PARAM. - */ -#ifdef DEBUG -class JSGuardObjectNotifier -{ -private: - bool* mStatementDone; -public: - JSGuardObjectNotifier() : mStatementDone(NULL) {} - - ~JSGuardObjectNotifier() { - *mStatementDone = true; - } - - void setStatementDone(bool *aStatementDone) { - mStatementDone = aStatementDone; - } -}; - -class JSGuardObjectNotificationReceiver -{ -private: - bool mStatementDone; -public: - JSGuardObjectNotificationReceiver() : mStatementDone(false) {} - - ~JSGuardObjectNotificationReceiver() { - /* - * Assert that the guard object was not used as a temporary. - * (Note that this assert might also fire if Init is not called - * because the guard object's implementation is not using the - * above macros correctly.) - */ - JS_ASSERT(mStatementDone); - } - - void Init(const JSGuardObjectNotifier &aNotifier) { - /* - * aNotifier is passed as a const reference so that we can pass a - * temporary, but we really intend it as non-const - */ - const_cast(aNotifier). - setStatementDone(&mStatementDone); - } -}; - -#define JS_DECL_USE_GUARD_OBJECT_NOTIFIER \ - JSGuardObjectNotificationReceiver _mCheckNotUsedAsTemporary; -#define JS_GUARD_OBJECT_NOTIFIER_PARAM \ - , const JSGuardObjectNotifier& _notifier = JSGuardObjectNotifier() -#define JS_GUARD_OBJECT_NOTIFIER_PARAM0 \ - const JSGuardObjectNotifier& _notifier = JSGuardObjectNotifier() -#define JS_GUARD_OBJECT_NOTIFIER_INIT \ - JS_BEGIN_MACRO _mCheckNotUsedAsTemporary.Init(_notifier); JS_END_MACRO - -#else /* defined(DEBUG) */ - -#define JS_DECL_USE_GUARD_OBJECT_NOTIFIER -#define JS_GUARD_OBJECT_NOTIFIER_PARAM -#define JS_GUARD_OBJECT_NOTIFIER_PARAM0 -#define JS_GUARD_OBJECT_NOTIFIER_INIT JS_BEGIN_MACRO JS_END_MACRO - -#endif /* !defined(DEBUG) */ - -namespace js { - -template -JS_ALWAYS_INLINE static void -PodZero(T *t) -{ - memset(t, 0, sizeof(T)); -} - -template -JS_ALWAYS_INLINE static void -PodZero(T *t, size_t nelem) -{ - memset(t, 0, nelem * sizeof(T)); -} - -/* - * Arrays implicitly convert to pointers to their first element, which is - * dangerous when combined with the above PodZero definitions. Adding an - * overload for arrays is ambiguous, so we need another identifier. The - * ambiguous overload is left to catch mistaken uses of PodZero; if you get a - * compile error involving PodZero and array types, use PodArrayZero instead. - */ -template static void PodZero(T (&)[N]); /* undefined */ -template static void PodZero(T (&)[N], size_t); /* undefined */ - -template -JS_ALWAYS_INLINE static void -PodArrayZero(T (&t)[N]) -{ - memset(t, 0, N * sizeof(T)); -} - -template -JS_ALWAYS_INLINE static void -PodCopy(T *dst, const T *src, size_t nelem) -{ - /* Cannot find portable word-sized abs(). */ - JS_ASSERT_IF(dst >= src, size_t(dst - src) >= nelem); - JS_ASSERT_IF(src >= dst, size_t(src - dst) >= nelem); - - if (nelem < 128) { - for (const T *srcend = src + nelem; src != srcend; ++src, ++dst) - *dst = *src; - } else { - memcpy(dst, src, nelem * sizeof(T)); - } -} - -} /* namespace js */ - -#endif /* defined(__cplusplus) */ - -#endif /* jsutil_h___ */ diff --git a/x86/mozilla/include/jsval.h b/x86/mozilla/include/jsval.h deleted file mode 100644 index f629862..0000000 --- a/x86/mozilla/include/jsval.h +++ /dev/null @@ -1,831 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=4 sw=4 et tw=99 ft=cpp: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released - * June 30, 2010 - * - * The Initial Developer of the Original Code is - * the Mozilla Corporation. - * - * Contributor(s): - * Luke Wagner - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsvalimpl_h__ -#define jsvalimpl_h__ -/* - * JS value implementation details for operations on jsval and jsid. - * Embeddings should not rely on any of the definitions in this file. For a - * description of the value representation and the engine-internal C++ value - * interface, js::Value, see jsvalue.h. - */ -#include "jsutil.h" - -JS_BEGIN_EXTERN_C - -/* - * Try to get jsvals 64-bit aligned. We could almost assert that all values are - * aligned, but MSVC and GCC occasionally break alignment. - */ -#ifdef __GNUC__ -# define JSVAL_ALIGNMENT __attribute__((aligned (8))) -#elif defined(_MSC_VER) - /* - * Structs can be aligned with MSVC, but not if they are used as parameters, - * so we just don't try to align. - */ -# define JSVAL_ALIGNMENT -#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) -# define JSVAL_ALIGNMENT -#endif - -#if JS_BITS_PER_WORD == 64 -# define JSVAL_TAG_SHIFT 47 -#endif - -/* - * We try to use enums so that printing a jsval_layout in the debugger shows - * nice symbolic type tags, however we can only do this when we can force the - * underlying type of the enum to be the desired size. - */ -#if defined(__cplusplus) && !defined(__SUNPRO_CC) - -#if defined(_MSC_VER) -# define JS_ENUM_HEADER(id, type) enum id : type -# define JS_ENUM_MEMBER(id, type, value) id = (type)value, -# define JS_LAST_ENUM_MEMBER(id, type, value) id = (type)value -# define JS_ENUM_FOOTER(id) -#else -# define JS_ENUM_HEADER(id, type) enum id -# define JS_ENUM_MEMBER(id, type, value) id = (type)value, -# define JS_LAST_ENUM_MEMBER(id, type, value) id = (type)value -# define JS_ENUM_FOOTER(id) __attribute__((packed)) -#endif - -/* Remember to propagate changes to the C defines below. */ -JS_ENUM_HEADER(JSValueType, uint8) -{ - JSVAL_TYPE_DOUBLE = 0x00, - JSVAL_TYPE_INT32 = 0x01, - JSVAL_TYPE_UNDEFINED = 0x02, - JSVAL_TYPE_BOOLEAN = 0x03, - JSVAL_TYPE_MAGIC = 0x04, - JSVAL_TYPE_STRING = 0x05, - JSVAL_TYPE_NULL = 0x06, - JSVAL_TYPE_OBJECT = 0x07, - - /* The below types never appear in a jsval; they are only used in tracing. */ - - JSVAL_TYPE_NONFUNOBJ = 0x57, - JSVAL_TYPE_FUNOBJ = 0x67, - - JSVAL_TYPE_STRORNULL = 0x97, - JSVAL_TYPE_OBJORNULL = 0x98, - - JSVAL_TYPE_BOXED = 0x99 -} JS_ENUM_FOOTER(JSValueType); - -JS_STATIC_ASSERT(sizeof(JSValueType) == 1); - -#if JS_BITS_PER_WORD == 32 - -/* Remember to propagate changes to the C defines below. */ -JS_ENUM_HEADER(JSValueTag, uint32) -{ - JSVAL_TAG_CLEAR = 0xFFFF0000, - JSVAL_TAG_INT32 = JSVAL_TAG_CLEAR | JSVAL_TYPE_INT32, - JSVAL_TAG_UNDEFINED = JSVAL_TAG_CLEAR | JSVAL_TYPE_UNDEFINED, - JSVAL_TAG_STRING = JSVAL_TAG_CLEAR | JSVAL_TYPE_STRING, - JSVAL_TAG_BOOLEAN = JSVAL_TAG_CLEAR | JSVAL_TYPE_BOOLEAN, - JSVAL_TAG_MAGIC = JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC, - JSVAL_TAG_NULL = JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL, - JSVAL_TAG_OBJECT = JSVAL_TAG_CLEAR | JSVAL_TYPE_OBJECT -} JS_ENUM_FOOTER(JSValueTag); - -JS_STATIC_ASSERT(sizeof(JSValueTag) == 4); - -#elif JS_BITS_PER_WORD == 64 - -/* Remember to propagate changes to the C defines below. */ -JS_ENUM_HEADER(JSValueTag, uint32) -{ - JSVAL_TAG_MAX_DOUBLE = 0x1FFF0, - JSVAL_TAG_INT32 = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_INT32, - JSVAL_TAG_UNDEFINED = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_UNDEFINED, - JSVAL_TAG_STRING = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_STRING, - JSVAL_TAG_BOOLEAN = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_BOOLEAN, - JSVAL_TAG_MAGIC = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_MAGIC, - JSVAL_TAG_NULL = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_NULL, - JSVAL_TAG_OBJECT = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_OBJECT -} JS_ENUM_FOOTER(JSValueTag); - -JS_STATIC_ASSERT(sizeof(JSValueTag) == sizeof(uint32)); - -JS_ENUM_HEADER(JSValueShiftedTag, uint64) -{ - JSVAL_SHIFTED_TAG_MAX_DOUBLE = ((((uint64)JSVAL_TAG_MAX_DOUBLE) << JSVAL_TAG_SHIFT) | 0xFFFFFFFF), - JSVAL_SHIFTED_TAG_INT32 = (((uint64)JSVAL_TAG_INT32) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_UNDEFINED = (((uint64)JSVAL_TAG_UNDEFINED) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_STRING = (((uint64)JSVAL_TAG_STRING) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_BOOLEAN = (((uint64)JSVAL_TAG_BOOLEAN) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_MAGIC = (((uint64)JSVAL_TAG_MAGIC) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_NULL = (((uint64)JSVAL_TAG_NULL) << JSVAL_TAG_SHIFT), - JSVAL_SHIFTED_TAG_OBJECT = (((uint64)JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT) -} JS_ENUM_FOOTER(JSValueShiftedTag); - -JS_STATIC_ASSERT(sizeof(JSValueShiftedTag) == sizeof(uint64)); - -#endif - -#else /* defined(__cplusplus) */ - -typedef uint8 JSValueType; -#define JSVAL_TYPE_DOUBLE ((uint8)0x00) -#define JSVAL_TYPE_INT32 ((uint8)0x01) -#define JSVAL_TYPE_UNDEFINED ((uint8)0x02) -#define JSVAL_TYPE_BOOLEAN ((uint8)0x03) -#define JSVAL_TYPE_MAGIC ((uint8)0x04) -#define JSVAL_TYPE_STRING ((uint8)0x05) -#define JSVAL_TYPE_NULL ((uint8)0x06) -#define JSVAL_TYPE_OBJECT ((uint8)0x07) -#define JSVAL_TYPE_NONFUNOBJ ((uint8)0x57) -#define JSVAL_TYPE_FUNOBJ ((uint8)0x67) -#define JSVAL_TYPE_STRORNULL ((uint8)0x97) -#define JSVAL_TYPE_OBJORNULL ((uint8)0x98) -#define JSVAL_TYPE_BOXED ((uint8)0x99) -#define JSVAL_TYPE_UNINITIALIZED ((uint8)0xcd) - -#if JS_BITS_PER_WORD == 32 - -typedef uint32 JSValueTag; -#define JSVAL_TAG_CLEAR ((uint32)(0xFFFF0000)) -#define JSVAL_TAG_INT32 ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_INT32)) -#define JSVAL_TAG_UNDEFINED ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_UNDEFINED)) -#define JSVAL_TAG_STRING ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_STRING)) -#define JSVAL_TAG_BOOLEAN ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_BOOLEAN)) -#define JSVAL_TAG_MAGIC ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC)) -#define JSVAL_TAG_NULL ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL)) -#define JSVAL_TAG_OBJECT ((uint32)(JSVAL_TAG_CLEAR | JSVAL_TYPE_OBJECT)) - -#elif JS_BITS_PER_WORD == 64 - -typedef uint32 JSValueTag; -#define JSVAL_TAG_MAX_DOUBLE ((uint32)(0x1FFF0)) -#define JSVAL_TAG_INT32 (uint32)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_INT32) -#define JSVAL_TAG_UNDEFINED (uint32)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_UNDEFINED) -#define JSVAL_TAG_STRING (uint32)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_STRING) -#define JSVAL_TAG_BOOLEAN (uint32)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_BOOLEAN) -#define JSVAL_TAG_MAGIC (uint32)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_MAGIC) -#define JSVAL_TAG_NULL (uint32)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_NULL) -#define JSVAL_TAG_OBJECT (uint32)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_OBJECT) - -typedef uint64 JSValueShiftedTag; -#define JSVAL_SHIFTED_TAG_MAX_DOUBLE ((((uint64)JSVAL_TAG_MAX_DOUBLE) << JSVAL_TAG_SHIFT) | 0xFFFFFFFF) -#define JSVAL_SHIFTED_TAG_INT32 (((uint64)JSVAL_TAG_INT32) << JSVAL_TAG_SHIFT) -#define JSVAL_SHIFTED_TAG_UNDEFINED (((uint64)JSVAL_TAG_UNDEFINED) << JSVAL_TAG_SHIFT) -#define JSVAL_SHIFTED_TAG_STRING (((uint64)JSVAL_TAG_STRING) << JSVAL_TAG_SHIFT) -#define JSVAL_SHIFTED_TAG_BOOLEAN (((uint64)JSVAL_TAG_BOOLEAN) << JSVAL_TAG_SHIFT) -#define JSVAL_SHIFTED_TAG_MAGIC (((uint64)JSVAL_TAG_MAGIC) << JSVAL_TAG_SHIFT) -#define JSVAL_SHIFTED_TAG_NULL (((uint64)JSVAL_TAG_NULL) << JSVAL_TAG_SHIFT) -#define JSVAL_SHIFTED_TAG_OBJECT (((uint64)JSVAL_TAG_OBJECT) << JSVAL_TAG_SHIFT) - -#endif /* JS_BITS_PER_WORD */ -#endif /* defined(__cplusplus) && !defined(__SUNPRO_CC) */ - -#define JSVAL_LOWER_INCL_TYPE_OF_OBJ_OR_NULL_SET JSVAL_TYPE_NULL -#define JSVAL_UPPER_EXCL_TYPE_OF_PRIMITIVE_SET JSVAL_TYPE_OBJECT -#define JSVAL_UPPER_INCL_TYPE_OF_NUMBER_SET JSVAL_TYPE_INT32 -#define JSVAL_LOWER_INCL_TYPE_OF_PTR_PAYLOAD_SET JSVAL_TYPE_MAGIC -#define JSVAL_UPPER_INCL_TYPE_OF_VALUE_SET JSVAL_TYPE_OBJECT -#define JSVAL_UPPER_INCL_TYPE_OF_BOXABLE_SET JSVAL_TYPE_FUNOBJ - -#if JS_BITS_PER_WORD == 32 - -#define JSVAL_TYPE_TO_TAG(type) ((JSValueTag)(JSVAL_TAG_CLEAR | (type))) - -#define JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET JSVAL_TAG_NULL -#define JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET JSVAL_TAG_OBJECT -#define JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET JSVAL_TAG_INT32 -#define JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET JSVAL_TAG_STRING - -#elif JS_BITS_PER_WORD == 64 - -#define JSVAL_PAYLOAD_MASK 0x00007FFFFFFFFFFFLL -#define JSVAL_TAG_MASK 0xFFFF800000000000LL -#define JSVAL_TYPE_TO_TAG(type) ((JSValueTag)(JSVAL_TAG_MAX_DOUBLE | (type))) -#define JSVAL_TYPE_TO_SHIFTED_TAG(type) (((uint64)JSVAL_TYPE_TO_TAG(type)) << JSVAL_TAG_SHIFT) - -#define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET JSVAL_SHIFTED_TAG_NULL -#define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET JSVAL_SHIFTED_TAG_OBJECT -#define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET JSVAL_SHIFTED_TAG_UNDEFINED -#define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_PTR_PAYLOAD_SET JSVAL_SHIFTED_TAG_MAGIC -#define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET JSVAL_SHIFTED_TAG_STRING - -#endif /* JS_BITS_PER_WORD */ - -typedef enum JSWhyMagic -{ - JS_ARRAY_HOLE, /* a hole in a dense array */ - JS_ARGS_HOLE, /* a hole in the args object's array */ - JS_NATIVE_ENUMERATE, /* indicates that a custom enumerate hook forwarded - * to js_Enumerate, which really means the object can be - * enumerated like a native object. */ - JS_NO_ITER_VALUE, /* there is not a pending iterator value */ - JS_GENERATOR_CLOSING, /* exception value thrown when closing a generator */ - JS_NO_CONSTANT, /* compiler sentinel value */ - JS_THIS_POISON, /* used in debug builds to catch tracing errors */ - JS_ARG_POISON, /* used in debug builds to catch tracing errors */ - JS_SERIALIZE_NO_NODE, /* an empty subnode in the AST serializer */ - JS_GENERIC_MAGIC /* for local use */ -} JSWhyMagic; - -typedef struct JSString JSString; -typedef struct JSFlatString JSFlatString; -typedef struct JSObject JSObject; - -#if defined(IS_LITTLE_ENDIAN) -# if JS_BITS_PER_WORD == 32 -typedef union jsval_layout -{ - uint64 asBits; - struct { - union { - int32 i32; - uint32 u32; - JSBool boo; - JSString *str; - JSObject *obj; - void *ptr; - JSWhyMagic why; - jsuword word; - } payload; - JSValueTag tag; - } s; - double asDouble; - void *asPtr; -} jsval_layout; -# elif JS_BITS_PER_WORD == 64 -typedef union jsval_layout -{ - uint64 asBits; -#if (!defined(_WIN64) && defined(__cplusplus)) - /* MSVC does not pack these correctly :-( */ - struct { - uint64 payload47 : 47; - JSValueTag tag : 17; - } debugView; -#endif - struct { - union { - int32 i32; - uint32 u32; - JSWhyMagic why; - jsuword word; - } payload; - } s; - double asDouble; - void *asPtr; -} jsval_layout; -# endif /* JS_BITS_PER_WORD */ -#else /* defined(IS_LITTLE_ENDIAN) */ -# if JS_BITS_PER_WORD == 32 -typedef union jsval_layout -{ - uint64 asBits; - struct { - JSValueTag tag; - union { - int32 i32; - uint32 u32; - JSBool boo; - JSString *str; - JSObject *obj; - void *ptr; - JSWhyMagic why; - jsuword word; - } payload; - } s; - double asDouble; - void *asPtr; -} jsval_layout; -# elif JS_BITS_PER_WORD == 64 -typedef union jsval_layout -{ - uint64 asBits; - struct { - JSValueTag tag : 17; - uint64 payload47 : 47; - } debugView; - struct { - union { - int32 i32; - uint32 u32; - JSWhyMagic why; - } payload; - } s; - double asDouble; - void *asPtr; -} jsval_layout; -# endif /* JS_BITS_PER_WORD */ -#endif /* defined(IS_LITTLE_ENDIAN) */ - -#if JS_BITS_PER_WORD == 32 - -/* - * N.B. GCC, in some but not all cases, chooses to emit signed comparison of - * JSValueTag even though its underlying type has been forced to be uint32. - * Thus, all comparisons should explicitly cast operands to uint32. - */ - -#define BUILD_JSVAL(tag, payload) \ - ((((uint64)(uint32)(tag)) << 32) | (uint32)(payload)) - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_DOUBLE_IMPL(jsval_layout l) -{ - return (uint32)l.s.tag <= (uint32)JSVAL_TAG_CLEAR; -} - -static JS_ALWAYS_INLINE jsval_layout -DOUBLE_TO_JSVAL_IMPL(double d) -{ - jsval_layout l; - l.asDouble = d; - JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(l)); - return l; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_INT32_IMPL(jsval_layout l) -{ - return l.s.tag == JSVAL_TAG_INT32; -} - -static JS_ALWAYS_INLINE int32 -JSVAL_TO_INT32_IMPL(jsval_layout l) -{ - return l.s.payload.i32; -} - -static JS_ALWAYS_INLINE jsval_layout -INT32_TO_JSVAL_IMPL(int32 i) -{ - jsval_layout l; - l.s.tag = JSVAL_TAG_INT32; - l.s.payload.i32 = i; - return l; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_NUMBER_IMPL(jsval_layout l) -{ - JSValueTag tag = l.s.tag; - JS_ASSERT(tag != JSVAL_TAG_CLEAR); - return (uint32)tag <= (uint32)JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_UNDEFINED_IMPL(jsval_layout l) -{ - return l.s.tag == JSVAL_TAG_UNDEFINED; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_STRING_IMPL(jsval_layout l) -{ - return l.s.tag == JSVAL_TAG_STRING; -} - -static JS_ALWAYS_INLINE jsval_layout -STRING_TO_JSVAL_IMPL(JSString *str) -{ - jsval_layout l; - JS_ASSERT(str); - l.s.tag = JSVAL_TAG_STRING; - l.s.payload.str = str; - return l; -} - -static JS_ALWAYS_INLINE JSString * -JSVAL_TO_STRING_IMPL(jsval_layout l) -{ - return l.s.payload.str; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_BOOLEAN_IMPL(jsval_layout l) -{ - return l.s.tag == JSVAL_TAG_BOOLEAN; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_TO_BOOLEAN_IMPL(jsval_layout l) -{ - return l.s.payload.boo; -} - -static JS_ALWAYS_INLINE jsval_layout -BOOLEAN_TO_JSVAL_IMPL(JSBool b) -{ - jsval_layout l; - l.s.tag = JSVAL_TAG_BOOLEAN; - l.s.payload.boo = b; - return l; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_MAGIC_IMPL(jsval_layout l) -{ - return l.s.tag == JSVAL_TAG_MAGIC; -} - -static JS_ALWAYS_INLINE JSObject * -MAGIC_JSVAL_TO_OBJECT_OR_NULL_IMPL(jsval_layout l) -{ - JS_ASSERT(JSVAL_IS_MAGIC_IMPL(l)); - return l.s.payload.obj; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_OBJECT_IMPL(jsval_layout l) -{ - return l.s.tag == JSVAL_TAG_OBJECT; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_PRIMITIVE_IMPL(jsval_layout l) -{ - return (uint32)l.s.tag < (uint32)JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_OBJECT_OR_NULL_IMPL(jsval_layout l) -{ - JS_ASSERT((uint32)l.s.tag <= (uint32)JSVAL_TAG_OBJECT); - return (uint32)l.s.tag >= (uint32)JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET; -} - -static JS_ALWAYS_INLINE JSObject * -JSVAL_TO_OBJECT_IMPL(jsval_layout l) -{ - return l.s.payload.obj; -} - -static JS_ALWAYS_INLINE jsval_layout -OBJECT_TO_JSVAL_IMPL(JSObject *obj) -{ - jsval_layout l; - JS_ASSERT(obj); - l.s.tag = JSVAL_TAG_OBJECT; - l.s.payload.obj = obj; - return l; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_NULL_IMPL(jsval_layout l) -{ - return l.s.tag == JSVAL_TAG_NULL; -} - -static JS_ALWAYS_INLINE jsval_layout -PRIVATE_PTR_TO_JSVAL_IMPL(void *ptr) -{ - jsval_layout l; - JS_ASSERT(((uint32)ptr & 1) == 0); - l.s.tag = (JSValueTag)0; - l.s.payload.ptr = ptr; - JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(l)); - return l; -} - -static JS_ALWAYS_INLINE void * -JSVAL_TO_PRIVATE_PTR_IMPL(jsval_layout l) -{ - return l.s.payload.ptr; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_GCTHING_IMPL(jsval_layout l) -{ - /* gcc sometimes generates signed < without explicit casts. */ - return (uint32)l.s.tag >= (uint32)JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET; -} - -static JS_ALWAYS_INLINE void * -JSVAL_TO_GCTHING_IMPL(jsval_layout l) -{ - return l.s.payload.ptr; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_TRACEABLE_IMPL(jsval_layout l) -{ - return l.s.tag == JSVAL_TAG_STRING || l.s.tag == JSVAL_TAG_OBJECT; -} - -static JS_ALWAYS_INLINE uint32 -JSVAL_TRACE_KIND_IMPL(jsval_layout l) -{ - return (uint32)(JSBool)JSVAL_IS_STRING_IMPL(l); -} - -#elif JS_BITS_PER_WORD == 64 - -#define BUILD_JSVAL(tag, payload) \ - ((((uint64)(uint32)(tag)) << JSVAL_TAG_SHIFT) | (payload)) - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_DOUBLE_IMPL(jsval_layout l) -{ - return l.asBits <= JSVAL_SHIFTED_TAG_MAX_DOUBLE; -} - -static JS_ALWAYS_INLINE jsval_layout -DOUBLE_TO_JSVAL_IMPL(double d) -{ - jsval_layout l; - l.asDouble = d; - JS_ASSERT(l.asBits <= JSVAL_SHIFTED_TAG_MAX_DOUBLE); - return l; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_INT32_IMPL(jsval_layout l) -{ - return (uint32)(l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_INT32; -} - -static JS_ALWAYS_INLINE int32 -JSVAL_TO_INT32_IMPL(jsval_layout l) -{ - return (int32)l.asBits; -} - -static JS_ALWAYS_INLINE jsval_layout -INT32_TO_JSVAL_IMPL(int32 i32) -{ - jsval_layout l; - l.asBits = ((uint64)(uint32)i32) | JSVAL_SHIFTED_TAG_INT32; - return l; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_NUMBER_IMPL(jsval_layout l) -{ - return l.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_UNDEFINED_IMPL(jsval_layout l) -{ - return l.asBits == JSVAL_SHIFTED_TAG_UNDEFINED; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_STRING_IMPL(jsval_layout l) -{ - return (uint32)(l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_STRING; -} - -static JS_ALWAYS_INLINE jsval_layout -STRING_TO_JSVAL_IMPL(JSString *str) -{ - jsval_layout l; - uint64 strBits = (uint64)str; - JS_ASSERT(str); - JS_ASSERT((strBits >> JSVAL_TAG_SHIFT) == 0); - l.asBits = strBits | JSVAL_SHIFTED_TAG_STRING; - return l; -} - -static JS_ALWAYS_INLINE JSString * -JSVAL_TO_STRING_IMPL(jsval_layout l) -{ - return (JSString *)(l.asBits & JSVAL_PAYLOAD_MASK); -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_BOOLEAN_IMPL(jsval_layout l) -{ - return (uint32)(l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_BOOLEAN; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_TO_BOOLEAN_IMPL(jsval_layout l) -{ - return (JSBool)l.asBits; -} - -static JS_ALWAYS_INLINE jsval_layout -BOOLEAN_TO_JSVAL_IMPL(JSBool b) -{ - jsval_layout l; - l.asBits = ((uint64)(uint32)b) | JSVAL_SHIFTED_TAG_BOOLEAN; - return l; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_MAGIC_IMPL(jsval_layout l) -{ - return (l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_MAGIC; -} - -static JS_ALWAYS_INLINE JSObject * -MAGIC_JSVAL_TO_OBJECT_OR_NULL_IMPL(jsval_layout l) -{ - uint64 ptrBits = l.asBits & JSVAL_PAYLOAD_MASK; - JS_ASSERT(JSVAL_IS_MAGIC_IMPL(l)); - JS_ASSERT((ptrBits >> JSVAL_TAG_SHIFT) == 0); - return (JSObject *)ptrBits; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_PRIMITIVE_IMPL(jsval_layout l) -{ - return l.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_OBJECT_IMPL(jsval_layout l) -{ - JS_ASSERT((l.asBits >> JSVAL_TAG_SHIFT) <= JSVAL_SHIFTED_TAG_OBJECT); - return l.asBits >= JSVAL_SHIFTED_TAG_OBJECT; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_OBJECT_OR_NULL_IMPL(jsval_layout l) -{ - JS_ASSERT((l.asBits >> JSVAL_TAG_SHIFT) <= JSVAL_TAG_OBJECT); - return l.asBits >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET; -} - -static JS_ALWAYS_INLINE JSObject * -JSVAL_TO_OBJECT_IMPL(jsval_layout l) -{ - uint64 ptrBits = l.asBits & JSVAL_PAYLOAD_MASK; - JS_ASSERT((ptrBits & 0x7) == 0); - return (JSObject *)ptrBits; -} - -static JS_ALWAYS_INLINE jsval_layout -OBJECT_TO_JSVAL_IMPL(JSObject *obj) -{ - jsval_layout l; - uint64 objBits = (uint64)obj; - JS_ASSERT(obj); - JS_ASSERT((objBits >> JSVAL_TAG_SHIFT) == 0); - l.asBits = objBits | JSVAL_SHIFTED_TAG_OBJECT; - return l; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_NULL_IMPL(jsval_layout l) -{ - return l.asBits == JSVAL_SHIFTED_TAG_NULL; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_GCTHING_IMPL(jsval_layout l) -{ - return l.asBits >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET; -} - -static JS_ALWAYS_INLINE void * -JSVAL_TO_GCTHING_IMPL(jsval_layout l) -{ - uint64 ptrBits = l.asBits & JSVAL_PAYLOAD_MASK; - JS_ASSERT((ptrBits & 0x7) == 0); - return (void *)ptrBits; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_TRACEABLE_IMPL(jsval_layout l) -{ - return JSVAL_IS_GCTHING_IMPL(l) && !JSVAL_IS_NULL_IMPL(l); -} - -static JS_ALWAYS_INLINE uint32 -JSVAL_TRACE_KIND_IMPL(jsval_layout l) -{ - return (uint32)(JSBool)!(JSVAL_IS_OBJECT_IMPL(l)); -} - -static JS_ALWAYS_INLINE jsval_layout -PRIVATE_PTR_TO_JSVAL_IMPL(void *ptr) -{ - jsval_layout l; - uint64 ptrBits = (uint64)ptr; - JS_ASSERT((ptrBits & 1) == 0); - l.asBits = ptrBits >> 1; - JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(l)); - return l; -} - -static JS_ALWAYS_INLINE void * -JSVAL_TO_PRIVATE_PTR_IMPL(jsval_layout l) -{ - JS_ASSERT((l.asBits & 0x8000000000000000LL) == 0); - return (void *)(l.asBits << 1); -} - -#endif - -static JS_ALWAYS_INLINE double -JS_CANONICALIZE_NAN(double d) -{ - if (JS_UNLIKELY(d != d)) { - jsval_layout l; - l.asBits = 0x7FF8000000000000LL; - return l.asDouble; - } - return d; -} - -/* See JS_USE_JSVAL_JSID_STRUCT_TYPES comment in jsapi.h. */ -#if defined(DEBUG) && !defined(JS_NO_JSVAL_JSID_STRUCT_TYPES) -# define JS_USE_JSVAL_JSID_STRUCT_TYPES -#endif - -#ifdef JS_USE_JSVAL_JSID_STRUCT_TYPES - -typedef JSVAL_ALIGNMENT jsval_layout jsval; -typedef struct jsid { size_t asBits; } jsid; - -#if defined(__cplusplus) -extern "C++" -{ - static JS_ALWAYS_INLINE bool - operator==(jsid lhs, jsid rhs) - { - return lhs.asBits == rhs.asBits; - } - - static JS_ALWAYS_INLINE bool - operator!=(jsid lhs, jsid rhs) - { - return lhs.asBits != rhs.asBits; - } - - static JS_ALWAYS_INLINE bool - operator==(jsval lhs, jsval rhs) - { - return lhs.asBits == rhs.asBits; - } - - static JS_ALWAYS_INLINE bool - operator!=(jsval lhs, jsval rhs) - { - return lhs.asBits != rhs.asBits; - } -} -# endif /* defined(__cplusplus) */ - -/* Internal helper macros */ -#define JSVAL_BITS(v) ((v).asBits) -#define JSVAL_FROM_LAYOUT(l) (l) -#define IMPL_TO_JSVAL(v) (v) -#define JSID_BITS(id) ((id).asBits) - -#else /* defined(JS_USE_JSVAL_JSID_STRUCT_TYPES) */ - -/* Use different primitive types so overloading works. */ -typedef JSVAL_ALIGNMENT uint64 jsval; -typedef ptrdiff_t jsid; - -/* Internal helper macros */ -#define JSVAL_BITS(v) (v) -#define JSVAL_FROM_LAYOUT(l) ((l).asBits) -#define IMPL_TO_JSVAL(v) ((v).asBits) -#define JSID_BITS(id) (id) - -#endif /* defined(JS_USE_JSVAL_JSID_STRUCT_TYPES) */ - -JS_END_EXTERN_C - -#endif /* jsvalimpl_h__ */ diff --git a/x86/mozilla/include/jsvalue.h b/x86/mozilla/include/jsvalue.h deleted file mode 100644 index 7baa2c4..0000000 --- a/x86/mozilla/include/jsvalue.h +++ /dev/null @@ -1,1239 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99 ft=cpp: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released - * June 30, 2010 - * - * The Initial Developer of the Original Code is - * the Mozilla Corporation. - * - * Contributor(s): - * Luke Wagner - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsvalue_h__ -#define jsvalue_h__ -/* - * Private value interface. - */ -#include "jsprvtd.h" -#include "jsstdint.h" - -/* - * js::Value is a C++-ified version of jsval that provides more information and - * helper functions than the basic jsval interface exposed by jsapi.h. A few - * general notes on js::Value: - * - * - Since js::Value and jsval have the same representation, values of these - * types, function pointer types differing only in these types, and structs - * differing only in these types can be converted back and forth at no cost - * using the Jsvalify() and Valueify(). See Jsvalify comment below. - * - * - js::Value has setX() and isX() members for X in - * - * { Int32, Double, String, Boolean, Undefined, Null, Object, Magic } - * - * js::Value also contains toX() for each of the non-singleton types. - * - * - Magic is a singleton type whose payload contains a JSWhyMagic "reason" for - * the magic value. By providing JSWhyMagic values when creating and checking - * for magic values, it is possible to assert, at runtime, that only magic - * values with the expected reason flow through a particular value. For - * example, if cx->exception has a magic value, the reason must be - * JS_GENERATOR_CLOSING. - * - * - A key difference between jsval and js::Value is that js::Value gives null - * a separate type. Thus - * - * JSVAL_IS_OBJECT(v) === v.isObjectOrNull() - * !JSVAL_IS_PRIMITIVE(v) === v.isObject() - * - * To help prevent mistakenly boxing a nullable JSObject* as an object, - * Value::setObject takes a JSObject&. (Conversely, Value::asObject returns a - * JSObject&. A convenience member Value::setObjectOrNull is provided. - * - * - JSVAL_VOID is the same as the singleton value of the Undefined type. - * - * - Note that js::Value is always 64-bit. Thus, on 32-bit user code should - * avoid copying jsval/js::Value as much as possible, preferring to pass by - * const Value &. - */ - -/******************************************************************************/ - -/* To avoid a circular dependency, pull in the necessary pieces of jsnum.h. */ - -#include -#if defined(XP_WIN) || defined(XP_OS2) -#include -#endif -#ifdef SOLARIS -#include -#endif - -static inline int -JSDOUBLE_IS_NEGZERO(jsdouble d) -{ -#ifdef WIN32 - return (d == 0 && (_fpclass(d) & _FPCLASS_NZ)); -#elif defined(SOLARIS) - return (d == 0 && copysign(1, d) < 0); -#else - return (d == 0 && signbit(d)); -#endif -} - -static inline bool -JSDOUBLE_IS_INT32(jsdouble d, int32_t* pi) -{ - if (JSDOUBLE_IS_NEGZERO(d)) - return false; - return d == (*pi = int32_t(d)); -} - -/******************************************************************************/ - -/* Additional value operations used in js::Value but not in jsapi.h. */ - -#if JS_BITS_PER_WORD == 32 - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_SPECIFIC_INT32_IMPL(jsval_layout l, int32 i32) -{ - return l.s.tag == JSVAL_TAG_INT32 && l.s.payload.i32 == i32; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_SPECIFIC_BOOLEAN(jsval_layout l, JSBool b) -{ - return (l.s.tag == JSVAL_TAG_BOOLEAN) && (l.s.payload.boo == b); -} - -static JS_ALWAYS_INLINE jsval_layout -MAGIC_TO_JSVAL_IMPL(JSWhyMagic why) -{ - jsval_layout l; - l.s.tag = JSVAL_TAG_MAGIC; - l.s.payload.why = why; - return l; -} - -static JS_ALWAYS_INLINE jsval_layout -MAGIC_TO_JSVAL_IMPL(JSObject *obj) -{ - jsval_layout l; - l.s.tag = JSVAL_TAG_MAGIC; - l.s.payload.obj = obj; - return l; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_SAME_TYPE_IMPL(jsval_layout lhs, jsval_layout rhs) -{ - JSValueTag ltag = lhs.s.tag, rtag = rhs.s.tag; - return ltag == rtag || (ltag < JSVAL_TAG_CLEAR && rtag < JSVAL_TAG_CLEAR); -} - -static JS_ALWAYS_INLINE jsval_layout -PRIVATE_UINT32_TO_JSVAL_IMPL(uint32 ui) -{ - jsval_layout l; - l.s.tag = (JSValueTag)0; - l.s.payload.u32 = ui; - JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(l)); - return l; -} - -static JS_ALWAYS_INLINE uint32 -JSVAL_TO_PRIVATE_UINT32_IMPL(jsval_layout l) -{ - return l.s.payload.u32; -} - -static JS_ALWAYS_INLINE JSValueType -JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(jsval_layout l) -{ - uint32 type = l.s.tag & 0xF; - JS_ASSERT(type > JSVAL_TYPE_DOUBLE); - return (JSValueType)type; -} - -static JS_ALWAYS_INLINE JSValueTag -JSVAL_EXTRACT_NON_DOUBLE_TAG_IMPL(jsval_layout l) -{ - JSValueTag tag = l.s.tag; - JS_ASSERT(tag >= JSVAL_TAG_INT32); - return tag; -} - -#ifdef __cplusplus -JS_STATIC_ASSERT((JSVAL_TYPE_NONFUNOBJ & 0xF) == JSVAL_TYPE_OBJECT); -JS_STATIC_ASSERT((JSVAL_TYPE_FUNOBJ & 0xF) == JSVAL_TYPE_OBJECT); -#endif - -static JS_ALWAYS_INLINE jsval_layout -BOX_NON_DOUBLE_JSVAL(JSValueType type, uint64 *slot) -{ - jsval_layout l; - JS_ASSERT(type > JSVAL_TYPE_DOUBLE && type <= JSVAL_UPPER_INCL_TYPE_OF_BOXABLE_SET); - JS_ASSERT_IF(type == JSVAL_TYPE_STRING || - type == JSVAL_TYPE_OBJECT || - type == JSVAL_TYPE_NONFUNOBJ || - type == JSVAL_TYPE_FUNOBJ, - *(uint32 *)slot != 0); - l.s.tag = JSVAL_TYPE_TO_TAG(type & 0xF); - /* A 32-bit value in a 64-bit slot always occupies the low-addressed end. */ - l.s.payload.u32 = *(uint32 *)slot; - return l; -} - -static JS_ALWAYS_INLINE void -UNBOX_NON_DOUBLE_JSVAL(jsval_layout l, uint64 *out) -{ - JS_ASSERT(!JSVAL_IS_DOUBLE_IMPL(l)); - *(uint32 *)out = l.s.payload.u32; -} - -#elif JS_BITS_PER_WORD == 64 - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_SPECIFIC_INT32_IMPL(jsval_layout l, int32 i32) -{ - return l.asBits == (((uint64)(uint32)i32) | JSVAL_SHIFTED_TAG_INT32); -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_IS_SPECIFIC_BOOLEAN(jsval_layout l, JSBool b) -{ - return l.asBits == (((uint64)(uint32)b) | JSVAL_SHIFTED_TAG_BOOLEAN); -} - -static JS_ALWAYS_INLINE jsval_layout -MAGIC_TO_JSVAL_IMPL(JSWhyMagic why) -{ - jsval_layout l; - l.asBits = ((uint64)(uint32)why) | JSVAL_SHIFTED_TAG_MAGIC; - return l; -} - -static JS_ALWAYS_INLINE jsval_layout -MAGIC_TO_JSVAL_IMPL(JSObject *obj) -{ - jsval_layout l; - l.asBits = ((uint64)obj) | JSVAL_SHIFTED_TAG_MAGIC; - return l; -} - -static JS_ALWAYS_INLINE JSBool -JSVAL_SAME_TYPE_IMPL(jsval_layout lhs, jsval_layout rhs) -{ - uint64 lbits = lhs.asBits, rbits = rhs.asBits; - return (lbits <= JSVAL_TAG_MAX_DOUBLE && rbits <= JSVAL_TAG_MAX_DOUBLE) || - (((lbits ^ rbits) & 0xFFFF800000000000LL) == 0); -} - -static JS_ALWAYS_INLINE jsval_layout -PRIVATE_UINT32_TO_JSVAL_IMPL(uint32 ui) -{ - jsval_layout l; - l.asBits = (uint64)ui; - JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(l)); - return l; -} - -static JS_ALWAYS_INLINE uint32 -JSVAL_TO_PRIVATE_UINT32_IMPL(jsval_layout l) -{ - JS_ASSERT((l.asBits >> 32) == 0); - return (uint32)l.asBits; -} - -static JS_ALWAYS_INLINE JSValueType -JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(jsval_layout l) -{ - uint64 type = (l.asBits >> JSVAL_TAG_SHIFT) & 0xF; - JS_ASSERT(type > JSVAL_TYPE_DOUBLE); - return (JSValueType)type; -} - -static JS_ALWAYS_INLINE JSValueTag -JSVAL_EXTRACT_NON_DOUBLE_TAG_IMPL(jsval_layout l) -{ - uint64 tag = l.asBits >> JSVAL_TAG_SHIFT; - JS_ASSERT(tag > JSVAL_TAG_MAX_DOUBLE); - return (JSValueTag)tag; -} - -#ifdef __cplusplus -JS_STATIC_ASSERT(offsetof(jsval_layout, s.payload) == 0); -JS_STATIC_ASSERT((JSVAL_TYPE_NONFUNOBJ & 0xF) == JSVAL_TYPE_OBJECT); -JS_STATIC_ASSERT((JSVAL_TYPE_FUNOBJ & 0xF) == JSVAL_TYPE_OBJECT); -#endif - -static JS_ALWAYS_INLINE jsval_layout -BOX_NON_DOUBLE_JSVAL(JSValueType type, uint64 *slot) -{ - /* N.B. for 32-bit payloads, the high 32 bits of the slot are trash. */ - jsval_layout l; - JS_ASSERT(type > JSVAL_TYPE_DOUBLE && type <= JSVAL_UPPER_INCL_TYPE_OF_BOXABLE_SET); - uint32 isI32 = (uint32)(type < JSVAL_LOWER_INCL_TYPE_OF_PTR_PAYLOAD_SET); - uint32 shift = isI32 * 32; - uint64 mask = ((uint64)-1) >> shift; - uint64 payload = *slot & mask; - JS_ASSERT_IF(type == JSVAL_TYPE_STRING || - type == JSVAL_TYPE_OBJECT || - type == JSVAL_TYPE_NONFUNOBJ || - type == JSVAL_TYPE_FUNOBJ, - payload != 0); - l.asBits = payload | JSVAL_TYPE_TO_SHIFTED_TAG(type & 0xF); - return l; -} - -static JS_ALWAYS_INLINE void -UNBOX_NON_DOUBLE_JSVAL(jsval_layout l, uint64 *out) -{ - JS_ASSERT(!JSVAL_IS_DOUBLE_IMPL(l)); - *out = (l.asBits & JSVAL_PAYLOAD_MASK); -} - -#endif - -/******************************************************************************/ - -namespace js { - -class Value -{ - public: - /* - * N.B. the default constructor leaves Value unitialized. Adding a default - * constructor prevents Value from being stored in a union. - */ - - /*** Mutatators ***/ - - JS_ALWAYS_INLINE - void setNull() { - data.asBits = JSVAL_BITS(JSVAL_NULL); - } - - JS_ALWAYS_INLINE - void setUndefined() { - data.asBits = JSVAL_BITS(JSVAL_VOID); - } - - JS_ALWAYS_INLINE - void setInt32(int32 i) { - data = INT32_TO_JSVAL_IMPL(i); - } - - JS_ALWAYS_INLINE - int32 &getInt32Ref() { - JS_ASSERT(isInt32()); - return data.s.payload.i32; - } - - JS_ALWAYS_INLINE - void setDouble(double d) { - data = DOUBLE_TO_JSVAL_IMPL(d); - } - - JS_ALWAYS_INLINE - double &getDoubleRef() { - JS_ASSERT(isDouble()); - return data.asDouble; - } - - JS_ALWAYS_INLINE - void setString(JSString *str) { - data = STRING_TO_JSVAL_IMPL(str); - } - - JS_ALWAYS_INLINE - void setObject(JSObject &obj) { - data = OBJECT_TO_JSVAL_IMPL(&obj); - } - - JS_ALWAYS_INLINE - void setBoolean(bool b) { - data = BOOLEAN_TO_JSVAL_IMPL(b); - } - - JS_ALWAYS_INLINE - void setMagic(JSWhyMagic why) { - data = MAGIC_TO_JSVAL_IMPL(why); - } - - JS_ALWAYS_INLINE - void setMagicWithObjectOrNullPayload(JSObject *obj) { - data = MAGIC_TO_JSVAL_IMPL(obj); - } - - JS_ALWAYS_INLINE - JSObject *getMagicObjectOrNullPayload() const { - return MAGIC_JSVAL_TO_OBJECT_OR_NULL_IMPL(data); - } - - JS_ALWAYS_INLINE - void setNumber(uint32 ui) { - if (ui > JSVAL_INT_MAX) - setDouble((double)ui); - else - setInt32((int32)ui); - } - - JS_ALWAYS_INLINE - void setNumber(double d) { - int32_t i; - if (JSDOUBLE_IS_INT32(d, &i)) - setInt32(i); - else - setDouble(d); - } - - JS_ALWAYS_INLINE - void setObjectOrNull(JSObject *arg) { - if (arg) - setObject(*arg); - else - setNull(); - } - - JS_ALWAYS_INLINE - void setObjectOrUndefined(JSObject *arg) { - if (arg) - setObject(*arg); - else - setUndefined(); - } - - JS_ALWAYS_INLINE - void swap(Value &rhs) { - uint64 tmp = rhs.data.asBits; - rhs.data.asBits = data.asBits; - data.asBits = tmp; - } - - /*** Value type queries ***/ - - JS_ALWAYS_INLINE - bool isUndefined() const { - return JSVAL_IS_UNDEFINED_IMPL(data); - } - - JS_ALWAYS_INLINE - bool isNull() const { - return JSVAL_IS_NULL_IMPL(data); - } - - JS_ALWAYS_INLINE - bool isNullOrUndefined() const { - return isNull() || isUndefined(); - } - - JS_ALWAYS_INLINE - bool isInt32() const { - return JSVAL_IS_INT32_IMPL(data); - } - - JS_ALWAYS_INLINE - bool isInt32(int32 i32) const { - return JSVAL_IS_SPECIFIC_INT32_IMPL(data, i32); - } - - JS_ALWAYS_INLINE - bool isDouble() const { - return JSVAL_IS_DOUBLE_IMPL(data); - } - - JS_ALWAYS_INLINE - bool isNumber() const { - return JSVAL_IS_NUMBER_IMPL(data); - } - - JS_ALWAYS_INLINE - bool isString() const { - return JSVAL_IS_STRING_IMPL(data); - } - - JS_ALWAYS_INLINE - bool isObject() const { - return JSVAL_IS_OBJECT_IMPL(data); - } - - JS_ALWAYS_INLINE - bool isPrimitive() const { - return JSVAL_IS_PRIMITIVE_IMPL(data); - } - - JS_ALWAYS_INLINE - bool isObjectOrNull() const { - return JSVAL_IS_OBJECT_OR_NULL_IMPL(data); - } - - JS_ALWAYS_INLINE - bool isGCThing() const { - return JSVAL_IS_GCTHING_IMPL(data); - } - - JS_ALWAYS_INLINE - bool isBoolean() const { - return JSVAL_IS_BOOLEAN_IMPL(data); - } - - JS_ALWAYS_INLINE - bool isTrue() const { - return JSVAL_IS_SPECIFIC_BOOLEAN(data, true); - } - - JS_ALWAYS_INLINE - bool isFalse() const { - return JSVAL_IS_SPECIFIC_BOOLEAN(data, false); - } - - JS_ALWAYS_INLINE - bool isMagic() const { - return JSVAL_IS_MAGIC_IMPL(data); - } - - JS_ALWAYS_INLINE - bool isMagic(JSWhyMagic why) const { - JS_ASSERT_IF(isMagic(), data.s.payload.why == why); - return JSVAL_IS_MAGIC_IMPL(data); - } - -#if JS_BITS_PER_WORD == 64 - JS_ALWAYS_INLINE - bool hasPtrPayload() const { - return data.asBits >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_PTR_PAYLOAD_SET; - } -#endif - - JS_ALWAYS_INLINE - bool isMarkable() const { - return JSVAL_IS_TRACEABLE_IMPL(data); - } - - JS_ALWAYS_INLINE - int32 gcKind() const { - JS_ASSERT(isMarkable()); - return JSVAL_TRACE_KIND_IMPL(data); - } - -#ifdef DEBUG - JS_ALWAYS_INLINE - JSWhyMagic whyMagic() const { - JS_ASSERT(isMagic()); - return data.s.payload.why; - } -#endif - - /*** Comparison ***/ - - JS_ALWAYS_INLINE - bool operator==(const Value &rhs) const { - return data.asBits == rhs.data.asBits; - } - - JS_ALWAYS_INLINE - bool operator!=(const Value &rhs) const { - return data.asBits != rhs.data.asBits; - } - - /* This function used to be inlined here, but this triggered a gcc bug - due to SameType being used in a template method. - See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38850 */ - friend bool SameType(const Value &lhs, const Value &rhs); - - /*** Extract the value's typed payload ***/ - - JS_ALWAYS_INLINE - int32 toInt32() const { - JS_ASSERT(isInt32()); - return JSVAL_TO_INT32_IMPL(data); - } - - JS_ALWAYS_INLINE - double toDouble() const { - JS_ASSERT(isDouble()); - return data.asDouble; - } - - JS_ALWAYS_INLINE - double toNumber() const { - JS_ASSERT(isNumber()); - return isDouble() ? toDouble() : double(toInt32()); - } - - JS_ALWAYS_INLINE - JSString *toString() const { - JS_ASSERT(isString()); - return JSVAL_TO_STRING_IMPL(data); - } - - JS_ALWAYS_INLINE - JSObject &toObject() const { - JS_ASSERT(isObject()); - return *JSVAL_TO_OBJECT_IMPL(data); - } - - JS_ALWAYS_INLINE - JSObject *toObjectOrNull() const { - JS_ASSERT(isObjectOrNull()); - return JSVAL_TO_OBJECT_IMPL(data); - } - - JS_ALWAYS_INLINE - void *toGCThing() const { - JS_ASSERT(isGCThing()); - return JSVAL_TO_GCTHING_IMPL(data); - } - - JS_ALWAYS_INLINE - bool toBoolean() const { - JS_ASSERT(isBoolean()); - return JSVAL_TO_BOOLEAN_IMPL(data); - } - - JS_ALWAYS_INLINE - uint32 payloadAsRawUint32() const { - JS_ASSERT(!isDouble()); - return data.s.payload.u32; - } - - JS_ALWAYS_INLINE - uint64 asRawBits() const { - return data.asBits; - } - - /* - * In the extract/box/unbox functions below, "NonDouble" means this - * functions must not be called on a value that is a double. This allows - * these operations to be implemented more efficiently, since doubles - * generally already require special handling by the caller. - */ - JS_ALWAYS_INLINE - JSValueType extractNonDoubleType() const { - return JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(data); - } - - JS_ALWAYS_INLINE - JSValueTag extractNonDoubleTag() const { - return JSVAL_EXTRACT_NON_DOUBLE_TAG_IMPL(data); - } - - JS_ALWAYS_INLINE - void unboxNonDoubleTo(uint64 *out) const { - UNBOX_NON_DOUBLE_JSVAL(data, out); - } - - JS_ALWAYS_INLINE - void boxNonDoubleFrom(JSValueType type, uint64 *out) { - data = BOX_NON_DOUBLE_JSVAL(type, out); - } - - /* - * The trace-jit specializes JSVAL_TYPE_OBJECT into JSVAL_TYPE_FUNOBJ and - * JSVAL_TYPE_NONFUNOBJ. Since these two operations just return the type of - * a value, the caller must handle JSVAL_TYPE_OBJECT separately. - */ - JS_ALWAYS_INLINE - JSValueType extractNonDoubleObjectTraceType() const { - JS_ASSERT(!isObject()); - return JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(data); - } - - JS_ALWAYS_INLINE - JSValueTag extractNonDoubleObjectTraceTag() const { - JS_ASSERT(!isObject()); - return JSVAL_EXTRACT_NON_DOUBLE_TAG_IMPL(data); - } - - /* - * Private API - * - * Private setters/getters allow the caller to read/write arbitrary types - * that fit in the 64-bit payload. It is the caller's responsibility, after - * storing to a value with setPrivateX to read only using getPrivateX. - * Privates values are given a type type which ensures they are not marked. - */ - - JS_ALWAYS_INLINE - void setPrivate(void *ptr) { - data = PRIVATE_PTR_TO_JSVAL_IMPL(ptr); - } - - JS_ALWAYS_INLINE - void *toPrivate() const { - JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(data)); - return JSVAL_TO_PRIVATE_PTR_IMPL(data); - } - - JS_ALWAYS_INLINE - void setPrivateUint32(uint32 ui) { - data = PRIVATE_UINT32_TO_JSVAL_IMPL(ui); - } - - JS_ALWAYS_INLINE - uint32 toPrivateUint32() const { - JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(data)); - return JSVAL_TO_PRIVATE_UINT32_IMPL(data); - } - - JS_ALWAYS_INLINE - uint32 &getPrivateUint32Ref() { - JS_ASSERT(isDouble()); - return data.s.payload.u32; - } - - /* - * An unmarked value is just a void* cast as a Value. Thus, the Value is - * not safe for GC and must not be marked. This API avoids raw casts - * and the ensuing strict-aliasing warnings. - */ - - JS_ALWAYS_INLINE - void setUnmarkedPtr(void *ptr) { - data.asPtr = ptr; - } - - JS_ALWAYS_INLINE - void *toUnmarkedPtr() const { - return data.asPtr; - } - - const jsuword *payloadWord() const { - return &data.s.payload.word; - } - - private: - void staticAssertions() { - JS_STATIC_ASSERT(sizeof(JSValueType) == 1); - JS_STATIC_ASSERT(sizeof(JSValueTag) == 4); - JS_STATIC_ASSERT(sizeof(JSBool) == 4); - JS_STATIC_ASSERT(sizeof(JSWhyMagic) <= 4); - JS_STATIC_ASSERT(sizeof(jsval) == 8); - } - - jsval_layout data; -} JSVAL_ALIGNMENT; - -JS_ALWAYS_INLINE bool -SameType(const Value &lhs, const Value &rhs) -{ - return JSVAL_SAME_TYPE_IMPL(lhs.data, rhs.data); -} - -static JS_ALWAYS_INLINE Value -NullValue() -{ - Value v; - v.setNull(); - return v; -} - -static JS_ALWAYS_INLINE Value -UndefinedValue() -{ - Value v; - v.setUndefined(); - return v; -} - -static JS_ALWAYS_INLINE Value -Int32Value(int32 i32) -{ - Value v; - v.setInt32(i32); - return v; -} - -static JS_ALWAYS_INLINE Value -DoubleValue(double dbl) -{ - Value v; - v.setDouble(dbl); - return v; -} - -static JS_ALWAYS_INLINE Value -StringValue(JSString *str) -{ - Value v; - v.setString(str); - return v; -} - -static JS_ALWAYS_INLINE Value -BooleanValue(bool boo) -{ - Value v; - v.setBoolean(boo); - return v; -} - -static JS_ALWAYS_INLINE Value -ObjectValue(JSObject &obj) -{ - Value v; - v.setObject(obj); - return v; -} - -static JS_ALWAYS_INLINE Value -MagicValue(JSWhyMagic why) -{ - Value v; - v.setMagic(why); - return v; -} - -static JS_ALWAYS_INLINE Value -NumberValue(double dbl) -{ - Value v; - v.setNumber(dbl); - return v; -} - -static JS_ALWAYS_INLINE Value -ObjectOrNullValue(JSObject *obj) -{ - Value v; - v.setObjectOrNull(obj); - return v; -} - -static JS_ALWAYS_INLINE Value -PrivateValue(void *ptr) -{ - Value v; - v.setPrivate(ptr); - return v; -} - -static JS_ALWAYS_INLINE void -ClearValueRange(Value *vec, uintN len, bool useHoles) -{ - if (useHoles) { - for (uintN i = 0; i < len; i++) - vec[i].setMagic(JS_ARRAY_HOLE); - } else { - for (uintN i = 0; i < len; i++) - vec[i].setUndefined(); - } -} - -/******************************************************************************/ - -/* - * As asserted above, js::Value and jsval are layout equivalent. This means: - * - an instance of jsval may be reinterpreted as a js::Value and vice versa; - * - a pointer to a function taking jsval arguments may be reinterpreted as a - * function taking the same arguments, s/jsval/js::Value/, and vice versa; - * - a struct containing jsval members may be reinterpreted as a struct with - * the same members, s/jsval/js::Value/, and vice versa. - * - * To prevent widespread conversion using casts, which would effectively - * disable the C++ typesystem in places where we want it, a set of safe - * conversions between known-equivalent types is provided below. Given a type - * JsvalT expressedin terms of jsval and an equivalent type ValueT expressed in - * terms of js::Value, instances may be converted back and forth using: - * - * JsvalT *x = ... - * ValueT *y = js::Valueify(x); - * JsvalT *z = js::Jsvalify(y); - * assert(x == z); - * - * Conversions between references is also provided for some types. If it seems - * like a cast is needed to convert between jsval/js::Value, consider adding a - * new safe overload to Jsvalify/Valueify. - */ - -static inline jsval * Jsvalify(Value *v) { return (jsval *)v; } -static inline const jsval * Jsvalify(const Value *v) { return (const jsval *)v; } -static inline jsval & Jsvalify(Value &v) { return (jsval &)v; } -static inline const jsval & Jsvalify(const Value &v) { return (const jsval &)v; } -static inline Value * Valueify(jsval *v) { return (Value *)v; } -static inline const Value * Valueify(const jsval *v) { return (const Value *)v; } -static inline Value ** Valueify(jsval **v) { return (Value **)v; } -static inline Value & Valueify(jsval &v) { return (Value &)v; } -static inline const Value & Valueify(const jsval &v) { return (const Value &)v; } - -struct Class; - -typedef JSBool -(* Native)(JSContext *cx, uintN argc, Value *vp); -typedef JSBool -(* PropertyOp)(JSContext *cx, JSObject *obj, jsid id, Value *vp); -typedef JSBool -(* StrictPropertyOp)(JSContext *cx, JSObject *obj, jsid id, JSBool strict, Value *vp); -typedef JSBool -(* ConvertOp)(JSContext *cx, JSObject *obj, JSType type, Value *vp); -typedef JSBool -(* NewEnumerateOp)(JSContext *cx, JSObject *obj, JSIterateOp enum_op, - Value *statep, jsid *idp); -typedef JSBool -(* HasInstanceOp)(JSContext *cx, JSObject *obj, const Value *v, JSBool *bp); -typedef JSBool -(* CheckAccessOp)(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, - Value *vp); -typedef JSBool -(* EqualityOp)(JSContext *cx, JSObject *obj, const Value *v, JSBool *bp); -typedef JSBool -(* DefinePropOp)(JSContext *cx, JSObject *obj, jsid id, const Value *value, - PropertyOp getter, StrictPropertyOp setter, uintN attrs); -typedef JSBool -(* PropertyIdOp)(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp); -typedef JSBool -(* StrictPropertyIdOp)(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict); -typedef JSBool -(* DeleteIdOp)(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict); -typedef JSBool -(* CallOp)(JSContext *cx, uintN argc, Value *vp); -typedef JSBool -(* LookupPropOp)(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, - JSProperty **propp); -typedef JSBool -(* AttributesOp)(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp); -typedef JSType -(* TypeOfOp)(JSContext *cx, JSObject *obj); -typedef void -(* TraceOp)(JSTracer *trc, JSObject *obj); -typedef JSObject * -(* ObjectOp)(JSContext *cx, JSObject *obj); -typedef void -(* FinalizeOp)(JSContext *cx, JSObject *obj); - -class AutoIdVector; - -/* - * Prepare to make |obj| non-extensible; in particular, fully resolve its properties. - * On error, return false. - * If |obj| is now ready to become non-extensible, set |*fixed| to true and return true. - * If |obj| refuses to become non-extensible, set |*fixed| to false and return true; the - * caller will throw an appropriate error. - */ -typedef JSBool -(* FixOp)(JSContext *cx, JSObject *obj, bool *fixed, AutoIdVector *props); - -static inline Native Valueify(JSNative f) { return (Native)f; } -static inline JSNative Jsvalify(Native f) { return (JSNative)f; } -static inline PropertyOp Valueify(JSPropertyOp f) { return (PropertyOp)f; } -static inline JSPropertyOp Jsvalify(PropertyOp f) { return (JSPropertyOp)f; } -static inline StrictPropertyOp Valueify(JSStrictPropertyOp f) { return (StrictPropertyOp)f; } -static inline JSStrictPropertyOp Jsvalify(StrictPropertyOp f) { return (JSStrictPropertyOp)f; } -static inline ConvertOp Valueify(JSConvertOp f) { return (ConvertOp)f; } -static inline JSConvertOp Jsvalify(ConvertOp f) { return (JSConvertOp)f; } -static inline NewEnumerateOp Valueify(JSNewEnumerateOp f) { return (NewEnumerateOp)f; } -static inline JSNewEnumerateOp Jsvalify(NewEnumerateOp f) { return (JSNewEnumerateOp)f; } -static inline HasInstanceOp Valueify(JSHasInstanceOp f) { return (HasInstanceOp)f; } -static inline JSHasInstanceOp Jsvalify(HasInstanceOp f) { return (JSHasInstanceOp)f; } -static inline CheckAccessOp Valueify(JSCheckAccessOp f) { return (CheckAccessOp)f; } -static inline JSCheckAccessOp Jsvalify(CheckAccessOp f) { return (JSCheckAccessOp)f; } -static inline EqualityOp Valueify(JSEqualityOp f); /* Same type as JSHasInstanceOp */ -static inline JSEqualityOp Jsvalify(EqualityOp f); /* Same type as HasInstanceOp */ - -static const PropertyOp PropertyStub = (PropertyOp)JS_PropertyStub; -static const StrictPropertyOp StrictPropertyStub = (StrictPropertyOp)JS_StrictPropertyStub; -static const JSEnumerateOp EnumerateStub = JS_EnumerateStub; -static const JSResolveOp ResolveStub = JS_ResolveStub; -static const ConvertOp ConvertStub = (ConvertOp)JS_ConvertStub; -static const JSFinalizeOp FinalizeStub = JS_FinalizeStub; - -#define JS_CLASS_MEMBERS \ - const char *name; \ - uint32 flags; \ - \ - /* Mandatory non-null function pointer members. */ \ - PropertyOp addProperty; \ - PropertyOp delProperty; \ - PropertyOp getProperty; \ - StrictPropertyOp setProperty; \ - JSEnumerateOp enumerate; \ - JSResolveOp resolve; \ - ConvertOp convert; \ - JSFinalizeOp finalize; \ - \ - /* Optionally non-null members start here. */ \ - JSClassInternal reserved0; \ - CheckAccessOp checkAccess; \ - Native call; \ - Native construct; \ - JSXDRObjectOp xdrObject; \ - HasInstanceOp hasInstance; \ - JSMarkOp mark - - -/* - * The helper struct to measure the size of JS_CLASS_MEMBERS to know how much - * we have to padd js::Class to match the size of JSClass; - */ -struct ClassSizeMeasurement { - JS_CLASS_MEMBERS; -}; - -struct ClassExtension { - EqualityOp equality; - JSObjectOp outerObject; - JSObjectOp innerObject; - JSIteratorOp iteratorObject; - void *unused; -}; - -#define JS_NULL_CLASS_EXT {NULL,NULL,NULL,NULL,NULL} - -struct ObjectOps { - js::LookupPropOp lookupProperty; - js::DefinePropOp defineProperty; - js::PropertyIdOp getProperty; - js::StrictPropertyIdOp setProperty; - js::AttributesOp getAttributes; - js::AttributesOp setAttributes; - js::DeleteIdOp deleteProperty; - js::NewEnumerateOp enumerate; - js::TypeOfOp typeOf; - js::TraceOp trace; - js::FixOp fix; - js::ObjectOp thisObject; - js::FinalizeOp clear; -}; - -#define JS_NULL_OBJECT_OPS {NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL} - -struct Class { - JS_CLASS_MEMBERS; - ClassExtension ext; - ObjectOps ops; - uint8 pad[sizeof(JSClass) - sizeof(ClassSizeMeasurement) - - sizeof(ClassExtension) - sizeof(ObjectOps)]; - - /* Class is not native and its map is not a scope. */ - static const uint32 NON_NATIVE = JSCLASS_INTERNAL_FLAG2; - - bool isNative() const { - return !(flags & NON_NATIVE); - } -}; - -JS_STATIC_ASSERT(offsetof(JSClass, name) == offsetof(Class, name)); -JS_STATIC_ASSERT(offsetof(JSClass, flags) == offsetof(Class, flags)); -JS_STATIC_ASSERT(offsetof(JSClass, addProperty) == offsetof(Class, addProperty)); -JS_STATIC_ASSERT(offsetof(JSClass, delProperty) == offsetof(Class, delProperty)); -JS_STATIC_ASSERT(offsetof(JSClass, getProperty) == offsetof(Class, getProperty)); -JS_STATIC_ASSERT(offsetof(JSClass, setProperty) == offsetof(Class, setProperty)); -JS_STATIC_ASSERT(offsetof(JSClass, enumerate) == offsetof(Class, enumerate)); -JS_STATIC_ASSERT(offsetof(JSClass, resolve) == offsetof(Class, resolve)); -JS_STATIC_ASSERT(offsetof(JSClass, convert) == offsetof(Class, convert)); -JS_STATIC_ASSERT(offsetof(JSClass, finalize) == offsetof(Class, finalize)); -JS_STATIC_ASSERT(offsetof(JSClass, reserved0) == offsetof(Class, reserved0)); -JS_STATIC_ASSERT(offsetof(JSClass, checkAccess) == offsetof(Class, checkAccess)); -JS_STATIC_ASSERT(offsetof(JSClass, call) == offsetof(Class, call)); -JS_STATIC_ASSERT(offsetof(JSClass, construct) == offsetof(Class, construct)); -JS_STATIC_ASSERT(offsetof(JSClass, xdrObject) == offsetof(Class, xdrObject)); -JS_STATIC_ASSERT(offsetof(JSClass, hasInstance) == offsetof(Class, hasInstance)); -JS_STATIC_ASSERT(offsetof(JSClass, mark) == offsetof(Class, mark)); -JS_STATIC_ASSERT(sizeof(JSClass) == sizeof(Class)); - -struct PropertyDescriptor { - JSObject *obj; - uintN attrs; - PropertyOp getter; - StrictPropertyOp setter; - Value value; - uintN shortid; -}; -JS_STATIC_ASSERT(offsetof(JSPropertyDescriptor, obj) == offsetof(PropertyDescriptor, obj)); -JS_STATIC_ASSERT(offsetof(JSPropertyDescriptor, attrs) == offsetof(PropertyDescriptor, attrs)); -JS_STATIC_ASSERT(offsetof(JSPropertyDescriptor, getter) == offsetof(PropertyDescriptor, getter)); -JS_STATIC_ASSERT(offsetof(JSPropertyDescriptor, setter) == offsetof(PropertyDescriptor, setter)); -JS_STATIC_ASSERT(offsetof(JSPropertyDescriptor, value) == offsetof(PropertyDescriptor, value)); -JS_STATIC_ASSERT(offsetof(JSPropertyDescriptor, shortid) == offsetof(PropertyDescriptor, shortid)); -JS_STATIC_ASSERT(sizeof(JSPropertyDescriptor) == sizeof(PropertyDescriptor)); - -static JS_ALWAYS_INLINE JSClass * Jsvalify(Class *c) { return (JSClass *)c; } -static JS_ALWAYS_INLINE Class * Valueify(JSClass *c) { return (Class *)c; } -static JS_ALWAYS_INLINE JSPropertyDescriptor * Jsvalify(PropertyDescriptor *p) { return (JSPropertyDescriptor *) p; } -static JS_ALWAYS_INLINE PropertyDescriptor * Valueify(JSPropertyDescriptor *p) { return (PropertyDescriptor *) p; } - -/******************************************************************************/ - -/* - * Any cast-via-function-call, inlined or not, will cause initialization to - * happen at startup, rather than statically, so just cast in release builds. - */ -#ifdef DEBUG - -# define JS_VALUEIFY(type, v) js::Valueify(v) -# define JS_JSVALIFY(type, v) js::Jsvalify(v) - -static inline JSNative JsvalifyNative(Native n) { return (JSNative)n; } -static inline JSNative JsvalifyNative(JSNative n) { return n; } -static inline Native ValueifyNative(JSNative n) { return (Native)n; } -static inline Native ValueifyNative(Native n) { return n; } - -# define JS_VALUEIFY_NATIVE(n) js::ValueifyNative(n) -# define JS_JSVALIFY_NATIVE(n) js::JsvalifyNative(n) - -#else - -# define JS_VALUEIFY(type, v) ((type)(v)) -# define JS_JSVALIFY(type, v) ((type)(v)) - -# define JS_VALUEIFY_NATIVE(n) ((js::Native)(n)) -# define JS_JSVALIFY_NATIVE(n) ((JSNative)(n)) - -#endif - -/* - * JSFunctionSpec uses JSAPI jsval in function signatures whereas the engine - * uses js::Value. To avoid widespread (JSNative) casting, have JS_FN perfom a - * type-safe cast. - */ -#undef JS_FN -#define JS_FN(name,call,nargs,flags) \ - {name, JS_JSVALIFY_NATIVE(call), nargs, (flags) | JSFUN_STUB_GSOPS} - -/******************************************************************************/ - -/* - * In some cases (quickstubs) we want to take a value in whatever manner is - * appropriate for the architecture and normalize to a const js::Value &. On - * x64, passing a js::Value may cause the to unnecessarily be passed through - * memory instead of registers, so jsval, which is a builtin uint64 is used. - */ -#if JS_BITS_PER_WORD == 32 -typedef const js::Value *ValueArgType; - -static JS_ALWAYS_INLINE const js::Value & -ValueArgToConstRef(const js::Value *arg) -{ - return *arg; -} - -#elif JS_BITS_PER_WORD == 64 -typedef js::Value ValueArgType; - -static JS_ALWAYS_INLINE const Value & -ValueArgToConstRef(const Value &v) -{ - return v; -} -#endif - -/******************************************************************************/ - -static JS_ALWAYS_INLINE void -MakeRangeGCSafe(Value *vec, size_t len) -{ - PodZero(vec, len); -} - -static JS_ALWAYS_INLINE void -MakeRangeGCSafe(Value *beg, Value *end) -{ - PodZero(beg, end - beg); -} - -static JS_ALWAYS_INLINE void -MakeRangeGCSafe(jsid *beg, jsid *end) -{ - for (jsid *id = beg; id != end; ++id) - *id = INT_TO_JSID(0); -} - -static JS_ALWAYS_INLINE void -MakeRangeGCSafe(jsid *vec, size_t len) -{ - MakeRangeGCSafe(vec, vec + len); -} - -static JS_ALWAYS_INLINE void -MakeRangeGCSafe(const Shape **beg, const Shape **end) -{ - PodZero(beg, end - beg); -} - -static JS_ALWAYS_INLINE void -MakeRangeGCSafe(const Shape **vec, size_t len) -{ - PodZero(vec, len); -} - -static JS_ALWAYS_INLINE void -SetValueRangeToUndefined(Value *beg, Value *end) -{ - for (Value *v = beg; v != end; ++v) - v->setUndefined(); -} - -static JS_ALWAYS_INLINE void -SetValueRangeToUndefined(Value *vec, size_t len) -{ - SetValueRangeToUndefined(vec, vec + len); -} - -static JS_ALWAYS_INLINE void -SetValueRangeToNull(Value *beg, Value *end) -{ - for (Value *v = beg; v != end; ++v) - v->setNull(); -} - -static JS_ALWAYS_INLINE void -SetValueRangeToNull(Value *vec, size_t len) -{ - SetValueRangeToNull(vec, vec + len); -} - -/* - * To really poison a set of values, using 'magic' or 'undefined' isn't good - * enough since often these will just be ignored by buggy code (see bug 629974) - * in debug builds and crash in release builds. Instead, we use a safe-for-crash - * pointer. - */ -static JS_ALWAYS_INLINE void -Debug_SetValueRangeToCrashOnTouch(Value *beg, Value *end) -{ -#ifdef DEBUG - for (Value *v = beg; v != end; ++v) - v->setObject(*reinterpret_cast(0x42)); -#endif -} - -static JS_ALWAYS_INLINE void -Debug_SetValueRangeToCrashOnTouch(Value *vec, size_t len) -{ -#ifdef DEBUG - Debug_SetValueRangeToCrashOnTouch(vec, vec + len); -#endif -} - -} /* namespace js */ -#endif /* jsvalue_h__ */ diff --git a/x86/mozilla/include/jsvector.h b/x86/mozilla/include/jsvector.h deleted file mode 100644 index ab432ba..0000000 --- a/x86/mozilla/include/jsvector.h +++ /dev/null @@ -1,759 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=99 ft=cpp: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released - * June 12, 2009. - * - * The Initial Developer of the Original Code is - * the Mozilla Corporation. - * - * Contributor(s): - * Luke Wagner - * Nicholas Nethercote - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsvector_h_ -#define jsvector_h_ - -#include "jstl.h" -#include "jsprvtd.h" - -/* Silence dire "bugs in previous versions of MSVC have been fixed" warnings */ -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4345) -#endif - -/* Gross special case for Gecko, which defines malloc/calloc/free. */ -#ifdef mozilla_mozalloc_macro_wrappers_h -# define JSVECTOR_UNDEFD_MOZALLOC_WRAPPERS -# include "mozilla/mozalloc_undef_macro_wrappers.h" -#endif - -namespace js { - -/* - * This template class provides a default implementation for vector operations - * when the element type is not known to be a POD, as judged by IsPodType. - */ -template -struct VectorImpl -{ - /* Destroys constructed objects in the range [begin, end). */ - static inline void destroy(T *begin, T *end) { - for (T *p = begin; p != end; ++p) - p->~T(); - } - - /* Constructs objects in the uninitialized range [begin, end). */ - static inline void initialize(T *begin, T *end) { - for (T *p = begin; p != end; ++p) - new(p) T(); - } - - /* - * Copy-constructs objects in the uninitialized range - * [dst, dst+(srcend-srcbeg)) from the range [srcbeg, srcend). - */ - template - static inline void copyConstruct(T *dst, const U *srcbeg, const U *srcend) { - for (const U *p = srcbeg; p != srcend; ++p, ++dst) - new(dst) T(*p); - } - - /* - * Copy-constructs objects in the uninitialized range [dst, dst+n) from the - * same object u. - */ - template - static inline void copyConstructN(T *dst, size_t n, const U &u) { - for (T *end = dst + n; dst != end; ++dst) - new(dst) T(u); - } - - /* - * Grows the given buffer to have capacity newcap, preserving the objects - * constructed in the range [begin, end) and updating v. Assumes that (1) - * newcap has not overflowed, and (2) multiplying newcap by sizeof(T) will - * not overflow. - */ - static inline bool growTo(Vector &v, size_t newcap) { - JS_ASSERT(!v.usingInlineStorage()); - T *newbuf = reinterpret_cast(v.malloc(newcap * sizeof(T))); - if (!newbuf) - return false; - for (T *dst = newbuf, *src = v.beginNoCheck(); src != v.endNoCheck(); ++dst, ++src) - new(dst) T(*src); - VectorImpl::destroy(v.beginNoCheck(), v.endNoCheck()); - v.free(v.mBegin); - v.mBegin = newbuf; - /* v.mLength is unchanged. */ - v.mCapacity = newcap; - return true; - } -}; - -/* - * This partial template specialization provides a default implementation for - * vector operations when the element type is known to be a POD, as judged by - * IsPodType. - */ -template -struct VectorImpl -{ - static inline void destroy(T *, T *) {} - - static inline void initialize(T *begin, T *end) { - /* - * You would think that memset would be a big win (or even break even) - * when we know T is a POD. But currently it's not. This is probably - * because |append| tends to be given small ranges and memset requires - * a function call that doesn't get inlined. - * - * memset(begin, 0, sizeof(T) * (end-begin)); - */ - for (T *p = begin; p != end; ++p) - new(p) T(); - } - - template - static inline void copyConstruct(T *dst, const U *srcbeg, const U *srcend) { - /* - * See above memset comment. Also, notice that copyConstruct is - * currently templated (T != U), so memcpy won't work without - * requiring T == U. - * - * memcpy(dst, srcbeg, sizeof(T) * (srcend - srcbeg)); - */ - for (const U *p = srcbeg; p != srcend; ++p, ++dst) - *dst = *p; - } - - static inline void copyConstructN(T *dst, size_t n, const T &t) { - for (T *p = dst, *end = dst + n; p != end; ++p) - *p = t; - } - - static inline bool growTo(Vector &v, size_t newcap) { - JS_ASSERT(!v.usingInlineStorage()); - size_t bytes = sizeof(T) * newcap; - T *newbuf = reinterpret_cast(v.realloc(v.mBegin, bytes)); - if (!newbuf) - return false; - v.mBegin = newbuf; - /* v.mLength is unchanged. */ - v.mCapacity = newcap; - return true; - } -}; - -/* - * JS-friendly, STL-like container providing a short-lived, dynamic buffer. - * Vector calls the constructors/destructors of all elements stored in - * its internal buffer, so non-PODs may be safely used. Additionally, - * Vector will store the first N elements in-place before resorting to - * dynamic allocation. - * - * T requirements: - * - default and copy constructible, assignable, destructible - * - operations do not throw - * N requirements: - * - any value, however, N is clamped to min/max values - * AllocPolicy: - * - see "Allocation policies" in jstl.h (default ContextAllocPolicy) - * - * N.B: Vector is not reentrant: T member functions called during Vector member - * functions must not call back into the same object. - */ -template -class Vector : AllocPolicy -{ - /* utilities */ - - static const bool sElemIsPod = tl::IsPodType::result; - typedef VectorImpl Impl; - friend struct VectorImpl; - - bool calculateNewCapacity(size_t curLength, size_t lengthInc, size_t &newCap); - bool growStorageBy(size_t lengthInc); - bool growHeapStorageBy(size_t lengthInc); - bool convertToHeapStorage(size_t lengthInc); - - template inline bool growByImpl(size_t inc); - - /* magic constants */ - - static const int sMaxInlineBytes = 1024; - - /* compute constants */ - - static const size_t sInlineCapacity = - tl::Min::result; - - /* Calculate inline buffer size; avoid 0-sized array. */ - static const size_t sInlineBytes = - tl::Max<1, sInlineCapacity * sizeof(T)>::result; - - /* member data */ - - /* - * Pointer to the buffer, be it inline or heap-allocated. Only [mBegin, - * mBegin + mLength) hold valid constructed T objects. The range [mBegin + - * mLength, mBegin + mCapacity) holds uninitialized memory. - */ - T *mBegin; - size_t mLength; /* Number of elements in the Vector. */ - size_t mCapacity; /* Max number of elements storable in the Vector without resizing. */ - - AlignedStorage storage; - -#ifdef DEBUG - friend class ReentrancyGuard; - bool entered; -#endif - - Vector(const Vector &); - Vector &operator=(const Vector &); - - /* private accessors */ - - bool usingInlineStorage() const { - return mBegin == (T *)storage.addr(); - } - - T *beginNoCheck() const { - return mBegin; - } - - T *endNoCheck() { - return mBegin + mLength; - } - - const T *endNoCheck() const { - return mBegin + mLength; - } - - public: - typedef T ElementType; - - Vector(AllocPolicy = AllocPolicy()); - ~Vector(); - - /* accessors */ - - const AllocPolicy &allocPolicy() const { - return *this; - } - - enum { InlineLength = N }; - - size_t length() const { - return mLength; - } - - bool empty() const { - return mLength == 0; - } - - size_t capacity() const { - return mCapacity; - } - - T *begin() const { - JS_ASSERT(!entered); - return mBegin; - } - - T *end() { - JS_ASSERT(!entered); - return mBegin + mLength; - } - - const T *end() const { - JS_ASSERT(!entered); - return mBegin + mLength; - } - - T &operator[](size_t i) { - JS_ASSERT(!entered && i < mLength); - return begin()[i]; - } - - const T &operator[](size_t i) const { - JS_ASSERT(!entered && i < mLength); - return begin()[i]; - } - - T &back() { - JS_ASSERT(!entered && !empty()); - return *(end() - 1); - } - - const T &back() const { - JS_ASSERT(!entered && !empty()); - return *(end() - 1); - } - - /* mutators */ - - /* If reserve(length() + N) succeeds, the N next appends are guaranteed to succeed. */ - bool reserve(size_t capacity); - - /* Destroy elements in the range [begin() + incr, end()). */ - void shrinkBy(size_t incr); - - /* Grow the vector by incr elements. */ - bool growBy(size_t incr); - - /* Call shrinkBy or growBy based on whether newSize > length(). */ - bool resize(size_t newLength); - - /* Leave new elements as uninitialized memory. */ - bool growByUninitialized(size_t incr); - bool resizeUninitialized(size_t newLength); - - void clear(); - - bool append(const T &t); - bool appendN(const T &t, size_t n); - template bool append(const U *begin, const U *end); - template bool append(const U *begin, size_t length); - template bool append(const Vector &other); - - void popBack(); - - T popCopy(); - - /* - * Transfers ownership of the internal buffer used by Vector to the caller. - * After this call, the Vector is empty. Since the returned buffer may need - * to be allocated (if the elements are currently stored in-place), the - * call can fail, returning NULL. - * - * N.B. Although a T*, only the range [0, length()) is constructed. - */ - T *extractRawBuffer(); - - /* - * Transfer ownership of an array of objects into the Vector. - * N.B. This call assumes that there are no uninitialized elements in the - * passed array. - */ - void replaceRawBuffer(T *p, size_t length); - - /* - * Places |val| at position |p|, shifting existing elements - * from |p| onward one position higher. - */ - bool insert(T *p, const T &val); - - /* - * Removes the element |t|, which must fall in the bounds [begin, end), - * shifting existing elements from |t + 1| onward one position lower. - */ - void erase(T *t); -}; - -/* This does the re-entrancy check plus several other sanity checks. */ -#define REENTRANCY_GUARD_ET_AL \ - ReentrancyGuard g(*this); \ - JS_ASSERT_IF(usingInlineStorage(), mCapacity == sInlineCapacity); \ - JS_ASSERT(mLength <= mCapacity) - -/* Vector Implementation */ - -template -JS_ALWAYS_INLINE -Vector::Vector(AllocPolicy ap) - : AllocPolicy(ap), mBegin((T *)storage.addr()), mLength(0), - mCapacity(sInlineCapacity) -#ifdef DEBUG - , entered(false) -#endif -{} - -template -JS_ALWAYS_INLINE -Vector::~Vector() -{ - REENTRANCY_GUARD_ET_AL; - Impl::destroy(beginNoCheck(), endNoCheck()); - if (!usingInlineStorage()) - this->free(beginNoCheck()); -} - -/* - * Calculate a new capacity that is at least lengthInc greater than - * curLength and check for overflow. - */ -template -STATIC_POSTCONDITION(!return || newCap >= curLength + lengthInc) -inline bool -Vector::calculateNewCapacity(size_t curLength, size_t lengthInc, - size_t &newCap) -{ - size_t newMinCap = curLength + lengthInc; - - /* - * Check for overflow in the above addition, below CEILING_LOG2, and later - * multiplication by sizeof(T). - */ - if (newMinCap < curLength || - newMinCap & tl::MulOverflowMask<2 * sizeof(T)>::result) { - this->reportAllocOverflow(); - return false; - } - - /* Round up to next power of 2. */ - newCap = RoundUpPow2(newMinCap); - - /* - * Do not allow a buffer large enough that the expression ((char *)end() - - * (char *)begin()) overflows ptrdiff_t. See Bug 510319. - */ - if (newCap & tl::UnsafeRangeSizeMask::result) { - this->reportAllocOverflow(); - return false; - } - return true; -} - -/* - * This function will grow the current heap capacity to have capacity - * (mLength + lengthInc) and fail on OOM or integer overflow. - */ -template -JS_ALWAYS_INLINE bool -Vector::growHeapStorageBy(size_t lengthInc) -{ - JS_ASSERT(!usingInlineStorage()); - size_t newCap; - return calculateNewCapacity(mLength, lengthInc, newCap) && - Impl::growTo(*this, newCap); -} - -/* - * This function will create a new heap buffer with capacity (mLength + - * lengthInc()), move all elements in the inline buffer to this new buffer, - * and fail on OOM or integer overflow. - */ -template -inline bool -Vector::convertToHeapStorage(size_t lengthInc) -{ - JS_ASSERT(usingInlineStorage()); - size_t newCap; - if (!calculateNewCapacity(mLength, lengthInc, newCap)) - return false; - - /* Allocate buffer. */ - T *newBuf = reinterpret_cast(this->malloc(newCap * sizeof(T))); - if (!newBuf) - return false; - - /* Copy inline elements into heap buffer. */ - Impl::copyConstruct(newBuf, beginNoCheck(), endNoCheck()); - Impl::destroy(beginNoCheck(), endNoCheck()); - - /* Switch in heap buffer. */ - mBegin = newBuf; - /* mLength is unchanged. */ - mCapacity = newCap; - return true; -} - -template -JS_NEVER_INLINE bool -Vector::growStorageBy(size_t incr) -{ - JS_ASSERT(mLength + incr > mCapacity); - return usingInlineStorage() - ? convertToHeapStorage(incr) - : growHeapStorageBy(incr); -} - -template -inline bool -Vector::reserve(size_t request) -{ - REENTRANCY_GUARD_ET_AL; - if (request > mCapacity) - return growStorageBy(request - mLength); - return true; -} - -template -inline void -Vector::shrinkBy(size_t incr) -{ - REENTRANCY_GUARD_ET_AL; - JS_ASSERT(incr <= mLength); - Impl::destroy(endNoCheck() - incr, endNoCheck()); - mLength -= incr; -} - -template -template -JS_ALWAYS_INLINE bool -Vector::growByImpl(size_t incr) -{ - REENTRANCY_GUARD_ET_AL; - if (incr > mCapacity - mLength && !growStorageBy(incr)) - return false; - - JS_ASSERT(mLength + incr <= mCapacity); - T *newend = endNoCheck() + incr; - if (InitNewElems) - Impl::initialize(endNoCheck(), newend); - mLength += incr; - return true; -} - -template -JS_ALWAYS_INLINE bool -Vector::growBy(size_t incr) -{ - return growByImpl(incr); -} - -template -JS_ALWAYS_INLINE bool -Vector::growByUninitialized(size_t incr) -{ - return growByImpl(incr); -} - -template -STATIC_POSTCONDITION(!return || ubound(this->begin()) >= newLength) -inline bool -Vector::resize(size_t newLength) -{ - size_t curLength = mLength; - if (newLength > curLength) - return growBy(newLength - curLength); - shrinkBy(curLength - newLength); - return true; -} - -template -JS_ALWAYS_INLINE bool -Vector::resizeUninitialized(size_t newLength) -{ - size_t curLength = mLength; - if (newLength > curLength) - return growByUninitialized(newLength - curLength); - shrinkBy(curLength - newLength); - return true; -} - -template -inline void -Vector::clear() -{ - REENTRANCY_GUARD_ET_AL; - Impl::destroy(beginNoCheck(), endNoCheck()); - mLength = 0; -} - -template -JS_ALWAYS_INLINE bool -Vector::append(const T &t) -{ - REENTRANCY_GUARD_ET_AL; - if (mLength == mCapacity && !growStorageBy(1)) - return false; - - JS_ASSERT(mLength < mCapacity); - new(endNoCheck()) T(t); - ++mLength; - return true; -} - -template -JS_ALWAYS_INLINE bool -Vector::appendN(const T &t, size_t needed) -{ - REENTRANCY_GUARD_ET_AL; - if (mLength + needed > mCapacity && !growStorageBy(needed)) - return false; - - JS_ASSERT(mLength + needed <= mCapacity); - Impl::copyConstructN(endNoCheck(), needed, t); - mLength += needed; - return true; -} - -template -inline bool -Vector::insert(T *p, const T &val) -{ - JS_ASSERT(begin() <= p && p <= end()); - size_t pos = p - begin(); - JS_ASSERT(pos <= mLength); - size_t oldLength = mLength; - if (pos == oldLength) - return append(val); - { - T oldBack = back(); - if (!append(oldBack)) /* Dup the last element. */ - return false; - } - for (size_t i = oldLength; i > pos; --i) - (*this)[i] = (*this)[i - 1]; - (*this)[pos] = val; - return true; -} - -template -inline void -Vector::erase(T *it) -{ - JS_ASSERT(begin() <= it && it < end()); - while (it + 1 != end()) { - *it = *(it + 1); - ++it; - } - popBack(); -} - -template -template -JS_ALWAYS_INLINE bool -Vector::append(const U *insBegin, const U *insEnd) -{ - REENTRANCY_GUARD_ET_AL; - size_t needed = PointerRangeSize(insBegin, insEnd); - if (mLength + needed > mCapacity && !growStorageBy(needed)) - return false; - - JS_ASSERT(mLength + needed <= mCapacity); - Impl::copyConstruct(endNoCheck(), insBegin, insEnd); - mLength += needed; - return true; -} - -template -template -inline bool -Vector::append(const Vector &other) -{ - return append(other.begin(), other.end()); -} - -template -template -JS_ALWAYS_INLINE bool -Vector::append(const U *insBegin, size_t length) -{ - return this->append(insBegin, insBegin + length); -} - -template -JS_ALWAYS_INLINE void -Vector::popBack() -{ - REENTRANCY_GUARD_ET_AL; - JS_ASSERT(!empty()); - --mLength; - endNoCheck()->~T(); -} - -template -JS_ALWAYS_INLINE T -Vector::popCopy() -{ - T ret = back(); - popBack(); - return ret; -} - -template -inline T * -Vector::extractRawBuffer() -{ - T *ret; - if (usingInlineStorage()) { - ret = reinterpret_cast(this->malloc(mLength * sizeof(T))); - if (!ret) - return NULL; - Impl::copyConstruct(ret, beginNoCheck(), endNoCheck()); - Impl::destroy(beginNoCheck(), endNoCheck()); - /* mBegin, mCapacity are unchanged. */ - mLength = 0; - } else { - ret = mBegin; - mBegin = (T *)storage.addr(); - mLength = 0; - mCapacity = sInlineCapacity; - } - return ret; -} - -template -inline void -Vector::replaceRawBuffer(T *p, size_t length) -{ - REENTRANCY_GUARD_ET_AL; - - /* Destroy what we have. */ - Impl::destroy(beginNoCheck(), endNoCheck()); - if (!usingInlineStorage()) - this->free(beginNoCheck()); - - /* Take in the new buffer. */ - if (length <= sInlineCapacity) { - /* - * We convert to inline storage if possible, even though p might - * otherwise be acceptable. Maybe this behaviour should be - * specifiable with an argument to this function. - */ - mBegin = (T *)storage.addr(); - mLength = length; - mCapacity = sInlineCapacity; - Impl::copyConstruct(mBegin, p, p + length); - Impl::destroy(p, p + length); - this->free(p); - } else { - mBegin = p; - mLength = length; - mCapacity = length; - } -} - -} /* namespace js */ - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -#ifdef JSVECTOR_UNDEFD_MOZALLOC_WRAPPERS -# include "mozilla/mozalloc_macro_wrappers.h" -#endif - -#endif /* jsvector_h_ */ diff --git a/x86/mozilla/include/jsversion.h b/x86/mozilla/include/jsversion.h deleted file mode 100644 index f72af49..0000000 --- a/x86/mozilla/include/jsversion.h +++ /dev/null @@ -1,221 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * JS configuration macros. - */ -#ifndef JS_VERSION -#define JS_VERSION 185 -#endif - -/* - * Compile-time JS version configuration. The JS version numbers lie on the - * number line like so: - * - * 1.0 1.1 1.2 1.3 1.4 ECMAv3 1.5 1.6 1.7 1.8 ECMAv5 - * ^ ^ - * | | - * basis for ECMAv1 close to ECMAv2 - * - * where ECMAv3 stands for ECMA-262 Edition 3, and ECMAv5 stands for Edition 5. - * See the runtime version enum JSVersion in jspubtd.h. Code in the engine can - * therefore count on version <= JSVERSION_1_4 to mean "before the Third - * Edition of ECMA-262" and version > JSVERSION_1_4 to mean "at or after the - * Third Edition". - * - * In the (likely?) event that SpiderMonkey grows to implement JavaScript 2.0, - * the version number to use would be near 200, or greater. - * - * The JS_VERSION_ECMA_3 version is the minimal configuration conforming to - * the ECMA-262 Edition 3 specification. Use it for minimal embeddings, where - * you're sure you don't need any of the extensions disabled in this version. - * In order to facilitate testing, JS_HAS_OBJ_PROTO_PROP is defined as part of - * the JS_VERSION_ECMA_3_TEST version. - * - * To keep things sane in the modern age, where we need exceptions in order to - * implement, e.g., iterators and generators, we are dropping support for all - * versions <= 1.4. - */ -#define JS_VERSION_ECMA_3 148 -#define JS_VERSION_ECMA_3_TEST 149 - -#if JS_VERSION == JS_VERSION_ECMA_3 || \ - JS_VERSION == JS_VERSION_ECMA_3_TEST - -#define JS_HAS_STR_HTML_HELPERS 0 /* has str.anchor, str.bold, etc. */ -#define JS_HAS_PERL_SUBSTR 0 /* has str.substr */ -#if JS_VERSION == JS_VERSION_ECMA_3_TEST -#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */ -#else -#define JS_HAS_OBJ_PROTO_PROP 0 /* has o.__proto__ etc. */ -#endif -#define JS_HAS_OBJ_WATCHPOINT 0 /* has o.watch and o.unwatch */ -#define JS_HAS_SHARP_VARS 0 /* has #n=, #n# for object literals */ -#define JS_HAS_XDR 0 /* has XDR API and internal support */ -#define JS_HAS_TOSOURCE 0 /* has Object/Array toSource method */ -#define JS_HAS_CATCH_GUARD 0 /* has exception handling catch guard */ -#define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty elems */ -#define JS_HAS_UNEVAL 0 /* has uneval() top-level function */ -#define JS_HAS_CONST 0 /* has JS2 const as alternative var */ -#define JS_HAS_FUN_EXPR_STMT 0 /* has function expression statement */ -#define JS_HAS_NO_SUCH_METHOD 0 /* has o.__noSuchMethod__ handler */ -#define JS_HAS_XML_SUPPORT 0 /* has ECMAScript for XML support */ -#define JS_HAS_ARRAY_EXTRAS 0 /* has indexOf and Lispy extras */ -#define JS_HAS_GENERATORS 0 /* has yield in generator function */ -#define JS_HAS_BLOCK_SCOPE 0 /* has block scope via let/arraycomp */ -#define JS_HAS_DESTRUCTURING 0 /* has [a,b] = ... or {p:a,q:b} = ... */ -#define JS_HAS_GENERATOR_EXPRS 0 /* has (expr for (lhs in iterable)) */ -#define JS_HAS_EXPR_CLOSURES 0 /* has function (formals) listexpr */ - -#elif JS_VERSION < 150 - -#error "unsupported JS_VERSION" - -#elif JS_VERSION == 150 - -#define JS_HAS_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. */ -#define JS_HAS_PERL_SUBSTR 1 /* has str.substr */ -#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */ -#define JS_HAS_OBJ_WATCHPOINT 1 /* has o.watch and o.unwatch */ -#define JS_HAS_SHARP_VARS 1 /* has #n=, #n# for object literals */ -#define JS_HAS_XDR 1 /* has XDR API and internal support */ -#define JS_HAS_TOSOURCE 1 /* has Object/Array toSource method */ -#define JS_HAS_CATCH_GUARD 1 /* has exception handling catch guard */ -#define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty elems */ -#define JS_HAS_UNEVAL 1 /* has uneval() top-level function */ -#define JS_HAS_CONST 1 /* has JS2 const as alternative var */ -#define JS_HAS_FUN_EXPR_STMT 1 /* has function expression statement */ -#define JS_HAS_NO_SUCH_METHOD 1 /* has o.__noSuchMethod__ handler */ -#define JS_HAS_XML_SUPPORT 0 /* has ECMAScript for XML support */ -#define JS_HAS_ARRAY_EXTRAS 0 /* has indexOf and Lispy extras */ -#define JS_HAS_GENERATORS 0 /* has yield in generator function */ -#define JS_HAS_BLOCK_SCOPE 0 /* has block scope via let/arraycomp */ -#define JS_HAS_DESTRUCTURING 0 /* has [a,b] = ... or {p:a,q:b} = ... */ -#define JS_HAS_GENERATOR_EXPRS 0 /* has (expr for (lhs in iterable)) */ -#define JS_HAS_EXPR_CLOSURES 0 /* has function (formals) listexpr */ - -#elif JS_VERSION == 160 - -#define JS_HAS_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. */ -#define JS_HAS_PERL_SUBSTR 1 /* has str.substr */ -#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */ -#define JS_HAS_OBJ_WATCHPOINT 1 /* has o.watch and o.unwatch */ -#define JS_HAS_SHARP_VARS 1 /* has #n=, #n# for object literals */ -#define JS_HAS_XDR 1 /* has XDR API and internal support */ -#define JS_HAS_TOSOURCE 1 /* has Object/Array toSource method */ -#define JS_HAS_CATCH_GUARD 1 /* has exception handling catch guard */ -#define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty elems */ -#define JS_HAS_UNEVAL 1 /* has uneval() top-level function */ -#define JS_HAS_CONST 1 /* has JS2 const as alternative var */ -#define JS_HAS_FUN_EXPR_STMT 1 /* has function expression statement */ -#define JS_HAS_NO_SUCH_METHOD 1 /* has o.__noSuchMethod__ handler */ -#define JS_HAS_XML_SUPPORT 1 /* has ECMAScript for XML support */ -#define JS_HAS_ARRAY_EXTRAS 1 /* has indexOf and Lispy extras */ -#define JS_HAS_GENERATORS 0 /* has yield in generator function */ -#define JS_HAS_BLOCK_SCOPE 0 /* has block scope via let/arraycomp */ -#define JS_HAS_DESTRUCTURING 0 /* has [a,b] = ... or {p:a,q:b} = ... */ -#define JS_HAS_GENERATOR_EXPRS 0 /* has (expr for (lhs in iterable)) */ -#define JS_HAS_EXPR_CLOSURES 0 /* has function (formals) listexpr */ - -#elif JS_VERSION == 170 - -#define JS_HAS_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. */ -#define JS_HAS_PERL_SUBSTR 1 /* has str.substr */ -#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */ -#define JS_HAS_OBJ_WATCHPOINT 1 /* has o.watch and o.unwatch */ -#define JS_HAS_SHARP_VARS 1 /* has #n=, #n# for object literals */ -#define JS_HAS_XDR 1 /* has XDR API and internal support */ -#define JS_HAS_TOSOURCE 1 /* has Object/Array toSource method */ -#define JS_HAS_CATCH_GUARD 1 /* has exception handling catch guard */ -#define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty elems */ -#define JS_HAS_UNEVAL 1 /* has uneval() top-level function */ -#define JS_HAS_CONST 1 /* has JS2 const as alternative var */ -#define JS_HAS_FUN_EXPR_STMT 1 /* has function expression statement */ -#define JS_HAS_NO_SUCH_METHOD 1 /* has o.__noSuchMethod__ handler */ -#define JS_HAS_XML_SUPPORT 1 /* has ECMAScript for XML support */ -#define JS_HAS_ARRAY_EXTRAS 1 /* has indexOf and Lispy extras */ -#define JS_HAS_GENERATORS 1 /* has yield in generator function */ -#define JS_HAS_BLOCK_SCOPE 1 /* has block scope via let/arraycomp */ -#define JS_HAS_DESTRUCTURING 1 /* has [a,b] = ... or {p:a,q:b} = ... */ -#define JS_HAS_GENERATOR_EXPRS 0 /* has (expr for (lhs in iterable)) */ -#define JS_HAS_EXPR_CLOSURES 0 /* has function (formals) listexpr */ - -#elif 180 <= JS_VERSION && JS_VERSION <= 185 - -#define JS_HAS_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. */ -#define JS_HAS_PERL_SUBSTR 1 /* has str.substr */ -#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */ -#define JS_HAS_OBJ_WATCHPOINT 1 /* has o.watch and o.unwatch */ -#define JS_HAS_SHARP_VARS 1 /* has #n=, #n# for object literals */ -#define JS_HAS_XDR 1 /* has XDR API and internal support */ -#define JS_HAS_TOSOURCE 1 /* has Object/Array toSource method */ -#define JS_HAS_CATCH_GUARD 1 /* has exception handling catch guard */ -#define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty elems */ -#define JS_HAS_UNEVAL 1 /* has uneval() top-level function */ -#define JS_HAS_CONST 1 /* has JS2 const as alternative var */ -#define JS_HAS_FUN_EXPR_STMT 1 /* has function expression statement */ -#define JS_HAS_NO_SUCH_METHOD 1 /* has o.__noSuchMethod__ handler */ -#define JS_HAS_XML_SUPPORT 1 /* has ECMAScript for XML support */ -#define JS_HAS_ARRAY_EXTRAS 1 /* has indexOf and Lispy extras */ -#define JS_HAS_GENERATORS 1 /* has yield in generator function */ -#define JS_HAS_BLOCK_SCOPE 1 /* has block scope via let/arraycomp */ -#define JS_HAS_DESTRUCTURING 2 /* has [a,b] = ... or {p:a,q:b} = ... */ -#define JS_HAS_GENERATOR_EXPRS 1 /* has (expr for (lhs in iterable)) */ -#define JS_HAS_EXPR_CLOSURES 1 /* has function (formals) listexpr */ - -#else - -#error "unknown JS_VERSION" - -#endif - -/* Support for JS_NewGlobalObject. */ -#define JS_HAS_NEW_GLOBAL_OBJECT 1 - -/* Support for JS_MakeSystemObject. */ -#define JS_HAS_MAKE_SYSTEM_OBJECT 1 - -/* Feature-test macro for evolving destructuring support. */ -#define JS_HAS_DESTRUCTURING_SHORTHAND (JS_HAS_DESTRUCTURING == 2) - -/* - * Feature for Object.prototype.__{define,lookup}{G,S}etter__ legacy support; - * support likely to be made opt-in at some future time. - */ -#define OLD_GETTER_SETTER_METHODS 1 diff --git a/x86/mozilla/include/jswrapper.h b/x86/mozilla/include/jswrapper.h deleted file mode 100644 index 23514ff..0000000 --- a/x86/mozilla/include/jswrapper.h +++ /dev/null @@ -1,193 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=4 sw=4 et tw=99: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released - * May 28, 2008. - * - * The Initial Developer of the Original Code is - * Mozilla Foundation - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Andreas Gal - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jswrapper_h___ -#define jswrapper_h___ - -#include "jsapi.h" -#include "jsproxy.h" - -JS_BEGIN_EXTERN_C - -/* No-op wrapper handler base class. */ -class JS_FRIEND_API(JSWrapper) : public js::JSProxyHandler { - uintN mFlags; - public: - uintN flags() const { return mFlags; } - - explicit JSWrapper(uintN flags); - - typedef enum { PermitObjectAccess, PermitPropertyAccess, DenyAccess } Permission; - - virtual ~JSWrapper(); - - /* ES5 Harmony fundamental wrapper traps. */ - virtual bool getPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id, bool set, - js::PropertyDescriptor *desc); - virtual bool getOwnPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id, bool set, - js::PropertyDescriptor *desc); - virtual bool defineProperty(JSContext *cx, JSObject *wrapper, jsid id, - js::PropertyDescriptor *desc); - virtual bool getOwnPropertyNames(JSContext *cx, JSObject *wrapper, js::AutoIdVector &props); - virtual bool delete_(JSContext *cx, JSObject *wrapper, jsid id, bool *bp); - virtual bool enumerate(JSContext *cx, JSObject *wrapper, js::AutoIdVector &props); - virtual bool fix(JSContext *cx, JSObject *wrapper, js::Value *vp); - - /* ES5 Harmony derived wrapper traps. */ - virtual bool has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp); - virtual bool hasOwn(JSContext *cx, JSObject *wrapper, jsid id, bool *bp); - virtual bool get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, js::Value *vp); - virtual bool set(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, bool strict, - js::Value *vp); - virtual bool keys(JSContext *cx, JSObject *wrapper, js::AutoIdVector &props); - virtual bool iterate(JSContext *cx, JSObject *wrapper, uintN flags, js::Value *vp); - - /* Spidermonkey extensions. */ - virtual bool call(JSContext *cx, JSObject *wrapper, uintN argc, js::Value *vp); - virtual bool construct(JSContext *cx, JSObject *wrapper, uintN argc, js::Value *argv, - js::Value *rval); - virtual bool hasInstance(JSContext *cx, JSObject *wrapper, const js::Value *vp, bool *bp); - virtual JSType typeOf(JSContext *cx, JSObject *proxy); - virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper); - virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, uintN indent); - - virtual void trace(JSTracer *trc, JSObject *wrapper); - - /* Policy enforcement traps. */ - enum Action { GET, SET, CALL }; - virtual bool enter(JSContext *cx, JSObject *wrapper, jsid id, Action act, bool *bp); - virtual void leave(JSContext *cx, JSObject *wrapper); - - static JSWrapper singleton; - - static JSObject *New(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent, - JSWrapper *handler); - - static inline JSObject *wrappedObject(const JSObject *wrapper) { - return wrapper->getProxyPrivate().toObjectOrNull(); - } - static inline JSWrapper *wrapperHandler(const JSObject *wrapper) { - return static_cast(wrapper->getProxyHandler()); - } - - enum { - CROSS_COMPARTMENT = 1 << 0, - LAST_USED_FLAG = CROSS_COMPARTMENT - }; - - static void *getWrapperFamily(); -}; - -/* Base class for all cross compartment wrapper handlers. */ -class JS_FRIEND_API(JSCrossCompartmentWrapper) : public JSWrapper { - public: - JSCrossCompartmentWrapper(uintN flags); - - virtual ~JSCrossCompartmentWrapper(); - - /* ES5 Harmony fundamental wrapper traps. */ - virtual bool getPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id, bool set, - js::PropertyDescriptor *desc); - virtual bool getOwnPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id, bool set, - js::PropertyDescriptor *desc); - virtual bool defineProperty(JSContext *cx, JSObject *wrapper, jsid id, - js::PropertyDescriptor *desc); - virtual bool getOwnPropertyNames(JSContext *cx, JSObject *wrapper, js::AutoIdVector &props); - virtual bool delete_(JSContext *cx, JSObject *wrapper, jsid id, bool *bp); - virtual bool enumerate(JSContext *cx, JSObject *wrapper, js::AutoIdVector &props); - - /* ES5 Harmony derived wrapper traps. */ - virtual bool has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp); - virtual bool hasOwn(JSContext *cx, JSObject *wrapper, jsid id, bool *bp); - virtual bool get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, js::Value *vp); - virtual bool set(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, bool strict, - js::Value *vp); - virtual bool keys(JSContext *cx, JSObject *wrapper, js::AutoIdVector &props); - virtual bool iterate(JSContext *cx, JSObject *wrapper, uintN flags, js::Value *vp); - - /* Spidermonkey extensions. */ - virtual bool call(JSContext *cx, JSObject *wrapper, uintN argc, js::Value *vp); - virtual bool construct(JSContext *cx, JSObject *wrapper, - uintN argc, js::Value *argv, js::Value *rval); - virtual bool hasInstance(JSContext *cx, JSObject *wrapper, const js::Value *vp, bool *bp); - virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper); - virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, uintN indent); - - static JSCrossCompartmentWrapper singleton; -}; - -namespace js { - -class AutoCompartment -{ - public: - JSContext * const context; - JSCompartment * const origin; - JSObject * const target; - JSCompartment * const destination; - private: - LazilyConstructed frame; - JSFrameRegs regs; - AutoStringRooter input; - bool entered; - - public: - AutoCompartment(JSContext *cx, JSObject *target); - ~AutoCompartment(); - - bool enter(); - void leave(); - - private: - // Prohibit copying. - AutoCompartment(const AutoCompartment &); - AutoCompartment & operator=(const AutoCompartment &); -}; - -extern JSObject * -TransparentObjectWrapper(JSContext *cx, JSObject *obj, JSObject *wrappedProto, JSObject *parent, - uintN flags); - -} - -JS_END_EXTERN_C - -#endif diff --git a/x86/mozilla/include/jsxdrapi.h b/x86/mozilla/include/jsxdrapi.h deleted file mode 100644 index 87f633f..0000000 --- a/x86/mozilla/include/jsxdrapi.h +++ /dev/null @@ -1,219 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sw=4 et tw=78: - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsxdrapi_h___ -#define jsxdrapi_h___ - -/* - * JS external data representation interface API. - * - * The XDR system is comprised of three major parts: - * - * - the state serialization/deserialization APIs, which allow consumers - * of the API to serialize JS runtime state (script bytecodes, atom maps, - * object graphs, etc.) for later restoration. These portions - * are implemented in various appropriate files, such as jsscript.c - * for the script portions and jsobj.c for object state. - * - the callback APIs through which the runtime requests an opaque - * representation of a native object, and through which the runtime - * constructs a live native object from an opaque representation. These - * portions are the responsibility of the native object implementor. - * - utility functions for en/decoding of primitive types, such as - * JSStrings. This portion is implemented in jsxdrapi.c. - * - * Spiritually guided by Sun's XDR, where appropriate. - */ - -#include "jspubtd.h" -#include "jsprvtd.h" - -JS_BEGIN_EXTERN_C - -/* We use little-endian byteorder for all encoded data */ - -#if defined IS_LITTLE_ENDIAN -#define JSXDR_SWAB32(x) x -#define JSXDR_SWAB16(x) x -#elif defined IS_BIG_ENDIAN -#define JSXDR_SWAB32(x) (((uint32)(x) >> 24) | \ - (((uint32)(x) >> 8) & 0xff00) | \ - (((uint32)(x) << 8) & 0xff0000) | \ - ((uint32)(x) << 24)) -#define JSXDR_SWAB16(x) (((uint16)(x) >> 8) | ((uint16)(x) << 8)) -#else -#error "unknown byte order" -#endif - -#define JSXDR_ALIGN 4 - -typedef enum JSXDRMode { - JSXDR_ENCODE, - JSXDR_DECODE, - JSXDR_FREE -} JSXDRMode; - -typedef enum JSXDRWhence { - JSXDR_SEEK_SET, - JSXDR_SEEK_CUR, - JSXDR_SEEK_END -} JSXDRWhence; - -typedef struct JSXDROps { - JSBool (*get32)(JSXDRState *, uint32 *); - JSBool (*set32)(JSXDRState *, uint32 *); - JSBool (*getbytes)(JSXDRState *, char *, uint32); - JSBool (*setbytes)(JSXDRState *, char *, uint32); - void * (*raw)(JSXDRState *, uint32); - JSBool (*seek)(JSXDRState *, int32, JSXDRWhence); - uint32 (*tell)(JSXDRState *); - void (*finalize)(JSXDRState *); -} JSXDROps; - -struct JSXDRState { - JSXDRMode mode; - JSXDROps *ops; - JSContext *cx; - JSClass **registry; - uintN numclasses; - uintN maxclasses; - void *reghash; - void *userdata; - JSScript *script; -}; - -extern JS_PUBLIC_API(void) -JS_XDRInitBase(JSXDRState *xdr, JSXDRMode mode, JSContext *cx); - -extern JS_PUBLIC_API(JSXDRState *) -JS_XDRNewMem(JSContext *cx, JSXDRMode mode); - -extern JS_PUBLIC_API(void *) -JS_XDRMemGetData(JSXDRState *xdr, uint32 *lp); - -extern JS_PUBLIC_API(void) -JS_XDRMemSetData(JSXDRState *xdr, void *data, uint32 len); - -extern JS_PUBLIC_API(uint32) -JS_XDRMemDataLeft(JSXDRState *xdr); - -extern JS_PUBLIC_API(void) -JS_XDRMemResetData(JSXDRState *xdr); - -extern JS_PUBLIC_API(void) -JS_XDRDestroy(JSXDRState *xdr); - -extern JS_PUBLIC_API(JSBool) -JS_XDRUint8(JSXDRState *xdr, uint8 *b); - -extern JS_PUBLIC_API(JSBool) -JS_XDRUint16(JSXDRState *xdr, uint16 *s); - -extern JS_PUBLIC_API(JSBool) -JS_XDRUint32(JSXDRState *xdr, uint32 *lp); - -extern JS_PUBLIC_API(JSBool) -JS_XDRBytes(JSXDRState *xdr, char *bytes, uint32 len); - -extern JS_PUBLIC_API(JSBool) -JS_XDRCString(JSXDRState *xdr, char **sp); - -extern JS_PUBLIC_API(JSBool) -JS_XDRCStringOrNull(JSXDRState *xdr, char **sp); - -extern JS_PUBLIC_API(JSBool) -JS_XDRString(JSXDRState *xdr, JSString **strp); - -extern JS_PUBLIC_API(JSBool) -JS_XDRStringOrNull(JSXDRState *xdr, JSString **strp); - -extern JS_PUBLIC_API(JSBool) -JS_XDRDouble(JSXDRState *xdr, jsdouble *dp); - -extern JS_PUBLIC_API(JSBool) -JS_XDRValue(JSXDRState *xdr, jsval *vp); - -extern JS_PUBLIC_API(JSBool) -JS_XDRScript(JSXDRState *xdr, JSScript **scriptp); - -extern JS_PUBLIC_API(JSBool) -JS_XDRRegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *lp); - -extern JS_PUBLIC_API(uint32) -JS_XDRFindClassIdByName(JSXDRState *xdr, const char *name); - -extern JS_PUBLIC_API(JSClass *) -JS_XDRFindClassById(JSXDRState *xdr, uint32 id); - -/* - * Magic numbers. - */ -#define JSXDR_MAGIC_SCRIPT_1 0xdead0001 -#define JSXDR_MAGIC_SCRIPT_2 0xdead0002 -#define JSXDR_MAGIC_SCRIPT_3 0xdead0003 -#define JSXDR_MAGIC_SCRIPT_4 0xdead0004 -#define JSXDR_MAGIC_SCRIPT_5 0xdead0005 -#define JSXDR_MAGIC_SCRIPT_6 0xdead0006 -#define JSXDR_MAGIC_SCRIPT_7 0xdead0007 -#define JSXDR_MAGIC_SCRIPT_8 0xdead0008 -#define JSXDR_MAGIC_SCRIPT_9 0xdead0009 -#define JSXDR_MAGIC_SCRIPT_10 0xdead000a -#define JSXDR_MAGIC_SCRIPT_11 0xdead000b -#define JSXDR_MAGIC_SCRIPT_CURRENT JSXDR_MAGIC_SCRIPT_11 - -/* - * Bytecode version number. Increment the subtrahend whenever JS bytecode - * changes incompatibly. - * - * This version number should be XDR'ed once near the front of any file or - * larger storage unit containing XDR'ed bytecode and other data, and checked - * before deserialization of bytecode. If the saved version does not match - * the current version, abort deserialization and invalidate the file. - */ -#define JSXDR_BYTECODE_VERSION (0xb973c0de - 82) - -/* - * Library-private functions. - */ -extern JSBool -js_XDRAtom(JSXDRState *xdr, JSAtom **atomp); - -JS_END_EXTERN_C - -#endif /* ! jsxdrapi_h___ */ diff --git a/x86/mozilla/include/jsxml.h b/x86/mozilla/include/jsxml.h deleted file mode 100644 index 566ec5d..0000000 --- a/x86/mozilla/include/jsxml.h +++ /dev/null @@ -1,374 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is SpiderMonkey E4X code, released August, 2004. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsxml_h___ -#define jsxml_h___ - -#include "jspubtd.h" -#include "jsobj.h" -#include "jscell.h" - -extern const char js_AnyName_str[]; -extern const char js_AttributeName_str[]; -extern const char js_isXMLName_str[]; -extern const char js_XMLList_str[]; - -extern const char js_amp_entity_str[]; -extern const char js_gt_entity_str[]; -extern const char js_lt_entity_str[]; -extern const char js_quot_entity_str[]; - -typedef JSBool -(* JSIdentityOp)(const void *a, const void *b); - -struct JSXMLArray { - uint32 length; - uint32 capacity; - void **vector; - JSXMLArrayCursor *cursors; - - void init() { - length = capacity = 0; - vector = NULL; - cursors = NULL; - } - - void finish(JSContext *cx); - - bool setCapacity(JSContext *cx, uint32 capacity); - void trim(); -}; - -struct JSXMLArrayCursor -{ - JSXMLArray *array; - uint32 index; - JSXMLArrayCursor *next; - JSXMLArrayCursor **prevp; - void *root; - - JSXMLArrayCursor(JSXMLArray *array) - : array(array), index(0), next(array->cursors), prevp(&array->cursors), - root(NULL) - { - if (next) - next->prevp = &next; - array->cursors = this; - } - - ~JSXMLArrayCursor() { disconnect(); } - - void disconnect() { - if (!array) - return; - if (next) - next->prevp = prevp; - *prevp = next; - array = NULL; - } - - void *getNext() { - if (!array || index >= array->length) - return NULL; - return root = array->vector[index++]; - } - - void *getCurrent() { - if (!array || index >= array->length) - return NULL; - return root = array->vector[index]; - } - - void trace(JSTracer *trc); -}; - -#define JSXML_PRESET_CAPACITY JS_BIT(31) -#define JSXML_CAPACITY_MASK JS_BITMASK(31) -#define JSXML_CAPACITY(array) ((array)->capacity & JSXML_CAPACITY_MASK) - -/* - * NB: don't reorder this enum without changing all array initializers that - * depend on it in jsxml.c. - */ -typedef enum JSXMLClass { - JSXML_CLASS_LIST, - JSXML_CLASS_ELEMENT, - JSXML_CLASS_ATTRIBUTE, - JSXML_CLASS_PROCESSING_INSTRUCTION, - JSXML_CLASS_TEXT, - JSXML_CLASS_COMMENT, - JSXML_CLASS_LIMIT -} JSXMLClass; - -#define JSXML_CLASS_HAS_KIDS(class_) ((class_) < JSXML_CLASS_ATTRIBUTE) -#define JSXML_CLASS_HAS_VALUE(class_) ((class_) >= JSXML_CLASS_ATTRIBUTE) -#define JSXML_CLASS_HAS_NAME(class_) \ - ((uintN)((class_) - JSXML_CLASS_ELEMENT) <= \ - (uintN)(JSXML_CLASS_PROCESSING_INSTRUCTION - JSXML_CLASS_ELEMENT)) - -#ifdef DEBUG_notme -#include "jsclist.h" -#endif - -typedef struct JSXMLListVar { - JSXMLArray kids; /* NB: must come first */ - JSXML *target; - JSObject *targetprop; -} JSXMLListVar; - -typedef struct JSXMLElemVar { - JSXMLArray kids; /* NB: must come first */ - JSXMLArray namespaces; - JSXMLArray attrs; -} JSXMLElemVar; - -/* union member shorthands */ -#define xml_kids u.list.kids -#define xml_target u.list.target -#define xml_targetprop u.list.targetprop -#define xml_namespaces u.elem.namespaces -#define xml_attrs u.elem.attrs -#define xml_value u.value - -/* xml_class-testing macros */ -#define JSXML_HAS_KIDS(xml) JSXML_CLASS_HAS_KIDS((xml)->xml_class) -#define JSXML_HAS_VALUE(xml) JSXML_CLASS_HAS_VALUE((xml)->xml_class) -#define JSXML_HAS_NAME(xml) JSXML_CLASS_HAS_NAME((xml)->xml_class) -#define JSXML_LENGTH(xml) (JSXML_CLASS_HAS_KIDS((xml)->xml_class) \ - ? (xml)->xml_kids.length \ - : 0) - -struct JSXML : js::gc::Cell { -#ifdef DEBUG_notme - JSCList links; - uint32 serial; -#endif - JSObject *object; - void *domnode; /* DOM node if mapped info item */ - JSXML *parent; - JSObject *name; - uint32 xml_class; /* discriminates u, below */ - uint32 xml_flags; /* flags, see below */ - union { - JSXMLListVar list; - JSXMLElemVar elem; - JSString *value; - } u; - - void finalize(JSContext *cx) { - if (JSXML_HAS_KIDS(this)) { - xml_kids.finish(cx); - if (xml_class == JSXML_CLASS_ELEMENT) { - xml_namespaces.finish(cx); - xml_attrs.finish(cx); - } - } -#ifdef DEBUG_notme - JS_REMOVE_LINK(&links); -#endif - } -}; - -/* xml_flags values */ -#define XMLF_WHITESPACE_TEXT 0x1 - -extern JSXML * -js_NewXML(JSContext *cx, JSXMLClass xml_class); - -extern void -js_TraceXML(JSTracer *trc, JSXML *xml); - -extern JSObject * -js_NewXMLObject(JSContext *cx, JSXMLClass xml_class); - -extern JSObject * -js_GetXMLObject(JSContext *cx, JSXML *xml); - -extern JS_FRIEND_DATA(js::Class) js_XMLClass; -extern JS_FRIEND_DATA(js::Class) js_NamespaceClass; -extern JS_FRIEND_DATA(js::Class) js_QNameClass; -extern JS_FRIEND_DATA(js::Class) js_AttributeNameClass; -extern JS_FRIEND_DATA(js::Class) js_AnyNameClass; -extern js::Class js_XMLFilterClass; - -/* - * Methods to test whether an object or a value is of type "xml" (per typeof). - */ -inline bool -JSObject::isXML() const -{ - return getClass() == &js_XMLClass; -} - -inline bool -JSObject::isXMLId() const -{ - js::Class *clasp = getClass(); - return clasp == &js_QNameClass || - clasp == &js_AttributeNameClass || - clasp == &js_AnyNameClass; -} - -#define VALUE_IS_XML(v) (!JSVAL_IS_PRIMITIVE(v) && JSVAL_TO_OBJECT(v)->isXML()) - -inline bool -JSObject::isNamespace() const -{ - return getClass() == &js_NamespaceClass; -} - -inline bool -JSObject::isQName() const -{ - js::Class* clasp = getClass(); - return clasp == &js_QNameClass || - clasp == &js_AttributeNameClass || - clasp == &js_AnyNameClass; -} - -static inline bool -IsXML(const js::Value &v) -{ - return v.isObject() && v.toObject().isXML(); -} - -extern JSObject * -js_InitNamespaceClass(JSContext *cx, JSObject *obj); - -extern JSObject * -js_InitQNameClass(JSContext *cx, JSObject *obj); - -extern JSObject * -js_InitXMLClass(JSContext *cx, JSObject *obj); - -extern JSObject * -js_InitXMLClasses(JSContext *cx, JSObject *obj); - -extern JSBool -js_GetFunctionNamespace(JSContext *cx, js::Value *vp); - -/* - * If obj is QName corresponding to function::name, set *funidp to name's id, - * otherwise set *funidp to void. - */ -JSBool -js_IsFunctionQName(JSContext *cx, JSObject *obj, jsid *funidp); - -extern JSBool -js_GetDefaultXMLNamespace(JSContext *cx, jsval *vp); - -extern JSBool -js_SetDefaultXMLNamespace(JSContext *cx, const js::Value &v); - -/* - * Return true if v is a XML QName object, or if it converts to a string that - * contains a valid XML qualified name (one containing no :), false otherwise. - * NB: This function is an infallible predicate, it hides exceptions. - */ -extern JSBool -js_IsXMLName(JSContext *cx, jsval v); - -extern JSBool -js_ToAttributeName(JSContext *cx, js::Value *vp); - -extern JSFlatString * -js_EscapeAttributeValue(JSContext *cx, JSString *str, JSBool quote); - -extern JSString * -js_AddAttributePart(JSContext *cx, JSBool isName, JSString *str, - JSString *str2); - -extern JSFlatString * -js_EscapeElementValue(JSContext *cx, JSString *str); - -extern JSString * -js_ValueToXMLString(JSContext *cx, const js::Value &v); - -extern JSObject * -js_ConstructXMLQNameObject(JSContext *cx, const js::Value & nsval, - const js::Value & lnval); - -extern JSBool -js_GetAnyName(JSContext *cx, jsid *idp); - -/* - * Note: nameval must be either QName, AttributeName, or AnyName. - */ -extern JSBool -js_FindXMLProperty(JSContext *cx, const js::Value &nameval, JSObject **objp, jsid *idp); - -extern JSBool -js_GetXMLMethod(JSContext *cx, JSObject *obj, jsid id, js::Value *vp); - -extern JSBool -js_GetXMLDescendants(JSContext *cx, JSObject *obj, jsval id, jsval *vp); - -extern JSBool -js_DeleteXMLListElements(JSContext *cx, JSObject *listobj); - -extern JSBool -js_StepXMLListFilter(JSContext *cx, JSBool initialized); - -extern JSObject * -js_ValueToXMLObject(JSContext *cx, const js::Value &v); - -extern JSObject * -js_ValueToXMLListObject(JSContext *cx, const js::Value &v); - -extern JSObject * -js_NewXMLSpecialObject(JSContext *cx, JSXMLClass xml_class, JSString *name, - JSString *value); - -extern JSString * -js_MakeXMLCDATAString(JSContext *cx, JSString *str); - -extern JSString * -js_MakeXMLCommentString(JSContext *cx, JSString *str); - -extern JSString * -js_MakeXMLPIString(JSContext *cx, JSString *name, JSString *str); - -/* The caller must ensure that either v1 or v2 is an object. */ -extern JSBool -js_TestXMLEquality(JSContext *cx, const js::Value &v1, const js::Value &v2, - JSBool *bp); - -extern JSBool -js_ConcatenateXML(JSContext *cx, JSObject *obj1, JSObject *obj2, js::Value *vp); - -#endif /* jsxml_h___ */ diff --git a/x86/mozilla/include/nanojit.h b/x86/mozilla/include/nanojit.h deleted file mode 100644 index 706389b..0000000 --- a/x86/mozilla/include/nanojit.h +++ /dev/null @@ -1,382 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ -/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is [Open Source Virtual Machine]. - * - * The Initial Developer of the Original Code is - * Adobe System Incorporated. - * Portions created by the Initial Developer are Copyright (C) 2004-2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Adobe AS3 Team - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef __nanojit_h__ -#define __nanojit_h__ - -#include "avmplus.h" - -#ifdef FEATURE_NANOJIT - -#if defined AVMPLUS_IA32 - #define NANOJIT_IA32 -#elif defined AVMPLUS_ARM - #define NANOJIT_ARM -#elif defined AVMPLUS_PPC - #define NANOJIT_PPC -#elif defined AVMPLUS_SPARC - #define NANOJIT_SPARC -#elif defined AVMPLUS_AMD64 - #define NANOJIT_X64 -#elif defined VMCFG_SH4 - #define NANOJIT_SH4 -#elif defined AVMPLUS_MIPS - #define NANOJIT_MIPS -#else - #error "unknown nanojit architecture" -#endif - -#ifdef AVMPLUS_64BIT -#define NANOJIT_64BIT -#endif - -#if defined NANOJIT_64BIT - #define IF_64BIT(...) __VA_ARGS__ - #define UNLESS_64BIT(...) - #define CASE32(x) - #define CASE64(x) case x -#else - #define IF_64BIT(...) - #define UNLESS_64BIT(...) __VA_ARGS__ - #define CASE32(x) case x - #define CASE64(x) -#endif - -#if defined NANOJIT_IA32 || defined NANOJIT_X64 - #define CASE86(x) case x -#else - #define CASE86(x) -#endif - -// Embed no-op macros that let Valgrind work with the JIT. -#ifdef MOZ_VALGRIND -# define JS_VALGRIND -#endif -#ifdef JS_VALGRIND -# include -#elif !defined(VALGRIND_DISCARD_TRANSLATIONS) -# define VALGRIND_DISCARD_TRANSLATIONS(addr, szB) -#endif - -namespace nanojit -{ - /** - * ------------------------------------------- - * START AVM bridging definitions - * ------------------------------------------- - */ - typedef avmplus::AvmCore AvmCore; - - const uint32_t MAXARGS = 8; - - #ifdef NJ_NO_VARIADIC_MACROS - inline void NanoAssertMsgf(bool a,const char *f,...) {} - inline void NanoAssertMsg(bool a,const char *m) {} - inline void NanoAssert(bool a) {} - #elif defined(_DEBUG) - - #define __NanoAssertMsgf(a, file_, line_, f, ...) \ - if (!(a)) { \ - avmplus::AvmLog("Assertion failure: " f "%s (%s:%d)\n", __VA_ARGS__, #a, file_, line_); \ - avmplus::AvmAssertFail(""); \ - } - - #define _NanoAssertMsgf(a, file_, line_, f, ...) __NanoAssertMsgf(a, file_, line_, f, __VA_ARGS__) - - #define NanoAssertMsgf(a,f,...) do { __NanoAssertMsgf(a, __FILE__, __LINE__, f ": ", __VA_ARGS__); } while (0) - #define NanoAssertMsg(a,m) do { __NanoAssertMsgf(a, __FILE__, __LINE__, "\"%s\": ", m); } while (0) - #define NanoAssert(a) do { __NanoAssertMsgf(a, __FILE__, __LINE__, "%s", ""); } while (0) - #else - #define NanoAssertMsgf(a,f,...) do { } while (0) /* no semi */ - #define NanoAssertMsg(a,m) do { } while (0) /* no semi */ - #define NanoAssert(a) do { } while (0) /* no semi */ - #endif - - /* - * Sun Studio C++ compiler has a bug - * "sizeof expression not accepted as size of array parameter" - * The bug number is 6688515. It is not public yet. - * Turn off this assert for Sun Studio until this bug is fixed. - */ - #ifdef __SUNPRO_CC - #define NanoStaticAssert(condition) - #else - #define NanoStaticAssert(condition) \ - extern void nano_static_assert(int arg[(condition) ? 1 : -1]) - #endif - - - /** - * ------------------------------------------- - * END AVM bridging definitions - * ------------------------------------------- - */ -} - -#ifdef AVMPLUS_VERBOSE - #define NJ_VERBOSE 1 -#endif - -#ifdef NJ_NO_VARIADIC_MACROS - #include - #define verbose_outputf if (_logc->lcbits & LC_Native) \ - Assembler::outputf - #define verbose_only(x) x -#elif defined(NJ_VERBOSE) - #include - #define verbose_outputf if (_logc->lcbits & LC_Native) \ - Assembler::outputf - #define verbose_only(...) __VA_ARGS__ -#else - #define verbose_outputf - #define verbose_only(...) -#endif /*NJ_VERBOSE*/ - -#ifdef _DEBUG - #define debug_only(x) x -#else - #define debug_only(x) -#endif /* DEBUG */ - -#define isS8(i) ( int32_t(i) == int8_t(i) ) -#define isU8(i) ( int32_t(i) == uint8_t(i) ) -#define isS16(i) ( int32_t(i) == int16_t(i) ) -#define isU16(i) ( int32_t(i) == uint16_t(i) ) -#define isS24(i) ( (int32_t((i)<<8)>>8) == (i) ) - -static inline bool isS32(intptr_t i) { - return int32_t(i) == i; -} - -static inline bool isU32(uintptr_t i) { - return uint32_t(i) == i; -} - -#define alignTo(x,s) ((((uintptr_t)(x)))&~(((uintptr_t)s)-1)) -#define alignUp(x,s) ((((uintptr_t)(x))+(((uintptr_t)s)-1))&~(((uintptr_t)s)-1)) - -#define NJ_MIN(x, y) ((x) < (y) ? (x) : (y)) -#define NJ_MAX(x, y) ((x) > (y) ? (x) : (y)) - -namespace nanojit -{ -// Define msbSet32(), lsbSet32(), msbSet64(), and lsbSet64() functions using -// fast find-first-bit instructions intrinsics when available. -// The fall-back implementations use iteration. -#if defined(_WIN32) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) - - extern "C" unsigned char _BitScanForward(unsigned long * Index, unsigned long Mask); - extern "C" unsigned char _BitScanReverse(unsigned long * Index, unsigned long Mask); - # pragma intrinsic(_BitScanForward) - # pragma intrinsic(_BitScanReverse) - - // Returns the index of the most significant bit that is set. - static inline int msbSet32(uint32_t x) { - unsigned long idx; - _BitScanReverse(&idx, (unsigned long)(x | 1)); // the '| 1' ensures a 0 result when x==0 - return idx; - } - - // Returns the index of the least significant bit that is set. - static inline int lsbSet32(uint32_t x) { - unsigned long idx; - _BitScanForward(&idx, (unsigned long)(x | 0x80000000)); // the '| 0x80000000' ensures a 0 result when x==0 - return idx; - } - -#if defined(_M_AMD64) || defined(_M_X64) - extern "C" unsigned char _BitScanForward64(unsigned long * Index, unsigned __int64 Mask); - extern "C" unsigned char _BitScanReverse64(unsigned long * Index, unsigned __int64 Mask); - # pragma intrinsic(_BitScanForward64) - # pragma intrinsic(_BitScanReverse64) - - // Returns the index of the most significant bit that is set. - static inline int msbSet64(uint64_t x) { - unsigned long idx; - _BitScanReverse64(&idx, (unsigned __int64)(x | 1)); // the '| 1' ensures a 0 result when x==0 - return idx; - } - - // Returns the index of the least significant bit that is set. - static inline int lsbSet64(uint64_t x) { - unsigned long idx; - _BitScanForward64(&idx, (unsigned __int64)(x | 0x8000000000000000LL)); // the '| 0x80000000' ensures a 0 result when x==0 - return idx; - } -#else - // Returns the index of the most significant bit that is set. - static int msbSet64(uint64_t x) { - return (x & 0xffffffff00000000LL) ? msbSet32(uint32_t(x >> 32)) + 32 : msbSet32(uint32_t(x)); - } - // Returns the index of the least significant bit that is set. - static int lsbSet64(uint64_t x) { - return (x & 0x00000000ffffffffLL) ? lsbSet32(uint32_t(x)) : lsbSet32(uint32_t(x >> 32)) + 32; - } -#endif - -#elif (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) - - // Returns the index of the most significant bit that is set. - static inline int msbSet32(uint32_t x) { - return 31 - __builtin_clz(x | 1); - } - - // Returns the index of the least significant bit that is set. - static inline int lsbSet32(uint32_t x) { - return __builtin_ctz(x | 0x80000000); - } - - // Returns the index of the most significant bit that is set. - static inline int msbSet64(uint64_t x) { - return 63 - __builtin_clzll(x | 1); - } - - // Returns the index of the least significant bit that is set. - static inline int lsbSet64(uint64_t x) { - return __builtin_ctzll(x | 0x8000000000000000LL); - } - -#else - - // Slow fall-back: return most significant bit set by searching iteratively. - static int msbSet32(uint32_t x) { - for (int i = 31; i >= 0; i--) - if ((1 << i) & x) - return i; - return 0; - } - - // Slow fall-back: return least significant bit set by searching iteratively. - static int lsbSet32(uint32_t x) { - for (int i = 0; i < 32; i++) - if ((1 << i) & x) - return i; - return 31; - } - - // Slow fall-back: return most significant bit set by searching iteratively. - static int msbSet64(uint64_t x) { - for (int i = 63; i >= 0; i--) - if ((1LL << i) & x) - return i; - return 0; - } - - // Slow fall-back: return least significant bit set by searching iteratively. - static int lsbSet64(uint64_t x) { - for (int i = 0; i < 64; i++) - if ((1LL << i) & x) - return i; - return 63; - } - -#endif // select compiler -} // namespace nanojit - -// ------------------------------------------------------------------- -// START debug-logging definitions -// ------------------------------------------------------------------- - -/* Debug printing stuff. All Nanojit and jstracer debug printing - should be routed through LogControl::printf. Don't use - ad-hoc calls to printf, fprintf(stderr, ...) etc. - - Similarly, don't use ad-hoc getenvs etc to decide whether or not to - print debug output. Instead consult the relevant control bit in - LogControl::lcbits in the LogControl object you are supplied with. -*/ - -# if defined(__GNUC__) -# define PRINTF_CHECK(x, y) __attribute__((format(__printf__, x, y))) -# else -# define PRINTF_CHECK(x, y) -# endif - -namespace nanojit { - - // LogControl, a class for controlling and routing debug output - - enum LC_Bits { - /* Output control bits for Nanojit code. Only use bits 15 - and below, so that callers can use bits 16 and above for - themselves. */ - // TODO: add entries for the writer pipeline - LC_FragProfile = 1<<8, // collect per-frag usage counts - LC_Liveness = 1<<7, // show LIR liveness analysis - LC_ReadLIR = 1<<6, // as read from LirBuffer - LC_AfterSF = 1<<5, // after StackFilter - LC_AfterDCE = 1<<4, // after dead code elimination - LC_Bytes = 1<<3, // byte values of native instruction - LC_Native = 1<<2, // final native code - LC_RegAlloc = 1<<1, // stuff to do with reg alloc - LC_Activation = 1<<0 // enable printActivationState - }; - - class LogControl - { - public: - // All Nanojit and jstracer printing should be routed through - // this function. - virtual ~LogControl() {} - #ifdef NJ_VERBOSE - virtual void printf( const char* format, ... ) PRINTF_CHECK(2,3); - #endif - - // An OR of LC_Bits values, indicating what should be output - uint32_t lcbits; - }; -} - -// ------------------------------------------------------------------- -// END debug-logging definitions -// ------------------------------------------------------------------- - - -#include "njconfig.h" -#include "Allocator.h" -#include "Containers.h" -#include "Native.h" -#include "CodeAlloc.h" -#include "LIR.h" -#include "RegAlloc.h" -#include "Fragmento.h" -#include "Assembler.h" - -#endif // FEATURE_NANOJIT -#endif // __nanojit_h__ diff --git a/x86/mozilla/include/njconfig.h b/x86/mozilla/include/njconfig.h deleted file mode 100644 index 548adc3..0000000 --- a/x86/mozilla/include/njconfig.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ -/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is [Open Source Virtual Machine]. - * - * The Initial Developer of the Original Code is - * Adobe System Incorporated. - * Portions created by the Initial Developer are Copyright (C) 2004-2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Adobe AS3 Team - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef __njconfig_h__ -#define __njconfig_h__ - -#include "avmplus.h" - -// Do not include nanojit.h here; this file should be usable without it. - -#ifdef FEATURE_NANOJIT - -namespace nanojit -{ - /*** - * A struct used to configure the assumptions that Assembler can make when - * generating code. The ctor will fill in all fields with the most reasonable - * values it can derive from compiler flags and/or runtime detection, but - * the embedder is free to override any or all of them as it sees fit. - * Using the ctor-provided default setup is guaranteed to provide a safe - * runtime environment (though perhaps suboptimal in some cases), so an embedder - * should replace these values with great care. - * - * Note that although many fields are used on only specific architecture(s), - * this struct is deliberately declared without ifdef's for them, so (say) ARM-specific - * fields are declared everywhere. This reduces build dependencies (so that this - * files does not require nanojit.h to be included beforehand) and also reduces - * clutter in this file; the extra storage space required is trivial since most - * fields are single bits. - */ - struct Config - { - public: - // fills in reasonable default values for all fields. - Config(); - - // ARM architecture to assume when generate instructions for (currently, 4 <= arm_arch <= 7) - uint8_t arm_arch; - - // If true, use CSE. - uint32_t cseopt:1; - - // Can we use SSE2 instructions? (x86-only) - uint32_t i386_sse2:1; - - // Can we use cmov instructions? (x86-only) - uint32_t i386_use_cmov:1; - - // Should we use a virtual stack pointer? (x86-only) - uint32_t i386_fixed_esp:1; - - // Whether or not to generate VFP instructions. (ARM only) - uint32_t arm_vfp:1; - - // @todo, document me - uint32_t arm_show_stats:1; - - // If true, use softfloat for all floating point operations, - // whether or not an FPU is present. (ARM only for now, but might also includes MIPS in the future) - uint32_t soft_float:1; - - // If true, compiler will insert a random amount of space in between functions (x86-32 only) - uint32_t harden_function_alignment:1; - - // If true, compiler will insert randomly choosen no-op instructions at random locations within a compiled method (x86-32 only) - uint32_t harden_nop_insertion:1; - }; -} - -#endif // FEATURE_NANOJIT -#endif // __njconfig_h__ diff --git a/x86/mozilla/include/njcpudetect.h b/x86/mozilla/include/njcpudetect.h deleted file mode 100644 index db2313f..0000000 --- a/x86/mozilla/include/njcpudetect.h +++ /dev/null @@ -1,115 +0,0 @@ -/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ -/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is [Open Source Virtual Machine]. - * - * The Initial Developer of the Original Code is - * Adobe System Incorporated. - * Portions created by the Initial Developer are Copyright (C) 2004-2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Adobe AS3 Team - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef __njcpudetect__ -#define __njcpudetect__ - -/*** - * Note: this file should not include *any* other files, nor should it wrap - * itself in ifdef FEATURE_NANOJIT, nor should it do anything other than - * define preprocessor symbols. - */ - -/*** - * NJ_COMPILER_ARM_ARCH attempts to specify the minimum ARM architecture - * that the C++ compiler has specified. Note that although Config::arm_arch - * is initialized to this value by default, there is no requirement that they - * be in sync. - * - * Note, this is done via #define so that downstream preprocessor usage can - * examine it, but please don't attempt to redefine it. - * - * Note, this is deliberately not encased in "ifdef NANOJIT_ARM", as this file - * may be included before that is defined. On non-ARM platforms we will hit the - * "Unable to determine" case. - */ - -// GCC and RealView usually define __ARM_ARCH__ -#if defined(__ARM_ARCH__) - - #define NJ_COMPILER_ARM_ARCH __ARM_ARCH__ - -// ok, try well-known GCC flags ( see http://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html ) -#elif defined(__ARM_ARCH_7__) || \ - defined(__ARM_ARCH_7A__) || \ - defined(__ARM_ARCH_7M__) || \ - defined(__ARM_ARCH_7R__) || \ - defined(_ARM_ARCH_7) - - #define NJ_COMPILER_ARM_ARCH 7 - -#elif defined(__ARM_ARCH_6__) || \ - defined(__ARM_ARCH_6J__) || \ - defined(__ARM_ARCH_6T2__) || \ - defined(__ARM_ARCH_6Z__) || \ - defined(__ARM_ARCH_6ZK__) || \ - defined(__ARM_ARCH_6M__) || \ - defined(_ARM_ARCH_6) - - #define NJ_COMPILER_ARM_ARCH 6 - -#elif defined(__ARM_ARCH_5__) || \ - defined(__ARM_ARCH_5T__) || \ - defined(__ARM_ARCH_5E__) || \ - defined(__ARM_ARCH_5TE__) - - #define NJ_COMPILER_ARM_ARCH 5 - -#elif defined(__ARM_ARCH_4T__) - - #define NJ_COMPILER_ARM_ARCH 4 - -// Visual C has its own mojo -#elif defined(_MSC_VER) && defined(_M_ARM) - - #define NJ_COMPILER_ARM_ARCH _M_ARM - -// RVCT -#elif defined(__TARGET_ARCH_ARM) - - #define NJ_COMPILER_ARM_ARCH __TARGET_ARCH_ARM - -#else - - // non-numeric value - #define NJ_COMPILER_ARM_ARCH "Unable to determine valid NJ_COMPILER_ARM_ARCH (nanojit only supports ARMv4T or later)" - -#endif - -#endif // __njcpudetect__ diff --git a/x86/mozilla/include/prmjtime.h b/x86/mozilla/include/prmjtime.h deleted file mode 100644 index 44bc2b9..0000000 --- a/x86/mozilla/include/prmjtime.h +++ /dev/null @@ -1,227 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (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.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef prmjtime_h___ -#define prmjtime_h___ -/* - * PR date stuff for mocha and java. Placed here temporarily not to break - * Navigator and localize changes to mocha. - */ -#include - -#include "jslong.h" -#ifdef MOZILLA_CLIENT -#include "jscompat.h" -#endif - -struct JSContext; - -/* - * Implements a small cache for daylight saving time offset computation. - * - * The basic idea is premised upon this fact: the DST offset never changes more - * than once in any thirty-day period. If we know the offset at t_0 is o_0, - * the offset at [t_1, t_2] is also o_0, where t_1 + 3_0 days == t_2, - * t_1 <= t_0, and t0 <= t2. (In other words, t_0 is always somewhere within a - * thirty-day range where the DST offset is constant: DST changes never occur - * more than once in any thirty-day period.) Therefore, if we intelligently - * retain knowledge of the offset for a range of dates (which may vary over - * time), and if requests are usually for dates within that range, we can often - * provide a response without repeated offset calculation. - * - * Our caching strategy is as follows: on the first request at date t_0 compute - * the requested offset o_0. Save { start: t_0, end: t_0, offset: o_0 } as the - * cache's state. Subsequent requests within that range are straightforwardly - * handled. If a request for t_i is far outside the range (more than thirty - * days), compute o_i = dstOffset(t_i) and save { start: t_i, end: t_i, - * offset: t_i }. Otherwise attempt to *overextend* the range to either - * [start - 30d, end] or [start, end + 30d] as appropriate to encompass - * t_i. If the offset o_i30 is the same as the cached offset, extend the - * range. Otherwise the over-guess crossed a DST change -- compute - * o_i = dstOffset(t_i) and either extend the original range (if o_i == offset) - * or start a new one beneath/above the current one with o_i30 as the offset. - * - * This cache strategy results in 0 to 2 DST offset computations. The naive - * always-compute strategy is 1 computation, and since cache maintenance is a - * handful of integer arithmetic instructions the speed difference between - * always-1 and 1-with-cache is negligible. Caching loses if two computations - * happen: when the date is within 30 days of the cached range and when that - * 30-day range crosses a DST change. This is relatively uncommon. Further, - * instances of such are often dominated by in-range hits, so caching is an - * overall slight win. - * - * Why 30 days? For correctness the duration must be smaller than any possible - * duration between DST changes. Past that, note that 1) a large duration - * increases the likelihood of crossing a DST change while reducing the number - * of cache misses, and 2) a small duration decreases the size of the cached - * range while producing more misses. Using a month as the interval change is - * a balance between these two that tries to optimize for the calendar month at - * a time that a site might display. (One could imagine an adaptive duration - * that accommodates near-DST-change dates better; we don't believe the - * potential win from better caching offsets the loss from extra complexity.) - */ -class DSTOffsetCache { - public: - inline DSTOffsetCache(); - JSInt64 getDSTOffsetMilliseconds(int64 localTimeMilliseconds, JSContext *cx); - - inline void purge(); -#ifdef JS_METER_DST_OFFSET_CACHING - void dumpStats(); -#endif - - private: - JSInt64 computeDSTOffsetMilliseconds(int64 localTimeSeconds); - - JSInt64 offsetMilliseconds; - JSInt64 rangeStartSeconds, rangeEndSeconds; - - JSInt64 oldOffsetMilliseconds; - JSInt64 oldRangeStartSeconds, oldRangeEndSeconds; - -#ifdef JS_METER_DST_OFFSET_CACHING - size_t totalCalculations; - size_t hit; - size_t missIncreasing; - size_t missDecreasing; - size_t missIncreasingOffsetChangeUpper; - size_t missIncreasingOffsetChangeExpand; - size_t missLargeIncrease; - size_t missDecreasingOffsetChangeLower; - size_t missDecreasingOffsetChangeExpand; - size_t missLargeDecrease; -#endif - - static const JSInt64 MAX_UNIX_TIMET = 2145859200; /* time_t 12/31/2037 */ - static const JSInt64 MILLISECONDS_PER_SECOND = 1000; - static const JSInt64 SECONDS_PER_MINUTE = 60; - static const JSInt64 SECONDS_PER_HOUR = 60 * SECONDS_PER_MINUTE; - static const JSInt64 SECONDS_PER_DAY = 24 * SECONDS_PER_HOUR; - - static const JSInt64 RANGE_EXPANSION_AMOUNT = 30 * SECONDS_PER_DAY; - - private: - void sanityCheck(); - -#ifdef JS_METER_DST_OFFSET_CACHING -#define NOTE_GENERIC(member) this->member++ -#else -#define NOTE_GENERIC(member) ((void)0) -#endif - void noteOffsetCalculation() { - NOTE_GENERIC(totalCalculations); - } - void noteCacheHit() { - NOTE_GENERIC(hit); - } - void noteCacheMissIncrease() { - NOTE_GENERIC(missIncreasing); - } - void noteCacheMissDecrease() { - NOTE_GENERIC(missDecreasing); - } - void noteCacheMissIncreasingOffsetChangeUpper() { - NOTE_GENERIC(missIncreasingOffsetChangeUpper); - } - void noteCacheMissIncreasingOffsetChangeExpand() { - NOTE_GENERIC(missIncreasingOffsetChangeExpand); - } - void noteCacheMissLargeIncrease() { - NOTE_GENERIC(missLargeIncrease); - } - void noteCacheMissDecreasingOffsetChangeLower() { - NOTE_GENERIC(missDecreasingOffsetChangeLower); - } - void noteCacheMissDecreasingOffsetChangeExpand() { - NOTE_GENERIC(missDecreasingOffsetChangeExpand); - } - void noteCacheMissLargeDecrease() { - NOTE_GENERIC(missLargeDecrease); - } -#undef NOTE_GENERIC -}; - -JS_BEGIN_EXTERN_C - -typedef struct PRMJTime PRMJTime; - -/* - * Broken down form of 64 bit time value. - */ -struct PRMJTime { - JSInt32 tm_usec; /* microseconds of second (0-999999) */ - JSInt8 tm_sec; /* seconds of minute (0-59) */ - JSInt8 tm_min; /* minutes of hour (0-59) */ - JSInt8 tm_hour; /* hour of day (0-23) */ - JSInt8 tm_mday; /* day of month (1-31) */ - JSInt8 tm_mon; /* month of year (0-11) */ - JSInt8 tm_wday; /* 0=sunday, 1=monday, ... */ - JSInt32 tm_year; /* absolute year, AD */ - JSInt16 tm_yday; /* day of year (0 to 365) */ - JSInt8 tm_isdst; /* non-zero if DST in effect */ -}; - -/* Some handy constants */ -#define PRMJ_USEC_PER_SEC 1000000L -#define PRMJ_USEC_PER_MSEC 1000L - -/* Return the current local time in micro-seconds */ -extern JSInt64 -PRMJ_Now(void); - -/* Release the resources associated with PRMJ_Now; don't call PRMJ_Now again */ -#if defined(JS_THREADSAFE) && (defined(HAVE_GETSYSTEMTIMEASFILETIME) || defined(HAVE_SYSTEMTIMETOFILETIME)) -extern void -PRMJ_NowShutdown(void); -#else -#define PRMJ_NowShutdown() -#endif - -/* get the difference between this time zone and gmt timezone in seconds */ -extern JSInt32 -PRMJ_LocalGMTDifference(void); - -/* Format a time value into a buffer. Same semantics as strftime() */ -extern size_t -PRMJ_FormatTime(char *buf, int buflen, const char *fmt, PRMJTime *tm); - -JS_END_EXTERN_C - -#endif /* prmjtime_h___ */ - diff --git a/x86/mozilla/libjs_static.a b/x86/mozilla/libjs_static.a deleted file mode 100644 index 2c99938..0000000 Binary files a/x86/mozilla/libjs_static.a and /dev/null differ diff --git a/x86_64/lib/libSDL-1.2.so.0 b/x86_64/lib-static-hide/libSDL-1.2.so.0 old mode 100755 new mode 100644 similarity index 100% rename from x86_64/lib/libSDL-1.2.so.0 rename to x86_64/lib-static-hide/libSDL-1.2.so.0 diff --git a/x86_64/lib-static-hide/libespeak.so.1 b/x86_64/lib-static-hide/libespeak.so.1 new file mode 120000 index 0000000..c3fa981 --- /dev/null +++ b/x86_64/lib-static-hide/libespeak.so.1 @@ -0,0 +1 @@ +libespeak.so.1.pulseaudio \ No newline at end of file diff --git a/x86_64/lib/libespeak.so.1 b/x86_64/lib-static-hide/libespeak.so.1.alsa old mode 100755 new mode 100644 similarity index 100% rename from x86_64/lib/libespeak.so.1 rename to x86_64/lib-static-hide/libespeak.so.1.alsa diff --git a/x86_64/lib/libespeak.so.1.pulseaudio b/x86_64/lib-static-hide/libespeak.so.1.pulseaudio old mode 100755 new mode 100644 similarity index 100% rename from x86_64/lib/libespeak.so.1.pulseaudio rename to x86_64/lib-static-hide/libespeak.so.1.pulseaudio diff --git a/x86_64/lib/libogg.so.0 b/x86_64/lib-static-hide/libogg.so.0 old mode 100755 new mode 100644 similarity index 100% rename from x86_64/lib/libogg.so.0 rename to x86_64/lib-static-hide/libogg.so.0 diff --git a/x86_64/lib/libpng14.so.14 b/x86_64/lib-static-hide/libpng14.so.14 old mode 100755 new mode 100644 similarity index 100% rename from x86_64/lib/libpng14.so.14 rename to x86_64/lib-static-hide/libpng14.so.14 diff --git a/x86_64/lib/libvorbis.so.0 b/x86_64/lib-static-hide/libvorbis.so.0 old mode 100755 new mode 100644 similarity index 100% rename from x86_64/lib/libvorbis.so.0 rename to x86_64/lib-static-hide/libvorbis.so.0 diff --git a/x86_64/lib/libvorbisfile.so.3 b/x86_64/lib-static-hide/libvorbisfile.so.3 old mode 100755 new mode 100644 similarity index 100% rename from x86_64/lib/libvorbisfile.so.3 rename to x86_64/lib-static-hide/libvorbisfile.so.3 diff --git a/x86_64/lib/libz.so.1 b/x86_64/lib-static-hide/libz.so.1 old mode 100755 new mode 100644 similarity index 100% rename from x86_64/lib/libz.so.1 rename to x86_64/lib-static-hide/libz.so.1 diff --git a/x86_64/lib/libffi.so.4 b/x86_64/lib/libffi.so.4 deleted file mode 100755 index 5437d49..0000000 Binary files a/x86_64/lib/libffi.so.4 and /dev/null differ diff --git a/x86_64/lib/libgcrypt.so.20 b/x86_64/lib/libgcrypt.so.20 deleted file mode 100755 index ec8ea2b..0000000 Binary files a/x86_64/lib/libgcrypt.so.20 and /dev/null differ diff --git a/x86_64/lib/libgmp.so.10 b/x86_64/lib/libgmp.so.10 deleted file mode 100755 index aa5ed0c..0000000 Binary files a/x86_64/lib/libgmp.so.10 and /dev/null differ diff --git a/x86_64/lib/libgnustep-base.so.1.20 b/x86_64/lib/libgnustep-base.so.1.20 deleted file mode 100755 index 4153ea8..0000000 Binary files a/x86_64/lib/libgnustep-base.so.1.20 and /dev/null differ diff --git a/x86_64/lib/libgnutls.so.30 b/x86_64/lib/libgnutls.so.30 deleted file mode 100755 index fb26492..0000000 Binary files a/x86_64/lib/libgnutls.so.30 and /dev/null differ diff --git a/x86_64/lib/libgpg-error.so.0 b/x86_64/lib/libgpg-error.so.0 deleted file mode 100755 index 72473ee..0000000 Binary files a/x86_64/lib/libgpg-error.so.0 and /dev/null differ diff --git a/x86_64/lib/libhogweed.so.4 b/x86_64/lib/libhogweed.so.4 deleted file mode 100755 index bdb1b2e..0000000 Binary files a/x86_64/lib/libhogweed.so.4 and /dev/null differ diff --git a/x86_64/lib/libnettle.so.6 b/x86_64/lib/libnettle.so.6 deleted file mode 100755 index 7a12c30..0000000 Binary files a/x86_64/lib/libnettle.so.6 and /dev/null differ diff --git a/x86_64/lib/libnsl.so.1 b/x86_64/lib/libnsl.so.1 deleted file mode 100644 index 25e793b..0000000 Binary files a/x86_64/lib/libnsl.so.1 and /dev/null differ diff --git a/x86_64/lib/libnspr4.so.0d b/x86_64/lib/libnspr4.so.0d deleted file mode 100644 index 0fe0bb1..0000000 Binary files a/x86_64/lib/libnspr4.so.0d and /dev/null differ diff --git a/x86_64/lib/libobjc.so.2 b/x86_64/lib/libobjc.so.2 deleted file mode 100755 index 40991ce..0000000 Binary files a/x86_64/lib/libobjc.so.2 and /dev/null differ diff --git a/x86_64/lib/libopenal.so.1 b/x86_64/lib/libopenal.so.1 deleted file mode 100644 index 3536973..0000000 Binary files a/x86_64/lib/libopenal.so.1 and /dev/null differ diff --git a/x86_64/lib/libplc4.so.0d b/x86_64/lib/libplc4.so.0d deleted file mode 100644 index 1374659..0000000 Binary files a/x86_64/lib/libplc4.so.0d and /dev/null differ diff --git a/x86_64/lib/libplds4.so.0d b/x86_64/lib/libplds4.so.0d deleted file mode 100644 index ac3d4ab..0000000 Binary files a/x86_64/lib/libplds4.so.0d and /dev/null differ diff --git a/x86_64/lib/libportaudio.so.2 b/x86_64/lib/libportaudio.so.2 deleted file mode 100755 index fb6acc9..0000000 Binary files a/x86_64/lib/libportaudio.so.2 and /dev/null differ diff --git a/x86_64/lib_linker/make_so_links.sh b/x86_64/lib_linker/make_so_links.sh index 7b7f892..038d291 100755 --- a/x86_64/lib_linker/make_so_links.sh +++ b/x86_64/lib_linker/make_so_links.sh @@ -1,36 +1,97 @@ #!/bin/sh -if ! [ -f 'libespeak.so' ]; then - ln -s ../lib/libespeak.so.1 libespeak.so -fi +# Flibble tweaked this . +# added stanza to copy required libraries from build system +# and made symlink references more dynamic +# +# If we are here, then use_deps is in play, so we might like to +# bundle anything which might break on other distros. -if ! [ -f 'libpng.so' ]; then - ln -s ../lib/libpng14.so.14 libpng.so -fi +p=x86_64 -if ! [ -f 'libSDL.so' ]; then - ln -s ../lib/libSDL-1.2.so.0 libSDL.so +if [ "x$1" = "xclean" ] ; then + rm *.so + rm -Rf ../lib + rm -Rf ../../espeak-ng-data + exit fi -if ! [ -f 'libopenal.so' ]; then - ln -s ../lib/libopenal.so.1 libopenal.so -fi +# Currently bundling libgnustep-base +# +# 1: The specific version is called for by oolite, but it WILL work with a +# symlink to a newer system version. +# +# 2: The gdnc daemon from a newer version seems not to work on some +# platforms without installing a bucketload of deps. On kubuntu 25.04 I +# had to "apt install dh-exec" to get dpkg-architecture. After doing that +# once, I apt autopurged dh-exec, and gdnc continued to work with both +# versions. Baffling! +# +# gdnc comes from package gnustep-base-runtime +# +# Perhaps someone could figure out why Oolite calls the specific version +# of libgnustep-base from the build host. +# +# Else I suppose we could include gdnc into deps/bin and add that to PATH +# -if ! [ -f 'libogg.so' ]; then - ln -s ../lib/libogg.so.0 libogg.so -fi +mkdir -p ../lib +cp ../lib-static/* ../lib/ +cp --dereference \ +/usr/lib/libgnustep-base.so.[0-9].[0-9][0-9] \ +/usr/lib/$p-linux-gnu/libicudata.so.[0-9][0-9] \ +/usr/lib/$p-linux-gnu/libicui18n.so.[0-9][0-9] \ +/usr/lib/$p-linux-gnu/libicuuc.so.[0-9][0-9] \ +../lib -if ! [ -f 'libvorbis.so' ]; then - ln -s ../lib/libvorbis.so.0 libvorbis.so -fi +#cp -rf /usr/lib/$p-linux-gnu/espeak-ng-data ../../ -if ! [ -f 'libvorbisfile.so' ]; then - ln -s ../lib/libvorbisfile.so.3 libvorbisfile.so -fi +#These work using distro libraries so should only need re-including where +# a future distro no longer has one of them at an appropriate version. +#/usr/lib/$p-linux-gnu/libespeak-ng.so.[0-9] +#/usr/lib/$p-linux-gnu/libcaca.so.0 +#/usr/lib/$p-linux-gnu/libffi.so.[0-9] +#/usr/lib/$p-linux-gnu/libjack.so.[0-9] +#/usr/lib/$p-linux-gnu/libportaudio.so.[0-9] +#/usr/lib/$p-linux-gnu/libsndio.so.[0-9].0 +#/usr/lib/$p-linux-gnu/libnspr[0-9].so +#/usr/lib/$p-linux-gnu/libobjc.so.[0-9] +#/usr/lib/$p-linux-gnu/libxslt.so.[0-9] +#/usr/lib/$p-linux-gnu/libSDL.so -if ! [ -f 'libz.so' ]; then - ln -s ../lib/libz.so.1 libz.so -fi +#essential +##if ! [ -f 'libespeak.so' ]; then +## ln -s ../lib/libespeak.so.1 libespeak.so +##fi + +#essential +##if ! [ -f 'libpng.so' ]; then +## ln -s ../lib/libpng[0-9][0-9].so.[0-9][0-9] libpng.so +##fi + +#if ! [ -f 'libSDL.so' ]; then +# ln -s ../lib/libSDL-1.2.so.0 libSDL.so +#fi + +#if ! [ -f 'libopenal.so' ]; then +# ln -s ../lib/libopenal.so.[0-9] libopenal.so +#fi + +#if ! [ -f 'libogg.so' ]; then +# ln -s ../lib/libogg.so.0 libogg.so +#fi + +#if ! [ -f 'libvorbis.so' ]; then +# ln -s ../lib/libvorbis.so.[0-9] libvorbis.so +#fi + +#if ! [ -f 'libvorbisfile.so' ]; then +# ln -s ../lib/libvorbisfile.so.[0-9] libvorbisfile.so +#fi + +#if ! [ -f 'libz.so' ]; then +# ln -s ../lib/libz.so.[0-9] libz.so +#fi exit;