| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/bootstrap_natives.h" | 5 #include "vm/bootstrap_natives.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 #include "vm/exceptions.h" | 8 #include "vm/exceptions.h" |
| 9 #include "vm/dart_api_impl.h" | 9 #include "vm/dart_api_impl.h" |
| 10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 utf32_array[i] = value32; | 84 utf32_array[i] = value32; |
| 85 } | 85 } |
| 86 if (is_one_byte_string) { | 86 if (is_one_byte_string) { |
| 87 return OneByteString::New(utf32_array, array_len, Heap::kNew); | 87 return OneByteString::New(utf32_array, array_len, Heap::kNew); |
| 88 } | 88 } |
| 89 return TwoByteString::New(utf16_len, utf32_array, array_len, Heap::kNew); | 89 return TwoByteString::New(utf16_len, utf32_array, array_len, Heap::kNew); |
| 90 } | 90 } |
| 91 | 91 |
| 92 | 92 |
| 93 DEFINE_NATIVE_ENTRY(StringBase_substringUnchecked, 3) { | 93 DEFINE_NATIVE_ENTRY(StringBase_substringUnchecked, 3) { |
| 94 const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0)); | 94 const String& receiver = String::CheckedHandle(zone, |
| 95 arguments->NativeArgAt(0)); |
| 95 GET_NON_NULL_NATIVE_ARGUMENT(Smi, start_obj, arguments->NativeArgAt(1)); | 96 GET_NON_NULL_NATIVE_ARGUMENT(Smi, start_obj, arguments->NativeArgAt(1)); |
| 96 GET_NON_NULL_NATIVE_ARGUMENT(Smi, end_obj, arguments->NativeArgAt(2)); | 97 GET_NON_NULL_NATIVE_ARGUMENT(Smi, end_obj, arguments->NativeArgAt(2)); |
| 97 | 98 |
| 98 intptr_t start = start_obj.Value(); | 99 intptr_t start = start_obj.Value(); |
| 99 intptr_t end = end_obj.Value(); | 100 intptr_t end = end_obj.Value(); |
| 100 return String::SubString(receiver, start, (end - start)); | 101 return String::SubString(receiver, start, (end - start)); |
| 101 } | 102 } |
| 102 | 103 |
| 103 | 104 |
| 104 | 105 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 if (char_limit > 0xff) { | 157 if (char_limit > 0xff) { |
| 157 return false; | 158 return false; |
| 158 } | 159 } |
| 159 } | 160 } |
| 160 } | 161 } |
| 161 return true; | 162 return true; |
| 162 } | 163 } |
| 163 | 164 |
| 164 | 165 |
| 165 DEFINE_NATIVE_ENTRY(StringBase_joinReplaceAllResult, 4) { | 166 DEFINE_NATIVE_ENTRY(StringBase_joinReplaceAllResult, 4) { |
| 166 const String& base = String::CheckedHandle(arguments->NativeArgAt(0)); | 167 const String& base = String::CheckedHandle(zone, |
| 168 arguments->NativeArgAt(0)); |
| 167 GET_NON_NULL_NATIVE_ARGUMENT(GrowableObjectArray, | 169 GET_NON_NULL_NATIVE_ARGUMENT(GrowableObjectArray, |
| 168 matches_growable, arguments->NativeArgAt(1)); | 170 matches_growable, arguments->NativeArgAt(1)); |
| 169 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length_obj, arguments->NativeArgAt(2)); | 171 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length_obj, arguments->NativeArgAt(2)); |
| 170 GET_NON_NULL_NATIVE_ARGUMENT(Bool, is_onebyte_obj, arguments->NativeArgAt(3)); | 172 GET_NON_NULL_NATIVE_ARGUMENT(Bool, is_onebyte_obj, arguments->NativeArgAt(3)); |
| 171 | 173 |
| 172 intptr_t len = matches_growable.Length(); | 174 intptr_t len = matches_growable.Length(); |
| 173 const Array& matches = Array::Handle(zone, matches_growable.data()); | 175 const Array& matches = Array::Handle(zone, matches_growable.data()); |
| 174 | 176 |
| 175 const intptr_t length = length_obj.Value(); | 177 const intptr_t length = length_obj.Value(); |
| 176 if (length < 0) { | 178 if (length < 0) { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 write_index += replacement_length; | 246 write_index += replacement_length; |
| 245 } | 247 } |
| 246 } | 248 } |
| 247 if (write_index < length) { | 249 if (write_index < length) { |
| 248 Exceptions::ThrowArgumentError(matches_growable); | 250 Exceptions::ThrowArgumentError(matches_growable); |
| 249 } | 251 } |
| 250 return result.raw(); | 252 return result.raw(); |
| 251 } | 253 } |
| 252 | 254 |
| 253 DEFINE_NATIVE_ENTRY(OneByteString_substringUnchecked, 3) { | 255 DEFINE_NATIVE_ENTRY(OneByteString_substringUnchecked, 3) { |
| 254 const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0)); | 256 const String& receiver = String::CheckedHandle(zone, |
| 257 arguments->NativeArgAt(0)); |
| 255 ASSERT(receiver.IsOneByteString()); | 258 ASSERT(receiver.IsOneByteString()); |
| 256 GET_NON_NULL_NATIVE_ARGUMENT(Smi, start_obj, arguments->NativeArgAt(1)); | 259 GET_NON_NULL_NATIVE_ARGUMENT(Smi, start_obj, arguments->NativeArgAt(1)); |
| 257 GET_NON_NULL_NATIVE_ARGUMENT(Smi, end_obj, arguments->NativeArgAt(2)); | 260 GET_NON_NULL_NATIVE_ARGUMENT(Smi, end_obj, arguments->NativeArgAt(2)); |
| 258 | 261 |
| 259 const intptr_t start = start_obj.Value(); | 262 const intptr_t start = start_obj.Value(); |
| 260 const intptr_t end = end_obj.Value(); | 263 const intptr_t end = end_obj.Value(); |
| 261 return OneByteString::New(receiver, start, end - start, Heap::kNew); | 264 return OneByteString::New(receiver, start, end - start, Heap::kNew); |
| 262 } | 265 } |
| 263 | 266 |
| 264 | 267 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 | 299 |
| 297 | 300 |
| 298 DEFINE_NATIVE_ENTRY(OneByteString_allocate, 1) { | 301 DEFINE_NATIVE_ENTRY(OneByteString_allocate, 1) { |
| 299 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length_obj, arguments->NativeArgAt(0)); | 302 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length_obj, arguments->NativeArgAt(0)); |
| 300 Heap::Space space = isolate->heap()->SpaceForAllocation(kOneByteStringCid); | 303 Heap::Space space = isolate->heap()->SpaceForAllocation(kOneByteStringCid); |
| 301 return OneByteString::New(length_obj.Value(), space); | 304 return OneByteString::New(length_obj.Value(), space); |
| 302 } | 305 } |
| 303 | 306 |
| 304 | 307 |
| 305 DEFINE_NATIVE_ENTRY(OneByteString_allocateFromOneByteList, 3) { | 308 DEFINE_NATIVE_ENTRY(OneByteString_allocateFromOneByteList, 3) { |
| 306 Instance& list = Instance::CheckedHandle(arguments->NativeArgAt(0)); | 309 Instance& list = Instance::CheckedHandle(zone, |
| 310 arguments->NativeArgAt(0)); |
| 307 GET_NON_NULL_NATIVE_ARGUMENT(Smi, start_obj, arguments->NativeArgAt(1)); | 311 GET_NON_NULL_NATIVE_ARGUMENT(Smi, start_obj, arguments->NativeArgAt(1)); |
| 308 GET_NON_NULL_NATIVE_ARGUMENT(Smi, end_obj, arguments->NativeArgAt(2)); | 312 GET_NON_NULL_NATIVE_ARGUMENT(Smi, end_obj, arguments->NativeArgAt(2)); |
| 309 | 313 |
| 310 intptr_t start = start_obj.Value(); | 314 intptr_t start = start_obj.Value(); |
| 311 intptr_t end = end_obj.Value(); | 315 intptr_t end = end_obj.Value(); |
| 312 if (start < 0) { | 316 if (start < 0) { |
| 313 const Array& args = Array::Handle(Array::New(1)); | 317 const Array& args = Array::Handle(Array::New(1)); |
| 314 args.SetAt(0, start_obj); | 318 args.SetAt(0, start_obj); |
| 315 Exceptions::ThrowByType(Exceptions::kArgument, args); | 319 Exceptions::ThrowByType(Exceptions::kArgument, args); |
| 316 } | 320 } |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 return Object::null(); | 403 return Object::null(); |
| 400 } | 404 } |
| 401 | 405 |
| 402 | 406 |
| 403 DEFINE_NATIVE_ENTRY(ExternalOneByteString_getCid, 0) { | 407 DEFINE_NATIVE_ENTRY(ExternalOneByteString_getCid, 0) { |
| 404 return Smi::New(kExternalOneByteStringCid); | 408 return Smi::New(kExternalOneByteStringCid); |
| 405 } | 409 } |
| 406 | 410 |
| 407 | 411 |
| 408 DEFINE_NATIVE_ENTRY(TwoByteString_allocateFromTwoByteList, 3) { | 412 DEFINE_NATIVE_ENTRY(TwoByteString_allocateFromTwoByteList, 3) { |
| 409 Instance& list = Instance::CheckedHandle(arguments->NativeArgAt(0)); | 413 Instance& list = Instance::CheckedHandle(zone, |
| 414 arguments->NativeArgAt(0)); |
| 410 GET_NON_NULL_NATIVE_ARGUMENT(Smi, start_obj, arguments->NativeArgAt(1)); | 415 GET_NON_NULL_NATIVE_ARGUMENT(Smi, start_obj, arguments->NativeArgAt(1)); |
| 411 GET_NON_NULL_NATIVE_ARGUMENT(Smi, end_obj, arguments->NativeArgAt(2)); | 416 GET_NON_NULL_NATIVE_ARGUMENT(Smi, end_obj, arguments->NativeArgAt(2)); |
| 412 | 417 |
| 413 intptr_t start = start_obj.Value(); | 418 intptr_t start = start_obj.Value(); |
| 414 intptr_t end = end_obj.Value(); | 419 intptr_t end = end_obj.Value(); |
| 415 if (start < 0) { | 420 if (start < 0) { |
| 416 Exceptions::ThrowArgumentError(start_obj); | 421 Exceptions::ThrowArgumentError(start_obj); |
| 417 } | 422 } |
| 418 intptr_t length = end - start; | 423 intptr_t length = end - start; |
| 419 if (length < 0) { | 424 if (length < 0) { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 TwoByteString::SetCharAt(string, i, value); | 490 TwoByteString::SetCharAt(string, i, value); |
| 486 } | 491 } |
| 487 return string.raw(); | 492 return string.raw(); |
| 488 } | 493 } |
| 489 UNREACHABLE(); | 494 UNREACHABLE(); |
| 490 return Object::null(); | 495 return Object::null(); |
| 491 } | 496 } |
| 492 | 497 |
| 493 | 498 |
| 494 DEFINE_NATIVE_ENTRY(String_getHashCode, 1) { | 499 DEFINE_NATIVE_ENTRY(String_getHashCode, 1) { |
| 495 const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0)); | 500 const String& receiver = String::CheckedHandle(zone, |
| 501 arguments->NativeArgAt(0)); |
| 496 intptr_t hash_val = receiver.Hash(); | 502 intptr_t hash_val = receiver.Hash(); |
| 497 ASSERT(hash_val > 0); | 503 ASSERT(hash_val > 0); |
| 498 ASSERT(Smi::IsValid(hash_val)); | 504 ASSERT(Smi::IsValid(hash_val)); |
| 499 return Smi::New(hash_val); | 505 return Smi::New(hash_val); |
| 500 } | 506 } |
| 501 | 507 |
| 502 | 508 |
| 503 DEFINE_NATIVE_ENTRY(String_getLength, 1) { | 509 DEFINE_NATIVE_ENTRY(String_getLength, 1) { |
| 504 const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0)); | 510 const String& receiver = String::CheckedHandle(zone, |
| 511 arguments->NativeArgAt(0)); |
| 505 return Smi::New(receiver.Length()); | 512 return Smi::New(receiver.Length()); |
| 506 } | 513 } |
| 507 | 514 |
| 508 | 515 |
| 509 static uint16_t StringValueAt(const String& str, const Integer& index) { | 516 static uint16_t StringValueAt(const String& str, const Integer& index) { |
| 510 if (index.IsSmi()) { | 517 if (index.IsSmi()) { |
| 511 const intptr_t index_value = Smi::Cast(index).Value(); | 518 const intptr_t index_value = Smi::Cast(index).Value(); |
| 512 if ((0 <= index_value) && (index_value < str.Length())) { | 519 if ((0 <= index_value) && (index_value < str.Length())) { |
| 513 return str.CharAt(index_value); | 520 return str.CharAt(index_value); |
| 514 } | 521 } |
| 515 } | 522 } |
| 516 | 523 |
| 517 // An index larger than Smi is always illegal. | 524 // An index larger than Smi is always illegal. |
| 518 Exceptions::ThrowRangeError("index", index, 0, str.Length() - 1); | 525 Exceptions::ThrowRangeError("index", index, 0, str.Length() - 1); |
| 519 return 0; | 526 return 0; |
| 520 } | 527 } |
| 521 | 528 |
| 522 | 529 |
| 523 DEFINE_NATIVE_ENTRY(String_charAt, 2) { | 530 DEFINE_NATIVE_ENTRY(String_charAt, 2) { |
| 524 const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0)); | 531 const String& receiver = String::CheckedHandle(zone, |
| 532 arguments->NativeArgAt(0)); |
| 525 GET_NON_NULL_NATIVE_ARGUMENT(Integer, index, arguments->NativeArgAt(1)); | 533 GET_NON_NULL_NATIVE_ARGUMENT(Integer, index, arguments->NativeArgAt(1)); |
| 526 uint16_t value = StringValueAt(receiver, index); | 534 uint16_t value = StringValueAt(receiver, index); |
| 527 return Symbols::FromCharCode(thread, static_cast<int32_t>(value)); | 535 return Symbols::FromCharCode(thread, static_cast<int32_t>(value)); |
| 528 } | 536 } |
| 529 | 537 |
| 530 | 538 |
| 531 // Returns the 16-bit UTF-16 code unit at the given index. | 539 // Returns the 16-bit UTF-16 code unit at the given index. |
| 532 DEFINE_NATIVE_ENTRY(String_codeUnitAt, 2) { | 540 DEFINE_NATIVE_ENTRY(String_codeUnitAt, 2) { |
| 533 const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0)); | 541 const String& receiver = String::CheckedHandle(zone, |
| 542 arguments->NativeArgAt(0)); |
| 534 GET_NON_NULL_NATIVE_ARGUMENT(Integer, index, arguments->NativeArgAt(1)); | 543 GET_NON_NULL_NATIVE_ARGUMENT(Integer, index, arguments->NativeArgAt(1)); |
| 535 uint16_t value = StringValueAt(receiver, index); | 544 uint16_t value = StringValueAt(receiver, index); |
| 536 return Smi::New(static_cast<intptr_t>(value)); | 545 return Smi::New(static_cast<intptr_t>(value)); |
| 537 } | 546 } |
| 538 | 547 |
| 539 | 548 |
| 540 DEFINE_NATIVE_ENTRY(String_concat, 2) { | 549 DEFINE_NATIVE_ENTRY(String_concat, 2) { |
| 541 const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0)); | 550 const String& receiver = String::CheckedHandle(zone, |
| 551 arguments->NativeArgAt(0)); |
| 542 GET_NON_NULL_NATIVE_ARGUMENT(String, b, arguments->NativeArgAt(1)); | 552 GET_NON_NULL_NATIVE_ARGUMENT(String, b, arguments->NativeArgAt(1)); |
| 543 return String::Concat(receiver, b); | 553 return String::Concat(receiver, b); |
| 544 } | 554 } |
| 545 | 555 |
| 546 | 556 |
| 547 DEFINE_NATIVE_ENTRY(String_toLowerCase, 1) { | 557 DEFINE_NATIVE_ENTRY(String_toLowerCase, 1) { |
| 548 const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0)); | 558 const String& receiver = String::CheckedHandle(zone, |
| 559 arguments->NativeArgAt(0)); |
| 549 ASSERT(!receiver.IsNull()); | 560 ASSERT(!receiver.IsNull()); |
| 550 return String::ToLowerCase(receiver); | 561 return String::ToLowerCase(receiver); |
| 551 } | 562 } |
| 552 | 563 |
| 553 | 564 |
| 554 DEFINE_NATIVE_ENTRY(String_toUpperCase, 1) { | 565 DEFINE_NATIVE_ENTRY(String_toUpperCase, 1) { |
| 555 const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0)); | 566 const String& receiver = String::CheckedHandle(zone, |
| 567 arguments->NativeArgAt(0)); |
| 556 ASSERT(!receiver.IsNull()); | 568 ASSERT(!receiver.IsNull()); |
| 557 return String::ToUpperCase(receiver); | 569 return String::ToUpperCase(receiver); |
| 558 } | 570 } |
| 559 | 571 |
| 560 | 572 |
| 561 DEFINE_NATIVE_ENTRY(String_concatRange, 3) { | 573 DEFINE_NATIVE_ENTRY(String_concatRange, 3) { |
| 562 GET_NON_NULL_NATIVE_ARGUMENT(Instance, argument, arguments->NativeArgAt(0)); | 574 GET_NON_NULL_NATIVE_ARGUMENT(Instance, argument, arguments->NativeArgAt(0)); |
| 563 GET_NON_NULL_NATIVE_ARGUMENT(Smi, start, arguments->NativeArgAt(1)); | 575 GET_NON_NULL_NATIVE_ARGUMENT(Smi, start, arguments->NativeArgAt(1)); |
| 564 GET_NON_NULL_NATIVE_ARGUMENT(Smi, end, arguments->NativeArgAt(2)); | 576 GET_NON_NULL_NATIVE_ARGUMENT(Smi, end, arguments->NativeArgAt(2)); |
| 565 const intptr_t start_ix = start.Value(); | 577 const intptr_t start_ix = start.Value(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 607 ? String::Handle(OneByteString::New(length_value, Heap::kNew)) | 619 ? String::Handle(OneByteString::New(length_value, Heap::kNew)) |
| 608 : String::Handle(TwoByteString::New(length_value, Heap::kNew)); | 620 : String::Handle(TwoByteString::New(length_value, Heap::kNew)); |
| 609 NoSafepointScope no_safepoint; | 621 NoSafepointScope no_safepoint; |
| 610 | 622 |
| 611 uint16_t* data_position = reinterpret_cast<uint16_t*>(codeUnits.DataAddr(0)); | 623 uint16_t* data_position = reinterpret_cast<uint16_t*>(codeUnits.DataAddr(0)); |
| 612 String::Copy(result, 0, data_position, length_value); | 624 String::Copy(result, 0, data_position, length_value); |
| 613 return result.raw(); | 625 return result.raw(); |
| 614 } | 626 } |
| 615 | 627 |
| 616 } // namespace dart | 628 } // namespace dart |
| OLD | NEW |