+class WatchpointSet;
+
+enum ResolveMode {
+ ThrowIfNotFound,
+ DoNotThrowIfNotFound
+};
+
+enum ResolveType {
+ // Lexical scope guaranteed a certain type of variable access.
+ GlobalProperty,
+ GlobalVar,
+ ClosureVar,
+ LocalClosureVar,
+
+ // Ditto, but at least one intervening scope used non-strict eval, which
+ // can inject an intercepting var delcaration at runtime.
+ GlobalPropertyWithVarInjectionChecks,
+ GlobalVarWithVarInjectionChecks,
+ ClosureVarWithVarInjectionChecks,
+
+ // Lexical scope didn't prove anything -- probably because of a 'with' scope.
+ Dynamic
+};
+
+const char* resolveModeName(ResolveMode mode);
+const char* resolveTypeName(ResolveType type);
+
+inline ResolveType makeType(ResolveType type, bool needsVarInjectionChecks)
+{
+ if (!needsVarInjectionChecks)
+ return type;
+
+ switch (type) {
+ case GlobalProperty:
+ return GlobalPropertyWithVarInjectionChecks;
+ case GlobalVar:
+ return GlobalVarWithVarInjectionChecks;
+ case ClosureVar:
+ case LocalClosureVar:
+ return ClosureVarWithVarInjectionChecks;
+ case GlobalPropertyWithVarInjectionChecks:
+ case GlobalVarWithVarInjectionChecks:
+ case ClosureVarWithVarInjectionChecks:
+ case Dynamic:
+ return type;
+ }
+
+ RELEASE_ASSERT_NOT_REACHED();
+ return type;
+}
+
+inline bool needsVarInjectionChecks(ResolveType type)
+{
+ switch (type) {
+ case GlobalProperty:
+ case GlobalVar:
+ case ClosureVar:
+ case LocalClosureVar:
+ return false;
+ case GlobalPropertyWithVarInjectionChecks:
+ case GlobalVarWithVarInjectionChecks:
+ case ClosureVarWithVarInjectionChecks:
+ case Dynamic:
+ return true;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ return true;
+ }
+}
+
+struct ResolveOp {
+ ResolveOp(ResolveType type, size_t depth, Structure* structure, JSLexicalEnvironment* lexicalEnvironment, WatchpointSet* watchpointSet, uintptr_t operand)
+ : type(type)
+ , depth(depth)
+ , structure(structure)
+ , lexicalEnvironment(lexicalEnvironment)
+ , watchpointSet(watchpointSet)
+ , operand(operand)
+ {
+ }
+
+ ResolveType type;
+ size_t depth;
+ Structure* structure;
+ JSLexicalEnvironment* lexicalEnvironment;
+ WatchpointSet* watchpointSet;
+ uintptr_t operand;
+};
+
+class ResolveModeAndType {
+ typedef unsigned Operand;
+public:
+ static const size_t shift = sizeof(Operand) * 8 / 2;
+ static const unsigned mask = (1 << shift) - 1;
+
+ ResolveModeAndType(ResolveMode resolveMode, ResolveType resolveType)
+ : m_operand((resolveMode << shift) | resolveType)
+ {
+ }
+
+ explicit ResolveModeAndType(unsigned operand)
+ : m_operand(operand)
+ {
+ }
+
+ ResolveMode mode() { return static_cast<ResolveMode>(m_operand >> shift); }
+ ResolveType type() { return static_cast<ResolveType>(m_operand & mask); }
+ unsigned operand() { return m_operand; }
+
+private:
+ Operand m_operand;
+};
+
+enum GetOrPut { Get, Put };