Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/objects.cc

Issue 6992072: Implement set trap for proxies, and revamp class hierarchy in preparation (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address review. Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698