Chromium Code Reviews| 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 |