| 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 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 651 isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_GET); | 651 isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_GET); |
| 652 return heap->undefined_value(); | 652 return heap->undefined_value(); |
| 653 } | 653 } |
| 654 } | 654 } |
| 655 | 655 |
| 656 if (js_object->HasIndexedInterceptor()) { | 656 if (js_object->HasIndexedInterceptor()) { |
| 657 return js_object->GetElementWithInterceptor(receiver, index); | 657 return js_object->GetElementWithInterceptor(receiver, index); |
| 658 } | 658 } |
| 659 | 659 |
| 660 if (js_object->elements() != heap->empty_fixed_array()) { | 660 if (js_object->elements() != heap->empty_fixed_array()) { |
| 661 MaybeObject* result = js_object->GetElementsAccessor()->GetWithReceiver( | 661 MaybeObject* result = js_object->GetElementsAccessor()->Get( |
| 662 js_object->elements(), |
| 663 index, |
| 662 js_object, | 664 js_object, |
| 663 receiver, | 665 receiver); |
| 664 index); | |
| 665 if (result != heap->the_hole_value()) return result; | 666 if (result != heap->the_hole_value()) return result; |
| 666 } | 667 } |
| 667 } | 668 } |
| 668 | 669 |
| 669 return heap->undefined_value(); | 670 return heap->undefined_value(); |
| 670 } | 671 } |
| 671 | 672 |
| 672 | 673 |
| 673 Object* Object::GetPrototype() { | 674 Object* Object::GetPrototype() { |
| 674 if (IsSmi()) { | 675 if (IsSmi()) { |
| (...skipping 1650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2325 } | 2326 } |
| 2326 | 2327 |
| 2327 // Call trap function. | 2328 // Call trap function. |
| 2328 Object** args[] = { name.location() }; | 2329 Object** args[] = { name.location() }; |
| 2329 bool has_exception; | 2330 bool has_exception; |
| 2330 Handle<Object> result = | 2331 Handle<Object> result = |
| 2331 Execution::Call(trap, handler, ARRAY_SIZE(args), args, &has_exception); | 2332 Execution::Call(trap, handler, ARRAY_SIZE(args), args, &has_exception); |
| 2332 if (has_exception) return Failure::Exception(); | 2333 if (has_exception) return Failure::Exception(); |
| 2333 | 2334 |
| 2334 Object* bool_result = result->ToBoolean(); | 2335 Object* bool_result = result->ToBoolean(); |
| 2335 if (mode == STRICT_DELETION && bool_result == GetHeap()->false_value()) { | 2336 if (mode == STRICT_DELETION && |
| 2337 bool_result == isolate->heap()->false_value()) { |
| 2336 Handle<Object> args[] = { handler, trap_name }; | 2338 Handle<Object> args[] = { handler, trap_name }; |
| 2337 Handle<Object> error = isolate->factory()->NewTypeError( | 2339 Handle<Object> error = isolate->factory()->NewTypeError( |
| 2338 "handler_failed", HandleVector(args, ARRAY_SIZE(args))); | 2340 "handler_failed", HandleVector(args, ARRAY_SIZE(args))); |
| 2339 isolate->Throw(*error); | 2341 isolate->Throw(*error); |
| 2340 return Failure::Exception(); | 2342 return Failure::Exception(); |
| 2341 } | 2343 } |
| 2342 return bool_result; | 2344 return bool_result; |
| 2343 } | 2345 } |
| 2344 | 2346 |
| 2345 | 2347 |
| (...skipping 833 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3179 { | 3181 { |
| 3180 // Leaving JavaScript. | 3182 // Leaving JavaScript. |
| 3181 VMState state(isolate, EXTERNAL); | 3183 VMState state(isolate, EXTERNAL); |
| 3182 result = deleter(index, info); | 3184 result = deleter(index, info); |
| 3183 } | 3185 } |
| 3184 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 3186 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 3185 if (!result.IsEmpty()) { | 3187 if (!result.IsEmpty()) { |
| 3186 ASSERT(result->IsBoolean()); | 3188 ASSERT(result->IsBoolean()); |
| 3187 return *v8::Utils::OpenHandle(*result); | 3189 return *v8::Utils::OpenHandle(*result); |
| 3188 } | 3190 } |
| 3189 MaybeObject* raw_result = GetElementsAccessor()->Delete(*this_handle, | 3191 MaybeObject* raw_result = this_handle->GetElementsAccessor()->Delete( |
| 3190 index, | 3192 *this_handle, |
| 3191 NORMAL_DELETION); | 3193 index, |
| 3194 NORMAL_DELETION); |
| 3192 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 3195 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 3193 return raw_result; | 3196 return raw_result; |
| 3194 } | 3197 } |
| 3195 | 3198 |
| 3196 | 3199 |
| 3197 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { | 3200 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { |
| 3198 Isolate* isolate = GetIsolate(); | 3201 Isolate* isolate = GetIsolate(); |
| 3199 // Check access rights if needed. | 3202 // Check access rights if needed. |
| 3200 if (IsAccessCheckNeeded() && | 3203 if (IsAccessCheckNeeded() && |
| 3201 !isolate->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { | 3204 !isolate->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { |
| (...skipping 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4476 | 4479 |
| 4477 void CodeCacheHashTable::RemoveByIndex(int index) { | 4480 void CodeCacheHashTable::RemoveByIndex(int index) { |
| 4478 ASSERT(index >= 0); | 4481 ASSERT(index >= 0); |
| 4479 Heap* heap = GetHeap(); | 4482 Heap* heap = GetHeap(); |
| 4480 set(EntryToIndex(index), heap->null_value()); | 4483 set(EntryToIndex(index), heap->null_value()); |
| 4481 set(EntryToIndex(index) + 1, heap->null_value()); | 4484 set(EntryToIndex(index) + 1, heap->null_value()); |
| 4482 ElementRemoved(); | 4485 ElementRemoved(); |
| 4483 } | 4486 } |
| 4484 | 4487 |
| 4485 | 4488 |
| 4486 static bool HasKey(FixedArray* array, Object* key) { | |
| 4487 int len0 = array->length(); | |
| 4488 for (int i = 0; i < len0; i++) { | |
| 4489 Object* element = array->get(i); | |
| 4490 if (element->IsSmi() && key->IsSmi() && (element == key)) return true; | |
| 4491 if (element->IsString() && | |
| 4492 key->IsString() && String::cast(element)->Equals(String::cast(key))) { | |
| 4493 return true; | |
| 4494 } | |
| 4495 } | |
| 4496 return false; | |
| 4497 } | |
| 4498 | |
| 4499 | |
| 4500 MaybeObject* PolymorphicCodeCache::Update(MapList* maps, | 4489 MaybeObject* PolymorphicCodeCache::Update(MapList* maps, |
| 4501 Code::Flags flags, | 4490 Code::Flags flags, |
| 4502 Code* code) { | 4491 Code* code) { |
| 4503 // Initialize cache if necessary. | 4492 // Initialize cache if necessary. |
| 4504 if (cache()->IsUndefined()) { | 4493 if (cache()->IsUndefined()) { |
| 4505 Object* result; | 4494 Object* result; |
| 4506 { MaybeObject* maybe_result = | 4495 { MaybeObject* maybe_result = |
| 4507 PolymorphicCodeCacheHashTable::Allocate( | 4496 PolymorphicCodeCacheHashTable::Allocate( |
| 4508 PolymorphicCodeCacheHashTable::kInitialSize); | 4497 PolymorphicCodeCacheHashTable::kInitialSize); |
| 4509 if (!maybe_result->ToObject(&result)) return maybe_result; | 4498 if (!maybe_result->ToObject(&result)) return maybe_result; |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4649 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 4638 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 4650 } | 4639 } |
| 4651 cache->set(EntryToIndex(entry), obj); | 4640 cache->set(EntryToIndex(entry), obj); |
| 4652 cache->set(EntryToIndex(entry) + 1, code); | 4641 cache->set(EntryToIndex(entry) + 1, code); |
| 4653 cache->ElementAdded(); | 4642 cache->ElementAdded(); |
| 4654 return cache; | 4643 return cache; |
| 4655 } | 4644 } |
| 4656 | 4645 |
| 4657 | 4646 |
| 4658 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) { | 4647 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) { |
| 4659 ASSERT(!array->HasExternalArrayElements()); | 4648 ElementsAccessor* accessor = array->GetElementsAccessor(); |
| 4660 switch (array->GetElementsKind()) { | 4649 MaybeObject* maybe_result = |
| 4661 case JSObject::FAST_ELEMENTS: | 4650 accessor->AddElementsToFixedArray(array->elements(), this, array, array); |
| 4662 return UnionOfKeys(FixedArray::cast(array->elements())); | 4651 FixedArray* result; |
| 4663 case JSObject::FAST_DOUBLE_ELEMENTS: | 4652 if (!maybe_result->To<FixedArray>(&result)) return maybe_result; |
| 4664 return UnionOfDoubleKeys(FixedDoubleArray::cast(array->elements())); | 4653 #ifdef DEBUG |
| 4665 break; | 4654 if (FLAG_enable_slow_asserts) { |
| 4666 case JSObject::DICTIONARY_ELEMENTS: { | 4655 for (int i = 0; i < result->length(); i++) { |
| 4667 NumberDictionary* dict = array->element_dictionary(); | 4656 Object* current = result->get(i); |
| 4668 int size = dict->NumberOfElements(); | 4657 ASSERT(current->IsNumber() || current->IsString()); |
| 4669 | |
| 4670 // Allocate a temporary fixed array. | |
| 4671 Object* object; | |
| 4672 { MaybeObject* maybe_object = GetHeap()->AllocateFixedArray(size); | |
| 4673 if (!maybe_object->ToObject(&object)) return maybe_object; | |
| 4674 } | |
| 4675 FixedArray* key_array = FixedArray::cast(object); | |
| 4676 | |
| 4677 int capacity = dict->Capacity(); | |
| 4678 int pos = 0; | |
| 4679 // Copy the elements from the JSArray to the temporary fixed array. | |
| 4680 for (int i = 0; i < capacity; i++) { | |
| 4681 if (dict->IsKey(dict->KeyAt(i))) { | |
| 4682 key_array->set(pos++, dict->ValueAt(i)); | |
| 4683 } | |
| 4684 } | |
| 4685 // Compute the union of this and the temporary fixed array. | |
| 4686 return UnionOfKeys(key_array); | |
| 4687 } | 4658 } |
| 4688 case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: | |
| 4689 UNIMPLEMENTED(); | |
| 4690 break; | |
| 4691 case JSObject::EXTERNAL_BYTE_ELEMENTS: | |
| 4692 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | |
| 4693 case JSObject::EXTERNAL_SHORT_ELEMENTS: | |
| 4694 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | |
| 4695 case JSObject::EXTERNAL_INT_ELEMENTS: | |
| 4696 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: | |
| 4697 case JSObject::EXTERNAL_FLOAT_ELEMENTS: | |
| 4698 case JSObject::EXTERNAL_DOUBLE_ELEMENTS: | |
| 4699 case JSObject::EXTERNAL_PIXEL_ELEMENTS: | |
| 4700 break; | |
| 4701 } | 4659 } |
| 4702 UNREACHABLE(); | 4660 #endif |
| 4703 return GetHeap()->null_value(); // Failure case needs to "return" a value. | 4661 return result; |
| 4704 } | 4662 } |
| 4705 | 4663 |
| 4706 | 4664 |
| 4707 MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) { | 4665 MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) { |
| 4708 int len0 = length(); | 4666 ElementsAccessor* accessor = ElementsAccessor::ForArray(other); |
| 4667 MaybeObject* maybe_result = |
| 4668 accessor->AddElementsToFixedArray(other, this, NULL, NULL); |
| 4669 FixedArray* result; |
| 4670 if (!maybe_result->To<FixedArray>(&result)) return maybe_result; |
| 4709 #ifdef DEBUG | 4671 #ifdef DEBUG |
| 4710 if (FLAG_enable_slow_asserts) { | 4672 if (FLAG_enable_slow_asserts) { |
| 4711 for (int i = 0; i < len0; i++) { | 4673 for (int i = 0; i < result->length(); i++) { |
| 4712 ASSERT(get(i)->IsString() || get(i)->IsNumber()); | 4674 Object* current = result->get(i); |
| 4675 ASSERT(current->IsNumber() || current->IsString()); |
| 4713 } | 4676 } |
| 4714 } | 4677 } |
| 4715 #endif | 4678 #endif |
| 4716 int len1 = other->length(); | |
| 4717 // Optimize if 'other' is empty. | |
| 4718 // We cannot optimize if 'this' is empty, as other may have holes | |
| 4719 // or non keys. | |
| 4720 if (len1 == 0) return this; | |
| 4721 | |
| 4722 // Compute how many elements are not in this. | |
| 4723 int extra = 0; | |
| 4724 for (int y = 0; y < len1; y++) { | |
| 4725 Object* value = other->get(y); | |
| 4726 if (!value->IsTheHole() && !HasKey(this, value)) extra++; | |
| 4727 } | |
| 4728 | |
| 4729 if (extra == 0) return this; | |
| 4730 | |
| 4731 // Allocate the result | |
| 4732 Object* obj; | |
| 4733 { MaybeObject* maybe_obj = GetHeap()->AllocateFixedArray(len0 + extra); | |
| 4734 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
| 4735 } | |
| 4736 // Fill in the content | |
| 4737 AssertNoAllocation no_gc; | |
| 4738 FixedArray* result = FixedArray::cast(obj); | |
| 4739 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | |
| 4740 for (int i = 0; i < len0; i++) { | |
| 4741 Object* e = get(i); | |
| 4742 ASSERT(e->IsString() || e->IsNumber()); | |
| 4743 result->set(i, e, mode); | |
| 4744 } | |
| 4745 // Fill in the extra keys. | |
| 4746 int index = 0; | |
| 4747 for (int y = 0; y < len1; y++) { | |
| 4748 Object* value = other->get(y); | |
| 4749 if (!value->IsTheHole() && !HasKey(this, value)) { | |
| 4750 Object* e = other->get(y); | |
| 4751 ASSERT(e->IsString() || e->IsNumber()); | |
| 4752 result->set(len0 + index, e, mode); | |
| 4753 index++; | |
| 4754 } | |
| 4755 } | |
| 4756 ASSERT(extra == index); | |
| 4757 return result; | 4679 return result; |
| 4758 } | 4680 } |
| 4759 | 4681 |
| 4760 | |
| 4761 MaybeObject* FixedArray::UnionOfDoubleKeys(FixedDoubleArray* other) { | |
| 4762 int len0 = length(); | |
| 4763 #ifdef DEBUG | |
| 4764 if (FLAG_enable_slow_asserts) { | |
| 4765 for (int i = 0; i < len0; i++) { | |
| 4766 ASSERT(get(i)->IsString() || get(i)->IsNumber()); | |
| 4767 } | |
| 4768 } | |
| 4769 #endif | |
| 4770 int len1 = other->length(); | |
| 4771 // Optimize if 'other' is empty. | |
| 4772 // We cannot optimize if 'this' is empty, as other may have holes | |
| 4773 // or non keys. | |
| 4774 if (len1 == 0) return this; | |
| 4775 | |
| 4776 // Compute how many elements are not in this. | |
| 4777 int extra = 0; | |
| 4778 Heap* heap = GetHeap(); | |
| 4779 Object* obj; | |
| 4780 for (int y = 0; y < len1; y++) { | |
| 4781 if (!other->is_the_hole(y)) { | |
| 4782 MaybeObject* maybe_obj = heap->NumberFromDouble(other->get_scalar(y)); | |
| 4783 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
| 4784 if (!HasKey(this, obj)) extra++; | |
| 4785 } | |
| 4786 } | |
| 4787 | |
| 4788 if (extra == 0) return this; | |
| 4789 | |
| 4790 // Allocate the result | |
| 4791 { MaybeObject* maybe_obj = GetHeap()->AllocateFixedArray(len0 + extra); | |
| 4792 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
| 4793 } | |
| 4794 // Fill in the content | |
| 4795 FixedArray* result = FixedArray::cast(obj); | |
| 4796 { | |
| 4797 // Limit the scope of the AssertNoAllocation | |
| 4798 AssertNoAllocation no_gc; | |
| 4799 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | |
| 4800 for (int i = 0; i < len0; i++) { | |
| 4801 Object* e = get(i); | |
| 4802 ASSERT(e->IsString() || e->IsNumber()); | |
| 4803 result->set(i, e, mode); | |
| 4804 } | |
| 4805 } | |
| 4806 | |
| 4807 // Fill in the extra keys. | |
| 4808 int index = 0; | |
| 4809 for (int y = 0; y < len1; y++) { | |
| 4810 if (!other->is_the_hole(y)) { | |
| 4811 MaybeObject* maybe_obj = heap->NumberFromDouble(other->get_scalar(y)); | |
| 4812 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
| 4813 if (!HasKey(this, obj)) { | |
| 4814 result->set(len0 + index, obj); | |
| 4815 index++; | |
| 4816 } | |
| 4817 } | |
| 4818 } | |
| 4819 ASSERT(extra == index); | |
| 4820 return result; | |
| 4821 } | |
| 4822 | |
| 4823 | 4682 |
| 4824 MaybeObject* FixedArray::CopySize(int new_length) { | 4683 MaybeObject* FixedArray::CopySize(int new_length) { |
| 4825 Heap* heap = GetHeap(); | 4684 Heap* heap = GetHeap(); |
| 4826 if (new_length == 0) return heap->empty_fixed_array(); | 4685 if (new_length == 0) return heap->empty_fixed_array(); |
| 4827 Object* obj; | 4686 Object* obj; |
| 4828 { MaybeObject* maybe_obj = heap->AllocateFixedArray(new_length); | 4687 { MaybeObject* maybe_obj = heap->AllocateFixedArray(new_length); |
| 4829 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 4688 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 4830 } | 4689 } |
| 4831 FixedArray* result = FixedArray::cast(obj); | 4690 FixedArray* result = FixedArray::cast(obj); |
| 4832 // Copy the content | 4691 // Copy the content |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5191 Access<StringInputBuffer> buffer( | 5050 Access<StringInputBuffer> buffer( |
| 5192 heap->isolate()->objects_string_input_buffer()); | 5051 heap->isolate()->objects_string_input_buffer()); |
| 5193 buffer->Reset(0, this); | 5052 buffer->Reset(0, this); |
| 5194 int result = 0; | 5053 int result = 0; |
| 5195 while (buffer->has_more()) | 5054 while (buffer->has_more()) |
| 5196 result += unibrow::Utf8::Length(buffer->GetNext()); | 5055 result += unibrow::Utf8::Length(buffer->GetNext()); |
| 5197 return result; | 5056 return result; |
| 5198 } | 5057 } |
| 5199 | 5058 |
| 5200 | 5059 |
| 5201 Vector<const char> String::ToAsciiVector() { | 5060 String::FlatContent String::GetFlatContent() { |
| 5202 ASSERT(IsAsciiRepresentation()); | |
| 5203 ASSERT(IsFlat()); | |
| 5204 | |
| 5205 int offset = 0; | |
| 5206 int length = this->length(); | 5061 int length = this->length(); |
| 5207 StringRepresentationTag string_tag = StringShape(this).representation_tag(); | 5062 StringShape shape(this); |
| 5208 String* string = this; | 5063 String* string = this; |
| 5209 if (string_tag == kConsStringTag) { | 5064 if (shape.representation_tag() == kConsStringTag) { |
| 5210 ConsString* cons = ConsString::cast(string); | 5065 ConsString* cons = ConsString::cast(string); |
| 5211 ASSERT(cons->second()->length() == 0); | 5066 if (cons->second()->length() != 0) { |
| 5067 return FlatContent(); |
| 5068 } |
| 5212 string = cons->first(); | 5069 string = cons->first(); |
| 5213 string_tag = StringShape(string).representation_tag(); | 5070 shape = StringShape(string); |
| 5214 } | 5071 } |
| 5215 if (string_tag == kSeqStringTag) { | 5072 if (shape.encoding_tag() == kAsciiStringTag) { |
| 5216 SeqAsciiString* seq = SeqAsciiString::cast(string); | 5073 const char* start; |
| 5217 char* start = seq->GetChars(); | 5074 if (shape.representation_tag() == kSeqStringTag) { |
| 5218 return Vector<const char>(start + offset, length); | 5075 start = SeqAsciiString::cast(string)->GetChars(); |
| 5076 } else { |
| 5077 start = ExternalAsciiString::cast(string)->resource()->data(); |
| 5078 } |
| 5079 return FlatContent(Vector<const char>(start, length)); |
| 5080 } else { |
| 5081 ASSERT(shape.encoding_tag() == kTwoByteStringTag); |
| 5082 const uc16* start; |
| 5083 if (shape.representation_tag() == kSeqStringTag) { |
| 5084 start = SeqTwoByteString::cast(string)->GetChars(); |
| 5085 } else { |
| 5086 start = ExternalTwoByteString::cast(string)->resource()->data(); |
| 5087 } |
| 5088 return FlatContent(Vector<const uc16>(start, length)); |
| 5219 } | 5089 } |
| 5220 ASSERT(string_tag == kExternalStringTag); | |
| 5221 ExternalAsciiString* ext = ExternalAsciiString::cast(string); | |
| 5222 const char* start = ext->resource()->data(); | |
| 5223 return Vector<const char>(start + offset, length); | |
| 5224 } | |
| 5225 | |
| 5226 | |
| 5227 Vector<const uc16> String::ToUC16Vector() { | |
| 5228 ASSERT(IsTwoByteRepresentation()); | |
| 5229 ASSERT(IsFlat()); | |
| 5230 | |
| 5231 int offset = 0; | |
| 5232 int length = this->length(); | |
| 5233 StringRepresentationTag string_tag = StringShape(this).representation_tag(); | |
| 5234 String* string = this; | |
| 5235 if (string_tag == kConsStringTag) { | |
| 5236 ConsString* cons = ConsString::cast(string); | |
| 5237 ASSERT(cons->second()->length() == 0); | |
| 5238 string = cons->first(); | |
| 5239 string_tag = StringShape(string).representation_tag(); | |
| 5240 } | |
| 5241 if (string_tag == kSeqStringTag) { | |
| 5242 SeqTwoByteString* seq = SeqTwoByteString::cast(string); | |
| 5243 return Vector<const uc16>(seq->GetChars() + offset, length); | |
| 5244 } | |
| 5245 ASSERT(string_tag == kExternalStringTag); | |
| 5246 ExternalTwoByteString* ext = ExternalTwoByteString::cast(string); | |
| 5247 const uc16* start = | |
| 5248 reinterpret_cast<const uc16*>(ext->resource()->data()); | |
| 5249 return Vector<const uc16>(start + offset, length); | |
| 5250 } | 5090 } |
| 5251 | 5091 |
| 5252 | 5092 |
| 5253 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, | 5093 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, |
| 5254 RobustnessFlag robust_flag, | 5094 RobustnessFlag robust_flag, |
| 5255 int offset, | 5095 int offset, |
| 5256 int length, | 5096 int length, |
| 5257 int* length_return) { | 5097 int* length_return) { |
| 5258 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { | 5098 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { |
| 5259 return SmartPointer<char>(NULL); | 5099 return SmartPointer<char>(NULL); |
| (...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5689 str_(0), | 5529 str_(0), |
| 5690 is_ascii_(true), | 5530 is_ascii_(true), |
| 5691 length_(input.length()), | 5531 length_(input.length()), |
| 5692 start_(input.start()) { } | 5532 start_(input.start()) { } |
| 5693 | 5533 |
| 5694 | 5534 |
| 5695 void FlatStringReader::PostGarbageCollection() { | 5535 void FlatStringReader::PostGarbageCollection() { |
| 5696 if (str_ == NULL) return; | 5536 if (str_ == NULL) return; |
| 5697 Handle<String> str(str_); | 5537 Handle<String> str(str_); |
| 5698 ASSERT(str->IsFlat()); | 5538 ASSERT(str->IsFlat()); |
| 5699 is_ascii_ = str->IsAsciiRepresentation(); | 5539 String::FlatContent content = str->GetFlatContent(); |
| 5540 ASSERT(content.IsFlat()); |
| 5541 is_ascii_ = content.IsAscii(); |
| 5700 if (is_ascii_) { | 5542 if (is_ascii_) { |
| 5701 start_ = str->ToAsciiVector().start(); | 5543 start_ = content.ToAsciiVector().start(); |
| 5702 } else { | 5544 } else { |
| 5703 start_ = str->ToUC16Vector().start(); | 5545 start_ = content.ToUC16Vector().start(); |
| 5704 } | 5546 } |
| 5705 } | 5547 } |
| 5706 | 5548 |
| 5707 | 5549 |
| 5708 void StringInputBuffer::Seek(unsigned pos) { | 5550 void StringInputBuffer::Seek(unsigned pos) { |
| 5709 Reset(pos, input_); | 5551 Reset(pos, input_); |
| 5710 } | 5552 } |
| 5711 | 5553 |
| 5712 | 5554 |
| 5713 void SafeStringInputBuffer::Seek(unsigned pos) { | 5555 void SafeStringInputBuffer::Seek(unsigned pos) { |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6013 } | 5855 } |
| 6014 } | 5856 } |
| 6015 return true; | 5857 return true; |
| 6016 } | 5858 } |
| 6017 | 5859 |
| 6018 | 5860 |
| 6019 template <typename IteratorA> | 5861 template <typename IteratorA> |
| 6020 static inline bool CompareStringContentsPartial(Isolate* isolate, | 5862 static inline bool CompareStringContentsPartial(Isolate* isolate, |
| 6021 IteratorA* ia, | 5863 IteratorA* ia, |
| 6022 String* b) { | 5864 String* b) { |
| 6023 if (b->IsFlat()) { | 5865 String::FlatContent content = b->GetFlatContent(); |
| 6024 if (b->IsAsciiRepresentation()) { | 5866 if (content.IsFlat()) { |
| 6025 VectorIterator<char> ib(b->ToAsciiVector()); | 5867 if (content.IsAscii()) { |
| 5868 VectorIterator<char> ib(content.ToAsciiVector()); |
| 6026 return CompareStringContents(ia, &ib); | 5869 return CompareStringContents(ia, &ib); |
| 6027 } else { | 5870 } else { |
| 6028 VectorIterator<uc16> ib(b->ToUC16Vector()); | 5871 VectorIterator<uc16> ib(content.ToUC16Vector()); |
| 6029 return CompareStringContents(ia, &ib); | 5872 return CompareStringContents(ia, &ib); |
| 6030 } | 5873 } |
| 6031 } else { | 5874 } else { |
| 6032 isolate->objects_string_compare_buffer_b()->Reset(0, b); | 5875 isolate->objects_string_compare_buffer_b()->Reset(0, b); |
| 6033 return CompareStringContents(ia, | 5876 return CompareStringContents(ia, |
| 6034 isolate->objects_string_compare_buffer_b()); | 5877 isolate->objects_string_compare_buffer_b()); |
| 6035 } | 5878 } |
| 6036 } | 5879 } |
| 6037 | 5880 |
| 6038 | 5881 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 6057 | 5900 |
| 6058 if (StringShape(lhs).IsSequentialAscii() && | 5901 if (StringShape(lhs).IsSequentialAscii() && |
| 6059 StringShape(rhs).IsSequentialAscii()) { | 5902 StringShape(rhs).IsSequentialAscii()) { |
| 6060 const char* str1 = SeqAsciiString::cast(lhs)->GetChars(); | 5903 const char* str1 = SeqAsciiString::cast(lhs)->GetChars(); |
| 6061 const char* str2 = SeqAsciiString::cast(rhs)->GetChars(); | 5904 const char* str2 = SeqAsciiString::cast(rhs)->GetChars(); |
| 6062 return CompareRawStringContents(Vector<const char>(str1, len), | 5905 return CompareRawStringContents(Vector<const char>(str1, len), |
| 6063 Vector<const char>(str2, len)); | 5906 Vector<const char>(str2, len)); |
| 6064 } | 5907 } |
| 6065 | 5908 |
| 6066 Isolate* isolate = GetIsolate(); | 5909 Isolate* isolate = GetIsolate(); |
| 6067 if (lhs->IsFlat()) { | 5910 String::FlatContent lhs_content = lhs->GetFlatContent(); |
| 6068 if (lhs->IsAsciiRepresentation()) { | 5911 String::FlatContent rhs_content = rhs->GetFlatContent(); |
| 6069 Vector<const char> vec1 = lhs->ToAsciiVector(); | 5912 if (lhs_content.IsFlat()) { |
| 6070 if (rhs->IsFlat()) { | 5913 if (lhs_content.IsAscii()) { |
| 6071 if (rhs->IsAsciiRepresentation()) { | 5914 Vector<const char> vec1 = lhs_content.ToAsciiVector(); |
| 6072 Vector<const char> vec2 = rhs->ToAsciiVector(); | 5915 if (rhs_content.IsFlat()) { |
| 5916 if (rhs_content.IsAscii()) { |
| 5917 Vector<const char> vec2 = rhs_content.ToAsciiVector(); |
| 6073 return CompareRawStringContents(vec1, vec2); | 5918 return CompareRawStringContents(vec1, vec2); |
| 6074 } else { | 5919 } else { |
| 6075 VectorIterator<char> buf1(vec1); | 5920 VectorIterator<char> buf1(vec1); |
| 6076 VectorIterator<uc16> ib(rhs->ToUC16Vector()); | 5921 VectorIterator<uc16> ib(rhs_content.ToUC16Vector()); |
| 6077 return CompareStringContents(&buf1, &ib); | 5922 return CompareStringContents(&buf1, &ib); |
| 6078 } | 5923 } |
| 6079 } else { | 5924 } else { |
| 6080 VectorIterator<char> buf1(vec1); | 5925 VectorIterator<char> buf1(vec1); |
| 6081 isolate->objects_string_compare_buffer_b()->Reset(0, rhs); | 5926 isolate->objects_string_compare_buffer_b()->Reset(0, rhs); |
| 6082 return CompareStringContents(&buf1, | 5927 return CompareStringContents(&buf1, |
| 6083 isolate->objects_string_compare_buffer_b()); | 5928 isolate->objects_string_compare_buffer_b()); |
| 6084 } | 5929 } |
| 6085 } else { | 5930 } else { |
| 6086 Vector<const uc16> vec1 = lhs->ToUC16Vector(); | 5931 Vector<const uc16> vec1 = lhs_content.ToUC16Vector(); |
| 6087 if (rhs->IsFlat()) { | 5932 if (rhs_content.IsFlat()) { |
| 6088 if (rhs->IsAsciiRepresentation()) { | 5933 if (rhs_content.IsAscii()) { |
| 6089 VectorIterator<uc16> buf1(vec1); | 5934 VectorIterator<uc16> buf1(vec1); |
| 6090 VectorIterator<char> ib(rhs->ToAsciiVector()); | 5935 VectorIterator<char> ib(rhs_content.ToAsciiVector()); |
| 6091 return CompareStringContents(&buf1, &ib); | 5936 return CompareStringContents(&buf1, &ib); |
| 6092 } else { | 5937 } else { |
| 6093 Vector<const uc16> vec2(rhs->ToUC16Vector()); | 5938 Vector<const uc16> vec2(rhs_content.ToUC16Vector()); |
| 6094 return CompareRawStringContents(vec1, vec2); | 5939 return CompareRawStringContents(vec1, vec2); |
| 6095 } | 5940 } |
| 6096 } else { | 5941 } else { |
| 6097 VectorIterator<uc16> buf1(vec1); | 5942 VectorIterator<uc16> buf1(vec1); |
| 6098 isolate->objects_string_compare_buffer_b()->Reset(0, rhs); | 5943 isolate->objects_string_compare_buffer_b()->Reset(0, rhs); |
| 6099 return CompareStringContents(&buf1, | 5944 return CompareStringContents(&buf1, |
| 6100 isolate->objects_string_compare_buffer_b()); | 5945 isolate->objects_string_compare_buffer_b()); |
| 6101 } | 5946 } |
| 6102 } | 5947 } |
| 6103 } else { | 5948 } else { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6136 uc32 r = decoder->GetNext(); | 5981 uc32 r = decoder->GetNext(); |
| 6137 if (Get(i) != r) return false; | 5982 if (Get(i) != r) return false; |
| 6138 } | 5983 } |
| 6139 return i == slen && !decoder->has_more(); | 5984 return i == slen && !decoder->has_more(); |
| 6140 } | 5985 } |
| 6141 | 5986 |
| 6142 | 5987 |
| 6143 bool String::IsAsciiEqualTo(Vector<const char> str) { | 5988 bool String::IsAsciiEqualTo(Vector<const char> str) { |
| 6144 int slen = length(); | 5989 int slen = length(); |
| 6145 if (str.length() != slen) return false; | 5990 if (str.length() != slen) return false; |
| 6146 if (IsFlat() && IsAsciiRepresentation()) { | 5991 FlatContent content = GetFlatContent(); |
| 6147 return CompareChars(ToAsciiVector().start(), str.start(), slen) == 0; | 5992 if (content.IsAscii()) { |
| 5993 return CompareChars(content.ToAsciiVector().start(), |
| 5994 str.start(), slen) == 0; |
| 6148 } | 5995 } |
| 6149 for (int i = 0; i < slen; i++) { | 5996 for (int i = 0; i < slen; i++) { |
| 6150 if (Get(i) != static_cast<uint16_t>(str[i])) return false; | 5997 if (Get(i) != static_cast<uint16_t>(str[i])) return false; |
| 6151 } | 5998 } |
| 6152 return true; | 5999 return true; |
| 6153 } | 6000 } |
| 6154 | 6001 |
| 6155 | 6002 |
| 6156 bool String::IsTwoByteEqualTo(Vector<const uc16> str) { | 6003 bool String::IsTwoByteEqualTo(Vector<const uc16> str) { |
| 6157 int slen = length(); | 6004 int slen = length(); |
| 6158 if (str.length() != slen) return false; | 6005 if (str.length() != slen) return false; |
| 6159 if (IsFlat() && IsTwoByteRepresentation()) { | 6006 FlatContent content = GetFlatContent(); |
| 6160 return CompareChars(ToUC16Vector().start(), str.start(), slen) == 0; | 6007 if (content.IsTwoByte()) { |
| 6008 return CompareChars(content.ToUC16Vector().start(), str.start(), slen) == 0; |
| 6161 } | 6009 } |
| 6162 for (int i = 0; i < slen; i++) { | 6010 for (int i = 0; i < slen; i++) { |
| 6163 if (Get(i) != str[i]) return false; | 6011 if (Get(i) != str[i]) return false; |
| 6164 } | 6012 } |
| 6165 return true; | 6013 return true; |
| 6166 } | 6014 } |
| 6167 | 6015 |
| 6168 | 6016 |
| 6169 uint32_t String::ComputeAndSetHash() { | 6017 uint32_t String::ComputeAndSetHash() { |
| 6170 // Should only be called if hash code has not yet been computed. | 6018 // Should only be called if hash code has not yet been computed. |
| (...skipping 911 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7082 | 6930 |
| 7083 | 6931 |
| 7084 #ifdef ENABLE_DISASSEMBLER | 6932 #ifdef ENABLE_DISASSEMBLER |
| 7085 | 6933 |
| 7086 void DeoptimizationInputData::DeoptimizationInputDataPrint(FILE* out) { | 6934 void DeoptimizationInputData::DeoptimizationInputDataPrint(FILE* out) { |
| 7087 disasm::NameConverter converter; | 6935 disasm::NameConverter converter; |
| 7088 int deopt_count = DeoptCount(); | 6936 int deopt_count = DeoptCount(); |
| 7089 PrintF(out, "Deoptimization Input Data (deopt points = %d)\n", deopt_count); | 6937 PrintF(out, "Deoptimization Input Data (deopt points = %d)\n", deopt_count); |
| 7090 if (0 == deopt_count) return; | 6938 if (0 == deopt_count) return; |
| 7091 | 6939 |
| 7092 PrintF(out, "%6s %6s %6s %12s\n", "index", "ast id", "argc", "commands"); | 6940 PrintF(out, "%6s %6s %6s %12s\n", "index", "ast id", "argc", |
| 6941 FLAG_print_code_verbose ? "commands" : ""); |
| 7093 for (int i = 0; i < deopt_count; i++) { | 6942 for (int i = 0; i < deopt_count; i++) { |
| 7094 PrintF(out, "%6d %6d %6d", | 6943 PrintF(out, "%6d %6d %6d", |
| 7095 i, AstId(i)->value(), ArgumentsStackHeight(i)->value()); | 6944 i, AstId(i)->value(), ArgumentsStackHeight(i)->value()); |
| 7096 | 6945 |
| 7097 if (!FLAG_print_code_verbose) continue; | 6946 if (!FLAG_print_code_verbose) { |
| 6947 PrintF(out, "\n"); |
| 6948 continue; |
| 6949 } |
| 7098 // Print details of the frame translation. | 6950 // Print details of the frame translation. |
| 7099 int translation_index = TranslationIndex(i)->value(); | 6951 int translation_index = TranslationIndex(i)->value(); |
| 7100 TranslationIterator iterator(TranslationByteArray(), translation_index); | 6952 TranslationIterator iterator(TranslationByteArray(), translation_index); |
| 7101 Translation::Opcode opcode = | 6953 Translation::Opcode opcode = |
| 7102 static_cast<Translation::Opcode>(iterator.Next()); | 6954 static_cast<Translation::Opcode>(iterator.Next()); |
| 7103 ASSERT(Translation::BEGIN == opcode); | 6955 ASSERT(Translation::BEGIN == opcode); |
| 7104 int frame_count = iterator.Next(); | 6956 int frame_count = iterator.Next(); |
| 7105 PrintF(out, " %s {count=%d}\n", Translation::StringFor(opcode), | 6957 PrintF(out, " %s {count=%d}\n", Translation::StringFor(opcode), |
| 7106 frame_count); | 6958 frame_count); |
| 7107 | 6959 |
| (...skipping 1416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8524 } else { | 8376 } else { |
| 8525 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 8377 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 8526 Handle<String> name = isolate->factory()->NumberToString(number); | 8378 Handle<String> name = isolate->factory()->NumberToString(number); |
| 8527 Handle<Object> args[1] = { name }; | 8379 Handle<Object> args[1] = { name }; |
| 8528 Handle<Object> error = | 8380 Handle<Object> error = |
| 8529 isolate->factory()->NewTypeError("object_not_extensible", | 8381 isolate->factory()->NewTypeError("object_not_extensible", |
| 8530 HandleVector(args, 1)); | 8382 HandleVector(args, 1)); |
| 8531 return isolate->Throw(*error); | 8383 return isolate->Throw(*error); |
| 8532 } | 8384 } |
| 8533 } | 8385 } |
| 8534 Object* new_dictionary; | 8386 FixedArrayBase* new_dictionary; |
| 8535 MaybeObject* maybe = dictionary->AtNumberPut(index, value); | 8387 MaybeObject* maybe = dictionary->AtNumberPut(index, value); |
| 8536 if (!maybe->ToObject(&new_dictionary)) return maybe; | 8388 if (!maybe->To<FixedArrayBase>(&new_dictionary)) return maybe; |
| 8537 if (dictionary != NumberDictionary::cast(new_dictionary)) { | 8389 if (dictionary != NumberDictionary::cast(new_dictionary)) { |
| 8538 if (is_arguments) { | 8390 if (is_arguments) { |
| 8539 elements->set(1, new_dictionary); | 8391 elements->set(1, new_dictionary); |
| 8540 } else { | 8392 } else { |
| 8541 set_elements(HeapObject::cast(new_dictionary)); | 8393 set_elements(new_dictionary); |
| 8542 } | 8394 } |
| 8543 dictionary = NumberDictionary::cast(new_dictionary); | 8395 dictionary = NumberDictionary::cast(new_dictionary); |
| 8544 } | 8396 } |
| 8545 } | 8397 } |
| 8546 | 8398 |
| 8547 // Update the array length if this JSObject is an array. | 8399 // Update the array length if this JSObject is an array. |
| 8548 if (IsJSArray()) { | 8400 if (IsJSArray()) { |
| 8549 MaybeObject* result = | 8401 MaybeObject* result = |
| 8550 JSArray::cast(this)->JSArrayUpdateLengthFromIndex(index, value); | 8402 JSArray::cast(this)->JSArrayUpdateLengthFromIndex(index, value); |
| 8551 if (result->IsFailure()) return result; | 8403 if (result->IsFailure()) return result; |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8820 // Leaving JavaScript. | 8672 // Leaving JavaScript. |
| 8821 VMState state(isolate, EXTERNAL); | 8673 VMState state(isolate, EXTERNAL); |
| 8822 result = getter(index, info); | 8674 result = getter(index, info); |
| 8823 } | 8675 } |
| 8824 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 8676 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 8825 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); | 8677 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); |
| 8826 } | 8678 } |
| 8827 | 8679 |
| 8828 Heap* heap = holder_handle->GetHeap(); | 8680 Heap* heap = holder_handle->GetHeap(); |
| 8829 ElementsAccessor* handler = holder_handle->GetElementsAccessor(); | 8681 ElementsAccessor* handler = holder_handle->GetElementsAccessor(); |
| 8830 MaybeObject* raw_result = handler->GetWithReceiver(*holder_handle, | 8682 MaybeObject* raw_result = handler->Get(holder_handle->elements(), |
| 8831 *this_handle, | 8683 index, |
| 8832 index); | 8684 *holder_handle, |
| 8685 *this_handle); |
| 8833 if (raw_result != heap->the_hole_value()) return raw_result; | 8686 if (raw_result != heap->the_hole_value()) return raw_result; |
| 8834 | 8687 |
| 8835 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 8688 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 8836 | 8689 |
| 8837 Object* pt = holder_handle->GetPrototype(); | 8690 Object* pt = holder_handle->GetPrototype(); |
| 8838 if (pt == heap->null_value()) return heap->undefined_value(); | 8691 if (pt == heap->null_value()) return heap->undefined_value(); |
| 8839 return pt->GetElementWithReceiver(*this_handle, index); | 8692 return pt->GetElementWithReceiver(*this_handle, index); |
| 8840 } | 8693 } |
| 8841 | 8694 |
| 8842 | 8695 |
| (...skipping 2867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11710 if (break_point_objects()->IsUndefined()) return 0; | 11563 if (break_point_objects()->IsUndefined()) return 0; |
| 11711 // Single break point. | 11564 // Single break point. |
| 11712 if (!break_point_objects()->IsFixedArray()) return 1; | 11565 if (!break_point_objects()->IsFixedArray()) return 1; |
| 11713 // Multiple break points. | 11566 // Multiple break points. |
| 11714 return FixedArray::cast(break_point_objects())->length(); | 11567 return FixedArray::cast(break_point_objects())->length(); |
| 11715 } | 11568 } |
| 11716 #endif | 11569 #endif |
| 11717 | 11570 |
| 11718 | 11571 |
| 11719 } } // namespace v8::internal | 11572 } } // namespace v8::internal |
| OLD | NEW |