+ class ForInContext {
+ public:
+ ForInContext(RegisterID* localRegister)
+ : m_localRegister(localRegister)
+ , m_isValid(true)
+ {
+ }
+
+ virtual ~ForInContext()
+ {
+ }
+
+ bool isValid() const { return m_isValid; }
+ void invalidate() { m_isValid = false; }
+
+ enum ForInContextType {
+ StructureForInContextType,
+ IndexedForInContextType
+ };
+ virtual ForInContextType type() const = 0;
+
+ RegisterID* local() const { return m_localRegister.get(); }
+
+ private:
+ RefPtr<RegisterID> m_localRegister;
+ bool m_isValid;
+ };
+
+ class StructureForInContext : public ForInContext {
+ public:
+ StructureForInContext(RegisterID* localRegister, RegisterID* indexRegister, RegisterID* propertyRegister, RegisterID* enumeratorRegister)
+ : ForInContext(localRegister)
+ , m_indexRegister(indexRegister)
+ , m_propertyRegister(propertyRegister)
+ , m_enumeratorRegister(enumeratorRegister)
+ {
+ }
+
+ virtual ForInContextType type() const
+ {
+ return StructureForInContextType;
+ }
+
+ RegisterID* index() const { return m_indexRegister.get(); }
+ RegisterID* property() const { return m_propertyRegister.get(); }
+ RegisterID* enumerator() const { return m_enumeratorRegister.get(); }
+
+ private:
+ RefPtr<RegisterID> m_indexRegister;
+ RefPtr<RegisterID> m_propertyRegister;
+ RefPtr<RegisterID> m_enumeratorRegister;
+ };
+
+ class IndexedForInContext : public ForInContext {
+ public:
+ IndexedForInContext(RegisterID* localRegister, RegisterID* indexRegister)
+ : ForInContext(localRegister)
+ , m_indexRegister(indexRegister)
+ {
+ }
+
+ virtual ForInContextType type() const
+ {
+ return IndexedForInContextType;
+ }
+
+ RegisterID* index() const { return m_indexRegister.get(); }
+
+ private:
+ RefPtr<RegisterID> m_indexRegister;