OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 2258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2269 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | 2269 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |
2270 | 2270 |
2271 // Lookup the property locally in the global object. If it isn't | 2271 // Lookup the property locally in the global object. If it isn't |
2272 // there, we add the property and take special precautions to always | 2272 // there, we add the property and take special precautions to always |
2273 // add it as a local property even in case of callbacks in the | 2273 // add it as a local property even in case of callbacks in the |
2274 // prototype chain (this rules out using SetProperty). | 2274 // prototype chain (this rules out using SetProperty). |
2275 // We use SetLocalPropertyIgnoreAttributes instead | 2275 // We use SetLocalPropertyIgnoreAttributes instead |
2276 LookupResult lookup(isolate); | 2276 LookupResult lookup(isolate); |
2277 global->LocalLookup(*name, &lookup); | 2277 global->LocalLookup(*name, &lookup); |
2278 if (!lookup.IsFound()) { | 2278 if (!lookup.IsFound()) { |
2279 return global->SetLocalPropertyIgnoreAttributes(*name, | 2279 HandleScope handle_scope(isolate); |
2280 *value, | 2280 Handle<GlobalObject> global(isolate->context()->global_object()); |
2281 attributes); | 2281 RETURN_IF_EMPTY_HANDLE( |
| 2282 isolate, |
| 2283 JSObject::SetLocalPropertyIgnoreAttributes(global, name, value, |
| 2284 attributes)); |
| 2285 return *value; |
2282 } | 2286 } |
2283 | 2287 |
2284 if (!lookup.IsReadOnly()) { | 2288 if (!lookup.IsReadOnly()) { |
2285 // Restore global object from context (in case of GC) and continue | 2289 // Restore global object from context (in case of GC) and continue |
2286 // with setting the value. | 2290 // with setting the value. |
2287 HandleScope handle_scope(isolate); | 2291 HandleScope handle_scope(isolate); |
2288 Handle<GlobalObject> global(isolate->context()->global_object()); | 2292 Handle<GlobalObject> global(isolate->context()->global_object()); |
2289 | 2293 |
2290 // BUG 1213575: Handle the case where we have to set a read-only | 2294 // BUG 1213575: Handle the case where we have to set a read-only |
2291 // property through an interceptor and only do it if it's | 2295 // property through an interceptor and only do it if it's |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2488 array->set_elements(elements); | 2492 array->set_elements(elements); |
2489 array->set_length(Smi::FromInt(elements_count)); | 2493 array->set_length(Smi::FromInt(elements_count)); |
2490 // Write in-object properties after the length of the array. | 2494 // Write in-object properties after the length of the array. |
2491 array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, args[1]); | 2495 array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, args[1]); |
2492 array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, args[2]); | 2496 array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, args[2]); |
2493 return array; | 2497 return array; |
2494 } | 2498 } |
2495 | 2499 |
2496 | 2500 |
2497 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpInitializeObject) { | 2501 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpInitializeObject) { |
2498 SealHandleScope shs(isolate); | 2502 HandleScope scope(isolate); |
2499 DisallowHeapAllocation no_allocation; | 2503 DisallowHeapAllocation no_allocation; |
2500 ASSERT(args.length() == 5); | 2504 ASSERT(args.length() == 5); |
2501 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); | 2505 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); |
2502 CONVERT_ARG_CHECKED(String, source, 1); | 2506 CONVERT_ARG_HANDLE_CHECKED(String, source, 1); |
2503 // If source is the empty string we set it to "(?:)" instead as | 2507 // If source is the empty string we set it to "(?:)" instead as |
2504 // suggested by ECMA-262, 5th, section 15.10.4.1. | 2508 // suggested by ECMA-262, 5th, section 15.10.4.1. |
2505 if (source->length() == 0) source = isolate->heap()->query_colon_string(); | 2509 if (source->length() == 0) source = isolate->factory()->query_colon_string(); |
2506 | 2510 |
2507 Object* global = args[2]; | 2511 CONVERT_ARG_HANDLE_CHECKED(Object, global, 2); |
2508 if (!global->IsTrue()) global = isolate->heap()->false_value(); | 2512 if (!global->IsTrue()) global = isolate->factory()->false_value(); |
2509 | 2513 |
2510 Object* ignoreCase = args[3]; | 2514 CONVERT_ARG_HANDLE_CHECKED(Object, ignoreCase, 3); |
2511 if (!ignoreCase->IsTrue()) ignoreCase = isolate->heap()->false_value(); | 2515 if (!ignoreCase->IsTrue()) ignoreCase = isolate->factory()->false_value(); |
2512 | 2516 |
2513 Object* multiline = args[4]; | 2517 CONVERT_ARG_HANDLE_CHECKED(Object, multiline, 4); |
2514 if (!multiline->IsTrue()) multiline = isolate->heap()->false_value(); | 2518 if (!multiline->IsTrue()) multiline = isolate->factory()->false_value(); |
2515 | 2519 |
2516 Map* map = regexp->map(); | 2520 Map* map = regexp->map(); |
2517 Object* constructor = map->constructor(); | 2521 Object* constructor = map->constructor(); |
2518 if (constructor->IsJSFunction() && | 2522 if (constructor->IsJSFunction() && |
2519 JSFunction::cast(constructor)->initial_map() == map) { | 2523 JSFunction::cast(constructor)->initial_map() == map) { |
2520 // If we still have the original map, set in-object properties directly. | 2524 // If we still have the original map, set in-object properties directly. |
2521 regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, source); | 2525 regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, *source); |
2522 // Both true and false are immovable immortal objects so no need for write | 2526 // Both true and false are immovable immortal objects so no need for write |
2523 // barrier. | 2527 // barrier. |
2524 regexp->InObjectPropertyAtPut( | 2528 regexp->InObjectPropertyAtPut( |
2525 JSRegExp::kGlobalFieldIndex, global, SKIP_WRITE_BARRIER); | 2529 JSRegExp::kGlobalFieldIndex, *global, SKIP_WRITE_BARRIER); |
2526 regexp->InObjectPropertyAtPut( | 2530 regexp->InObjectPropertyAtPut( |
2527 JSRegExp::kIgnoreCaseFieldIndex, ignoreCase, SKIP_WRITE_BARRIER); | 2531 JSRegExp::kIgnoreCaseFieldIndex, *ignoreCase, SKIP_WRITE_BARRIER); |
2528 regexp->InObjectPropertyAtPut( | 2532 regexp->InObjectPropertyAtPut( |
2529 JSRegExp::kMultilineFieldIndex, multiline, SKIP_WRITE_BARRIER); | 2533 JSRegExp::kMultilineFieldIndex, *multiline, SKIP_WRITE_BARRIER); |
2530 regexp->InObjectPropertyAtPut( | 2534 regexp->InObjectPropertyAtPut( |
2531 JSRegExp::kLastIndexFieldIndex, Smi::FromInt(0), SKIP_WRITE_BARRIER); | 2535 JSRegExp::kLastIndexFieldIndex, Smi::FromInt(0), SKIP_WRITE_BARRIER); |
2532 return regexp; | 2536 return *regexp; |
2533 } | 2537 } |
2534 | 2538 |
2535 // Map has changed, so use generic, but slower, method. | 2539 // Map has changed, so use generic, but slower, method. |
2536 PropertyAttributes final = | 2540 PropertyAttributes final = |
2537 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); | 2541 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); |
2538 PropertyAttributes writable = | 2542 PropertyAttributes writable = |
2539 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); | 2543 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); |
2540 Heap* heap = isolate->heap(); | 2544 Handle<Object> zero(Smi::FromInt(0), isolate); |
2541 MaybeObject* result; | 2545 Factory* factory = isolate->factory(); |
2542 result = regexp->SetLocalPropertyIgnoreAttributes(heap->source_string(), | 2546 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes( |
2543 source, | 2547 regexp, factory->source_string(), source, final)); |
2544 final); | 2548 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes( |
2545 // TODO(jkummerow): Turn these back into ASSERTs when we can be certain | 2549 regexp, factory->global_string(), global, final)); |
2546 // that it never fires in Release mode in the wild. | 2550 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes( |
2547 CHECK(!result->IsFailure()); | 2551 regexp, factory->ignore_case_string(), ignoreCase, final)); |
2548 result = regexp->SetLocalPropertyIgnoreAttributes(heap->global_string(), | 2552 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes( |
2549 global, | 2553 regexp, factory->multiline_string(), multiline, final)); |
2550 final); | 2554 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes( |
2551 CHECK(!result->IsFailure()); | 2555 regexp, factory->last_index_string(), zero, writable)); |
2552 result = | 2556 return *regexp; |
2553 regexp->SetLocalPropertyIgnoreAttributes(heap->ignore_case_string(), | |
2554 ignoreCase, | |
2555 final); | |
2556 CHECK(!result->IsFailure()); | |
2557 result = regexp->SetLocalPropertyIgnoreAttributes(heap->multiline_string(), | |
2558 multiline, | |
2559 final); | |
2560 CHECK(!result->IsFailure()); | |
2561 result = | |
2562 regexp->SetLocalPropertyIgnoreAttributes(heap->last_index_string(), | |
2563 Smi::FromInt(0), | |
2564 writable); | |
2565 CHECK(!result->IsFailure()); | |
2566 USE(result); | |
2567 return regexp; | |
2568 } | 2557 } |
2569 | 2558 |
2570 | 2559 |
2571 RUNTIME_FUNCTION(MaybeObject*, Runtime_FinishArrayPrototypeSetup) { | 2560 RUNTIME_FUNCTION(MaybeObject*, Runtime_FinishArrayPrototypeSetup) { |
2572 HandleScope scope(isolate); | 2561 HandleScope scope(isolate); |
2573 ASSERT(args.length() == 1); | 2562 ASSERT(args.length() == 1); |
2574 CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0); | 2563 CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0); |
2575 // This is necessary to enable fast checks for absence of elements | 2564 // This is necessary to enable fast checks for absence of elements |
2576 // on Array.prototype and below. | 2565 // on Array.prototype and below. |
2577 prototype->set_elements(isolate->heap()->empty_fixed_array()); | 2566 prototype->set_elements(isolate->heap()->empty_fixed_array()); |
(...skipping 2479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5057 (attr != result.GetAttributes() || result.IsPropertyCallbacks())) { | 5046 (attr != result.GetAttributes() || result.IsPropertyCallbacks())) { |
5058 // New attributes - normalize to avoid writing to instance descriptor | 5047 // New attributes - normalize to avoid writing to instance descriptor |
5059 if (js_object->IsJSGlobalProxy()) { | 5048 if (js_object->IsJSGlobalProxy()) { |
5060 // Since the result is a property, the prototype will exist so | 5049 // Since the result is a property, the prototype will exist so |
5061 // we don't have to check for null. | 5050 // we don't have to check for null. |
5062 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); | 5051 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); |
5063 } | 5052 } |
5064 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); | 5053 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); |
5065 // Use IgnoreAttributes version since a readonly property may be | 5054 // Use IgnoreAttributes version since a readonly property may be |
5066 // overridden and SetProperty does not allow this. | 5055 // overridden and SetProperty does not allow this. |
5067 return js_object->SetLocalPropertyIgnoreAttributes(*name, | 5056 Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes( |
5068 *obj_value, | 5057 js_object, name, obj_value, attr); |
5069 attr); | 5058 RETURN_IF_EMPTY_HANDLE(isolate, result); |
| 5059 return *result; |
5070 } | 5060 } |
5071 | 5061 |
5072 return Runtime::ForceSetObjectProperty(isolate, | 5062 return Runtime::ForceSetObjectProperty(isolate, |
5073 js_object, | 5063 js_object, |
5074 name, | 5064 name, |
5075 obj_value, | 5065 obj_value, |
5076 attr); | 5066 attr); |
5077 } | 5067 } |
5078 | 5068 |
5079 | 5069 |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5245 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); | 5235 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); |
5246 } | 5236 } |
5247 | 5237 |
5248 if (key->IsName()) { | 5238 if (key->IsName()) { |
5249 Handle<Name> name = Handle<Name>::cast(key); | 5239 Handle<Name> name = Handle<Name>::cast(key); |
5250 if (name->AsArrayIndex(&index)) { | 5240 if (name->AsArrayIndex(&index)) { |
5251 return js_object->SetElement( | 5241 return js_object->SetElement( |
5252 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); | 5242 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); |
5253 } else { | 5243 } else { |
5254 if (name->IsString()) Handle<String>::cast(name)->TryFlatten(); | 5244 if (name->IsString()) Handle<String>::cast(name)->TryFlatten(); |
5255 return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr); | 5245 Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes( |
| 5246 js_object, name, value, attr); |
| 5247 RETURN_IF_EMPTY_HANDLE(isolate, result); |
| 5248 return *result; |
5256 } | 5249 } |
5257 } | 5250 } |
5258 | 5251 |
5259 // Call-back into JavaScript to convert the key to a string. | 5252 // Call-back into JavaScript to convert the key to a string. |
5260 bool has_pending_exception = false; | 5253 bool has_pending_exception = false; |
5261 Handle<Object> converted = | 5254 Handle<Object> converted = |
5262 Execution::ToString(isolate, key, &has_pending_exception); | 5255 Execution::ToString(isolate, key, &has_pending_exception); |
5263 if (has_pending_exception) return Failure::Exception(); | 5256 if (has_pending_exception) return Failure::Exception(); |
5264 Handle<String> name = Handle<String>::cast(converted); | 5257 Handle<String> name = Handle<String>::cast(converted); |
5265 | 5258 |
5266 if (name->AsArrayIndex(&index)) { | 5259 if (name->AsArrayIndex(&index)) { |
5267 return js_object->SetElement( | 5260 return js_object->SetElement( |
5268 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); | 5261 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); |
5269 } else { | 5262 } else { |
5270 return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr); | 5263 Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes( |
| 5264 js_object, name, value, attr); |
| 5265 RETURN_IF_EMPTY_HANDLE(isolate, result); |
| 5266 return *result; |
5271 } | 5267 } |
5272 } | 5268 } |
5273 | 5269 |
5274 | 5270 |
5275 MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate, | 5271 MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate, |
5276 Handle<JSReceiver> receiver, | 5272 Handle<JSReceiver> receiver, |
5277 Handle<Object> key, | 5273 Handle<Object> key, |
5278 JSReceiver::DeleteMode mode) { | 5274 JSReceiver::DeleteMode mode) { |
5279 HandleScope scope(isolate); | 5275 HandleScope scope(isolate); |
5280 | 5276 |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5463 debug->ClearStepOut(); | 5459 debug->ClearStepOut(); |
5464 debug->FloodWithOneShot(callback); | 5460 debug->FloodWithOneShot(callback); |
5465 #endif // ENABLE_DEBUGGER_SUPPORT | 5461 #endif // ENABLE_DEBUGGER_SUPPORT |
5466 return isolate->heap()->undefined_value(); | 5462 return isolate->heap()->undefined_value(); |
5467 } | 5463 } |
5468 | 5464 |
5469 | 5465 |
5470 // Set a local property, even if it is READ_ONLY. If the property does not | 5466 // Set a local property, even if it is READ_ONLY. If the property does not |
5471 // exist, it will be added with attributes NONE. | 5467 // exist, it will be added with attributes NONE. |
5472 RUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) { | 5468 RUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) { |
5473 SealHandleScope shs(isolate); | 5469 HandleScope scope(isolate); |
5474 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); | 5470 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); |
5475 CONVERT_ARG_CHECKED(JSObject, object, 0); | 5471 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |
5476 CONVERT_ARG_CHECKED(Name, name, 1); | 5472 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); |
| 5473 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); |
5477 // Compute attributes. | 5474 // Compute attributes. |
5478 PropertyAttributes attributes = NONE; | 5475 PropertyAttributes attributes = NONE; |
5479 if (args.length() == 4) { | 5476 if (args.length() == 4) { |
5480 CONVERT_SMI_ARG_CHECKED(unchecked_value, 3); | 5477 CONVERT_SMI_ARG_CHECKED(unchecked_value, 3); |
5481 // Only attribute bits should be set. | 5478 // Only attribute bits should be set. |
5482 RUNTIME_ASSERT( | 5479 RUNTIME_ASSERT( |
5483 (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 5480 (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
5484 attributes = static_cast<PropertyAttributes>(unchecked_value); | 5481 attributes = static_cast<PropertyAttributes>(unchecked_value); |
5485 } | 5482 } |
5486 | 5483 Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes( |
5487 return object-> | 5484 object, name, value, attributes); |
5488 SetLocalPropertyIgnoreAttributes(name, args[2], attributes); | 5485 RETURN_IF_EMPTY_HANDLE(isolate, result); |
| 5486 return *result; |
5489 } | 5487 } |
5490 | 5488 |
5491 | 5489 |
5492 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteProperty) { | 5490 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteProperty) { |
5493 HandleScope scope(isolate); | 5491 HandleScope scope(isolate); |
5494 ASSERT(args.length() == 3); | 5492 ASSERT(args.length() == 3); |
5495 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); | 5493 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); |
5496 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); | 5494 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); |
5497 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2); | 5495 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2); |
5498 JSReceiver::DeleteMode delete_mode = (strict_mode == kStrictMode) | 5496 JSReceiver::DeleteMode delete_mode = (strict_mode == kStrictMode) |
(...skipping 9177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14676 // Handle last resort GC and make sure to allow future allocations | 14674 // Handle last resort GC and make sure to allow future allocations |
14677 // to grow the heap without causing GCs (if possible). | 14675 // to grow the heap without causing GCs (if possible). |
14678 isolate->counters()->gc_last_resort_from_js()->Increment(); | 14676 isolate->counters()->gc_last_resort_from_js()->Increment(); |
14679 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 14677 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
14680 "Runtime::PerformGC"); | 14678 "Runtime::PerformGC"); |
14681 } | 14679 } |
14682 } | 14680 } |
14683 | 14681 |
14684 | 14682 |
14685 } } // namespace v8::internal | 14683 } } // namespace v8::internal |
OLD | NEW |