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 |