+ SymbolTableEntry& copySlow(const SymbolTableEntry&);
+ JS_EXPORT_PRIVATE void notifyWriteSlow();
+
+ bool isFat() const
+ {
+ return !(m_bits & SlimFlag);
+ }
+
+ const FatEntry* fatEntry() const
+ {
+ ASSERT(isFat());
+ return bitwise_cast<const FatEntry*>(m_bits);
+ }
+
+ FatEntry* fatEntry()
+ {
+ ASSERT(isFat());
+ return bitwise_cast<FatEntry*>(m_bits);
+ }
+
+ FatEntry* inflate()
+ {
+ if (LIKELY(isFat()))
+ return fatEntry();
+ return inflateSlow();
+ }
+
+ FatEntry* inflateSlow();
+
+ ALWAYS_INLINE intptr_t bits() const
+ {
+ if (isFat())
+ return fatEntry()->m_bits;
+ return m_bits;
+ }
+
+ ALWAYS_INLINE intptr_t& bits()
+ {
+ if (isFat())
+ return fatEntry()->m_bits;
+ return m_bits;
+ }
+
+ void freeFatEntry()
+ {
+ if (LIKELY(!isFat()))
+ return;
+ freeFatEntrySlow();
+ }
+
+ JS_EXPORT_PRIVATE void freeFatEntrySlow();
+
+ void pack(int index, bool readOnly, bool dontEnum)
+ {
+ ASSERT(!isFat());
+ intptr_t& bitsRef = bits();
+ bitsRef = (static_cast<intptr_t>(index) << FlagBits) | NotNullFlag | SlimFlag;
+ if (readOnly)
+ bitsRef |= ReadOnlyFlag;
+ if (dontEnum)
+ bitsRef |= DontEnumFlag;
+ }
+
+ bool isValidIndex(int index)
+ {
+ return ((static_cast<intptr_t>(index) << FlagBits) >> FlagBits) == static_cast<intptr_t>(index);
+ }
+
+ intptr_t m_bits;
+};
+
+struct SymbolTableIndexHashTraits : HashTraits<SymbolTableEntry> {
+ static const bool needsDestruction = true;
+};
+
+typedef HashMap<RefPtr<StringImpl>, SymbolTableEntry, IdentifierRepHash, HashTraits<RefPtr<StringImpl> >, SymbolTableIndexHashTraits> SymbolTable;
+
+class SharedSymbolTable : public JSCell, public SymbolTable {
+public:
+ typedef JSCell Base;
+
+ static SharedSymbolTable* create(VM& vm)
+ {
+ SharedSymbolTable* sharedSymbolTable = new (NotNull, allocateCell<SharedSymbolTable>(vm.heap)) SharedSymbolTable(vm);
+ sharedSymbolTable->finishCreation(vm);
+ return sharedSymbolTable;
+ }
+ static const bool needsDestruction = true;
+ static const bool hasImmortalStructure = true;
+ static void destroy(JSCell*);
+
+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+ {
+ return Structure::create(vm, globalObject, prototype, TypeInfo(LeafType, StructureFlags), &s_info);
+ }
+
+ bool usesNonStrictEval() { return m_usesNonStrictEval; }
+ void setUsesNonStrictEval(bool usesNonStrictEval) { m_usesNonStrictEval = usesNonStrictEval; }
+
+ int captureStart() { return m_captureStart; }
+ void setCaptureStart(int captureStart) { m_captureStart = captureStart; }
+
+ int captureEnd() { return m_captureEnd; }
+ void setCaptureEnd(int captureEnd) { m_captureEnd = captureEnd; }
+
+ int captureCount() { return m_captureEnd - m_captureStart; }
+
+ int parameterCount() { return m_parameterCountIncludingThis - 1; }
+ int parameterCountIncludingThis() { return m_parameterCountIncludingThis; }
+ void setParameterCountIncludingThis(int parameterCountIncludingThis) { m_parameterCountIncludingThis = parameterCountIncludingThis; }
+
+ // 0 if we don't capture any arguments; parameterCount() in length if we do.
+ const SlowArgument* slowArguments() { return m_slowArguments.get(); }
+ void setSlowArguments(PassOwnArrayPtr<SlowArgument> slowArguments) { m_slowArguments = slowArguments; }
+
+ static JS_EXPORTDATA const ClassInfo s_info;
+
+private:
+ SharedSymbolTable(VM& vm)
+ : JSCell(vm, vm.sharedSymbolTableStructure.get())
+ , m_parameterCountIncludingThis(0)
+ , m_usesNonStrictEval(false)
+ , m_captureStart(0)
+ , m_captureEnd(0)
+ {
+ }
+
+ int m_parameterCountIncludingThis;
+ bool m_usesNonStrictEval;
+
+ int m_captureStart;
+ int m_captureEnd;
+
+ OwnArrayPtr<SlowArgument> m_slowArguments;
+};
+