Index: src/api.cc |
diff --git a/src/api.cc b/src/api.cc |
index 80a53bf158a4c521fe1020456d1765ebb528c7bd..196e1a55f5bb14a4a1e45b8d27654a7761aba6b3 100644 |
--- a/src/api.cc |
+++ b/src/api.cc |
@@ -2655,26 +2655,38 @@ int v8::Object::GetIdentityHash() { |
ENTER_V8; |
HandleScope scope; |
i::Handle<i::JSObject> self = Utils::OpenHandle(this); |
- i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, true)); |
- i::Handle<i::Object> hash_symbol = i::Factory::identity_hash_symbol(); |
- i::Handle<i::Object> hash = i::GetProperty(hidden_props, hash_symbol); |
- int hash_value; |
- if (hash->IsSmi()) { |
- hash_value = i::Smi::cast(*hash)->value(); |
- } else { |
- int attempts = 0; |
- do { |
- // Generate a random 32-bit hash value but limit range to fit |
- // within a smi. |
- hash_value = i::V8::Random() & i::Smi::kMaxValue; |
- attempts++; |
- } while (hash_value == 0 && attempts < 30); |
- hash_value = hash_value != 0 ? hash_value : 1; // never return 0 |
- i::SetProperty(hidden_props, |
- hash_symbol, |
- i::Handle<i::Object>(i::Smi::FromInt(hash_value)), |
- static_cast<PropertyAttributes>(None)); |
+ i::Handle<i::Object> hidden_props_obj(i::GetHiddenProperties(self, true)); |
+ if (!hidden_props_obj->IsJSObject()) { |
+ // We failed to create hidden properties. That's a detached |
+ // global proxy. |
+ ASSERT(hidden_props_obj->IsUndefined()); |
+ return 0; |
} |
+ i::Handle<i::JSObject> hidden_props = |
+ i::Handle<i::JSObject>::cast(hidden_props_obj); |
+ i::Handle<i::String> hash_symbol = i::Factory::identity_hash_symbol(); |
+ if (hidden_props->HasLocalProperty(*hash_symbol)) { |
+ i::Handle<i::Object> hash = i::GetProperty(hidden_props, hash_symbol); |
+ CHECK(!hash.is_null()); |
+ CHECK(hash->IsSmi()); |
+ return i::Smi::cast(*hash)->value(); |
+ } |
+ |
+ int hash_value; |
+ int attempts = 0; |
+ do { |
+ // Generate a random 32-bit hash value but limit range to fit |
+ // within a smi. |
+ hash_value = i::V8::Random() & i::Smi::kMaxValue; |
+ attempts++; |
+ } while (hash_value == 0 && attempts < 30); |
+ hash_value = hash_value != 0 ? hash_value : 1; // never return 0 |
+ CHECK(!i::SetLocalPropertyIgnoreAttributes( |
+ hidden_props, |
+ hash_symbol, |
+ i::Handle<i::Object>(i::Smi::FromInt(hash_value)), |
+ static_cast<PropertyAttributes>(None)).is_null()); |
+ |
return hash_value; |
} |