Index: src/api.cc |
=================================================================== |
--- src/api.cc (revision 8625) |
+++ src/api.cc (working copy) |
@@ -3085,7 +3085,39 @@ |
ENTER_V8(isolate); |
i::HandleScope scope(isolate); |
i::Handle<i::JSObject> self = Utils::OpenHandle(this); |
- return i::GetIdentityHash(self)->value(); |
+ 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 = isolate->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(self->GetIsolate()) & 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; |
} |