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