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 |