Chromium Code Reviews| 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 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 251 OneByteString::SetCharAt(receiver, index_obj.Value(), code_point_obj.Value()); | 251 OneByteString::SetCharAt(receiver, index_obj.Value(), code_point_obj.Value()); |
| 252 return Object::null(); | 252 return Object::null(); |
| 253 } | 253 } |
| 254 | 254 |
| 255 | 255 |
| 256 DEFINE_NATIVE_ENTRY(ExternalOneByteString_getCid, 0) { | 256 DEFINE_NATIVE_ENTRY(ExternalOneByteString_getCid, 0) { |
| 257 return Smi::New(kExternalOneByteStringCid); | 257 return Smi::New(kExternalOneByteStringCid); |
| 258 } | 258 } |
| 259 | 259 |
| 260 | 260 |
| 261 DEFINE_NATIVE_ENTRY(TwoByteString_allocateFromTwoByteList, 3) { | |
| 262 Instance& list = Instance::CheckedHandle(arguments->NativeArgAt(0)); | |
| 263 GET_NON_NULL_NATIVE_ARGUMENT(Smi, start_obj, arguments->NativeArgAt(1)); | |
| 264 GET_NON_NULL_NATIVE_ARGUMENT(Smi, end_obj, arguments->NativeArgAt(2)); | |
| 265 | |
| 266 intptr_t start = start_obj.Value(); | |
| 267 intptr_t end = end_obj.Value(); | |
| 268 if (start < 0) { | |
| 269 const Array& args = Array::Handle(Array::New(1)); | |
| 270 args.SetAt(0, start_obj); | |
| 271 Exceptions::ThrowByType(Exceptions::kArgument, args); | |
| 272 } | |
| 273 intptr_t length = end - start; | |
| 274 if (length < 0) { | |
| 275 const Array& args = Array::Handle(Array::New(1)); | |
| 276 args.SetAt(0, end_obj); | |
| 277 Exceptions::ThrowByType(Exceptions::kArgument, args); | |
| 278 } | |
| 279 ASSERT(length >= 0); | |
|
siva
2015/01/20 23:50:26
Not sure why this assertion is needed here conside
Lasse Reichstein Nielsen
2015/01/22 07:16:32
ACK, I added the explicit check later, and forgot
| |
| 280 | |
| 281 Heap::Space space = isolate->heap()->SpaceForAllocation(kTwoByteStringCid); | |
| 282 if (list.IsTypedData()) { | |
| 283 const TypedData& array = TypedData::Cast(list); | |
| 284 if (array.ElementType() != kUint16ArrayElement) { | |
| 285 const Array& args = Array::Handle(Array::New(1)); | |
| 286 args.SetAt(0, list); | |
| 287 Exceptions::ThrowByType(Exceptions::kArgument, args); | |
| 288 } | |
| 289 if (end > array.LengthInBytes()) { | |
| 290 const Array& args = Array::Handle(Array::New(1)); | |
| 291 args.SetAt(0, end_obj); | |
| 292 Exceptions::ThrowByType(Exceptions::kArgument, args); | |
| 293 } | |
|
siva
2015/01/20 23:50:26
Maybe you could abstract this code out into a stat
Lasse Reichstein Nielsen
2015/01/22 07:16:32
The function also needs the list and end_obj value
| |
| 294 return TwoByteString::New(array, start * sizeof(uint16_t), length, space); | |
| 295 } else if (list.IsExternalTypedData()) { | |
| 296 const ExternalTypedData& array = ExternalTypedData::Cast(list); | |
| 297 if (array.ElementType() != kUint16ArrayElement) { | |
| 298 const Array& args = Array::Handle(Array::New(1)); | |
| 299 args.SetAt(0, list); | |
| 300 Exceptions::ThrowByType(Exceptions::kArgument, args); | |
| 301 } | |
| 302 if (end > array.LengthInBytes()) { | |
| 303 const Array& args = Array::Handle(Array::New(1)); | |
| 304 args.SetAt(0, end_obj); | |
| 305 Exceptions::ThrowByType(Exceptions::kArgument, args); | |
| 306 } | |
| 307 return TwoByteString::New(array, start * sizeof(uint16_t), length, space); | |
| 308 } else if (RawObject::IsTypedDataViewClassId(list.GetClassId())) { | |
| 309 const intptr_t cid = list.GetClassId(); | |
| 310 if (cid != kTypedDataUint16ArrayViewCid) { | |
| 311 const Array& args = Array::Handle(Array::New(1)); | |
| 312 args.SetAt(0, list); | |
| 313 Exceptions::ThrowByType(Exceptions::kArgument, args); | |
| 314 } | |
| 315 if (end > Smi::Value(TypedDataView::Length(list))) { | |
| 316 const Array& args = Array::Handle(Array::New(1)); | |
| 317 args.SetAt(0, end_obj); | |
| 318 Exceptions::ThrowByType(Exceptions::kArgument, args); | |
| 319 } | |
| 320 const Instance& data_obj = Instance::Handle(TypedDataView::Data(list)); | |
| 321 intptr_t data_offset = Smi::Value(TypedDataView::OffsetInBytes(list)); | |
| 322 if (data_obj.IsTypedData()) { | |
| 323 const TypedData& array = TypedData::Cast(data_obj); | |
| 324 return TwoByteString::New(array, data_offset + start * sizeof(uint16_t), | |
| 325 length, space); | |
| 326 } else if (data_obj.IsExternalTypedData()) { | |
| 327 const ExternalTypedData& array = ExternalTypedData::Cast(data_obj); | |
| 328 return TwoByteString::New(array, data_offset + start * sizeof(uint16_t), | |
| 329 length, space); | |
| 330 } | |
| 331 } else if (list.IsArray()) { | |
| 332 const Array& array = Array::Cast(list); | |
| 333 if (end > array.Length()) { | |
| 334 const Array& args = Array::Handle(Array::New(1)); | |
| 335 args.SetAt(0, end_obj); | |
| 336 Exceptions::ThrowByType(Exceptions::kArgument, args); | |
| 337 } | |
| 338 String& string = String::Handle(TwoByteString::New(length, space)); | |
|
siva
2015/01/20 23:50:26
Since 'isolate' is available to you in the native
Lasse Reichstein Nielsen
2015/01/22 07:16:32
Done.
| |
| 339 for (int i = 0; i < length; i++) { | |
| 340 intptr_t value = | |
| 341 Smi::Value(reinterpret_cast<RawSmi*>(array.At(start + i))); | |
| 342 TwoByteString::SetCharAt(string, i, value); | |
| 343 } | |
| 344 return string.raw(); | |
| 345 } else if (list.IsGrowableObjectArray()) { | |
| 346 const GrowableObjectArray& array = GrowableObjectArray::Cast(list); | |
| 347 if (end > array.Length()) { | |
| 348 const Array& args = Array::Handle(Array::New(1)); | |
| 349 args.SetAt(0, end_obj); | |
| 350 Exceptions::ThrowByType(Exceptions::kArgument, args); | |
| 351 } | |
| 352 String& string = String::Handle(TwoByteString::New(length, space)); | |
|
siva
2015/01/20 23:50:26
Ditto.
Lasse Reichstein Nielsen
2015/01/22 07:16:32
Done.
| |
| 353 for (int i = 0; i < length; i++) { | |
| 354 intptr_t value = | |
| 355 Smi::Value(reinterpret_cast<RawSmi*>(array.At(start + i))); | |
| 356 TwoByteString::SetCharAt(string, i, value); | |
| 357 } | |
| 358 return string.raw(); | |
| 359 } | |
| 360 UNREACHABLE(); | |
| 361 return Object::null(); | |
| 362 } | |
| 363 | |
| 364 | |
| 261 DEFINE_NATIVE_ENTRY(String_getHashCode, 1) { | 365 DEFINE_NATIVE_ENTRY(String_getHashCode, 1) { |
| 262 const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0)); | 366 const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0)); |
| 263 intptr_t hash_val = receiver.Hash(); | 367 intptr_t hash_val = receiver.Hash(); |
| 264 ASSERT(hash_val > 0); | 368 ASSERT(hash_val > 0); |
| 265 ASSERT(Smi::IsValid(hash_val)); | 369 ASSERT(Smi::IsValid(hash_val)); |
| 266 return Smi::New(hash_val); | 370 return Smi::New(hash_val); |
| 267 } | 371 } |
| 268 | 372 |
| 269 | 373 |
| 270 DEFINE_NATIVE_ENTRY(String_getLength, 1) { | 374 DEFINE_NATIVE_ENTRY(String_getLength, 1) { |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 374 ? String::Handle(OneByteString::New(length_value, Heap::kNew)) | 478 ? String::Handle(OneByteString::New(length_value, Heap::kNew)) |
| 375 : String::Handle(TwoByteString::New(length_value, Heap::kNew)); | 479 : String::Handle(TwoByteString::New(length_value, Heap::kNew)); |
| 376 NoGCScope no_gc; | 480 NoGCScope no_gc; |
| 377 | 481 |
| 378 uint16_t* data_position = reinterpret_cast<uint16_t*>(codeUnits.DataAddr(0)); | 482 uint16_t* data_position = reinterpret_cast<uint16_t*>(codeUnits.DataAddr(0)); |
| 379 String::Copy(result, 0, data_position, length_value); | 483 String::Copy(result, 0, data_position, length_value); |
| 380 return result.raw(); | 484 return result.raw(); |
| 381 } | 485 } |
| 382 | 486 |
| 383 } // namespace dart | 487 } // namespace dart |
| OLD | NEW |