| 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(); |
| 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 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2132 } | 2133 } |
| 2133 | 2134 |
| 2134 HandleScope scope; | 2135 HandleScope scope; |
| 2135 Handle<Object> value_handle(value); | 2136 Handle<Object> value_handle(value); |
| 2136 Heap* heap = GetHeap(); | 2137 Heap* heap = GetHeap(); |
| 2137 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 2138 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 2138 return *value_handle; | 2139 return *value_handle; |
| 2139 } | 2140 } |
| 2140 | 2141 |
| 2141 | 2142 |
| 2142 MaybeObject* JSObject::SetProperty(LookupResult* result, | 2143 MaybeObject* JSReceiver::SetProperty(LookupResult* result, |
| 2144 String* key, |
| 2145 Object* value, |
| 2146 PropertyAttributes attributes, |
| 2147 StrictModeFlag strict_mode) { |
| 2148 if (result->IsFound() && result->type() == HANDLER) { |
| 2149 return JSProxy::cast(this)->SetPropertyWithHandler( |
| 2150 key, value, attributes, strict_mode); |
| 2151 } else { |
| 2152 return JSObject::cast(this)->SetPropertyForResult( |
| 2153 result, key, value, attributes, strict_mode); |
| 2154 } |
| 2155 } |
| 2156 |
| 2157 |
| 2158 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler( |
| 2159 String* name_raw, |
| 2160 Object* value_raw, |
| 2161 PropertyAttributes attributes, |
| 2162 StrictModeFlag strict_mode) { |
| 2163 Isolate* isolate = GetIsolate(); |
| 2164 HandleScope scope; |
| 2165 Handle<Object> receiver(this); |
| 2166 Handle<Object> name(name_raw); |
| 2167 Handle<Object> value(value_raw); |
| 2168 Handle<Object> handler(this->handler()); |
| 2169 |
| 2170 // Extract trap function. |
| 2171 Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("set"); |
| 2172 Handle<Object> trap(v8::internal::GetProperty(handler, trap_name)); |
| 2173 if (trap->IsUndefined()) { |
| 2174 trap = isolate->derived_set_trap(); |
| 2175 } |
| 2176 |
| 2177 // Call trap function. |
| 2178 Object** args[] = { |
| 2179 receiver.location(), name.location(), value.location() |
| 2180 }; |
| 2181 bool has_exception; |
| 2182 Handle<Object> result = |
| 2183 Execution::Call(trap, handler, ARRAY_SIZE(args), args, &has_exception); |
| 2184 if (has_exception) return Failure::Exception(); |
| 2185 |
| 2186 return value_raw; |
| 2187 } |
| 2188 |
| 2189 |
| 2190 MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler( |
| 2191 JSReceiver* receiver_raw, |
| 2192 String* name_raw, |
| 2193 bool* has_exception) { |
| 2194 Isolate* isolate = GetIsolate(); |
| 2195 HandleScope scope; |
| 2196 Handle<JSReceiver> receiver(receiver_raw); |
| 2197 Handle<Object> name(name_raw); |
| 2198 Handle<Object> handler(this->handler()); |
| 2199 |
| 2200 // Extract trap function. |
| 2201 Handle<String> trap_name = |
| 2202 isolate->factory()->LookupAsciiSymbol("getPropertyDescriptor"); |
| 2203 Handle<Object> trap(v8::internal::GetProperty(handler, trap_name)); |
| 2204 if (trap->IsUndefined()) { |
| 2205 Handle<Object> args[] = { handler, trap_name }; |
| 2206 Handle<Object> error = isolate->factory()->NewTypeError( |
| 2207 "handler_trap_missing", HandleVector(args, ARRAY_SIZE(args))); |
| 2208 isolate->Throw(*error); |
| 2209 *has_exception = true; |
| 2210 return NONE; |
| 2211 } |
| 2212 |
| 2213 // Call trap function. |
| 2214 Object** args[] = { name.location() }; |
| 2215 Handle<Object> result = |
| 2216 Execution::Call(trap, handler, ARRAY_SIZE(args), args, has_exception); |
| 2217 if (has_exception) return NONE; |
| 2218 |
| 2219 // TODO(rossberg): convert result to PropertyAttributes |
| 2220 USE(result); |
| 2221 return NONE; |
| 2222 } |
| 2223 |
| 2224 |
| 2225 MaybeObject* JSObject::SetPropertyForResult(LookupResult* result, |
| 2143 String* name, | 2226 String* name, |
| 2144 Object* value, | 2227 Object* value, |
| 2145 PropertyAttributes attributes, | 2228 PropertyAttributes attributes, |
| 2146 StrictModeFlag strict_mode) { | 2229 StrictModeFlag strict_mode) { |
| 2147 Heap* heap = GetHeap(); | 2230 Heap* heap = GetHeap(); |
| 2148 // Make sure that the top context does not change when doing callbacks or | 2231 // Make sure that the top context does not change when doing callbacks or |
| 2149 // interceptor calls. | 2232 // interceptor calls. |
| 2150 AssertNoContextChange ncc; | 2233 AssertNoContextChange ncc; |
| 2151 | 2234 |
| 2152 // Optimization for 2-byte strings often used as keys in a decompression | 2235 // Optimization for 2-byte strings often used as keys in a decompression |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2417 result = getter(v8::Utils::ToLocal(name_handle), info); | 2500 result = getter(v8::Utils::ToLocal(name_handle), info); |
| 2418 } | 2501 } |
| 2419 if (!result.IsEmpty()) return DONT_ENUM; | 2502 if (!result.IsEmpty()) return DONT_ENUM; |
| 2420 } | 2503 } |
| 2421 return holder_handle->GetPropertyAttributePostInterceptor(*receiver_handle, | 2504 return holder_handle->GetPropertyAttributePostInterceptor(*receiver_handle, |
| 2422 *name_handle, | 2505 *name_handle, |
| 2423 continue_search); | 2506 continue_search); |
| 2424 } | 2507 } |
| 2425 | 2508 |
| 2426 | 2509 |
| 2427 PropertyAttributes JSObject::GetPropertyAttributeWithReceiver( | 2510 PropertyAttributes JSReceiver::GetPropertyAttributeWithReceiver( |
| 2428 JSObject* receiver, | 2511 JSReceiver* receiver, |
| 2429 String* key) { | 2512 String* key) { |
| 2430 uint32_t index = 0; | 2513 uint32_t index = 0; |
| 2431 if (key->AsArrayIndex(&index)) { | 2514 if (IsJSObject() && key->AsArrayIndex(&index)) { |
| 2432 if (HasElementWithReceiver(receiver, index)) return NONE; | 2515 if (JSObject::cast(this)->HasElementWithReceiver(receiver, index)) |
| 2516 return NONE; |
| 2433 return ABSENT; | 2517 return ABSENT; |
| 2434 } | 2518 } |
| 2435 // Named property. | 2519 // Named property. |
| 2436 LookupResult result; | 2520 LookupResult result; |
| 2437 Lookup(key, &result); | 2521 Lookup(key, &result); |
| 2438 return GetPropertyAttribute(receiver, &result, key, true); | 2522 return GetPropertyAttribute(receiver, &result, key, true); |
| 2439 } | 2523 } |
| 2440 | 2524 |
| 2441 | 2525 |
| 2442 PropertyAttributes JSObject::GetPropertyAttribute(JSObject* receiver, | 2526 PropertyAttributes JSReceiver::GetPropertyAttribute(JSReceiver* receiver, |
| 2443 LookupResult* result, | 2527 LookupResult* result, |
| 2444 String* name, | 2528 String* name, |
| 2445 bool continue_search) { | 2529 bool continue_search) { |
| 2446 // Check access rights if needed. | 2530 // Check access rights if needed. |
| 2447 if (IsAccessCheckNeeded()) { | 2531 if (IsAccessCheckNeeded()) { |
| 2532 JSObject* this_obj = JSObject::cast(this); |
| 2448 Heap* heap = GetHeap(); | 2533 Heap* heap = GetHeap(); |
| 2449 if (!heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) { | 2534 if (!heap->isolate()->MayNamedAccess(this_obj, name, v8::ACCESS_HAS)) { |
| 2450 return GetPropertyAttributeWithFailedAccessCheck(receiver, | 2535 return this_obj->GetPropertyAttributeWithFailedAccessCheck( |
| 2451 result, | 2536 receiver, result, name, continue_search); |
| 2452 name, | |
| 2453 continue_search); | |
| 2454 } | 2537 } |
| 2455 } | 2538 } |
| 2456 if (result->IsProperty()) { | 2539 if (result->IsProperty()) { |
| 2457 switch (result->type()) { | 2540 switch (result->type()) { |
| 2458 case NORMAL: // fall through | 2541 case NORMAL: // fall through |
| 2459 case FIELD: | 2542 case FIELD: |
| 2460 case CONSTANT_FUNCTION: | 2543 case CONSTANT_FUNCTION: |
| 2461 case CALLBACKS: | 2544 case CALLBACKS: |
| 2462 return result->GetAttributes(); | 2545 return result->GetAttributes(); |
| 2546 case HANDLER: { |
| 2547 // TODO(rossberg): propagate exceptions properly. |
| 2548 bool has_exception = false; |
| 2549 return JSProxy::cast(this)->GetPropertyAttributeWithHandler( |
| 2550 receiver, name, &has_exception); |
| 2551 } |
| 2463 case INTERCEPTOR: | 2552 case INTERCEPTOR: |
| 2464 return result->holder()-> | 2553 return result->holder()->GetPropertyAttributeWithInterceptor( |
| 2465 GetPropertyAttributeWithInterceptor(receiver, name, continue_search); | 2554 JSObject::cast(receiver), name, continue_search); |
| 2466 default: | 2555 default: |
| 2467 UNREACHABLE(); | 2556 UNREACHABLE(); |
| 2468 } | 2557 } |
| 2469 } | 2558 } |
| 2470 return ABSENT; | 2559 return ABSENT; |
| 2471 } | 2560 } |
| 2472 | 2561 |
| 2473 | 2562 |
| 2474 PropertyAttributes JSObject::GetLocalPropertyAttribute(String* name) { | 2563 PropertyAttributes JSReceiver::GetLocalPropertyAttribute(String* name) { |
| 2475 // Check whether the name is an array index. | 2564 // Check whether the name is an array index. |
| 2476 uint32_t index = 0; | 2565 uint32_t index = 0; |
| 2477 if (name->AsArrayIndex(&index)) { | 2566 if (IsJSObject() && name->AsArrayIndex(&index)) { |
| 2478 if (HasLocalElement(index)) return NONE; | 2567 if (JSObject::cast(this)->HasLocalElement(index)) return NONE; |
| 2479 return ABSENT; | 2568 return ABSENT; |
| 2480 } | 2569 } |
| 2481 // Named property. | 2570 // Named property. |
| 2482 LookupResult result; | 2571 LookupResult result; |
| 2483 LocalLookup(name, &result); | 2572 LocalLookup(name, &result); |
| 2484 return GetPropertyAttribute(this, &result, name, false); | 2573 return GetPropertyAttribute(this, &result, name, false); |
| 2485 } | 2574 } |
| 2486 | 2575 |
| 2487 | 2576 |
| 2488 MaybeObject* NormalizedMapCache::Get(JSObject* obj, | 2577 MaybeObject* NormalizedMapCache::Get(JSObject* obj, |
| (...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3221 DescriptorArray* descs = instance_descriptors(); | 3310 DescriptorArray* descs = instance_descriptors(); |
| 3222 for (int i = 0; i < descs->number_of_descriptors(); i++) { | 3311 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
| 3223 if (name->Equals(descs->GetKey(i)) && descs->GetType(i) == CALLBACKS) { | 3312 if (name->Equals(descs->GetKey(i)) && descs->GetType(i) == CALLBACKS) { |
| 3224 return descs->GetCallbacks(i); | 3313 return descs->GetCallbacks(i); |
| 3225 } | 3314 } |
| 3226 } | 3315 } |
| 3227 return NULL; | 3316 return NULL; |
| 3228 } | 3317 } |
| 3229 | 3318 |
| 3230 | 3319 |
| 3320 void JSReceiver::LocalLookup(String* name, LookupResult* result) { |
| 3321 if (IsJSProxy()) { |
| 3322 result->HandlerResult(); |
| 3323 } else { |
| 3324 JSObject::cast(this)->LocalLookup(name, result); |
| 3325 } |
| 3326 } |
| 3327 |
| 3328 |
| 3231 void JSObject::LocalLookup(String* name, LookupResult* result) { | 3329 void JSObject::LocalLookup(String* name, LookupResult* result) { |
| 3232 ASSERT(name->IsString()); | 3330 ASSERT(name->IsString()); |
| 3233 | 3331 |
| 3234 Heap* heap = GetHeap(); | 3332 Heap* heap = GetHeap(); |
| 3235 | 3333 |
| 3236 if (IsJSGlobalProxy()) { | 3334 if (IsJSGlobalProxy()) { |
| 3237 Object* proto = GetPrototype(); | 3335 Object* proto = GetPrototype(); |
| 3238 if (proto->IsNull()) return result->NotFound(); | 3336 if (proto->IsNull()) return result->NotFound(); |
| 3239 ASSERT(proto->IsJSGlobalObject()); | 3337 ASSERT(proto->IsJSGlobalObject()); |
| 3240 return JSObject::cast(proto)->LocalLookup(name, result); | 3338 return JSObject::cast(proto)->LocalLookup(name, result); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3256 // Check for lookup interceptor except when bootstrapping. | 3354 // Check for lookup interceptor except when bootstrapping. |
| 3257 if (HasNamedInterceptor() && !heap->isolate()->bootstrapper()->IsActive()) { | 3355 if (HasNamedInterceptor() && !heap->isolate()->bootstrapper()->IsActive()) { |
| 3258 result->InterceptorResult(this); | 3356 result->InterceptorResult(this); |
| 3259 return; | 3357 return; |
| 3260 } | 3358 } |
| 3261 | 3359 |
| 3262 LocalLookupRealNamedProperty(name, result); | 3360 LocalLookupRealNamedProperty(name, result); |
| 3263 } | 3361 } |
| 3264 | 3362 |
| 3265 | 3363 |
| 3266 void JSObject::Lookup(String* name, LookupResult* result) { | 3364 void JSReceiver::Lookup(String* name, LookupResult* result) { |
| 3267 // Ecma-262 3rd 8.6.2.4 | 3365 // Ecma-262 3rd 8.6.2.4 |
| 3268 Heap* heap = GetHeap(); | 3366 Heap* heap = GetHeap(); |
| 3269 for (Object* current = this; | 3367 for (Object* current = this; |
| 3270 current != heap->null_value(); | 3368 current != heap->null_value(); |
| 3271 current = JSObject::cast(current)->GetPrototype()) { | 3369 current = JSObject::cast(current)->GetPrototype()) { |
| 3272 JSObject::cast(current)->LocalLookup(name, result); | 3370 JSObject::cast(current)->LocalLookup(name, result); |
| 3273 if (result->IsProperty()) return; | 3371 if (result->IsProperty()) return; |
| 3274 } | 3372 } |
| 3275 result->NotFound(); | 3373 result->NotFound(); |
| 3276 } | 3374 } |
| (...skipping 3742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7019 } | 7117 } |
| 7020 | 7118 |
| 7021 cache->set(finger, prototype); | 7119 cache->set(finger, prototype); |
| 7022 cache->set(finger + 1, map); | 7120 cache->set(finger + 1, map); |
| 7023 cache->set(0, Smi::FromInt(finger + 2)); | 7121 cache->set(0, Smi::FromInt(finger + 2)); |
| 7024 | 7122 |
| 7025 return cache; | 7123 return cache; |
| 7026 } | 7124 } |
| 7027 | 7125 |
| 7028 | 7126 |
| 7029 MaybeObject* JSObject::SetPrototype(Object* value, | 7127 MaybeObject* JSReceiver::SetPrototype(Object* value, |
| 7030 bool skip_hidden_prototypes) { | 7128 bool skip_hidden_prototypes) { |
| 7031 Heap* heap = GetHeap(); | 7129 Heap* heap = GetHeap(); |
| 7032 // Silently ignore the change if value is not a JSObject or null. | 7130 // Silently ignore the change if value is not a JSObject or null. |
| 7033 // SpiderMonkey behaves this way. | 7131 // SpiderMonkey behaves this way. |
| 7034 if (!value->IsJSObject() && !value->IsNull()) return value; | 7132 if (!value->IsJSReceiver() && !value->IsNull()) return value; |
| 7035 | 7133 |
| 7036 // From 8.6.2 Object Internal Methods | 7134 // From 8.6.2 Object Internal Methods |
| 7037 // ... | 7135 // ... |
| 7038 // In addition, if [[Extensible]] is false the value of the [[Class]] and | 7136 // In addition, if [[Extensible]] is false the value of the [[Class]] and |
| 7039 // [[Prototype]] internal properties of the object may not be modified. | 7137 // [[Prototype]] internal properties of the object may not be modified. |
| 7040 // ... | 7138 // ... |
| 7041 // Implementation specific extensions that modify [[Class]], [[Prototype]] | 7139 // Implementation specific extensions that modify [[Class]], [[Prototype]] |
| 7042 // or [[Extensible]] must not violate the invariants defined in the preceding | 7140 // or [[Extensible]] must not violate the invariants defined in the preceding |
| 7043 // paragraph. | 7141 // paragraph. |
| 7044 if (!this->map()->is_extensible()) { | 7142 if (!this->map()->is_extensible()) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 7055 // chain. | 7153 // chain. |
| 7056 for (Object* pt = value; pt != heap->null_value(); pt = pt->GetPrototype()) { | 7154 for (Object* pt = value; pt != heap->null_value(); pt = pt->GetPrototype()) { |
| 7057 if (JSObject::cast(pt) == this) { | 7155 if (JSObject::cast(pt) == this) { |
| 7058 // Cycle detected. | 7156 // Cycle detected. |
| 7059 HandleScope scope; | 7157 HandleScope scope; |
| 7060 return heap->isolate()->Throw( | 7158 return heap->isolate()->Throw( |
| 7061 *FACTORY->NewError("cyclic_proto", HandleVector<Object>(NULL, 0))); | 7159 *FACTORY->NewError("cyclic_proto", HandleVector<Object>(NULL, 0))); |
| 7062 } | 7160 } |
| 7063 } | 7161 } |
| 7064 | 7162 |
| 7065 JSObject* real_receiver = this; | 7163 JSReceiver* real_receiver = this; |
| 7066 | 7164 |
| 7067 if (skip_hidden_prototypes) { | 7165 if (skip_hidden_prototypes) { |
| 7068 // Find the first object in the chain whose prototype object is not | 7166 // Find the first object in the chain whose prototype object is not |
| 7069 // hidden and set the new prototype on that object. | 7167 // hidden and set the new prototype on that object. |
| 7070 Object* current_proto = real_receiver->GetPrototype(); | 7168 Object* current_proto = real_receiver->GetPrototype(); |
| 7071 while (current_proto->IsJSObject() && | 7169 while (current_proto->IsJSObject() && |
| 7072 JSObject::cast(current_proto)->map()->is_hidden_prototype()) { | 7170 JSObject::cast(current_proto)->map()->is_hidden_prototype()) { |
| 7073 real_receiver = JSObject::cast(current_proto); | 7171 real_receiver = JSObject::cast(current_proto); |
| 7074 current_proto = current_proto->GetPrototype(); | 7172 current_proto = current_proto->GetPrototype(); |
| 7075 } | 7173 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 7096 } | 7194 } |
| 7097 ASSERT(Map::cast(new_map)->prototype() == value); | 7195 ASSERT(Map::cast(new_map)->prototype() == value); |
| 7098 real_receiver->set_map(Map::cast(new_map)); | 7196 real_receiver->set_map(Map::cast(new_map)); |
| 7099 | 7197 |
| 7100 heap->ClearInstanceofCache(); | 7198 heap->ClearInstanceofCache(); |
| 7101 | 7199 |
| 7102 return value; | 7200 return value; |
| 7103 } | 7201 } |
| 7104 | 7202 |
| 7105 | 7203 |
| 7106 bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) { | 7204 bool JSObject::HasElementPostInterceptor(JSReceiver* receiver, uint32_t index) { |
| 7107 switch (GetElementsKind()) { | 7205 switch (GetElementsKind()) { |
| 7108 case FAST_ELEMENTS: { | 7206 case FAST_ELEMENTS: { |
| 7109 uint32_t length = IsJSArray() ? | 7207 uint32_t length = IsJSArray() ? |
| 7110 static_cast<uint32_t> | 7208 static_cast<uint32_t> |
| 7111 (Smi::cast(JSArray::cast(this)->length())->value()) : | 7209 (Smi::cast(JSArray::cast(this)->length())->value()) : |
| 7112 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 7210 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
| 7113 if ((index < length) && | 7211 if ((index < length) && |
| 7114 !FixedArray::cast(elements())->get(index)->IsTheHole()) { | 7212 !FixedArray::cast(elements())->get(index)->IsTheHole()) { |
| 7115 return true; | 7213 return true; |
| 7116 } | 7214 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7151 | 7249 |
| 7152 // Handle [] on String objects. | 7250 // Handle [] on String objects. |
| 7153 if (this->IsStringObjectWithCharacterAt(index)) return true; | 7251 if (this->IsStringObjectWithCharacterAt(index)) return true; |
| 7154 | 7252 |
| 7155 Object* pt = GetPrototype(); | 7253 Object* pt = GetPrototype(); |
| 7156 if (pt->IsNull()) return false; | 7254 if (pt->IsNull()) return false; |
| 7157 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); | 7255 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); |
| 7158 } | 7256 } |
| 7159 | 7257 |
| 7160 | 7258 |
| 7161 bool JSObject::HasElementWithInterceptor(JSObject* receiver, uint32_t index) { | 7259 bool JSObject::HasElementWithInterceptor(JSReceiver* receiver, uint32_t index) { |
| 7162 Isolate* isolate = GetIsolate(); | 7260 Isolate* isolate = GetIsolate(); |
| 7163 // Make sure that the top context does not change when doing | 7261 // Make sure that the top context does not change when doing |
| 7164 // callbacks or interceptor calls. | 7262 // callbacks or interceptor calls. |
| 7165 AssertNoContextChange ncc; | 7263 AssertNoContextChange ncc; |
| 7166 HandleScope scope(isolate); | 7264 HandleScope scope(isolate); |
| 7167 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 7265 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
| 7168 Handle<JSObject> receiver_handle(receiver); | 7266 Handle<JSReceiver> receiver_handle(receiver); |
| 7169 Handle<JSObject> holder_handle(this); | 7267 Handle<JSObject> holder_handle(this); |
| 7170 CustomArguments args(isolate, interceptor->data(), receiver, this); | 7268 CustomArguments args(isolate, interceptor->data(), receiver, this); |
| 7171 v8::AccessorInfo info(args.end()); | 7269 v8::AccessorInfo info(args.end()); |
| 7172 if (!interceptor->query()->IsUndefined()) { | 7270 if (!interceptor->query()->IsUndefined()) { |
| 7173 v8::IndexedPropertyQuery query = | 7271 v8::IndexedPropertyQuery query = |
| 7174 v8::ToCData<v8::IndexedPropertyQuery>(interceptor->query()); | 7272 v8::ToCData<v8::IndexedPropertyQuery>(interceptor->query()); |
| 7175 LOG(isolate, | 7273 LOG(isolate, |
| 7176 ApiIndexedPropertyAccess("interceptor-indexed-has", this, index)); | 7274 ApiIndexedPropertyAccess("interceptor-indexed-has", this, index)); |
| 7177 v8::Handle<v8::Integer> result; | 7275 v8::Handle<v8::Integer> result; |
| 7178 { | 7276 { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7267 } | 7365 } |
| 7268 default: | 7366 default: |
| 7269 UNREACHABLE(); | 7367 UNREACHABLE(); |
| 7270 break; | 7368 break; |
| 7271 } | 7369 } |
| 7272 | 7370 |
| 7273 return UNDEFINED_ELEMENT; | 7371 return UNDEFINED_ELEMENT; |
| 7274 } | 7372 } |
| 7275 | 7373 |
| 7276 | 7374 |
| 7277 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) { | 7375 bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) { |
| 7278 // Check access rights if needed. | 7376 // Check access rights if needed. |
| 7279 if (IsAccessCheckNeeded()) { | 7377 if (IsAccessCheckNeeded()) { |
| 7280 Heap* heap = GetHeap(); | 7378 Heap* heap = GetHeap(); |
| 7281 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { | 7379 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { |
| 7282 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 7380 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 7283 return false; | 7381 return false; |
| 7284 } | 7382 } |
| 7285 } | 7383 } |
| 7286 | 7384 |
| 7287 // Check for lookup interceptor | 7385 // Check for lookup interceptor |
| (...skipping 862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8150 ASSERT(map()->has_indexed_interceptor()); | 8248 ASSERT(map()->has_indexed_interceptor()); |
| 8151 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 8249 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
| 8152 ASSERT(constructor->shared()->IsApiFunction()); | 8250 ASSERT(constructor->shared()->IsApiFunction()); |
| 8153 Object* result = | 8251 Object* result = |
| 8154 constructor->shared()->get_api_func_data()->indexed_property_handler(); | 8252 constructor->shared()->get_api_func_data()->indexed_property_handler(); |
| 8155 return InterceptorInfo::cast(result); | 8253 return InterceptorInfo::cast(result); |
| 8156 } | 8254 } |
| 8157 | 8255 |
| 8158 | 8256 |
| 8159 MaybeObject* JSObject::GetPropertyPostInterceptor( | 8257 MaybeObject* JSObject::GetPropertyPostInterceptor( |
| 8160 JSObject* receiver, | 8258 JSReceiver* receiver, |
| 8161 String* name, | 8259 String* name, |
| 8162 PropertyAttributes* attributes) { | 8260 PropertyAttributes* attributes) { |
| 8163 // Check local property in holder, ignore interceptor. | 8261 // Check local property in holder, ignore interceptor. |
| 8164 LookupResult result; | 8262 LookupResult result; |
| 8165 LocalLookupRealNamedProperty(name, &result); | 8263 LocalLookupRealNamedProperty(name, &result); |
| 8166 if (result.IsProperty()) { | 8264 if (result.IsProperty()) { |
| 8167 return GetProperty(receiver, &result, name, attributes); | 8265 return GetProperty(receiver, &result, name, attributes); |
| 8168 } | 8266 } |
| 8169 // Continue searching via the prototype chain. | 8267 // Continue searching via the prototype chain. |
| 8170 Object* pt = GetPrototype(); | 8268 Object* pt = GetPrototype(); |
| 8171 *attributes = ABSENT; | 8269 *attributes = ABSENT; |
| 8172 if (pt->IsNull()) return GetHeap()->undefined_value(); | 8270 if (pt->IsNull()) return GetHeap()->undefined_value(); |
| 8173 return pt->GetPropertyWithReceiver(receiver, name, attributes); | 8271 return pt->GetPropertyWithReceiver(receiver, name, attributes); |
| 8174 } | 8272 } |
| 8175 | 8273 |
| 8176 | 8274 |
| 8177 MaybeObject* JSObject::GetLocalPropertyPostInterceptor( | 8275 MaybeObject* JSObject::GetLocalPropertyPostInterceptor( |
| 8178 JSObject* receiver, | 8276 JSReceiver* receiver, |
| 8179 String* name, | 8277 String* name, |
| 8180 PropertyAttributes* attributes) { | 8278 PropertyAttributes* attributes) { |
| 8181 // Check local property in holder, ignore interceptor. | 8279 // Check local property in holder, ignore interceptor. |
| 8182 LookupResult result; | 8280 LookupResult result; |
| 8183 LocalLookupRealNamedProperty(name, &result); | 8281 LocalLookupRealNamedProperty(name, &result); |
| 8184 if (result.IsProperty()) { | 8282 if (result.IsProperty()) { |
| 8185 return GetProperty(receiver, &result, name, attributes); | 8283 return GetProperty(receiver, &result, name, attributes); |
| 8186 } | 8284 } |
| 8187 return GetHeap()->undefined_value(); | 8285 return GetHeap()->undefined_value(); |
| 8188 } | 8286 } |
| 8189 | 8287 |
| 8190 | 8288 |
| 8191 MaybeObject* JSObject::GetPropertyWithInterceptor( | 8289 MaybeObject* JSObject::GetPropertyWithInterceptor( |
| 8192 JSObject* receiver, | 8290 JSReceiver* receiver, |
| 8193 String* name, | 8291 String* name, |
| 8194 PropertyAttributes* attributes) { | 8292 PropertyAttributes* attributes) { |
| 8195 Isolate* isolate = GetIsolate(); | 8293 Isolate* isolate = GetIsolate(); |
| 8196 InterceptorInfo* interceptor = GetNamedInterceptor(); | 8294 InterceptorInfo* interceptor = GetNamedInterceptor(); |
| 8197 HandleScope scope(isolate); | 8295 HandleScope scope(isolate); |
| 8198 Handle<JSObject> receiver_handle(receiver); | 8296 Handle<JSReceiver> receiver_handle(receiver); |
| 8199 Handle<JSObject> holder_handle(this); | 8297 Handle<JSObject> holder_handle(this); |
| 8200 Handle<String> name_handle(name); | 8298 Handle<String> name_handle(name); |
| 8201 | 8299 |
| 8202 if (!interceptor->getter()->IsUndefined()) { | 8300 if (!interceptor->getter()->IsUndefined()) { |
| 8203 v8::NamedPropertyGetter getter = | 8301 v8::NamedPropertyGetter getter = |
| 8204 v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter()); | 8302 v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter()); |
| 8205 LOG(isolate, | 8303 LOG(isolate, |
| 8206 ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name)); | 8304 ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name)); |
| 8207 CustomArguments args(isolate, interceptor->data(), receiver, this); | 8305 CustomArguments args(isolate, interceptor->data(), receiver, this); |
| 8208 v8::AccessorInfo info(args.end()); | 8306 v8::AccessorInfo info(args.end()); |
| (...skipping 2403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10612 if (break_point_objects()->IsUndefined()) return 0; | 10710 if (break_point_objects()->IsUndefined()) return 0; |
| 10613 // Single beak point. | 10711 // Single beak point. |
| 10614 if (!break_point_objects()->IsFixedArray()) return 1; | 10712 if (!break_point_objects()->IsFixedArray()) return 1; |
| 10615 // Multiple break points. | 10713 // Multiple break points. |
| 10616 return FixedArray::cast(break_point_objects())->length(); | 10714 return FixedArray::cast(break_point_objects())->length(); |
| 10617 } | 10715 } |
| 10618 #endif | 10716 #endif |
| 10619 | 10717 |
| 10620 | 10718 |
| 10621 } } // namespace v8::internal | 10719 } } // namespace v8::internal |
| OLD | NEW |