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

Side by Side Diff: src/objects.cc

Issue 7795055: Make integer indexed properties ("elements") work for proxies. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Oops. Created 9 years, 3 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 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 Handle<Object> result = CallTrap( 227 Handle<Object> result = CallTrap(
228 "get", isolate->derived_get_trap(), ARRAY_SIZE(args), args); 228 "get", isolate->derived_get_trap(), ARRAY_SIZE(args), args);
229 if (isolate->has_pending_exception()) return Failure::Exception(); 229 if (isolate->has_pending_exception()) return Failure::Exception();
230 230
231 return *result; 231 return *result;
232 } 232 }
233 233
234 234
235 MaybeObject* JSProxy::GetElementWithHandler(Object* receiver, 235 MaybeObject* JSProxy::GetElementWithHandler(Object* receiver,
236 uint32_t index) { 236 uint32_t index) {
237 Heap* heap = GetHeap();
238 Object* number;
239 MaybeObject* maybe = heap->NumberFromUint32(index);
240 if (!maybe->To<Object>(&number)) return maybe;
241 maybe = heap->NumberToString(number);
242 String* name; 237 String* name;
238 MaybeObject* maybe = GetHeap()->Uint32ToString(index);
243 if (!maybe->To<String>(&name)) return maybe; 239 if (!maybe->To<String>(&name)) return maybe;
244 return GetPropertyWithHandler(receiver, name); 240 return GetPropertyWithHandler(receiver, name);
245 } 241 }
246 242
247 243
244 MaybeObject* JSProxy::SetElementWithHandler(uint32_t index,
245 Object* value,
246 StrictModeFlag strict_mode) {
247 String* name;
248 MaybeObject* maybe = GetHeap()->Uint32ToString(index);
249 if (!maybe->To<String>(&name)) return maybe;
250 return SetPropertyWithHandler(name, value, NONE, strict_mode);
251 }
252
253
254 bool JSProxy::HasElementWithHandler(uint32_t index) {
255 String* name;
256 MaybeObject* maybe = GetHeap()->Uint32ToString(index);
257 if (!maybe->To<String>(&name)) return maybe;
258 return HasPropertyWithHandler(name);
259 }
260
261
248 MaybeObject* Object::GetPropertyWithDefinedGetter(Object* receiver, 262 MaybeObject* Object::GetPropertyWithDefinedGetter(Object* receiver,
249 JSFunction* getter) { 263 JSFunction* getter) {
250 HandleScope scope; 264 HandleScope scope;
251 Handle<JSFunction> fun(JSFunction::cast(getter)); 265 Handle<JSFunction> fun(JSFunction::cast(getter));
252 Handle<Object> self(receiver); 266 Handle<Object> self(receiver);
253 #ifdef ENABLE_DEBUGGER_SUPPORT 267 #ifdef ENABLE_DEBUGGER_SUPPORT
254 Debug* debug = fun->GetHeap()->isolate()->debug(); 268 Debug* debug = fun->GetHeap()->isolate()->debug();
255 // Handle stepping into a getter if step into is active. 269 // Handle stepping into a getter if step into is active.
256 if (debug->StepInActive()) { 270 if (debug->StepInActive()) {
257 debug->HandleStepIn(fun, Handle<Object>::null(), 0, false); 271 debug->HandleStepIn(fun, Handle<Object>::null(), 0, false);
(...skipping 1661 matching lines...) Expand 10 before | Expand all | Expand 10 after
1919 1933
1920 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( 1934 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes(
1921 uint32_t index, 1935 uint32_t index,
1922 Object* value, 1936 Object* value,
1923 bool* found, 1937 bool* found,
1924 StrictModeFlag strict_mode) { 1938 StrictModeFlag strict_mode) {
1925 Heap* heap = GetHeap(); 1939 Heap* heap = GetHeap();
1926 for (Object* pt = GetPrototype(); 1940 for (Object* pt = GetPrototype();
1927 pt != heap->null_value(); 1941 pt != heap->null_value();
1928 pt = pt->GetPrototype()) { 1942 pt = pt->GetPrototype()) {
1943 if (pt->IsJSProxy()) {
1944 String* name;
1945 MaybeObject* maybe = GetHeap()->Uint32ToString(index);
1946 if (!maybe->To<String>(&name)) {
1947 *found = true; // Force abort
1948 return maybe;
1949 }
1950 return JSProxy::cast(pt)->SetPropertyWithHandlerIfDefiningSetter(
1951 name, value, NONE, strict_mode, found);
1952 }
1929 if (!JSObject::cast(pt)->HasDictionaryElements()) { 1953 if (!JSObject::cast(pt)->HasDictionaryElements()) {
1930 continue; 1954 continue;
1931 } 1955 }
1932 NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary(); 1956 NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary();
1933 int entry = dictionary->FindEntry(index); 1957 int entry = dictionary->FindEntry(index);
1934 if (entry != NumberDictionary::kNotFound) { 1958 if (entry != NumberDictionary::kNotFound) {
1935 PropertyDetails details = dictionary->DetailsAt(entry); 1959 PropertyDetails details = dictionary->DetailsAt(entry);
1936 if (details.type() == CALLBACKS) { 1960 if (details.type() == CALLBACKS) {
1937 *found = true; 1961 *found = true;
1938 return SetElementWithCallback(dictionary->ValueAt(entry), 1962 return SetElementWithCallback(dictionary->ValueAt(entry),
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
2254 Handle<Object> value(value_raw); 2278 Handle<Object> value(value_raw);
2255 2279
2256 Handle<Object> args[] = { receiver, name, value }; 2280 Handle<Object> args[] = { receiver, name, value };
2257 CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args); 2281 CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args);
2258 if (isolate->has_pending_exception()) return Failure::Exception(); 2282 if (isolate->has_pending_exception()) return Failure::Exception();
2259 2283
2260 return *value; 2284 return *value;
2261 } 2285 }
2262 2286
2263 2287
2288 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandlerIfDefiningSetter(
2289 String* name_raw,
2290 Object* value_raw,
2291 PropertyAttributes attributes,
2292 StrictModeFlag strict_mode,
2293 bool* found) {
2294 *found = true; // except where defined otherwise...
2295 Isolate* isolate = GetHeap()->isolate();
2296 Handle<JSProxy> proxy(this);
2297 Handle<String> name(name_raw);
2298 Handle<Object> value(value_raw);
2299 Handle<Object> args[] = { name };
2300 Handle<Object> result = proxy->CallTrap(
2301 "getOwnPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args);
2302 if (isolate->has_pending_exception()) return Failure::Exception();
2303
2304 if (!result->IsUndefined()) {
2305 // The proxy handler cares about this property.
2306 // Check whether it is virtualized as an accessor.
2307 // Emulate [[GetProperty]] semantics for proxies.
2308 bool has_pending_exception;
2309 Object** argv[] = { result.location() };
2310 Handle<Object> desc =
2311 Execution::Call(isolate->to_complete_property_descriptor(), result,
2312 ARRAY_SIZE(argv), argv, &has_pending_exception);
2313 if (has_pending_exception) return Failure::Exception();
2314
2315 Handle<String> conf_name =
2316 isolate->factory()->LookupAsciiSymbol("configurable_");
2317 Handle<Object> configurable(v8::internal::GetProperty(desc, conf_name));
2318 ASSERT(!isolate->has_pending_exception());
2319 if (configurable->IsFalse()) {
2320 Handle<Object> args[] = { Handle<Object>(proxy->handler()), proxy, name };
2321 Handle<Object> error = isolate->factory()->NewTypeError(
2322 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args)));
2323 return isolate->Throw(*error);
2324 }
2325 ASSERT(configurable->IsTrue());
2326
2327 // Check for AccessorDescriptor.
2328 Handle<String> set_name = isolate->factory()->LookupAsciiSymbol("set_");
2329 Handle<Object> setter(v8::internal::GetProperty(desc, set_name));
2330 ASSERT(!isolate->has_pending_exception());
2331 if (!setter->IsUndefined()) {
2332 // We have a setter -- invoke it.
2333 return proxy->SetPropertyWithDefinedSetter(
2334 JSFunction::cast(*setter), *value);
2335 } else {
2336 Handle<String> get_name = isolate->factory()->LookupAsciiSymbol("get_");
2337 Handle<Object> getter(v8::internal::GetProperty(desc, get_name));
2338 ASSERT(!isolate->has_pending_exception());
2339 if (!getter->IsUndefined()) {
2340 // We have a getter but no setter -- the property may not be
2341 // written. In strict mode, throw an error.
2342 if (strict_mode == kNonStrictMode) return *value;
2343 Handle<Object> args[] = { name, proxy };
2344 Handle<Object> error = isolate->factory()->NewTypeError(
2345 "no_setter_in_callback", HandleVector(args, ARRAY_SIZE(args)));
2346 return isolate->Throw(*error);
2347 }
2348 }
2349 // Fall-through.
2350 }
2351
2352 // The proxy does not define the property as an accessor.
2353 *found = false;
2354 return *value;
2355 }
2356
2357
2264 MUST_USE_RESULT MaybeObject* JSProxy::DeletePropertyWithHandler( 2358 MUST_USE_RESULT MaybeObject* JSProxy::DeletePropertyWithHandler(
2265 String* name_raw, DeleteMode mode) { 2359 String* name_raw, DeleteMode mode) {
2266 Isolate* isolate = GetIsolate(); 2360 Isolate* isolate = GetIsolate();
2267 HandleScope scope(isolate); 2361 HandleScope scope(isolate);
2268 Handle<Object> receiver(this); 2362 Handle<Object> receiver(this);
2269 Handle<Object> name(name_raw); 2363 Handle<Object> name(name_raw);
2270 2364
2271 Handle<Object> args[] = { name }; 2365 Handle<Object> args[] = { name };
2272 Handle<Object> result = CallTrap( 2366 Handle<Object> result = CallTrap(
2273 "delete", Handle<Object>(), ARRAY_SIZE(args), args); 2367 "delete", Handle<Object>(), ARRAY_SIZE(args), args);
2274 if (isolate->has_pending_exception()) return Failure::Exception(); 2368 if (isolate->has_pending_exception()) return Failure::Exception();
2275 2369
2276 Object* bool_result = result->ToBoolean(); 2370 Object* bool_result = result->ToBoolean();
2277 if (mode == STRICT_DELETION && bool_result == GetHeap()->false_value()) { 2371 if (mode == STRICT_DELETION && bool_result == GetHeap()->false_value()) {
2278 Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("delete"); 2372 Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("delete");
2279 Handle<Object> args[] = { Handle<Object>(handler()), trap_name }; 2373 Handle<Object> args[] = { Handle<Object>(handler()), trap_name };
2280 Handle<Object> error = isolate->factory()->NewTypeError( 2374 Handle<Object> error = isolate->factory()->NewTypeError(
2281 "handler_failed", HandleVector(args, ARRAY_SIZE(args))); 2375 "handler_failed", HandleVector(args, ARRAY_SIZE(args)));
2282 isolate->Throw(*error); 2376 isolate->Throw(*error);
2283 return Failure::Exception(); 2377 return Failure::Exception();
2284 } 2378 }
2285 return bool_result; 2379 return bool_result;
2286 } 2380 }
2287 2381
2288 2382
2383 MUST_USE_RESULT MaybeObject* JSProxy::DeleteElementWithHandler(
2384 uint32_t index,
2385 DeleteMode mode) {
2386 Isolate* isolate = GetIsolate();
2387 HandleScope scope(isolate);
2388 Handle<String> name = isolate->factory()->Uint32ToString(index);
2389 return JSProxy::DeletePropertyWithHandler(*name, mode);
2390 }
2391
2392
2289 MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler( 2393 MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler(
2290 JSReceiver* receiver_raw, 2394 JSReceiver* receiver_raw,
2291 String* name_raw) { 2395 String* name_raw) {
2292 Isolate* isolate = GetIsolate(); 2396 Isolate* isolate = GetIsolate();
2293 HandleScope scope(isolate); 2397 HandleScope scope(isolate);
2398 Handle<JSProxy> proxy(this);
2294 Handle<JSReceiver> receiver(receiver_raw); 2399 Handle<JSReceiver> receiver(receiver_raw);
2295 Handle<Object> name(name_raw); 2400 Handle<Object> name(name_raw);
2296 2401
2297 Handle<Object> args[] = { name }; 2402 Handle<Object> args[] = { name };
2298 Handle<Object> result = CallTrap( 2403 Handle<Object> result = CallTrap(
2299 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args); 2404 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args);
2300 if (isolate->has_pending_exception()) return NONE; 2405 if (isolate->has_pending_exception()) return NONE;
2301 2406
2302 if (result->IsUndefined()) return ABSENT; 2407 if (result->IsUndefined()) return ABSENT;
2303 2408
2304 bool has_pending_exception; 2409 bool has_pending_exception;
2305 Object** argv[] = { result.location() }; 2410 Object** argv[] = { result.location() };
2306 Handle<Object> desc = 2411 Handle<Object> desc =
2307 Execution::Call(isolate->to_complete_property_descriptor(), result, 2412 Execution::Call(isolate->to_complete_property_descriptor(), result,
2308 ARRAY_SIZE(argv), argv, &has_pending_exception); 2413 ARRAY_SIZE(argv), argv, &has_pending_exception);
2309 if (has_pending_exception) return NONE; 2414 if (has_pending_exception) return NONE;
2310 2415
2311 // Convert result to PropertyAttributes. 2416 // Convert result to PropertyAttributes.
2312 Handle<String> enum_name = isolate->factory()->LookupAsciiSymbol("enumerable") ; 2417 Handle<String> enum_name =
2418 isolate->factory()->LookupAsciiSymbol("enumerable_");
2313 Handle<Object> enumerable(v8::internal::GetProperty(desc, enum_name)); 2419 Handle<Object> enumerable(v8::internal::GetProperty(desc, enum_name));
2314 if (isolate->has_pending_exception()) return NONE; 2420 if (isolate->has_pending_exception()) return NONE;
2315 Handle<String> conf_name = isolate->factory()->LookupAsciiSymbol("configurable "); 2421 Handle<String> conf_name =
2422 isolate->factory()->LookupAsciiSymbol("configurable_");
2316 Handle<Object> configurable(v8::internal::GetProperty(desc, conf_name)); 2423 Handle<Object> configurable(v8::internal::GetProperty(desc, conf_name));
2317 if (isolate->has_pending_exception()) return NONE; 2424 if (isolate->has_pending_exception()) return NONE;
2318 Handle<String> writ_name = isolate->factory()->LookupAsciiSymbol("writable"); 2425 Handle<String> writ_name = isolate->factory()->LookupAsciiSymbol("writable_");
2319 Handle<Object> writable(v8::internal::GetProperty(desc, writ_name)); 2426 Handle<Object> writable(v8::internal::GetProperty(desc, writ_name));
2320 if (isolate->has_pending_exception()) return NONE; 2427 if (isolate->has_pending_exception()) return NONE;
2321 2428
2429 if (configurable->IsFalse()) {
2430 Handle<Object> args[] = { Handle<Object>(proxy->handler()), proxy, name };
2431 Handle<Object> error = isolate->factory()->NewTypeError(
2432 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args)));
2433 isolate->Throw(*error);
2434 return NONE;
2435 }
2436
2322 int attributes = NONE; 2437 int attributes = NONE;
2323 if (enumerable->ToBoolean()->IsFalse()) attributes |= DONT_ENUM; 2438 if (enumerable->ToBoolean()->IsFalse()) attributes |= DONT_ENUM;
2324 if (configurable->ToBoolean()->IsFalse()) attributes |= DONT_DELETE; 2439 if (configurable->ToBoolean()->IsFalse()) attributes |= DONT_DELETE;
2325 if (writable->ToBoolean()->IsFalse()) attributes |= READ_ONLY; 2440 if (writable->ToBoolean()->IsFalse()) attributes |= READ_ONLY;
2326 return static_cast<PropertyAttributes>(attributes); 2441 return static_cast<PropertyAttributes>(attributes);
2327 } 2442 }
2328 2443
2329 2444
2445 MUST_USE_RESULT PropertyAttributes JSProxy::GetElementAttributeWithHandler(
2446 JSReceiver* receiver,
2447 uint32_t index) {
2448 Isolate* isolate = GetIsolate();
2449 HandleScope scope(isolate);
2450 Handle<String> name = isolate->factory()->Uint32ToString(index);
2451 return GetPropertyAttributeWithHandler(receiver, *name);
2452 }
2453
2454
2330 void JSProxy::Fix() { 2455 void JSProxy::Fix() {
2331 Isolate* isolate = GetIsolate(); 2456 Isolate* isolate = GetIsolate();
2332 HandleScope scope(isolate); 2457 HandleScope scope(isolate);
2333 Handle<JSProxy> self(this); 2458 Handle<JSProxy> self(this);
2334 2459
2335 if (IsJSFunctionProxy()) { 2460 if (IsJSFunctionProxy()) {
2336 isolate->factory()->BecomeJSFunction(self); 2461 isolate->factory()->BecomeJSFunction(self);
2337 // Code will be set on the JavaScript side. 2462 // Code will be set on the JavaScript side.
2338 } else { 2463 } else {
2339 isolate->factory()->BecomeJSObject(self); 2464 isolate->factory()->BecomeJSObject(self);
2340 } 2465 }
2341 ASSERT(self->IsJSObject()); 2466 ASSERT(self->IsJSObject());
2342 } 2467 }
2343 2468
2344 2469
2345 MUST_USE_RESULT Handle<Object> JSProxy::CallTrap( 2470 MUST_USE_RESULT Handle<Object> JSProxy::CallTrap(
2346 const char* name, 2471 const char* name,
2347 Handle<Object> derived, 2472 Handle<Object> derived,
2348 int argc, 2473 int argc,
2349 Handle<Object> args[]) { 2474 Handle<Object> args[]) {
2350 Isolate* isolate = GetIsolate(); 2475 Isolate* isolate = GetIsolate();
2351 Handle<Object> handler(this->handler()); 2476 Handle<Object> handler(this->handler());
2352 2477
2353 Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol(name); 2478 Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol(name);
2354 Handle<Object> trap(v8::internal::GetProperty(handler, trap_name)); 2479 Handle<Object> trap(v8::internal::GetProperty(handler, trap_name));
2355 if (isolate->has_pending_exception()) return trap; 2480 if (isolate->has_pending_exception()) return trap;
2356 2481
2357 if (trap->IsUndefined()) { 2482 if (trap->IsUndefined()) {
2358 if (*derived == NULL) { 2483 if (derived.is_null()) {
2359 Handle<Object> args[] = { handler, trap_name }; 2484 Handle<Object> args[] = { handler, trap_name };
2360 Handle<Object> error = isolate->factory()->NewTypeError( 2485 Handle<Object> error = isolate->factory()->NewTypeError(
2361 "handler_trap_missing", HandleVector(args, ARRAY_SIZE(args))); 2486 "handler_trap_missing", HandleVector(args, ARRAY_SIZE(args)));
2362 isolate->Throw(*error); 2487 isolate->Throw(*error);
2363 return Handle<Object>(); 2488 return Handle<Object>();
2364 } 2489 }
2365 trap = Handle<Object>(derived); 2490 trap = Handle<Object>(derived);
2366 } 2491 }
2367 2492
2368 Object*** argv = reinterpret_cast<Object***>(args); 2493 Object*** argv = reinterpret_cast<Object***>(args);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2417 if (accessor_result.IsFound()) { 2542 if (accessor_result.IsFound()) {
2418 if (accessor_result.type() == CALLBACKS) { 2543 if (accessor_result.type() == CALLBACKS) {
2419 return SetPropertyWithCallback(accessor_result.GetCallbackObject(), 2544 return SetPropertyWithCallback(accessor_result.GetCallbackObject(),
2420 name, 2545 name,
2421 value, 2546 value,
2422 accessor_result.holder(), 2547 accessor_result.holder(),
2423 strict_mode); 2548 strict_mode);
2424 } else if (accessor_result.type() == HANDLER) { 2549 } else if (accessor_result.type() == HANDLER) {
2425 // There is a proxy in the prototype chain. Invoke its 2550 // There is a proxy in the prototype chain. Invoke its
2426 // getOwnPropertyDescriptor trap. 2551 // getOwnPropertyDescriptor trap.
2427 Isolate* isolate = heap->isolate(); 2552 bool found = false;
2428 Handle<JSObject> self(this); 2553 Handle<JSObject> self(this);
2429 Handle<String> hname(name); 2554 Handle<String> hname(name);
2430 Handle<Object> hvalue(value); 2555 Handle<Object> hvalue(value);
2431 Handle<JSProxy> proxy(accessor_result.proxy()); 2556 MaybeObject* result =
2432 Handle<Object> args[] = { hname }; 2557 accessor_result.proxy()->SetPropertyWithHandlerIfDefiningSetter(
2433 Handle<Object> result = proxy->CallTrap( 2558 name, value, attributes, strict_mode, &found);
2434 "getOwnPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args); 2559 if (found) return result;
2435 if (isolate->has_pending_exception()) return Failure::Exception(); 2560 // The proxy does not define the property as an accessor.
2436 2561 // Consequently, it has no effect on setting the receiver.
2437 if (!result->IsUndefined()) { 2562 return self->AddProperty(*hname, *hvalue, attributes, strict_mode);
2438 // The proxy handler cares about this property.
2439 // Check whether it is virtualized as an accessor.
2440 Handle<String> getter_name =
2441 isolate->factory()->LookupAsciiSymbol("get");
2442 Handle<Object> getter(
2443 v8::internal::GetProperty(result, getter_name));
2444 if (isolate->has_pending_exception()) return Failure::Exception();
2445 Handle<String> setter_name =
2446 isolate->factory()->LookupAsciiSymbol("set");
2447 Handle<Object> setter(
2448 v8::internal::GetProperty(result, setter_name));
2449 if (isolate->has_pending_exception()) return Failure::Exception();
2450
2451 if (!setter->IsUndefined()) {
2452 // We have a setter -- invoke it.
2453 if (setter->IsJSFunction()) {
2454 return proxy->SetPropertyWithDefinedSetter(
2455 JSFunction::cast(*setter), *hvalue);
2456 }
2457 Handle<Object> args[] = { setter };
2458 Handle<Object> error = isolate->factory()->NewTypeError(
2459 "setter_must_be_callable", HandleVector(args, ARRAY_SIZE(args)));
2460 return isolate->Throw(*error);
2461 } else if (!getter->IsUndefined()) {
2462 // We have a getter but no setter -- the property may not be
2463 // written. In strict mode, throw an error.
2464 if (strict_mode == kNonStrictMode) return *hvalue;
2465 Handle<Object> args[] = { hname, proxy };
2466 Handle<Object> error = isolate->factory()->NewTypeError(
2467 "no_setter_in_callback", HandleVector(args, ARRAY_SIZE(args)));
2468 return isolate->Throw(*error);
2469 }
2470 // The proxy does not define the property as an accessor.
2471 // Consequently, it has no effect on setting the receiver.
2472 return self->AddProperty(*hname, *hvalue, attributes, strict_mode);
2473 }
2474 } 2563 }
2475 } 2564 }
2476 } 2565 }
2477 2566
2478 // At this point, no GC should have happened, as this would invalidate 2567 // At this point, no GC should have happened, as this would invalidate
2479 // 'result', which we cannot handlify! 2568 // 'result', which we cannot handlify!
2480 2569
2481 if (!result->IsFound()) { 2570 if (!result->IsFound()) {
2482 // Neither properties nor transitions found. 2571 // Neither properties nor transitions found.
2483 return AddProperty(name, value, attributes, strict_mode); 2572 return AddProperty(name, value, attributes, strict_mode);
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
2710 *name_handle, 2799 *name_handle,
2711 continue_search); 2800 continue_search);
2712 } 2801 }
2713 2802
2714 2803
2715 PropertyAttributes JSReceiver::GetPropertyAttributeWithReceiver( 2804 PropertyAttributes JSReceiver::GetPropertyAttributeWithReceiver(
2716 JSReceiver* receiver, 2805 JSReceiver* receiver,
2717 String* key) { 2806 String* key) {
2718 uint32_t index = 0; 2807 uint32_t index = 0;
2719 if (IsJSObject() && key->AsArrayIndex(&index)) { 2808 if (IsJSObject() && key->AsArrayIndex(&index)) {
2720 if (JSObject::cast(this)->HasElementWithReceiver(receiver, index)) 2809 return JSObject::cast(this)->HasElementWithReceiver(receiver, index)
2721 return NONE; 2810 ? NONE : ABSENT;
2722 return ABSENT;
2723 } 2811 }
2724 // Named property. 2812 // Named property.
2725 LookupResult result; 2813 LookupResult result;
2726 Lookup(key, &result); 2814 Lookup(key, &result);
2727 return GetPropertyAttribute(receiver, &result, key, true); 2815 return GetPropertyAttribute(receiver, &result, key, true);
2728 } 2816 }
2729 2817
2730 2818
2731 PropertyAttributes JSReceiver::GetPropertyAttribute(JSReceiver* receiver, 2819 PropertyAttributes JSReceiver::GetPropertyAttribute(JSReceiver* receiver,
2732 LookupResult* result, 2820 LookupResult* result,
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after
3245 mode = JSReceiver::FORCE_DELETION; 3333 mode = JSReceiver::FORCE_DELETION;
3246 } 3334 }
3247 3335
3248 return GetElementsAccessor()->Delete(this, index, mode); 3336 return GetElementsAccessor()->Delete(this, index, mode);
3249 } 3337 }
3250 3338
3251 3339
3252 MaybeObject* JSReceiver::DeleteProperty(String* name, DeleteMode mode) { 3340 MaybeObject* JSReceiver::DeleteProperty(String* name, DeleteMode mode) {
3253 if (IsJSProxy()) { 3341 if (IsJSProxy()) {
3254 return JSProxy::cast(this)->DeletePropertyWithHandler(name, mode); 3342 return JSProxy::cast(this)->DeletePropertyWithHandler(name, mode);
3255 } else {
3256 return JSObject::cast(this)->DeleteProperty(name, mode);
3257 } 3343 }
3344 return JSObject::cast(this)->DeleteProperty(name, mode);
3258 } 3345 }
3259 3346
3260 3347
3348 MaybeObject* JSReceiver::DeleteElement(uint32_t index, DeleteMode mode) {
3349 if (IsJSProxy()) {
3350 return JSProxy::cast(this)->DeleteElementWithHandler(index, mode);
3351 }
3352 return JSObject::cast(this)->DeleteElement(index, mode);
3353 }
3354
3355
3261 MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) { 3356 MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) {
3262 Isolate* isolate = GetIsolate(); 3357 Isolate* isolate = GetIsolate();
3263 // ECMA-262, 3rd, 8.6.2.5 3358 // ECMA-262, 3rd, 8.6.2.5
3264 ASSERT(name->IsString()); 3359 ASSERT(name->IsString());
3265 3360
3266 // Check access rights if needed. 3361 // Check access rights if needed.
3267 if (IsAccessCheckNeeded() && 3362 if (IsAccessCheckNeeded() &&
3268 !isolate->MayNamedAccess(this, name, v8::ACCESS_DELETE)) { 3363 !isolate->MayNamedAccess(this, name, v8::ACCESS_DELETE)) {
3269 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); 3364 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE);
3270 return isolate->heap()->false_value(); 3365 return isolate->heap()->false_value();
(...skipping 4609 matching lines...) Expand 10 before | Expand all | Expand 10 after
7880 case NON_STRICT_ARGUMENTS_ELEMENTS: 7975 case NON_STRICT_ARGUMENTS_ELEMENTS:
7881 UNREACHABLE(); 7976 UNREACHABLE();
7882 break; 7977 break;
7883 } 7978 }
7884 7979
7885 // Handle [] on String objects. 7980 // Handle [] on String objects.
7886 if (this->IsStringObjectWithCharacterAt(index)) return true; 7981 if (this->IsStringObjectWithCharacterAt(index)) return true;
7887 7982
7888 Object* pt = GetPrototype(); 7983 Object* pt = GetPrototype();
7889 if (pt->IsNull()) return false; 7984 if (pt->IsNull()) return false;
7985 if (pt->IsJSProxy()) {
7986 // We need to follow the spec and simulate a call to [[GetOwnProperty]].
7987 return JSProxy::cast(pt)->GetElementAttributeWithHandler(
7988 receiver, index) != ABSENT;
7989 }
7890 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); 7990 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index);
7891 } 7991 }
7892 7992
7893 7993
7894 bool JSObject::HasElementWithInterceptor(JSReceiver* receiver, uint32_t index) { 7994 bool JSObject::HasElementWithInterceptor(JSReceiver* receiver, uint32_t index) {
7895 Isolate* isolate = GetIsolate(); 7995 Isolate* isolate = GetIsolate();
7896 // Make sure that the top context does not change when doing 7996 // Make sure that the top context does not change when doing
7897 // callbacks or interceptor calls. 7997 // callbacks or interceptor calls.
7898 AssertNoContextChange ncc; 7998 AssertNoContextChange ncc;
7899 HandleScope scope(isolate); 7999 HandleScope scope(isolate);
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
8136 if (HasElementInElements(arguments, kind, index)) return true; 8236 if (HasElementInElements(arguments, kind, index)) return true;
8137 break; 8237 break;
8138 } 8238 }
8139 } 8239 }
8140 8240
8141 // Handle [] on String objects. 8241 // Handle [] on String objects.
8142 if (this->IsStringObjectWithCharacterAt(index)) return true; 8242 if (this->IsStringObjectWithCharacterAt(index)) return true;
8143 8243
8144 Object* pt = GetPrototype(); 8244 Object* pt = GetPrototype();
8145 if (pt->IsNull()) return false; 8245 if (pt->IsNull()) return false;
8246 if (pt->IsJSProxy()) {
8247 // We need to follow the spec and simulate a call to [[GetOwnProperty]].
8248 return JSProxy::cast(pt)->GetElementAttributeWithHandler(
8249 receiver, index) != ABSENT;
8250 }
8146 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); 8251 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index);
8147 } 8252 }
8148 8253
8149 8254
8150 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, 8255 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index,
8151 Object* value, 8256 Object* value,
8152 StrictModeFlag strict_mode, 8257 StrictModeFlag strict_mode,
8153 bool check_prototype) { 8258 bool check_prototype) {
8154 Isolate* isolate = GetIsolate(); 8259 Isolate* isolate = GetIsolate();
8155 // Make sure that the top context does not change when doing 8260 // Make sure that the top context does not change when doing
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
8568 ASSERT(elements()->IsFixedDoubleArray()); 8673 ASSERT(elements()->IsFixedDoubleArray());
8569 Object* obj; 8674 Object* obj;
8570 { MaybeObject* maybe_obj = NormalizeElements(); 8675 { MaybeObject* maybe_obj = NormalizeElements();
8571 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 8676 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8572 } 8677 }
8573 ASSERT(HasDictionaryElements()); 8678 ASSERT(HasDictionaryElements());
8574 return SetElement(index, value, strict_mode, check_prototype); 8679 return SetElement(index, value, strict_mode, check_prototype);
8575 } 8680 }
8576 8681
8577 8682
8683 MaybeObject* JSReceiver::SetElement(uint32_t index,
8684 Object* value,
8685 StrictModeFlag strict_mode,
8686 bool check_proto) {
8687 return IsJSProxy()
8688 ? JSProxy::cast(this)->SetElementWithHandler(index, value, strict_mode)
8689 : JSObject::cast(this)->SetElement(index, value, strict_mode, check_proto)
8690 ;
8691 }
8692
8693
8578 MaybeObject* JSObject::SetElement(uint32_t index, 8694 MaybeObject* JSObject::SetElement(uint32_t index,
8579 Object* value, 8695 Object* value,
8580 StrictModeFlag strict_mode, 8696 StrictModeFlag strict_mode,
8581 bool check_prototype) { 8697 bool check_prototype) {
8582 // Check access rights if needed. 8698 // Check access rights if needed.
8583 if (IsAccessCheckNeeded()) { 8699 if (IsAccessCheckNeeded()) {
8584 Heap* heap = GetHeap(); 8700 Heap* heap = GetHeap();
8585 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) { 8701 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) {
8586 HandleScope scope(heap->isolate()); 8702 HandleScope scope(heap->isolate());
8587 Handle<Object> value_handle(value); 8703 Handle<Object> value_handle(value);
(...skipping 3038 matching lines...) Expand 10 before | Expand all | Expand 10 after
11626 if (break_point_objects()->IsUndefined()) return 0; 11742 if (break_point_objects()->IsUndefined()) return 0;
11627 // Single break point. 11743 // Single break point.
11628 if (!break_point_objects()->IsFixedArray()) return 1; 11744 if (!break_point_objects()->IsFixedArray()) return 1;
11629 // Multiple break points. 11745 // Multiple break points.
11630 return FixedArray::cast(break_point_objects())->length(); 11746 return FixedArray::cast(break_point_objects())->length();
11631 } 11747 }
11632 #endif 11748 #endif
11633 11749
11634 11750
11635 } } // namespace v8::internal 11751 } } // 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