Index: src/ast/variables.h |
diff --git a/src/ast/variables.h b/src/ast/variables.h |
index 7d54bc09c4d8d77d52f2b53ba8b398d6bd50c499..950db3c0021263f93209609d24cfd61de8a2d58f 100644 |
--- a/src/ast/variables.h |
+++ b/src/ast/variables.h |
@@ -55,10 +55,6 @@ class Variable: public ZoneObject { |
int initializer_position() { return initializer_position_; } |
void set_initializer_position(int pos) { initializer_position_ = pos; } |
- bool IsVariable(Handle<String> n) const { |
- return !is_this() && name().is_identical_to(n); |
- } |
- |
bool IsUnallocated() const { |
return location_ == VariableLocation::UNALLOCATED; |
} |
@@ -90,13 +86,25 @@ class Variable: public ZoneObject { |
// any variable named "this" does indeed refer to a Variable::THIS binding; |
// the grammar ensures this to be the case. So wherever a "this" binding |
// might be provided by the global, use HasThisName instead of is_this(). |
- bool HasThisName(Isolate* isolate) const { |
- return is_this() || *name() == *isolate->factory()->this_string(); |
+ bool HasThisName(Isolate* isolate, |
+ HandleDereferenceMode deref_mode = |
+ HandleDereferenceMode::kAllowed) const { |
+ // Note: it is safe to dereference isolate->factory()->this_string() here |
+ // regardless of |deref_mode| because it is a constant root and so will |
+ // never be updated or moved. |
+ return is_this() || |
+ name_is_identical_to(isolate->factory()->this_string(), deref_mode); |
} |
// True if the variable is named eval and not known to be shadowed. |
- bool is_possibly_eval(Isolate* isolate) const { |
- return IsVariable(isolate->factory()->eval_string()); |
+ bool is_possibly_eval(Isolate* isolate, |
+ HandleDereferenceMode deref_mode = |
+ HandleDereferenceMode::kAllowed) const { |
+ // Note: it is safe to dereference isolate->factory()->eval_string() here |
+ // regardless of |deref_mode| because it is a constant root and so will |
+ // never be updated or moved. |
+ return !is_this() && |
+ name_is_identical_to(isolate->factory()->eval_string(), deref_mode); |
} |
Variable* local_if_not_shadowed() const { |
@@ -122,6 +130,20 @@ class Variable: public ZoneObject { |
static int CompareIndex(Variable* const* v, Variable* const* w); |
private: |
+ bool name_is_identical_to(Handle<Object> object, |
+ HandleDereferenceMode deref_mode) const { |
+ if (deref_mode == HandleDereferenceMode::kAllowed) { |
+ return *name() == *object; |
+ } else { |
+ // If handle dereference isn't allowed use the handle address for |
+ // identity. This depends on the variable name being internalized in a |
+ // CanonicalHandleScope, so that all handles created during the |
+ // internalization with identical values have identical locations, and any |
+ // handles created which point to roots have the root handle's location. |
+ return name().address() == object.address(); |
+ } |
+ } |
+ |
Scope* scope_; |
const AstRawString* name_; |
VariableMode mode_; |