OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
133 | 133 |
134 void Object::Lookup(String* name, LookupResult* result) { | 134 void Object::Lookup(String* name, LookupResult* result) { |
135 Object* holder = NULL; | 135 Object* holder = NULL; |
136 if (IsSmi()) { | 136 if (IsSmi()) { |
137 Context* global_context = Isolate::Current()->context()->global_context(); | 137 Context* global_context = Isolate::Current()->context()->global_context(); |
138 holder = global_context->number_function()->instance_prototype(); | 138 holder = global_context->number_function()->instance_prototype(); |
139 } else { | 139 } else { |
140 HeapObject* heap_object = HeapObject::cast(this); | 140 HeapObject* heap_object = HeapObject::cast(this); |
141 if (heap_object->IsJSObject()) { | 141 if (heap_object->IsJSObject()) { |
142 return JSObject::cast(this)->Lookup(name, result); | 142 return JSObject::cast(this)->Lookup(name, result); |
143 } else if (heap_object->IsJSProxy()) { | |
144 return result->HandlerResult(); | |
Kevin Millikin (Chromium)
2011/05/30 16:32:29
Indentation looks off.
rossberg
2011/05/31 14:50:24
Done.
| |
143 } | 145 } |
144 Context* global_context = Isolate::Current()->context()->global_context(); | 146 Context* global_context = Isolate::Current()->context()->global_context(); |
145 if (heap_object->IsString()) { | 147 if (heap_object->IsString()) { |
146 holder = global_context->string_function()->instance_prototype(); | 148 holder = global_context->string_function()->instance_prototype(); |
147 } else if (heap_object->IsHeapNumber()) { | 149 } else if (heap_object->IsHeapNumber()) { |
148 holder = global_context->number_function()->instance_prototype(); | 150 holder = global_context->number_function()->instance_prototype(); |
149 } else if (heap_object->IsBoolean()) { | 151 } else if (heap_object->IsBoolean()) { |
150 holder = global_context->boolean_function()->instance_prototype(); | 152 holder = global_context->boolean_function()->instance_prototype(); |
151 } else if (heap_object->IsJSProxy()) { | |
152 return result->HandlerResult(); | |
153 } | 153 } |
154 } | 154 } |
155 ASSERT(holder != NULL); // Cannot handle null or undefined. | 155 ASSERT(holder != NULL); // Cannot handle null or undefined. |
156 JSObject::cast(holder)->Lookup(name, result); | 156 JSObject::cast(holder)->Lookup(name, result); |
157 } | 157 } |
158 | 158 |
159 | 159 |
160 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver, | 160 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver, |
161 String* name, | 161 String* name, |
162 PropertyAttributes* attributes) { | 162 PropertyAttributes* attributes) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
229 MaybeObject* Object::GetPropertyWithHandler(Object* receiver_raw, | 229 MaybeObject* Object::GetPropertyWithHandler(Object* receiver_raw, |
230 String* name_raw, | 230 String* name_raw, |
231 Object* handler_raw) { | 231 Object* handler_raw) { |
232 Isolate* isolate = name_raw->GetIsolate(); | 232 Isolate* isolate = name_raw->GetIsolate(); |
233 HandleScope scope; | 233 HandleScope scope; |
234 Handle<Object> receiver(receiver_raw); | 234 Handle<Object> receiver(receiver_raw); |
235 Handle<Object> name(name_raw); | 235 Handle<Object> name(name_raw); |
236 Handle<Object> handler(handler_raw); | 236 Handle<Object> handler(handler_raw); |
237 | 237 |
238 // Extract trap function. | 238 // Extract trap function. |
239 LookupResult lookup; | 239 Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("get"); |
240 Handle<Object> trap(v8::internal::GetProperty(handler, "get", &lookup)); | 240 Handle<Object> trap(v8::internal::GetProperty(handler, trap_name)); |
241 if (!lookup.IsFound()) { | 241 if (trap->IsUndefined()) { |
242 // Get the derived `get' property. | 242 // Get the derived `get' property. |
243 trap = isolate->derived_get_trap(); | 243 trap = isolate->derived_get_trap(); |
244 } | 244 } |
245 | 245 |
246 // Call trap function. | 246 // Call trap function. |
247 Object** args[] = { receiver.location(), name.location() }; | 247 Object** args[] = { receiver.location(), name.location() }; |
248 bool has_exception; | 248 bool has_exception; |
249 Handle<Object> result = | 249 Handle<Object> result = |
250 Execution::Call(trap, handler, ARRAY_SIZE(args), args, &has_exception); | 250 Execution::Call(trap, handler, ARRAY_SIZE(args), args, &has_exception); |
251 if (has_exception) return Failure::Exception(); | 251 if (has_exception) return Failure::Exception(); |
(...skipping 1022 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1274 // allocation when producing post-crash stack traces, so we print into a | 1274 // allocation when producing post-crash stack traces, so we print into a |
1275 // buffer that is plenty big enough for any floating point number, then | 1275 // buffer that is plenty big enough for any floating point number, then |
1276 // print that using vsnprintf (which may truncate but never allocate if | 1276 // print that using vsnprintf (which may truncate but never allocate if |
1277 // there is no more space in the buffer). | 1277 // there is no more space in the buffer). |
1278 EmbeddedVector<char, 100> buffer; | 1278 EmbeddedVector<char, 100> buffer; |
1279 OS::SNPrintF(buffer, "%.16g", Number()); | 1279 OS::SNPrintF(buffer, "%.16g", Number()); |
1280 accumulator->Add("%s", buffer.start()); | 1280 accumulator->Add("%s", buffer.start()); |
1281 } | 1281 } |
1282 | 1282 |
1283 | 1283 |
1284 String* JSObject::class_name() { | 1284 String* JSReceiver::class_name() { |
1285 if (IsJSFunction()) { | 1285 if (IsJSFunction() && IsJSFunctionProxy()) { |
1286 return GetHeap()->function_class_symbol(); | 1286 return GetHeap()->function_class_symbol(); |
1287 } | 1287 } |
1288 if (map()->constructor()->IsJSFunction()) { | 1288 if (map()->constructor()->IsJSFunction()) { |
1289 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 1289 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
1290 return String::cast(constructor->shared()->instance_class_name()); | 1290 return String::cast(constructor->shared()->instance_class_name()); |
1291 } | 1291 } |
1292 // If the constructor is not present, return "Object". | 1292 // If the constructor is not present, return "Object". |
1293 return GetHeap()->Object_symbol(); | 1293 return GetHeap()->Object_symbol(); |
1294 } | 1294 } |
1295 | 1295 |
1296 | 1296 |
1297 String* JSObject::constructor_name() { | 1297 String* JSReceiver::constructor_name() { |
1298 if (map()->constructor()->IsJSFunction()) { | 1298 if (map()->constructor()->IsJSFunction()) { |
1299 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 1299 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
1300 String* name = String::cast(constructor->shared()->name()); | 1300 String* name = String::cast(constructor->shared()->name()); |
1301 if (name->length() > 0) return name; | 1301 if (name->length() > 0) return name; |
1302 String* inferred_name = constructor->shared()->inferred_name(); | 1302 String* inferred_name = constructor->shared()->inferred_name(); |
1303 if (inferred_name->length() > 0) return inferred_name; | 1303 if (inferred_name->length() > 0) return inferred_name; |
1304 Object* proto = GetPrototype(); | 1304 Object* proto = GetPrototype(); |
1305 if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name(); | 1305 if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name(); |
1306 } | 1306 } |
1307 // TODO(rossberg): what about proxies? | |
1307 // If the constructor is not present, return "Object". | 1308 // If the constructor is not present, return "Object". |
1308 return GetHeap()->Object_symbol(); | 1309 return GetHeap()->Object_symbol(); |
1309 } | 1310 } |
1310 | 1311 |
1311 | 1312 |
1312 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, | 1313 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, |
1313 String* name, | 1314 String* name, |
1314 Object* value) { | 1315 Object* value) { |
1315 int index = new_map->PropertyIndexFor(name); | 1316 int index = new_map->PropertyIndexFor(name); |
1316 if (map()->unused_property_fields() == 0) { | 1317 if (map()->unused_property_fields() == 0) { |
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1751 MaybeObject* raw_result = | 1752 MaybeObject* raw_result = |
1752 this_handle->SetPropertyPostInterceptor(*name_handle, | 1753 this_handle->SetPropertyPostInterceptor(*name_handle, |
1753 *value_handle, | 1754 *value_handle, |
1754 attributes, | 1755 attributes, |
1755 strict_mode); | 1756 strict_mode); |
1756 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 1757 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
1757 return raw_result; | 1758 return raw_result; |
1758 } | 1759 } |
1759 | 1760 |
1760 | 1761 |
1761 MaybeObject* JSObject::SetProperty(String* name, | 1762 MaybeObject* JSReceiver::SetProperty(String* name, |
1762 Object* value, | 1763 Object* value, |
1763 PropertyAttributes attributes, | 1764 PropertyAttributes attributes, |
1764 StrictModeFlag strict_mode) { | 1765 StrictModeFlag strict_mode) { |
1765 LookupResult result; | 1766 LookupResult result; |
1766 LocalLookup(name, &result); | 1767 LocalLookup(name, &result); |
1767 return SetProperty(&result, name, value, attributes, strict_mode); | 1768 return SetProperty(&result, name, value, attributes, strict_mode); |
1768 } | 1769 } |
1769 | 1770 |
1770 | 1771 |
1771 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, | 1772 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, |
1772 String* name, | 1773 String* name, |
1773 Object* value, | 1774 Object* value, |
1774 JSObject* holder) { | 1775 JSObject* holder) { |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2117 } | 2118 } |
2118 | 2119 |
2119 HandleScope scope; | 2120 HandleScope scope; |
2120 Handle<Object> value_handle(value); | 2121 Handle<Object> value_handle(value); |
2121 Heap* heap = GetHeap(); | 2122 Heap* heap = GetHeap(); |
2122 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 2123 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
2123 return *value_handle; | 2124 return *value_handle; |
2124 } | 2125 } |
2125 | 2126 |
2126 | 2127 |
2127 MaybeObject* JSObject::SetProperty(LookupResult* result, | 2128 MaybeObject* JSReceiver::SetProperty(LookupResult* result, |
2129 String* key, | |
2130 Object* value, | |
2131 PropertyAttributes attributes, | |
2132 StrictModeFlag strict_mode) { | |
2133 if (result->IsFound() && result->type() == HANDLER) { | |
2134 return JSProxy::cast(this)->SetPropertyWithHandler( | |
2135 key, value, attributes, strict_mode); | |
2136 } else { | |
2137 return JSObject::cast(this)->SetPropertyForResult( | |
2138 result, key, value, attributes, strict_mode); | |
2139 } | |
2140 } | |
2141 | |
2142 | |
2143 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler( | |
2144 String* name_raw, | |
2145 Object* value_raw, | |
2146 PropertyAttributes attributes, | |
2147 StrictModeFlag strict_mode) { | |
2148 Isolate* isolate = GetIsolate(); | |
2149 HandleScope scope; | |
2150 Handle<Object> receiver(this); | |
2151 Handle<Object> name(name_raw); | |
2152 Handle<Object> value(value_raw); | |
2153 Handle<Object> handler(this->handler()); | |
2154 | |
2155 // Extract trap function. | |
2156 Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("set"); | |
2157 Handle<Object> trap(v8::internal::GetProperty(handler, trap_name)); | |
2158 if (trap->IsUndefined()) { | |
2159 trap = isolate->derived_set_trap(); | |
2160 } | |
2161 | |
2162 // Call trap function. | |
2163 Object** args[] = { | |
2164 receiver.location(), name.location(), value.location() | |
2165 }; | |
2166 bool has_exception; | |
2167 Handle<Object> result = | |
2168 Execution::Call(trap, handler, ARRAY_SIZE(args), args, &has_exception); | |
2169 if (has_exception) return Failure::Exception(); | |
2170 | |
2171 return *result; | |
2172 } | |
2173 | |
2174 | |
2175 MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler( | |
2176 JSReceiver* receiver_raw, | |
2177 String* name_raw, | |
2178 bool* has_exception) { | |
2179 Isolate* isolate = GetIsolate(); | |
2180 HandleScope scope; | |
2181 Handle<JSReceiver> receiver(receiver_raw); | |
2182 Handle<Object> name(name_raw); | |
2183 Handle<Object> handler(this->handler()); | |
2184 | |
2185 // Extract trap function. | |
2186 Handle<String> trap_name = | |
2187 isolate->factory()->LookupAsciiSymbol("getPropertyDescriptor"); | |
2188 Handle<Object> trap(v8::internal::GetProperty(handler, trap_name)); | |
2189 if (trap->IsUndefined()) { | |
2190 Handle<Object> args[] = { handler, trap_name }; | |
2191 Handle<Object> error = isolate->factory()->NewTypeError( | |
2192 "handler_trap_missing", HandleVector(args, ARRAY_SIZE(args))); | |
2193 isolate->Throw(*error); | |
2194 *has_exception = true; | |
2195 return NONE; | |
2196 } | |
2197 | |
2198 // Call trap function. | |
2199 Object** args[] = { name.location() }; | |
2200 Handle<Object> result = | |
2201 Execution::Call(trap, handler, ARRAY_SIZE(args), args, has_exception); | |
2202 if (has_exception) return NONE; | |
2203 | |
2204 // TODO(rossberg): convert result to PropertyAttributes | |
2205 USE(result); | |
2206 return NONE; | |
2207 } | |
2208 | |
2209 | |
2210 MaybeObject* JSObject::SetPropertyForResult(LookupResult* result, | |
2128 String* name, | 2211 String* name, |
2129 Object* value, | 2212 Object* value, |
2130 PropertyAttributes attributes, | 2213 PropertyAttributes attributes, |
2131 StrictModeFlag strict_mode) { | 2214 StrictModeFlag strict_mode) { |
2132 Heap* heap = GetHeap(); | 2215 Heap* heap = GetHeap(); |
2133 // Make sure that the top context does not change when doing callbacks or | 2216 // Make sure that the top context does not change when doing callbacks or |
2134 // interceptor calls. | 2217 // interceptor calls. |
2135 AssertNoContextChange ncc; | 2218 AssertNoContextChange ncc; |
2136 | 2219 |
2137 // Optimization for 2-byte strings often used as keys in a decompression | 2220 // Optimization for 2-byte strings often used as keys in a decompression |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2392 result = getter(v8::Utils::ToLocal(name_handle), info); | 2475 result = getter(v8::Utils::ToLocal(name_handle), info); |
2393 } | 2476 } |
2394 if (!result.IsEmpty()) return DONT_ENUM; | 2477 if (!result.IsEmpty()) return DONT_ENUM; |
2395 } | 2478 } |
2396 return holder_handle->GetPropertyAttributePostInterceptor(*receiver_handle, | 2479 return holder_handle->GetPropertyAttributePostInterceptor(*receiver_handle, |
2397 *name_handle, | 2480 *name_handle, |
2398 continue_search); | 2481 continue_search); |
2399 } | 2482 } |
2400 | 2483 |
2401 | 2484 |
2402 PropertyAttributes JSObject::GetPropertyAttributeWithReceiver( | 2485 PropertyAttributes JSReceiver::GetPropertyAttributeWithReceiver( |
2403 JSObject* receiver, | 2486 JSReceiver* receiver, |
2404 String* key) { | 2487 String* key) { |
2405 uint32_t index = 0; | 2488 uint32_t index = 0; |
2406 if (key->AsArrayIndex(&index)) { | 2489 if (IsJSObject() && key->AsArrayIndex(&index)) { |
2407 if (HasElementWithReceiver(receiver, index)) return NONE; | 2490 if (JSObject::cast(this)->HasElementWithReceiver(receiver, index)) |
2491 return NONE; | |
2408 return ABSENT; | 2492 return ABSENT; |
2409 } | 2493 } |
2410 // Named property. | 2494 // Named property. |
2411 LookupResult result; | 2495 LookupResult result; |
2412 Lookup(key, &result); | 2496 Lookup(key, &result); |
2413 return GetPropertyAttribute(receiver, &result, key, true); | 2497 return GetPropertyAttribute(receiver, &result, key, true); |
2414 } | 2498 } |
2415 | 2499 |
2416 | 2500 |
2417 PropertyAttributes JSObject::GetPropertyAttribute(JSObject* receiver, | 2501 PropertyAttributes JSReceiver::GetPropertyAttribute(JSReceiver* receiver, |
2418 LookupResult* result, | 2502 LookupResult* result, |
2419 String* name, | 2503 String* name, |
2420 bool continue_search) { | 2504 bool continue_search) { |
2421 // Check access rights if needed. | 2505 // Check access rights if needed. |
2422 if (IsAccessCheckNeeded()) { | 2506 if (IsAccessCheckNeeded()) { |
2507 JSObject* this_obj = JSObject::cast(this); | |
2423 Heap* heap = GetHeap(); | 2508 Heap* heap = GetHeap(); |
2424 if (!heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) { | 2509 if (!heap->isolate()->MayNamedAccess(this_obj, name, v8::ACCESS_HAS)) { |
2425 return GetPropertyAttributeWithFailedAccessCheck(receiver, | 2510 return this_obj->GetPropertyAttributeWithFailedAccessCheck( |
2426 result, | 2511 receiver, result, name, continue_search); |
2427 name, | |
2428 continue_search); | |
2429 } | 2512 } |
2430 } | 2513 } |
2431 if (result->IsProperty()) { | 2514 if (result->IsProperty()) { |
2432 switch (result->type()) { | 2515 switch (result->type()) { |
2433 case NORMAL: // fall through | 2516 case NORMAL: // fall through |
2434 case FIELD: | 2517 case FIELD: |
2435 case CONSTANT_FUNCTION: | 2518 case CONSTANT_FUNCTION: |
2436 case CALLBACKS: | 2519 case CALLBACKS: |
2437 return result->GetAttributes(); | 2520 return result->GetAttributes(); |
2521 case HANDLER: { | |
2522 // TODO(rossberg): propagate exceptions properly. | |
2523 bool has_exception = false; | |
2524 return JSProxy::cast(this)->GetPropertyAttributeWithHandler( | |
2525 receiver, name, &has_exception); | |
2526 } | |
2438 case INTERCEPTOR: | 2527 case INTERCEPTOR: |
2439 return result->holder()-> | 2528 return result->holder()->GetPropertyAttributeWithInterceptor( |
2440 GetPropertyAttributeWithInterceptor(receiver, name, continue_search); | 2529 JSObject::cast(receiver), name, continue_search); |
2441 default: | 2530 default: |
2442 UNREACHABLE(); | 2531 UNREACHABLE(); |
2443 } | 2532 } |
2444 } | 2533 } |
2445 return ABSENT; | 2534 return ABSENT; |
2446 } | 2535 } |
2447 | 2536 |
2448 | 2537 |
2449 PropertyAttributes JSObject::GetLocalPropertyAttribute(String* name) { | 2538 PropertyAttributes JSReceiver::GetLocalPropertyAttribute(String* name) { |
2450 // Check whether the name is an array index. | 2539 // Check whether the name is an array index. |
2451 uint32_t index = 0; | 2540 uint32_t index = 0; |
2452 if (name->AsArrayIndex(&index)) { | 2541 if (IsJSObject() && name->AsArrayIndex(&index)) { |
2453 if (HasLocalElement(index)) return NONE; | 2542 if (JSObject::cast(this)->HasLocalElement(index)) return NONE; |
2454 return ABSENT; | 2543 return ABSENT; |
2455 } | 2544 } |
2456 // Named property. | 2545 // Named property. |
2457 LookupResult result; | 2546 LookupResult result; |
2458 LocalLookup(name, &result); | 2547 LocalLookup(name, &result); |
2459 return GetPropertyAttribute(this, &result, name, false); | 2548 return GetPropertyAttribute(this, &result, name, false); |
2460 } | 2549 } |
2461 | 2550 |
2462 | 2551 |
2463 MaybeObject* NormalizedMapCache::Get(JSObject* obj, | 2552 MaybeObject* NormalizedMapCache::Get(JSObject* obj, |
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3195 DescriptorArray* descs = instance_descriptors(); | 3284 DescriptorArray* descs = instance_descriptors(); |
3196 for (int i = 0; i < descs->number_of_descriptors(); i++) { | 3285 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
3197 if (name->Equals(descs->GetKey(i)) && descs->GetType(i) == CALLBACKS) { | 3286 if (name->Equals(descs->GetKey(i)) && descs->GetType(i) == CALLBACKS) { |
3198 return descs->GetCallbacks(i); | 3287 return descs->GetCallbacks(i); |
3199 } | 3288 } |
3200 } | 3289 } |
3201 return NULL; | 3290 return NULL; |
3202 } | 3291 } |
3203 | 3292 |
3204 | 3293 |
3294 void JSReceiver::LocalLookup(String* name, LookupResult* result) { | |
3295 if (IsJSProxy()) { | |
3296 result->HandlerResult(); | |
3297 } else { | |
3298 JSObject::cast(this)->LocalLookup(name, result); | |
3299 } | |
3300 } | |
3301 | |
3302 | |
3205 void JSObject::LocalLookup(String* name, LookupResult* result) { | 3303 void JSObject::LocalLookup(String* name, LookupResult* result) { |
3206 ASSERT(name->IsString()); | 3304 ASSERT(name->IsString()); |
3207 | 3305 |
3208 Heap* heap = GetHeap(); | 3306 Heap* heap = GetHeap(); |
3209 | 3307 |
3210 if (IsJSGlobalProxy()) { | 3308 if (IsJSGlobalProxy()) { |
3211 Object* proto = GetPrototype(); | 3309 Object* proto = GetPrototype(); |
3212 if (proto->IsNull()) return result->NotFound(); | 3310 if (proto->IsNull()) return result->NotFound(); |
3213 ASSERT(proto->IsJSGlobalObject()); | 3311 ASSERT(proto->IsJSGlobalObject()); |
3214 return JSObject::cast(proto)->LocalLookup(name, result); | 3312 return JSObject::cast(proto)->LocalLookup(name, result); |
(...skipping 15 matching lines...) Expand all Loading... | |
3230 // Check for lookup interceptor except when bootstrapping. | 3328 // Check for lookup interceptor except when bootstrapping. |
3231 if (HasNamedInterceptor() && !heap->isolate()->bootstrapper()->IsActive()) { | 3329 if (HasNamedInterceptor() && !heap->isolate()->bootstrapper()->IsActive()) { |
3232 result->InterceptorResult(this); | 3330 result->InterceptorResult(this); |
3233 return; | 3331 return; |
3234 } | 3332 } |
3235 | 3333 |
3236 LocalLookupRealNamedProperty(name, result); | 3334 LocalLookupRealNamedProperty(name, result); |
3237 } | 3335 } |
3238 | 3336 |
3239 | 3337 |
3240 void JSObject::Lookup(String* name, LookupResult* result) { | 3338 void JSReceiver::Lookup(String* name, LookupResult* result) { |
3241 // Ecma-262 3rd 8.6.2.4 | 3339 // Ecma-262 3rd 8.6.2.4 |
3242 Heap* heap = GetHeap(); | 3340 Heap* heap = GetHeap(); |
3243 for (Object* current = this; | 3341 for (Object* current = this; |
3244 current != heap->null_value(); | 3342 current != heap->null_value(); |
3245 current = JSObject::cast(current)->GetPrototype()) { | 3343 current = JSObject::cast(current)->GetPrototype()) { |
3246 JSObject::cast(current)->LocalLookup(name, result); | 3344 JSObject::cast(current)->LocalLookup(name, result); |
3247 if (result->IsProperty()) return; | 3345 if (result->IsProperty()) return; |
3248 } | 3346 } |
3249 result->NotFound(); | 3347 result->NotFound(); |
3250 } | 3348 } |
(...skipping 3734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6985 } | 7083 } |
6986 | 7084 |
6987 cache->set(finger, prototype); | 7085 cache->set(finger, prototype); |
6988 cache->set(finger + 1, map); | 7086 cache->set(finger + 1, map); |
6989 cache->set(0, Smi::FromInt(finger + 2)); | 7087 cache->set(0, Smi::FromInt(finger + 2)); |
6990 | 7088 |
6991 return cache; | 7089 return cache; |
6992 } | 7090 } |
6993 | 7091 |
6994 | 7092 |
6995 MaybeObject* JSObject::SetPrototype(Object* value, | 7093 MaybeObject* JSReceiver::SetPrototype(Object* value, |
6996 bool skip_hidden_prototypes) { | 7094 bool skip_hidden_prototypes) { |
6997 Heap* heap = GetHeap(); | 7095 Heap* heap = GetHeap(); |
6998 // Silently ignore the change if value is not a JSObject or null. | 7096 // Silently ignore the change if value is not a JSObject or null. |
6999 // SpiderMonkey behaves this way. | 7097 // SpiderMonkey behaves this way. |
7000 if (!value->IsJSObject() && !value->IsNull()) return value; | 7098 if (!value->IsJSReceiver() && !value->IsNull()) return value; |
7001 | 7099 |
7002 // From 8.6.2 Object Internal Methods | 7100 // From 8.6.2 Object Internal Methods |
7003 // ... | 7101 // ... |
7004 // In addition, if [[Extensible]] is false the value of the [[Class]] and | 7102 // In addition, if [[Extensible]] is false the value of the [[Class]] and |
7005 // [[Prototype]] internal properties of the object may not be modified. | 7103 // [[Prototype]] internal properties of the object may not be modified. |
7006 // ... | 7104 // ... |
7007 // Implementation specific extensions that modify [[Class]], [[Prototype]] | 7105 // Implementation specific extensions that modify [[Class]], [[Prototype]] |
7008 // or [[Extensible]] must not violate the invariants defined in the preceding | 7106 // or [[Extensible]] must not violate the invariants defined in the preceding |
7009 // paragraph. | 7107 // paragraph. |
7010 if (!this->map()->is_extensible()) { | 7108 if (!this->map()->is_extensible()) { |
(...skipping 10 matching lines...) Expand all Loading... | |
7021 // chain. | 7119 // chain. |
7022 for (Object* pt = value; pt != heap->null_value(); pt = pt->GetPrototype()) { | 7120 for (Object* pt = value; pt != heap->null_value(); pt = pt->GetPrototype()) { |
7023 if (JSObject::cast(pt) == this) { | 7121 if (JSObject::cast(pt) == this) { |
7024 // Cycle detected. | 7122 // Cycle detected. |
7025 HandleScope scope; | 7123 HandleScope scope; |
7026 return heap->isolate()->Throw( | 7124 return heap->isolate()->Throw( |
7027 *FACTORY->NewError("cyclic_proto", HandleVector<Object>(NULL, 0))); | 7125 *FACTORY->NewError("cyclic_proto", HandleVector<Object>(NULL, 0))); |
7028 } | 7126 } |
7029 } | 7127 } |
7030 | 7128 |
7031 JSObject* real_receiver = this; | 7129 JSReceiver* real_receiver = this; |
7032 | 7130 |
7033 if (skip_hidden_prototypes) { | 7131 if (skip_hidden_prototypes) { |
7034 // Find the first object in the chain whose prototype object is not | 7132 // Find the first object in the chain whose prototype object is not |
7035 // hidden and set the new prototype on that object. | 7133 // hidden and set the new prototype on that object. |
7036 Object* current_proto = real_receiver->GetPrototype(); | 7134 Object* current_proto = real_receiver->GetPrototype(); |
7037 while (current_proto->IsJSObject() && | 7135 while (current_proto->IsJSObject() && |
7038 JSObject::cast(current_proto)->map()->is_hidden_prototype()) { | 7136 JSObject::cast(current_proto)->map()->is_hidden_prototype()) { |
7039 real_receiver = JSObject::cast(current_proto); | 7137 real_receiver = JSObject::cast(current_proto); |
7040 current_proto = current_proto->GetPrototype(); | 7138 current_proto = current_proto->GetPrototype(); |
7041 } | 7139 } |
(...skipping 20 matching lines...) Expand all Loading... | |
7062 } | 7160 } |
7063 ASSERT(Map::cast(new_map)->prototype() == value); | 7161 ASSERT(Map::cast(new_map)->prototype() == value); |
7064 real_receiver->set_map(Map::cast(new_map)); | 7162 real_receiver->set_map(Map::cast(new_map)); |
7065 | 7163 |
7066 heap->ClearInstanceofCache(); | 7164 heap->ClearInstanceofCache(); |
7067 | 7165 |
7068 return value; | 7166 return value; |
7069 } | 7167 } |
7070 | 7168 |
7071 | 7169 |
7072 bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) { | 7170 bool JSObject::HasElementPostInterceptor(JSReceiver* receiver, uint32_t index) { |
7073 switch (GetElementsKind()) { | 7171 switch (GetElementsKind()) { |
7074 case FAST_ELEMENTS: { | 7172 case FAST_ELEMENTS: { |
7075 uint32_t length = IsJSArray() ? | 7173 uint32_t length = IsJSArray() ? |
7076 static_cast<uint32_t> | 7174 static_cast<uint32_t> |
7077 (Smi::cast(JSArray::cast(this)->length())->value()) : | 7175 (Smi::cast(JSArray::cast(this)->length())->value()) : |
7078 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 7176 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
7079 if ((index < length) && | 7177 if ((index < length) && |
7080 !FixedArray::cast(elements())->get(index)->IsTheHole()) { | 7178 !FixedArray::cast(elements())->get(index)->IsTheHole()) { |
7081 return true; | 7179 return true; |
7082 } | 7180 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7117 | 7215 |
7118 // Handle [] on String objects. | 7216 // Handle [] on String objects. |
7119 if (this->IsStringObjectWithCharacterAt(index)) return true; | 7217 if (this->IsStringObjectWithCharacterAt(index)) return true; |
7120 | 7218 |
7121 Object* pt = GetPrototype(); | 7219 Object* pt = GetPrototype(); |
7122 if (pt->IsNull()) return false; | 7220 if (pt->IsNull()) return false; |
7123 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); | 7221 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); |
7124 } | 7222 } |
7125 | 7223 |
7126 | 7224 |
7127 bool JSObject::HasElementWithInterceptor(JSObject* receiver, uint32_t index) { | 7225 bool JSObject::HasElementWithInterceptor(JSReceiver* receiver, uint32_t index) { |
7128 Isolate* isolate = GetIsolate(); | 7226 Isolate* isolate = GetIsolate(); |
7129 // Make sure that the top context does not change when doing | 7227 // Make sure that the top context does not change when doing |
7130 // callbacks or interceptor calls. | 7228 // callbacks or interceptor calls. |
7131 AssertNoContextChange ncc; | 7229 AssertNoContextChange ncc; |
7132 HandleScope scope(isolate); | 7230 HandleScope scope(isolate); |
7133 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 7231 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
7134 Handle<JSObject> receiver_handle(receiver); | 7232 Handle<JSReceiver> receiver_handle(receiver); |
7135 Handle<JSObject> holder_handle(this); | 7233 Handle<JSObject> holder_handle(this); |
7136 CustomArguments args(isolate, interceptor->data(), receiver, this); | 7234 CustomArguments args(isolate, interceptor->data(), receiver, this); |
7137 v8::AccessorInfo info(args.end()); | 7235 v8::AccessorInfo info(args.end()); |
7138 if (!interceptor->query()->IsUndefined()) { | 7236 if (!interceptor->query()->IsUndefined()) { |
7139 v8::IndexedPropertyQuery query = | 7237 v8::IndexedPropertyQuery query = |
7140 v8::ToCData<v8::IndexedPropertyQuery>(interceptor->query()); | 7238 v8::ToCData<v8::IndexedPropertyQuery>(interceptor->query()); |
7141 LOG(isolate, | 7239 LOG(isolate, |
7142 ApiIndexedPropertyAccess("interceptor-indexed-has", this, index)); | 7240 ApiIndexedPropertyAccess("interceptor-indexed-has", this, index)); |
7143 v8::Handle<v8::Integer> result; | 7241 v8::Handle<v8::Integer> result; |
7144 { | 7242 { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7233 } | 7331 } |
7234 default: | 7332 default: |
7235 UNREACHABLE(); | 7333 UNREACHABLE(); |
7236 break; | 7334 break; |
7237 } | 7335 } |
7238 | 7336 |
7239 return UNDEFINED_ELEMENT; | 7337 return UNDEFINED_ELEMENT; |
7240 } | 7338 } |
7241 | 7339 |
7242 | 7340 |
7243 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) { | 7341 bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) { |
7244 // Check access rights if needed. | 7342 // Check access rights if needed. |
7245 if (IsAccessCheckNeeded()) { | 7343 if (IsAccessCheckNeeded()) { |
7246 Heap* heap = GetHeap(); | 7344 Heap* heap = GetHeap(); |
7247 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { | 7345 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { |
7248 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 7346 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
7249 return false; | 7347 return false; |
7250 } | 7348 } |
7251 } | 7349 } |
7252 | 7350 |
7253 // Check for lookup interceptor | 7351 // Check for lookup interceptor |
(...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8103 ASSERT(map()->has_indexed_interceptor()); | 8201 ASSERT(map()->has_indexed_interceptor()); |
8104 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 8202 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
8105 ASSERT(constructor->shared()->IsApiFunction()); | 8203 ASSERT(constructor->shared()->IsApiFunction()); |
8106 Object* result = | 8204 Object* result = |
8107 constructor->shared()->get_api_func_data()->indexed_property_handler(); | 8205 constructor->shared()->get_api_func_data()->indexed_property_handler(); |
8108 return InterceptorInfo::cast(result); | 8206 return InterceptorInfo::cast(result); |
8109 } | 8207 } |
8110 | 8208 |
8111 | 8209 |
8112 MaybeObject* JSObject::GetPropertyPostInterceptor( | 8210 MaybeObject* JSObject::GetPropertyPostInterceptor( |
8113 JSObject* receiver, | 8211 JSReceiver* receiver, |
8114 String* name, | 8212 String* name, |
8115 PropertyAttributes* attributes) { | 8213 PropertyAttributes* attributes) { |
8116 // Check local property in holder, ignore interceptor. | 8214 // Check local property in holder, ignore interceptor. |
8117 LookupResult result; | 8215 LookupResult result; |
8118 LocalLookupRealNamedProperty(name, &result); | 8216 LocalLookupRealNamedProperty(name, &result); |
8119 if (result.IsProperty()) { | 8217 if (result.IsProperty()) { |
8120 return GetProperty(receiver, &result, name, attributes); | 8218 return GetProperty(receiver, &result, name, attributes); |
8121 } | 8219 } |
8122 // Continue searching via the prototype chain. | 8220 // Continue searching via the prototype chain. |
8123 Object* pt = GetPrototype(); | 8221 Object* pt = GetPrototype(); |
8124 *attributes = ABSENT; | 8222 *attributes = ABSENT; |
8125 if (pt->IsNull()) return GetHeap()->undefined_value(); | 8223 if (pt->IsNull()) return GetHeap()->undefined_value(); |
8126 return pt->GetPropertyWithReceiver(receiver, name, attributes); | 8224 return pt->GetPropertyWithReceiver(receiver, name, attributes); |
8127 } | 8225 } |
8128 | 8226 |
8129 | 8227 |
8130 MaybeObject* JSObject::GetLocalPropertyPostInterceptor( | 8228 MaybeObject* JSObject::GetLocalPropertyPostInterceptor( |
8131 JSObject* receiver, | 8229 JSReceiver* receiver, |
8132 String* name, | 8230 String* name, |
8133 PropertyAttributes* attributes) { | 8231 PropertyAttributes* attributes) { |
8134 // Check local property in holder, ignore interceptor. | 8232 // Check local property in holder, ignore interceptor. |
8135 LookupResult result; | 8233 LookupResult result; |
8136 LocalLookupRealNamedProperty(name, &result); | 8234 LocalLookupRealNamedProperty(name, &result); |
8137 if (result.IsProperty()) { | 8235 if (result.IsProperty()) { |
8138 return GetProperty(receiver, &result, name, attributes); | 8236 return GetProperty(receiver, &result, name, attributes); |
8139 } | 8237 } |
8140 return GetHeap()->undefined_value(); | 8238 return GetHeap()->undefined_value(); |
8141 } | 8239 } |
8142 | 8240 |
8143 | 8241 |
8144 MaybeObject* JSObject::GetPropertyWithInterceptor( | 8242 MaybeObject* JSObject::GetPropertyWithInterceptor( |
8145 JSObject* receiver, | 8243 JSReceiver* receiver, |
8146 String* name, | 8244 String* name, |
8147 PropertyAttributes* attributes) { | 8245 PropertyAttributes* attributes) { |
8148 Isolate* isolate = GetIsolate(); | 8246 Isolate* isolate = GetIsolate(); |
8149 InterceptorInfo* interceptor = GetNamedInterceptor(); | 8247 InterceptorInfo* interceptor = GetNamedInterceptor(); |
8150 HandleScope scope(isolate); | 8248 HandleScope scope(isolate); |
8151 Handle<JSObject> receiver_handle(receiver); | 8249 Handle<JSReceiver> receiver_handle(receiver); |
8152 Handle<JSObject> holder_handle(this); | 8250 Handle<JSObject> holder_handle(this); |
8153 Handle<String> name_handle(name); | 8251 Handle<String> name_handle(name); |
8154 | 8252 |
8155 if (!interceptor->getter()->IsUndefined()) { | 8253 if (!interceptor->getter()->IsUndefined()) { |
8156 v8::NamedPropertyGetter getter = | 8254 v8::NamedPropertyGetter getter = |
8157 v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter()); | 8255 v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter()); |
8158 LOG(isolate, | 8256 LOG(isolate, |
8159 ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name)); | 8257 ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name)); |
8160 CustomArguments args(isolate, interceptor->data(), receiver, this); | 8258 CustomArguments args(isolate, interceptor->data(), receiver, this); |
8161 v8::AccessorInfo info(args.end()); | 8259 v8::AccessorInfo info(args.end()); |
(...skipping 2329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10491 if (break_point_objects()->IsUndefined()) return 0; | 10589 if (break_point_objects()->IsUndefined()) return 0; |
10492 // Single beak point. | 10590 // Single beak point. |
10493 if (!break_point_objects()->IsFixedArray()) return 1; | 10591 if (!break_point_objects()->IsFixedArray()) return 1; |
10494 // Multiple break points. | 10592 // Multiple break points. |
10495 return FixedArray::cast(break_point_objects())->length(); | 10593 return FixedArray::cast(break_point_objects())->length(); |
10496 } | 10594 } |
10497 #endif | 10595 #endif |
10498 | 10596 |
10499 | 10597 |
10500 } } // namespace v8::internal | 10598 } } // namespace v8::internal |
OLD | NEW |