OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/allocation-site-scopes.h" | 8 #include "src/allocation-site-scopes.h" |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
(...skipping 988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
999 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); | 999 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); |
1000 DCHECK(memcmp(smart_chars.start(), | 1000 DCHECK(memcmp(smart_chars.start(), |
1001 resource->data(), | 1001 resource->data(), |
1002 resource->length() * sizeof(smart_chars[0])) == 0); | 1002 resource->length() * sizeof(smart_chars[0])) == 0); |
1003 } | 1003 } |
1004 #endif // DEBUG | 1004 #endif // DEBUG |
1005 int size = this->Size(); // Byte size of the original string. | 1005 int size = this->Size(); // Byte size of the original string. |
1006 // Abort if size does not allow in-place conversion. | 1006 // Abort if size does not allow in-place conversion. |
1007 if (size < ExternalString::kShortSize) return false; | 1007 if (size < ExternalString::kShortSize) return false; |
1008 Heap* heap = GetHeap(); | 1008 Heap* heap = GetHeap(); |
1009 bool is_ascii = this->IsOneByteRepresentation(); | 1009 bool is_one_byte = this->IsOneByteRepresentation(); |
1010 bool is_internalized = this->IsInternalizedString(); | 1010 bool is_internalized = this->IsInternalizedString(); |
1011 | 1011 |
1012 // Morph the string to an external string by replacing the map and | 1012 // Morph the string to an external string by replacing the map and |
1013 // reinitializing the fields. This won't work if the space the existing | 1013 // reinitializing the fields. This won't work if the space the existing |
1014 // string occupies is too small for a regular external string. | 1014 // string occupies is too small for a regular external string. |
1015 // Instead, we resort to a short external string instead, omitting | 1015 // Instead, we resort to a short external string instead, omitting |
1016 // the field caching the address of the backing store. When we encounter | 1016 // the field caching the address of the backing store. When we encounter |
1017 // short external strings in generated code, we need to bailout to runtime. | 1017 // short external strings in generated code, we need to bailout to runtime. |
1018 Map* new_map; | 1018 Map* new_map; |
1019 if (size < ExternalString::kSize) { | 1019 if (size < ExternalString::kSize) { |
1020 new_map = is_internalized | 1020 new_map = is_internalized |
1021 ? (is_ascii | 1021 ? (is_one_byte |
1022 ? heap-> | 1022 ? heap->short_external_internalized_string_with_one_byte_data_map() |
1023 short_external_internalized_string_with_one_byte_data_map() | 1023 : heap->short_external_internalized_string_map()) |
1024 : heap->short_external_internalized_string_map()) | 1024 : (is_one_byte ? heap->short_external_string_with_one_byte_data_map() |
1025 : (is_ascii | 1025 : heap->short_external_string_map()); |
1026 ? heap->short_external_string_with_one_byte_data_map() | |
1027 : heap->short_external_string_map()); | |
1028 } else { | 1026 } else { |
1029 new_map = is_internalized | 1027 new_map = is_internalized |
1030 ? (is_ascii | 1028 ? (is_one_byte |
1031 ? heap->external_internalized_string_with_one_byte_data_map() | 1029 ? heap->external_internalized_string_with_one_byte_data_map() |
1032 : heap->external_internalized_string_map()) | 1030 : heap->external_internalized_string_map()) |
1033 : (is_ascii | 1031 : (is_one_byte ? heap->external_string_with_one_byte_data_map() |
1034 ? heap->external_string_with_one_byte_data_map() | 1032 : heap->external_string_map()); |
1035 : heap->external_string_map()); | |
1036 } | 1033 } |
1037 | 1034 |
1038 // Byte size of the external String object. | 1035 // Byte size of the external String object. |
1039 int new_size = this->SizeFromMap(new_map); | 1036 int new_size = this->SizeFromMap(new_map); |
1040 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size); | 1037 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size); |
1041 | 1038 |
1042 // We are storing the new map using release store after creating a filler for | 1039 // We are storing the new map using release store after creating a filler for |
1043 // the left-over space to avoid races with the sweeper thread. | 1040 // the left-over space to avoid races with the sweeper thread. |
1044 this->synchronized_set_map(new_map); | 1041 this->synchronized_set_map(new_map); |
1045 | 1042 |
1046 ExternalTwoByteString* self = ExternalTwoByteString::cast(this); | 1043 ExternalTwoByteString* self = ExternalTwoByteString::cast(this); |
1047 self->set_resource(resource); | 1044 self->set_resource(resource); |
1048 if (is_internalized) self->Hash(); // Force regeneration of the hash value. | 1045 if (is_internalized) self->Hash(); // Force regeneration of the hash value. |
1049 | 1046 |
1050 heap->AdjustLiveBytes(this->address(), new_size - size, Heap::FROM_MUTATOR); | 1047 heap->AdjustLiveBytes(this->address(), new_size - size, Heap::FROM_MUTATOR); |
1051 return true; | 1048 return true; |
1052 } | 1049 } |
1053 | 1050 |
1054 | 1051 |
1055 bool String::MakeExternal(v8::String::ExternalAsciiStringResource* resource) { | 1052 bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) { |
1056 // Externalizing twice leaks the external resource, so it's | 1053 // Externalizing twice leaks the external resource, so it's |
1057 // prohibited by the API. | 1054 // prohibited by the API. |
1058 DCHECK(!this->IsExternalString()); | 1055 DCHECK(!this->IsExternalString()); |
1059 #ifdef ENABLE_SLOW_DCHECKS | 1056 #ifdef ENABLE_SLOW_DCHECKS |
1060 if (FLAG_enable_slow_asserts) { | 1057 if (FLAG_enable_slow_asserts) { |
1061 // Assert that the resource and the string are equivalent. | 1058 // Assert that the resource and the string are equivalent. |
1062 DCHECK(static_cast<size_t>(this->length()) == resource->length()); | 1059 DCHECK(static_cast<size_t>(this->length()) == resource->length()); |
1063 if (this->IsTwoByteRepresentation()) { | 1060 if (this->IsTwoByteRepresentation()) { |
1064 ScopedVector<uint16_t> smart_chars(this->length()); | 1061 ScopedVector<uint16_t> smart_chars(this->length()); |
1065 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); | 1062 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); |
(...skipping 14 matching lines...) Expand all Loading... |
1080 | 1077 |
1081 // Morph the string to an external string by replacing the map and | 1078 // Morph the string to an external string by replacing the map and |
1082 // reinitializing the fields. This won't work if the space the existing | 1079 // reinitializing the fields. This won't work if the space the existing |
1083 // string occupies is too small for a regular external string. | 1080 // string occupies is too small for a regular external string. |
1084 // Instead, we resort to a short external string instead, omitting | 1081 // Instead, we resort to a short external string instead, omitting |
1085 // the field caching the address of the backing store. When we encounter | 1082 // the field caching the address of the backing store. When we encounter |
1086 // short external strings in generated code, we need to bailout to runtime. | 1083 // short external strings in generated code, we need to bailout to runtime. |
1087 Map* new_map; | 1084 Map* new_map; |
1088 if (size < ExternalString::kSize) { | 1085 if (size < ExternalString::kSize) { |
1089 new_map = is_internalized | 1086 new_map = is_internalized |
1090 ? heap->short_external_ascii_internalized_string_map() | 1087 ? heap->short_external_one_byte_internalized_string_map() |
1091 : heap->short_external_ascii_string_map(); | 1088 : heap->short_external_one_byte_string_map(); |
1092 } else { | 1089 } else { |
1093 new_map = is_internalized | 1090 new_map = is_internalized |
1094 ? heap->external_ascii_internalized_string_map() | 1091 ? heap->external_one_byte_internalized_string_map() |
1095 : heap->external_ascii_string_map(); | 1092 : heap->external_one_byte_string_map(); |
1096 } | 1093 } |
1097 | 1094 |
1098 // Byte size of the external String object. | 1095 // Byte size of the external String object. |
1099 int new_size = this->SizeFromMap(new_map); | 1096 int new_size = this->SizeFromMap(new_map); |
1100 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size); | 1097 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size); |
1101 | 1098 |
1102 // We are storing the new map using release store after creating a filler for | 1099 // We are storing the new map using release store after creating a filler for |
1103 // the left-over space to avoid races with the sweeper thread. | 1100 // the left-over space to avoid races with the sweeper thread. |
1104 this->synchronized_set_map(new_map); | 1101 this->synchronized_set_map(new_map); |
1105 | 1102 |
1106 ExternalAsciiString* self = ExternalAsciiString::cast(this); | 1103 ExternalOneByteString* self = ExternalOneByteString::cast(this); |
1107 self->set_resource(resource); | 1104 self->set_resource(resource); |
1108 if (is_internalized) self->Hash(); // Force regeneration of the hash value. | 1105 if (is_internalized) self->Hash(); // Force regeneration of the hash value. |
1109 | 1106 |
1110 heap->AdjustLiveBytes(this->address(), new_size - size, Heap::FROM_MUTATOR); | 1107 heap->AdjustLiveBytes(this->address(), new_size - size, Heap::FROM_MUTATOR); |
1111 return true; | 1108 return true; |
1112 } | 1109 } |
1113 | 1110 |
1114 | 1111 |
1115 void String::StringShortPrint(StringStream* accumulator) { | 1112 void String::StringShortPrint(StringStream* accumulator) { |
1116 int len = length(); | 1113 int len = length(); |
1117 if (len > kMaxShortPrintLength) { | 1114 if (len > kMaxShortPrintLength) { |
1118 accumulator->Add("<Very long string[%u]>", len); | 1115 accumulator->Add("<Very long string[%u]>", len); |
1119 return; | 1116 return; |
1120 } | 1117 } |
1121 | 1118 |
1122 if (!LooksValid()) { | 1119 if (!LooksValid()) { |
1123 accumulator->Add("<Invalid String>"); | 1120 accumulator->Add("<Invalid String>"); |
1124 return; | 1121 return; |
1125 } | 1122 } |
1126 | 1123 |
1127 ConsStringIteratorOp op; | 1124 ConsStringIteratorOp op; |
1128 StringCharacterStream stream(this, &op); | 1125 StringCharacterStream stream(this, &op); |
1129 | 1126 |
1130 bool truncated = false; | 1127 bool truncated = false; |
1131 if (len > kMaxShortPrintLength) { | 1128 if (len > kMaxShortPrintLength) { |
1132 len = kMaxShortPrintLength; | 1129 len = kMaxShortPrintLength; |
1133 truncated = true; | 1130 truncated = true; |
1134 } | 1131 } |
1135 bool ascii = true; | 1132 bool one_byte = true; |
1136 for (int i = 0; i < len; i++) { | 1133 for (int i = 0; i < len; i++) { |
1137 uint16_t c = stream.GetNext(); | 1134 uint16_t c = stream.GetNext(); |
1138 | 1135 |
1139 if (c < 32 || c >= 127) { | 1136 if (c < 32 || c >= 127) { |
1140 ascii = false; | 1137 one_byte = false; |
1141 } | 1138 } |
1142 } | 1139 } |
1143 stream.Reset(this); | 1140 stream.Reset(this); |
1144 if (ascii) { | 1141 if (one_byte) { |
1145 accumulator->Add("<String[%u]: ", length()); | 1142 accumulator->Add("<String[%u]: ", length()); |
1146 for (int i = 0; i < len; i++) { | 1143 for (int i = 0; i < len; i++) { |
1147 accumulator->Put(static_cast<char>(stream.GetNext())); | 1144 accumulator->Put(static_cast<char>(stream.GetNext())); |
1148 } | 1145 } |
1149 accumulator->Put('>'); | 1146 accumulator->Put('>'); |
1150 } else { | 1147 } else { |
1151 // Backslash indicates that the string contains control | 1148 // Backslash indicates that the string contains control |
1152 // characters and that backslashes are therefore escaped. | 1149 // characters and that backslashes are therefore escaped. |
1153 accumulator->Add("<String[%u]\\: ", length()); | 1150 accumulator->Add("<String[%u]\\: ", length()); |
1154 for (int i = 0; i < len; i++) { | 1151 for (int i = 0; i < len; i++) { |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1548 case kSeqStringTag: | 1545 case kSeqStringTag: |
1549 break; | 1546 break; |
1550 case kConsStringTag: | 1547 case kConsStringTag: |
1551 ConsString::BodyDescriptor::IterateBody(this, v); | 1548 ConsString::BodyDescriptor::IterateBody(this, v); |
1552 break; | 1549 break; |
1553 case kSlicedStringTag: | 1550 case kSlicedStringTag: |
1554 SlicedString::BodyDescriptor::IterateBody(this, v); | 1551 SlicedString::BodyDescriptor::IterateBody(this, v); |
1555 break; | 1552 break; |
1556 case kExternalStringTag: | 1553 case kExternalStringTag: |
1557 if ((type & kStringEncodingMask) == kOneByteStringTag) { | 1554 if ((type & kStringEncodingMask) == kOneByteStringTag) { |
1558 reinterpret_cast<ExternalAsciiString*>(this)-> | 1555 reinterpret_cast<ExternalOneByteString*>(this) |
1559 ExternalAsciiStringIterateBody(v); | 1556 ->ExternalOneByteStringIterateBody(v); |
1560 } else { | 1557 } else { |
1561 reinterpret_cast<ExternalTwoByteString*>(this)-> | 1558 reinterpret_cast<ExternalTwoByteString*>(this)-> |
1562 ExternalTwoByteStringIterateBody(v); | 1559 ExternalTwoByteStringIterateBody(v); |
1563 } | 1560 } |
1564 break; | 1561 break; |
1565 } | 1562 } |
1566 return; | 1563 return; |
1567 } | 1564 } |
1568 | 1565 |
1569 switch (type) { | 1566 switch (type) { |
(...skipping 1881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3451 Execution::Call(isolate, | 3448 Execution::Call(isolate, |
3452 isolate->to_complete_property_descriptor(), | 3449 isolate->to_complete_property_descriptor(), |
3453 result, | 3450 result, |
3454 arraysize(argv), | 3451 arraysize(argv), |
3455 argv), | 3452 argv), |
3456 Object); | 3453 Object); |
3457 | 3454 |
3458 // [[GetProperty]] requires to check that all properties are configurable. | 3455 // [[GetProperty]] requires to check that all properties are configurable. |
3459 Handle<String> configurable_name = | 3456 Handle<String> configurable_name = |
3460 isolate->factory()->InternalizeOneByteString( | 3457 isolate->factory()->InternalizeOneByteString( |
3461 STATIC_ASCII_VECTOR("configurable_")); | 3458 STATIC_CHAR_VECTOR("configurable_")); |
3462 Handle<Object> configurable = | 3459 Handle<Object> configurable = |
3463 Object::GetProperty(desc, configurable_name).ToHandleChecked(); | 3460 Object::GetProperty(desc, configurable_name).ToHandleChecked(); |
3464 DCHECK(configurable->IsBoolean()); | 3461 DCHECK(configurable->IsBoolean()); |
3465 if (configurable->IsFalse()) { | 3462 if (configurable->IsFalse()) { |
3466 Handle<String> trap = | 3463 Handle<String> trap = isolate->factory()->InternalizeOneByteString( |
3467 isolate->factory()->InternalizeOneByteString( | 3464 STATIC_CHAR_VECTOR("getPropertyDescriptor")); |
3468 STATIC_ASCII_VECTOR("getPropertyDescriptor")); | |
3469 Handle<Object> args[] = { handler, trap, name }; | 3465 Handle<Object> args[] = { handler, trap, name }; |
3470 THROW_NEW_ERROR(isolate, NewTypeError("proxy_prop_not_configurable", | 3466 THROW_NEW_ERROR(isolate, NewTypeError("proxy_prop_not_configurable", |
3471 HandleVector(args, arraysize(args))), | 3467 HandleVector(args, arraysize(args))), |
3472 Object); | 3468 Object); |
3473 } | 3469 } |
3474 DCHECK(configurable->IsTrue()); | 3470 DCHECK(configurable->IsTrue()); |
3475 | 3471 |
3476 // Check for DataDescriptor. | 3472 // Check for DataDescriptor. |
3477 Handle<String> hasWritable_name = | 3473 Handle<String> hasWritable_name = |
3478 isolate->factory()->InternalizeOneByteString( | 3474 isolate->factory()->InternalizeOneByteString( |
3479 STATIC_ASCII_VECTOR("hasWritable_")); | 3475 STATIC_CHAR_VECTOR("hasWritable_")); |
3480 Handle<Object> hasWritable = | 3476 Handle<Object> hasWritable = |
3481 Object::GetProperty(desc, hasWritable_name).ToHandleChecked(); | 3477 Object::GetProperty(desc, hasWritable_name).ToHandleChecked(); |
3482 DCHECK(hasWritable->IsBoolean()); | 3478 DCHECK(hasWritable->IsBoolean()); |
3483 if (hasWritable->IsTrue()) { | 3479 if (hasWritable->IsTrue()) { |
3484 Handle<String> writable_name = | 3480 Handle<String> writable_name = isolate->factory()->InternalizeOneByteString( |
3485 isolate->factory()->InternalizeOneByteString( | 3481 STATIC_CHAR_VECTOR("writable_")); |
3486 STATIC_ASCII_VECTOR("writable_")); | |
3487 Handle<Object> writable = | 3482 Handle<Object> writable = |
3488 Object::GetProperty(desc, writable_name).ToHandleChecked(); | 3483 Object::GetProperty(desc, writable_name).ToHandleChecked(); |
3489 DCHECK(writable->IsBoolean()); | 3484 DCHECK(writable->IsBoolean()); |
3490 *done = writable->IsFalse(); | 3485 *done = writable->IsFalse(); |
3491 if (!*done) return isolate->factory()->the_hole_value(); | 3486 if (!*done) return isolate->factory()->the_hole_value(); |
3492 if (strict_mode == SLOPPY) return value; | 3487 if (strict_mode == SLOPPY) return value; |
3493 Handle<Object> args[] = { name, receiver }; | 3488 Handle<Object> args[] = { name, receiver }; |
3494 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", | 3489 THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property", |
3495 HandleVector(args, arraysize(args))), | 3490 HandleVector(args, arraysize(args))), |
3496 Object); | 3491 Object); |
3497 } | 3492 } |
3498 | 3493 |
3499 // We have an AccessorDescriptor. | 3494 // We have an AccessorDescriptor. |
3500 Handle<String> set_name = isolate->factory()->InternalizeOneByteString( | 3495 Handle<String> set_name = |
3501 STATIC_ASCII_VECTOR("set_")); | 3496 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("set_")); |
3502 Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked(); | 3497 Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked(); |
3503 if (!setter->IsUndefined()) { | 3498 if (!setter->IsUndefined()) { |
3504 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 3499 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
3505 return SetPropertyWithDefinedSetter( | 3500 return SetPropertyWithDefinedSetter( |
3506 receiver, Handle<JSReceiver>::cast(setter), value); | 3501 receiver, Handle<JSReceiver>::cast(setter), value); |
3507 } | 3502 } |
3508 | 3503 |
3509 if (strict_mode == SLOPPY) return value; | 3504 if (strict_mode == SLOPPY) return value; |
3510 Handle<Object> args2[] = { name, proxy }; | 3505 Handle<Object> args2[] = { name, proxy }; |
3511 THROW_NEW_ERROR(isolate, NewTypeError("no_setter_in_callback", | 3506 THROW_NEW_ERROR(isolate, NewTypeError("no_setter_in_callback", |
(...skipping 17 matching lines...) Expand all Loading... |
3529 "delete", | 3524 "delete", |
3530 Handle<Object>(), | 3525 Handle<Object>(), |
3531 arraysize(args), | 3526 arraysize(args), |
3532 args), | 3527 args), |
3533 Object); | 3528 Object); |
3534 | 3529 |
3535 bool result_bool = result->BooleanValue(); | 3530 bool result_bool = result->BooleanValue(); |
3536 if (mode == STRICT_DELETION && !result_bool) { | 3531 if (mode == STRICT_DELETION && !result_bool) { |
3537 Handle<Object> handler(proxy->handler(), isolate); | 3532 Handle<Object> handler(proxy->handler(), isolate); |
3538 Handle<String> trap_name = isolate->factory()->InternalizeOneByteString( | 3533 Handle<String> trap_name = isolate->factory()->InternalizeOneByteString( |
3539 STATIC_ASCII_VECTOR("delete")); | 3534 STATIC_CHAR_VECTOR("delete")); |
3540 Handle<Object> args[] = { handler, trap_name }; | 3535 Handle<Object> args[] = { handler, trap_name }; |
3541 THROW_NEW_ERROR(isolate, NewTypeError("handler_failed", | 3536 THROW_NEW_ERROR(isolate, NewTypeError("handler_failed", |
3542 HandleVector(args, arraysize(args))), | 3537 HandleVector(args, arraysize(args))), |
3543 Object); | 3538 Object); |
3544 } | 3539 } |
3545 return isolate->factory()->ToBoolean(result_bool); | 3540 return isolate->factory()->ToBoolean(result_bool); |
3546 } | 3541 } |
3547 | 3542 |
3548 | 3543 |
3549 MaybeHandle<Object> JSProxy::DeleteElementWithHandler( | 3544 MaybeHandle<Object> JSProxy::DeleteElementWithHandler( |
(...skipping 25 matching lines...) Expand all Loading... |
3575 Handle<Object> argv[] = { result }; | 3570 Handle<Object> argv[] = { result }; |
3576 Handle<Object> desc; | 3571 Handle<Object> desc; |
3577 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 3572 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
3578 isolate, desc, | 3573 isolate, desc, |
3579 Execution::Call(isolate, isolate->to_complete_property_descriptor(), | 3574 Execution::Call(isolate, isolate->to_complete_property_descriptor(), |
3580 result, arraysize(argv), argv), | 3575 result, arraysize(argv), argv), |
3581 Maybe<PropertyAttributes>()); | 3576 Maybe<PropertyAttributes>()); |
3582 | 3577 |
3583 // Convert result to PropertyAttributes. | 3578 // Convert result to PropertyAttributes. |
3584 Handle<String> enum_n = isolate->factory()->InternalizeOneByteString( | 3579 Handle<String> enum_n = isolate->factory()->InternalizeOneByteString( |
3585 STATIC_ASCII_VECTOR("enumerable_")); | 3580 STATIC_CHAR_VECTOR("enumerable_")); |
3586 Handle<Object> enumerable; | 3581 Handle<Object> enumerable; |
3587 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, enumerable, | 3582 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, enumerable, |
3588 Object::GetProperty(desc, enum_n), | 3583 Object::GetProperty(desc, enum_n), |
3589 Maybe<PropertyAttributes>()); | 3584 Maybe<PropertyAttributes>()); |
3590 Handle<String> conf_n = isolate->factory()->InternalizeOneByteString( | 3585 Handle<String> conf_n = isolate->factory()->InternalizeOneByteString( |
3591 STATIC_ASCII_VECTOR("configurable_")); | 3586 STATIC_CHAR_VECTOR("configurable_")); |
3592 Handle<Object> configurable; | 3587 Handle<Object> configurable; |
3593 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, configurable, | 3588 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, configurable, |
3594 Object::GetProperty(desc, conf_n), | 3589 Object::GetProperty(desc, conf_n), |
3595 Maybe<PropertyAttributes>()); | 3590 Maybe<PropertyAttributes>()); |
3596 Handle<String> writ_n = isolate->factory()->InternalizeOneByteString( | 3591 Handle<String> writ_n = isolate->factory()->InternalizeOneByteString( |
3597 STATIC_ASCII_VECTOR("writable_")); | 3592 STATIC_CHAR_VECTOR("writable_")); |
3598 Handle<Object> writable; | 3593 Handle<Object> writable; |
3599 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, writable, | 3594 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, writable, |
3600 Object::GetProperty(desc, writ_n), | 3595 Object::GetProperty(desc, writ_n), |
3601 Maybe<PropertyAttributes>()); | 3596 Maybe<PropertyAttributes>()); |
3602 if (!writable->BooleanValue()) { | 3597 if (!writable->BooleanValue()) { |
3603 Handle<String> set_n = isolate->factory()->InternalizeOneByteString( | 3598 Handle<String> set_n = isolate->factory()->InternalizeOneByteString( |
3604 STATIC_ASCII_VECTOR("set_")); | 3599 STATIC_CHAR_VECTOR("set_")); |
3605 Handle<Object> setter; | 3600 Handle<Object> setter; |
3606 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, setter, | 3601 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, setter, |
3607 Object::GetProperty(desc, set_n), | 3602 Object::GetProperty(desc, set_n), |
3608 Maybe<PropertyAttributes>()); | 3603 Maybe<PropertyAttributes>()); |
3609 writable = isolate->factory()->ToBoolean(!setter->IsUndefined()); | 3604 writable = isolate->factory()->ToBoolean(!setter->IsUndefined()); |
3610 } | 3605 } |
3611 | 3606 |
3612 if (configurable->IsFalse()) { | 3607 if (configurable->IsFalse()) { |
3613 Handle<Object> handler(proxy->handler(), isolate); | 3608 Handle<Object> handler(proxy->handler(), isolate); |
3614 Handle<String> trap = isolate->factory()->InternalizeOneByteString( | 3609 Handle<String> trap = isolate->factory()->InternalizeOneByteString( |
3615 STATIC_ASCII_VECTOR("getPropertyDescriptor")); | 3610 STATIC_CHAR_VECTOR("getPropertyDescriptor")); |
3616 Handle<Object> args[] = { handler, trap, name }; | 3611 Handle<Object> args[] = { handler, trap, name }; |
3617 Handle<Object> error; | 3612 Handle<Object> error; |
3618 MaybeHandle<Object> maybe_error = isolate->factory()->NewTypeError( | 3613 MaybeHandle<Object> maybe_error = isolate->factory()->NewTypeError( |
3619 "proxy_prop_not_configurable", HandleVector(args, arraysize(args))); | 3614 "proxy_prop_not_configurable", HandleVector(args, arraysize(args))); |
3620 if (maybe_error.ToHandle(&error)) isolate->Throw(*error); | 3615 if (maybe_error.ToHandle(&error)) isolate->Throw(*error); |
3621 return maybe(NONE); | 3616 return maybe(NONE); |
3622 } | 3617 } |
3623 | 3618 |
3624 int attributes = NONE; | 3619 int attributes = NONE; |
3625 if (!enumerable->BooleanValue()) attributes |= DONT_ENUM; | 3620 if (!enumerable->BooleanValue()) attributes |= DONT_ENUM; |
(...skipping 4344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7970 string = slice->parent(); | 7965 string = slice->parent(); |
7971 shape = StringShape(string); | 7966 shape = StringShape(string); |
7972 DCHECK(shape.representation_tag() != kConsStringTag && | 7967 DCHECK(shape.representation_tag() != kConsStringTag && |
7973 shape.representation_tag() != kSlicedStringTag); | 7968 shape.representation_tag() != kSlicedStringTag); |
7974 } | 7969 } |
7975 if (shape.encoding_tag() == kOneByteStringTag) { | 7970 if (shape.encoding_tag() == kOneByteStringTag) { |
7976 const uint8_t* start; | 7971 const uint8_t* start; |
7977 if (shape.representation_tag() == kSeqStringTag) { | 7972 if (shape.representation_tag() == kSeqStringTag) { |
7978 start = SeqOneByteString::cast(string)->GetChars(); | 7973 start = SeqOneByteString::cast(string)->GetChars(); |
7979 } else { | 7974 } else { |
7980 start = ExternalAsciiString::cast(string)->GetChars(); | 7975 start = ExternalOneByteString::cast(string)->GetChars(); |
7981 } | 7976 } |
7982 return FlatContent(start + offset, length); | 7977 return FlatContent(start + offset, length); |
7983 } else { | 7978 } else { |
7984 DCHECK(shape.encoding_tag() == kTwoByteStringTag); | 7979 DCHECK(shape.encoding_tag() == kTwoByteStringTag); |
7985 const uc16* start; | 7980 const uc16* start; |
7986 if (shape.representation_tag() == kSeqStringTag) { | 7981 if (shape.representation_tag() == kSeqStringTag) { |
7987 start = SeqTwoByteString::cast(string)->GetChars(); | 7982 start = SeqTwoByteString::cast(string)->GetChars(); |
7988 } else { | 7983 } else { |
7989 start = ExternalTwoByteString::cast(string)->GetChars(); | 7984 start = ExternalTwoByteString::cast(string)->GetChars(); |
7990 } | 7985 } |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8155 : Relocatable(isolate), | 8150 : Relocatable(isolate), |
8156 str_(str.location()), | 8151 str_(str.location()), |
8157 length_(str->length()) { | 8152 length_(str->length()) { |
8158 PostGarbageCollection(); | 8153 PostGarbageCollection(); |
8159 } | 8154 } |
8160 | 8155 |
8161 | 8156 |
8162 FlatStringReader::FlatStringReader(Isolate* isolate, Vector<const char> input) | 8157 FlatStringReader::FlatStringReader(Isolate* isolate, Vector<const char> input) |
8163 : Relocatable(isolate), | 8158 : Relocatable(isolate), |
8164 str_(0), | 8159 str_(0), |
8165 is_ascii_(true), | 8160 is_one_byte_(true), |
8166 length_(input.length()), | 8161 length_(input.length()), |
8167 start_(input.start()) { } | 8162 start_(input.start()) {} |
8168 | 8163 |
8169 | 8164 |
8170 void FlatStringReader::PostGarbageCollection() { | 8165 void FlatStringReader::PostGarbageCollection() { |
8171 if (str_ == NULL) return; | 8166 if (str_ == NULL) return; |
8172 Handle<String> str(str_); | 8167 Handle<String> str(str_); |
8173 DCHECK(str->IsFlat()); | 8168 DCHECK(str->IsFlat()); |
8174 DisallowHeapAllocation no_gc; | 8169 DisallowHeapAllocation no_gc; |
8175 // This does not actually prevent the vector from being relocated later. | 8170 // This does not actually prevent the vector from being relocated later. |
8176 String::FlatContent content = str->GetFlatContent(); | 8171 String::FlatContent content = str->GetFlatContent(); |
8177 DCHECK(content.IsFlat()); | 8172 DCHECK(content.IsFlat()); |
8178 is_ascii_ = content.IsAscii(); | 8173 is_one_byte_ = content.IsOneByte(); |
8179 if (is_ascii_) { | 8174 if (is_one_byte_) { |
8180 start_ = content.ToOneByteVector().start(); | 8175 start_ = content.ToOneByteVector().start(); |
8181 } else { | 8176 } else { |
8182 start_ = content.ToUC16Vector().start(); | 8177 start_ = content.ToUC16Vector().start(); |
8183 } | 8178 } |
8184 } | 8179 } |
8185 | 8180 |
8186 | 8181 |
8187 void ConsStringIteratorOp::Initialize(ConsString* cons_string, int offset) { | 8182 void ConsStringIteratorOp::Initialize(ConsString* cons_string, int offset) { |
8188 DCHECK(cons_string != NULL); | 8183 DCHECK(cons_string != NULL); |
8189 root_ = cons_string; | 8184 root_ = cons_string; |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8363 sinkchar* sink, | 8358 sinkchar* sink, |
8364 int f, | 8359 int f, |
8365 int t) { | 8360 int t) { |
8366 String* source = src; | 8361 String* source = src; |
8367 int from = f; | 8362 int from = f; |
8368 int to = t; | 8363 int to = t; |
8369 while (true) { | 8364 while (true) { |
8370 DCHECK(0 <= from && from <= to && to <= source->length()); | 8365 DCHECK(0 <= from && from <= to && to <= source->length()); |
8371 switch (StringShape(source).full_representation_tag()) { | 8366 switch (StringShape(source).full_representation_tag()) { |
8372 case kOneByteStringTag | kExternalStringTag: { | 8367 case kOneByteStringTag | kExternalStringTag: { |
8373 CopyChars(sink, | 8368 CopyChars(sink, ExternalOneByteString::cast(source)->GetChars() + from, |
8374 ExternalAsciiString::cast(source)->GetChars() + from, | |
8375 to - from); | 8369 to - from); |
8376 return; | 8370 return; |
8377 } | 8371 } |
8378 case kTwoByteStringTag | kExternalStringTag: { | 8372 case kTwoByteStringTag | kExternalStringTag: { |
8379 const uc16* data = | 8373 const uc16* data = |
8380 ExternalTwoByteString::cast(source)->GetChars(); | 8374 ExternalTwoByteString::cast(source)->GetChars(); |
8381 CopyChars(sink, | 8375 CopyChars(sink, |
8382 data + from, | 8376 data + from, |
8383 to - from); | 8377 to - from); |
8384 return; | 8378 return; |
(...skipping 25 matching lines...) Expand all Loading... |
8410 from -= boundary; | 8404 from -= boundary; |
8411 } | 8405 } |
8412 to -= boundary; | 8406 to -= boundary; |
8413 source = cons_string->second(); | 8407 source = cons_string->second(); |
8414 } else { | 8408 } else { |
8415 // Left hand side is longer. Recurse over right. | 8409 // Left hand side is longer. Recurse over right. |
8416 if (to > boundary) { | 8410 if (to > boundary) { |
8417 String* second = cons_string->second(); | 8411 String* second = cons_string->second(); |
8418 // When repeatedly appending to a string, we get a cons string that | 8412 // When repeatedly appending to a string, we get a cons string that |
8419 // is unbalanced to the left, a list, essentially. We inline the | 8413 // is unbalanced to the left, a list, essentially. We inline the |
8420 // common case of sequential ascii right child. | 8414 // common case of sequential one-byte right child. |
8421 if (to - boundary == 1) { | 8415 if (to - boundary == 1) { |
8422 sink[boundary - from] = static_cast<sinkchar>(second->Get(0)); | 8416 sink[boundary - from] = static_cast<sinkchar>(second->Get(0)); |
8423 } else if (second->IsSeqOneByteString()) { | 8417 } else if (second->IsSeqOneByteString()) { |
8424 CopyChars(sink + boundary - from, | 8418 CopyChars(sink + boundary - from, |
8425 SeqOneByteString::cast(second)->GetChars(), | 8419 SeqOneByteString::cast(second)->GetChars(), |
8426 to - boundary); | 8420 to - boundary); |
8427 } else { | 8421 } else { |
8428 WriteToFlat(second, | 8422 WriteToFlat(second, |
8429 sink + boundary - from, | 8423 sink + boundary - from, |
8430 0, | 8424 0, |
(...skipping 17 matching lines...) Expand all Loading... |
8448 } | 8442 } |
8449 | 8443 |
8450 | 8444 |
8451 | 8445 |
8452 template <typename SourceChar> | 8446 template <typename SourceChar> |
8453 static void CalculateLineEndsImpl(Isolate* isolate, | 8447 static void CalculateLineEndsImpl(Isolate* isolate, |
8454 List<int>* line_ends, | 8448 List<int>* line_ends, |
8455 Vector<const SourceChar> src, | 8449 Vector<const SourceChar> src, |
8456 bool include_ending_line) { | 8450 bool include_ending_line) { |
8457 const int src_len = src.length(); | 8451 const int src_len = src.length(); |
8458 StringSearch<uint8_t, SourceChar> search(isolate, STATIC_ASCII_VECTOR("\n")); | 8452 StringSearch<uint8_t, SourceChar> search(isolate, STATIC_CHAR_VECTOR("\n")); |
8459 | 8453 |
8460 // Find and record line ends. | 8454 // Find and record line ends. |
8461 int position = 0; | 8455 int position = 0; |
8462 while (position != -1 && position < src_len) { | 8456 while (position != -1 && position < src_len) { |
8463 position = search.Search(src, position); | 8457 position = search.Search(src, position); |
8464 if (position != -1) { | 8458 if (position != -1) { |
8465 line_ends->Add(position); | 8459 line_ends->Add(position); |
8466 position++; | 8460 position++; |
8467 } else if (include_ending_line) { | 8461 } else if (include_ending_line) { |
8468 // Even if the last line misses a line end, it is counted. | 8462 // Even if the last line misses a line end, it is counted. |
8469 line_ends->Add(src_len); | 8463 line_ends->Add(src_len); |
8470 return; | 8464 return; |
8471 } | 8465 } |
8472 } | 8466 } |
8473 } | 8467 } |
8474 | 8468 |
8475 | 8469 |
8476 Handle<FixedArray> String::CalculateLineEnds(Handle<String> src, | 8470 Handle<FixedArray> String::CalculateLineEnds(Handle<String> src, |
8477 bool include_ending_line) { | 8471 bool include_ending_line) { |
8478 src = Flatten(src); | 8472 src = Flatten(src); |
8479 // Rough estimate of line count based on a roughly estimated average | 8473 // Rough estimate of line count based on a roughly estimated average |
8480 // length of (unpacked) code. | 8474 // length of (unpacked) code. |
8481 int line_count_estimate = src->length() >> 4; | 8475 int line_count_estimate = src->length() >> 4; |
8482 List<int> line_ends(line_count_estimate); | 8476 List<int> line_ends(line_count_estimate); |
8483 Isolate* isolate = src->GetIsolate(); | 8477 Isolate* isolate = src->GetIsolate(); |
8484 { DisallowHeapAllocation no_allocation; // ensure vectors stay valid. | 8478 { DisallowHeapAllocation no_allocation; // ensure vectors stay valid. |
8485 // Dispatch on type of strings. | 8479 // Dispatch on type of strings. |
8486 String::FlatContent content = src->GetFlatContent(); | 8480 String::FlatContent content = src->GetFlatContent(); |
8487 DCHECK(content.IsFlat()); | 8481 DCHECK(content.IsFlat()); |
8488 if (content.IsAscii()) { | 8482 if (content.IsOneByte()) { |
8489 CalculateLineEndsImpl(isolate, | 8483 CalculateLineEndsImpl(isolate, |
8490 &line_ends, | 8484 &line_ends, |
8491 content.ToOneByteVector(), | 8485 content.ToOneByteVector(), |
8492 include_ending_line); | 8486 include_ending_line); |
8493 } else { | 8487 } else { |
8494 CalculateLineEndsImpl(isolate, | 8488 CalculateLineEndsImpl(isolate, |
8495 &line_ends, | 8489 &line_ends, |
8496 content.ToUC16Vector(), | 8490 content.ToUC16Vector(), |
8497 include_ending_line); | 8491 include_ending_line); |
8498 } | 8492 } |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8765 // before we try to flatten the strings. | 8759 // before we try to flatten the strings. |
8766 if (one->Get(0) != two->Get(0)) return false; | 8760 if (one->Get(0) != two->Get(0)) return false; |
8767 | 8761 |
8768 one = String::Flatten(one); | 8762 one = String::Flatten(one); |
8769 two = String::Flatten(two); | 8763 two = String::Flatten(two); |
8770 | 8764 |
8771 DisallowHeapAllocation no_gc; | 8765 DisallowHeapAllocation no_gc; |
8772 String::FlatContent flat1 = one->GetFlatContent(); | 8766 String::FlatContent flat1 = one->GetFlatContent(); |
8773 String::FlatContent flat2 = two->GetFlatContent(); | 8767 String::FlatContent flat2 = two->GetFlatContent(); |
8774 | 8768 |
8775 if (flat1.IsAscii() && flat2.IsAscii()) { | 8769 if (flat1.IsOneByte() && flat2.IsOneByte()) { |
8776 return CompareRawStringContents(flat1.ToOneByteVector().start(), | 8770 return CompareRawStringContents(flat1.ToOneByteVector().start(), |
8777 flat2.ToOneByteVector().start(), | 8771 flat2.ToOneByteVector().start(), |
8778 one_length); | 8772 one_length); |
8779 } else { | 8773 } else { |
8780 for (int i = 0; i < one_length; i++) { | 8774 for (int i = 0; i < one_length; i++) { |
8781 if (flat1.Get(i) != flat2.Get(i)) return false; | 8775 if (flat1.Get(i) != flat2.Get(i)) return false; |
8782 } | 8776 } |
8783 return true; | 8777 return true; |
8784 } | 8778 } |
8785 } | 8779 } |
8786 | 8780 |
8787 | 8781 |
8788 bool String::MarkAsUndetectable() { | 8782 bool String::MarkAsUndetectable() { |
8789 if (StringShape(this).IsInternalized()) return false; | 8783 if (StringShape(this).IsInternalized()) return false; |
8790 | 8784 |
8791 Map* map = this->map(); | 8785 Map* map = this->map(); |
8792 Heap* heap = GetHeap(); | 8786 Heap* heap = GetHeap(); |
8793 if (map == heap->string_map()) { | 8787 if (map == heap->string_map()) { |
8794 this->set_map(heap->undetectable_string_map()); | 8788 this->set_map(heap->undetectable_string_map()); |
8795 return true; | 8789 return true; |
8796 } else if (map == heap->ascii_string_map()) { | 8790 } else if (map == heap->one_byte_string_map()) { |
8797 this->set_map(heap->undetectable_ascii_string_map()); | 8791 this->set_map(heap->undetectable_one_byte_string_map()); |
8798 return true; | 8792 return true; |
8799 } | 8793 } |
8800 // Rest cannot be marked as undetectable | 8794 // Rest cannot be marked as undetectable |
8801 return false; | 8795 return false; |
8802 } | 8796 } |
8803 | 8797 |
8804 | 8798 |
8805 bool String::IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match) { | 8799 bool String::IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match) { |
8806 int slen = length(); | 8800 int slen = length(); |
8807 // Can't check exact length equality, but we can check bounds. | 8801 // Can't check exact length equality, but we can check bounds. |
(...skipping 22 matching lines...) Expand all Loading... |
8830 } | 8824 } |
8831 return (allow_prefix_match || i == slen) && remaining_in_str == 0; | 8825 return (allow_prefix_match || i == slen) && remaining_in_str == 0; |
8832 } | 8826 } |
8833 | 8827 |
8834 | 8828 |
8835 bool String::IsOneByteEqualTo(Vector<const uint8_t> str) { | 8829 bool String::IsOneByteEqualTo(Vector<const uint8_t> str) { |
8836 int slen = length(); | 8830 int slen = length(); |
8837 if (str.length() != slen) return false; | 8831 if (str.length() != slen) return false; |
8838 DisallowHeapAllocation no_gc; | 8832 DisallowHeapAllocation no_gc; |
8839 FlatContent content = GetFlatContent(); | 8833 FlatContent content = GetFlatContent(); |
8840 if (content.IsAscii()) { | 8834 if (content.IsOneByte()) { |
8841 return CompareChars(content.ToOneByteVector().start(), | 8835 return CompareChars(content.ToOneByteVector().start(), |
8842 str.start(), slen) == 0; | 8836 str.start(), slen) == 0; |
8843 } | 8837 } |
8844 for (int i = 0; i < slen; i++) { | 8838 for (int i = 0; i < slen; i++) { |
8845 if (Get(i) != static_cast<uint16_t>(str[i])) return false; | 8839 if (Get(i) != static_cast<uint16_t>(str[i])) return false; |
8846 } | 8840 } |
8847 return true; | 8841 return true; |
8848 } | 8842 } |
8849 | 8843 |
8850 | 8844 |
(...skipping 856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9707 if (source_string->Get(pos) == '\n') line++; | 9701 if (source_string->Get(pos) == '\n') line++; |
9708 } | 9702 } |
9709 return line; | 9703 return line; |
9710 } | 9704 } |
9711 | 9705 |
9712 | 9706 |
9713 Handle<Object> Script::GetNameOrSourceURL(Handle<Script> script) { | 9707 Handle<Object> Script::GetNameOrSourceURL(Handle<Script> script) { |
9714 Isolate* isolate = script->GetIsolate(); | 9708 Isolate* isolate = script->GetIsolate(); |
9715 Handle<String> name_or_source_url_key = | 9709 Handle<String> name_or_source_url_key = |
9716 isolate->factory()->InternalizeOneByteString( | 9710 isolate->factory()->InternalizeOneByteString( |
9717 STATIC_ASCII_VECTOR("nameOrSourceURL")); | 9711 STATIC_CHAR_VECTOR("nameOrSourceURL")); |
9718 Handle<JSObject> script_wrapper = Script::GetWrapper(script); | 9712 Handle<JSObject> script_wrapper = Script::GetWrapper(script); |
9719 Handle<Object> property = Object::GetProperty( | 9713 Handle<Object> property = Object::GetProperty( |
9720 script_wrapper, name_or_source_url_key).ToHandleChecked(); | 9714 script_wrapper, name_or_source_url_key).ToHandleChecked(); |
9721 DCHECK(property->IsJSFunction()); | 9715 DCHECK(property->IsJSFunction()); |
9722 Handle<JSFunction> method = Handle<JSFunction>::cast(property); | 9716 Handle<JSFunction> method = Handle<JSFunction>::cast(property); |
9723 Handle<Object> result; | 9717 Handle<Object> result; |
9724 // Do not check against pending exception, since this function may be called | 9718 // Do not check against pending exception, since this function may be called |
9725 // when an exception has already been pending. | 9719 // when an exception has already been pending. |
9726 if (!Execution::TryCall(method, script_wrapper, 0, NULL).ToHandle(&result)) { | 9720 if (!Execution::TryCall(method, script_wrapper, 0, NULL).ToHandle(&result)) { |
9727 return isolate->factory()->undefined_value(); | 9721 return isolate->factory()->undefined_value(); |
(...skipping 6678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16406 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16400 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16407 static const char* error_messages_[] = { | 16401 static const char* error_messages_[] = { |
16408 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16402 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16409 }; | 16403 }; |
16410 #undef ERROR_MESSAGES_TEXTS | 16404 #undef ERROR_MESSAGES_TEXTS |
16411 return error_messages_[reason]; | 16405 return error_messages_[reason]; |
16412 } | 16406 } |
16413 | 16407 |
16414 | 16408 |
16415 } } // namespace v8::internal | 16409 } } // namespace v8::internal |
OLD | NEW |