| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #include "accessors.h" | 7 #include "accessors.h" |
| 8 #include "allocation-site-scopes.h" | 8 #include "allocation-site-scopes.h" |
| 9 #include "api.h" | 9 #include "api.h" |
| 10 #include "arguments.h" | 10 #include "arguments.h" |
| (...skipping 5050 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5061 object->Print(); | 5061 object->Print(); |
| 5062 } | 5062 } |
| 5063 #endif | 5063 #endif |
| 5064 | 5064 |
| 5065 ASSERT(object->HasDictionaryElements() || | 5065 ASSERT(object->HasDictionaryElements() || |
| 5066 object->HasDictionaryArgumentsElements()); | 5066 object->HasDictionaryArgumentsElements()); |
| 5067 return dictionary; | 5067 return dictionary; |
| 5068 } | 5068 } |
| 5069 | 5069 |
| 5070 | 5070 |
| 5071 Smi* JSReceiver::GenerateIdentityHash() { | 5071 static Smi* GenerateIdentityHash(Isolate* isolate) { |
| 5072 Isolate* isolate = GetIsolate(); | |
| 5073 | |
| 5074 int hash_value; | 5072 int hash_value; |
| 5075 int attempts = 0; | 5073 int attempts = 0; |
| 5076 do { | 5074 do { |
| 5077 // Generate a random 32-bit hash value but limit range to fit | 5075 // Generate a random 32-bit hash value but limit range to fit |
| 5078 // within a smi. | 5076 // within a smi. |
| 5079 hash_value = isolate->random_number_generator()->NextInt() & Smi::kMaxValue; | 5077 hash_value = isolate->random_number_generator()->NextInt() & Smi::kMaxValue; |
| 5080 attempts++; | 5078 attempts++; |
| 5081 } while (hash_value == 0 && attempts < 30); | 5079 } while (hash_value == 0 && attempts < 30); |
| 5082 hash_value = hash_value != 0 ? hash_value : 1; // never return 0 | 5080 hash_value = hash_value != 0 ? hash_value : 1; // never return 0 |
| 5083 | 5081 |
| 5084 return Smi::FromInt(hash_value); | 5082 return Smi::FromInt(hash_value); |
| 5085 } | 5083 } |
| 5086 | 5084 |
| 5087 | 5085 |
| 5088 void JSObject::SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash) { | 5086 void JSObject::SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash) { |
| 5087 ASSERT(!object->IsJSGlobalProxy()); |
| 5089 Isolate* isolate = object->GetIsolate(); | 5088 Isolate* isolate = object->GetIsolate(); |
| 5090 SetHiddenProperty(object, isolate->factory()->identity_hash_string(), hash); | 5089 SetHiddenProperty(object, isolate->factory()->identity_hash_string(), hash); |
| 5091 } | 5090 } |
| 5092 | 5091 |
| 5093 | 5092 |
| 5093 template<typename ProxyType> |
| 5094 static Handle<Object> GetOrCreateIdentityHashHelper(Handle<ProxyType> proxy) { |
| 5095 Isolate* isolate = proxy->GetIsolate(); |
| 5096 |
| 5097 Handle<Object> hash(proxy->hash(), isolate); |
| 5098 if (hash->IsSmi()) return hash; |
| 5099 |
| 5100 hash = handle(GenerateIdentityHash(isolate), isolate); |
| 5101 proxy->set_hash(*hash); |
| 5102 return hash; |
| 5103 } |
| 5104 |
| 5105 |
| 5094 Object* JSObject::GetIdentityHash() { | 5106 Object* JSObject::GetIdentityHash() { |
| 5095 DisallowHeapAllocation no_gc; | 5107 DisallowHeapAllocation no_gc; |
| 5096 Isolate* isolate = GetIsolate(); | 5108 Isolate* isolate = GetIsolate(); |
| 5109 if (IsJSGlobalProxy()) { |
| 5110 return JSGlobalProxy::cast(this)->hash(); |
| 5111 } |
| 5097 Object* stored_value = | 5112 Object* stored_value = |
| 5098 GetHiddenProperty(isolate->factory()->identity_hash_string()); | 5113 GetHiddenProperty(isolate->factory()->identity_hash_string()); |
| 5099 return stored_value->IsSmi() | 5114 return stored_value->IsSmi() |
| 5100 ? stored_value | 5115 ? stored_value |
| 5101 : isolate->heap()->undefined_value(); | 5116 : isolate->heap()->undefined_value(); |
| 5102 } | 5117 } |
| 5103 | 5118 |
| 5104 | 5119 |
| 5105 Handle<Object> JSObject::GetOrCreateIdentityHash(Handle<JSObject> object) { | 5120 Handle<Object> JSObject::GetOrCreateIdentityHash(Handle<JSObject> object) { |
| 5106 Handle<Object> hash(object->GetIdentityHash(), object->GetIsolate()); | 5121 if (object->IsJSGlobalProxy()) { |
| 5107 if (hash->IsSmi()) | 5122 return GetOrCreateIdentityHashHelper(Handle<JSGlobalProxy>::cast(object)); |
| 5108 return hash; | 5123 } |
| 5109 | 5124 |
| 5110 Isolate* isolate = object->GetIsolate(); | 5125 Isolate* isolate = object->GetIsolate(); |
| 5111 | 5126 |
| 5112 hash = handle(object->GenerateIdentityHash(), isolate); | 5127 Handle<Object> hash(object->GetIdentityHash(), isolate); |
| 5113 Handle<Object> result = SetHiddenProperty(object, | 5128 if (hash->IsSmi()) return hash; |
| 5114 isolate->factory()->identity_hash_string(), hash); | |
| 5115 | 5129 |
| 5116 if (result->IsUndefined()) { | 5130 hash = handle(GenerateIdentityHash(isolate), isolate); |
| 5117 // Trying to get hash of detached proxy. | 5131 SetHiddenProperty(object, isolate->factory()->identity_hash_string(), hash); |
| 5118 return handle(Smi::FromInt(0), isolate); | |
| 5119 } | |
| 5120 | |
| 5121 return hash; | 5132 return hash; |
| 5122 } | 5133 } |
| 5123 | 5134 |
| 5124 | 5135 |
| 5125 Object* JSProxy::GetIdentityHash() { | 5136 Object* JSProxy::GetIdentityHash() { |
| 5126 return this->hash(); | 5137 return this->hash(); |
| 5127 } | 5138 } |
| 5128 | 5139 |
| 5129 | 5140 |
| 5130 Handle<Object> JSProxy::GetOrCreateIdentityHash(Handle<JSProxy> proxy) { | 5141 Handle<Object> JSProxy::GetOrCreateIdentityHash(Handle<JSProxy> proxy) { |
| 5131 Isolate* isolate = proxy->GetIsolate(); | 5142 return GetOrCreateIdentityHashHelper(proxy); |
| 5132 | |
| 5133 Handle<Object> hash(proxy->GetIdentityHash(), isolate); | |
| 5134 if (hash->IsSmi()) | |
| 5135 return hash; | |
| 5136 | |
| 5137 hash = handle(proxy->GenerateIdentityHash(), isolate); | |
| 5138 proxy->set_hash(*hash); | |
| 5139 return hash; | |
| 5140 } | 5143 } |
| 5141 | 5144 |
| 5142 | 5145 |
| 5143 Object* JSObject::GetHiddenProperty(Handle<Name> key) { | 5146 Object* JSObject::GetHiddenProperty(Handle<Name> key) { |
| 5144 DisallowHeapAllocation no_gc; | 5147 DisallowHeapAllocation no_gc; |
| 5145 ASSERT(key->IsUniqueName()); | 5148 ASSERT(key->IsUniqueName()); |
| 5146 if (IsJSGlobalProxy()) { | 5149 if (IsJSGlobalProxy()) { |
| 5150 // JSGlobalProxies store their hash internally. |
| 5151 ASSERT(*key != GetHeap()->identity_hash_string()); |
| 5147 // For a proxy, use the prototype as target object. | 5152 // For a proxy, use the prototype as target object. |
| 5148 Object* proxy_parent = GetPrototype(); | 5153 Object* proxy_parent = GetPrototype(); |
| 5149 // If the proxy is detached, return undefined. | 5154 // If the proxy is detached, return undefined. |
| 5150 if (proxy_parent->IsNull()) return GetHeap()->the_hole_value(); | 5155 if (proxy_parent->IsNull()) return GetHeap()->the_hole_value(); |
| 5151 ASSERT(proxy_parent->IsJSGlobalObject()); | 5156 ASSERT(proxy_parent->IsJSGlobalObject()); |
| 5152 return JSObject::cast(proxy_parent)->GetHiddenProperty(key); | 5157 return JSObject::cast(proxy_parent)->GetHiddenProperty(key); |
| 5153 } | 5158 } |
| 5154 ASSERT(!IsJSGlobalProxy()); | 5159 ASSERT(!IsJSGlobalProxy()); |
| 5155 Object* inline_value = GetHiddenPropertiesHashTable(); | 5160 Object* inline_value = GetHiddenPropertiesHashTable(); |
| 5156 | 5161 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 5171 } | 5176 } |
| 5172 | 5177 |
| 5173 | 5178 |
| 5174 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object, | 5179 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object, |
| 5175 Handle<Name> key, | 5180 Handle<Name> key, |
| 5176 Handle<Object> value) { | 5181 Handle<Object> value) { |
| 5177 Isolate* isolate = object->GetIsolate(); | 5182 Isolate* isolate = object->GetIsolate(); |
| 5178 | 5183 |
| 5179 ASSERT(key->IsUniqueName()); | 5184 ASSERT(key->IsUniqueName()); |
| 5180 if (object->IsJSGlobalProxy()) { | 5185 if (object->IsJSGlobalProxy()) { |
| 5186 // JSGlobalProxies store their hash internally. |
| 5187 ASSERT(*key != *isolate->factory()->identity_hash_string()); |
| 5181 // For a proxy, use the prototype as target object. | 5188 // For a proxy, use the prototype as target object. |
| 5182 Handle<Object> proxy_parent(object->GetPrototype(), isolate); | 5189 Handle<Object> proxy_parent(object->GetPrototype(), isolate); |
| 5183 // If the proxy is detached, return undefined. | 5190 // If the proxy is detached, return undefined. |
| 5184 if (proxy_parent->IsNull()) return isolate->factory()->undefined_value(); | 5191 if (proxy_parent->IsNull()) return isolate->factory()->undefined_value(); |
| 5185 ASSERT(proxy_parent->IsJSGlobalObject()); | 5192 ASSERT(proxy_parent->IsJSGlobalObject()); |
| 5186 return SetHiddenProperty(Handle<JSObject>::cast(proxy_parent), key, value); | 5193 return SetHiddenProperty(Handle<JSObject>::cast(proxy_parent), key, value); |
| 5187 } | 5194 } |
| 5188 ASSERT(!object->IsJSGlobalProxy()); | 5195 ASSERT(!object->IsJSGlobalProxy()); |
| 5189 | 5196 |
| 5190 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); | 5197 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); |
| (...skipping 12067 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17258 #define ERROR_MESSAGES_TEXTS(C, T) T, | 17265 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 17259 static const char* error_messages_[] = { | 17266 static const char* error_messages_[] = { |
| 17260 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 17267 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 17261 }; | 17268 }; |
| 17262 #undef ERROR_MESSAGES_TEXTS | 17269 #undef ERROR_MESSAGES_TEXTS |
| 17263 return error_messages_[reason]; | 17270 return error_messages_[reason]; |
| 17264 } | 17271 } |
| 17265 | 17272 |
| 17266 | 17273 |
| 17267 } } // namespace v8::internal | 17274 } } // namespace v8::internal |
| OLD | NEW |