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 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |