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 "vm/exceptions.h" | 7 #include "vm/exceptions.h" |
| 8 #include "vm/native_entry.h" | 8 #include "vm/native_entry.h" |
| 9 #include "vm/object.h" | 9 #include "vm/object.h" |
| 10 #include "vm/symbols.h" | 10 #include "vm/symbols.h" |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 207 } | 207 } |
| 208 | 208 |
| 209 | 209 |
| 210 DEFINE_NATIVE_ENTRY(String_toUpperCase, 1) { | 210 DEFINE_NATIVE_ENTRY(String_toUpperCase, 1) { |
| 211 const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0)); | 211 const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0)); |
| 212 ASSERT(!receiver.IsNull()); | 212 ASSERT(!receiver.IsNull()); |
| 213 return String::ToUpperCase(receiver); | 213 return String::ToUpperCase(receiver); |
| 214 } | 214 } |
| 215 | 215 |
| 216 | 216 |
| 217 DEFINE_NATIVE_ENTRY(Strings_concatAll, 1) { | 217 DEFINE_NATIVE_ENTRY(Strings_concatAll, 3) { |
| 218 GET_NON_NULL_NATIVE_ARGUMENT(Array, strings, arguments->NativeArgAt(0)); | 218 GET_NON_NULL_NATIVE_ARGUMENT(Instance, argument, arguments->NativeArgAt(0)); |
| 219 ASSERT(!strings.IsNull()); | 219 GET_NON_NULL_NATIVE_ARGUMENT(Smi, start, arguments->NativeArgAt(1)); |
| 220 GET_NON_NULL_NATIVE_ARGUMENT(Smi, end, arguments->NativeArgAt(2)); | |
| 221 const intptr_t start_ix = start.Value(); | |
| 222 const intptr_t end_ix = end.Value(); | |
| 223 if (start_ix < 0) { | |
| 224 const Array& args = Array::Handle(Array::New(1)); | |
| 225 args.SetAt(0, start); | |
| 226 Exceptions::ThrowByType(Exceptions::kArgument, args); | |
| 227 } | |
| 228 Array& strings = Array::Handle(); | |
| 229 if (argument.IsArray()) { | |
| 230 strings ^= argument.raw(); | |
| 231 if (end_ix > strings.Length()) { | |
| 232 const Array& args = Array::Handle(Array::New(1)); | |
| 233 args.SetAt(0, end); | |
| 234 Exceptions::ThrowByType(Exceptions::kArgument, args); | |
|
sra1
2013/09/30 17:54:43
This is such a common sequence I am surprised it i
srdjan
2013/10/01 14:57:44
Will do that in next CL.
| |
| 235 } | |
| 236 } else if (argument.IsGrowableObjectArray()) { | |
| 237 // Allocate new array and copy data into it. | |
|
sra1
2013/09/30 17:54:43
Comment is wrong - you don't copy the the array.
Y
srdjan
2013/10/01 14:57:44
Removed comment.
| |
| 238 GrowableObjectArray& g = GrowableObjectArray::Handle(); | |
| 239 g ^= argument.raw(); | |
|
siva
2013/09/30 18:27:21
'g' seems like a cryptic name, why not
strings =
srdjan
2013/10/01 14:57:44
strings is the backing store array whose length is
| |
| 240 strings = g.data(); | |
| 241 if (end_ix > g.Length()) { | |
| 242 const Array& args = Array::Handle(Array::New(1)); | |
| 243 args.SetAt(0, end); | |
| 244 Exceptions::ThrowByType(Exceptions::kArgument, args); | |
| 245 } | |
| 246 } else { | |
| 247 const Array& args = Array::Handle(Array::New(1)); | |
| 248 args.SetAt(0, argument); | |
| 249 Exceptions::ThrowByType(Exceptions::kArgument, args); | |
| 250 } | |
|
siva
2013/09/30 18:27:21
The
if (end_ix > length) {
....
....
}
blob ca
srdjan
2013/10/01 14:57:44
Yes.
| |
| 251 #if defined(DEBUG) | |
| 220 // Check that the array contains strings. | 252 // Check that the array contains strings. |
| 221 Instance& elem = Instance::Handle(); | 253 Instance& elem = Instance::Handle(); |
| 222 for (intptr_t i = 0; i < strings.Length(); i++) { | 254 for (intptr_t i = start_ix; i < end_ix; i++) { |
| 223 elem ^= strings.At(i); | 255 elem ^= strings.At(i); |
| 224 if (!elem.IsString()) { | 256 if (!elem.IsString()) { |
| 225 const Array& args = Array::Handle(Array::New(1)); | 257 const Array& args = Array::Handle(Array::New(1)); |
| 226 args.SetAt(0, elem); | 258 args.SetAt(0, elem); |
| 227 Exceptions::ThrowByType(Exceptions::kArgument, args); | 259 Exceptions::ThrowByType(Exceptions::kArgument, args); |
| 228 } | 260 } |
| 229 } | 261 } |
| 230 return String::ConcatAll(strings); | 262 #endif |
|
siva
2013/09/30 18:27:21
Why does this check have to be done in DEBUG mode?
srdjan
2013/10/01 14:57:44
Changing to ASSERT.
| |
| 263 return String::ConcatAllRange(strings, start_ix, end_ix, Heap::kNew); | |
| 231 } | 264 } |
| 232 | 265 |
| 233 | 266 |
| 234 DEFINE_NATIVE_ENTRY(StringBuffer_createStringFromUint16Array, 3) { | 267 DEFINE_NATIVE_ENTRY(StringBuffer_createStringFromUint16Array, 3) { |
| 235 GET_NON_NULL_NATIVE_ARGUMENT(TypedData, codeUnits, arguments->NativeArgAt(0)); | 268 GET_NON_NULL_NATIVE_ARGUMENT(TypedData, codeUnits, arguments->NativeArgAt(0)); |
| 236 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(1)); | 269 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(1)); |
| 237 GET_NON_NULL_NATIVE_ARGUMENT(Bool, isLatin1, arguments->NativeArgAt(2)); | 270 GET_NON_NULL_NATIVE_ARGUMENT(Bool, isLatin1, arguments->NativeArgAt(2)); |
| 238 intptr_t array_length = codeUnits.Length(); | 271 intptr_t array_length = codeUnits.Length(); |
| 239 intptr_t length_value = length.Value(); | 272 intptr_t length_value = length.Value(); |
| 240 if (length_value < 0 || length_value > array_length) { | 273 if (length_value < 0 || length_value > array_length) { |
| 241 const Array& args = Array::Handle(Array::New(1)); | 274 const Array& args = Array::Handle(Array::New(1)); |
| 242 args.SetAt(0, length); | 275 args.SetAt(0, length); |
| 243 Exceptions::ThrowByType(Exceptions::kRange, args); | 276 Exceptions::ThrowByType(Exceptions::kRange, args); |
| 244 } | 277 } |
| 245 const String& result = isLatin1.value() | 278 const String& result = isLatin1.value() |
| 246 ? String::Handle(OneByteString::New(length_value, Heap::kNew)) | 279 ? String::Handle(OneByteString::New(length_value, Heap::kNew)) |
| 247 : String::Handle(TwoByteString::New(length_value, Heap::kNew)); | 280 : String::Handle(TwoByteString::New(length_value, Heap::kNew)); |
| 248 NoGCScope no_gc; | 281 NoGCScope no_gc; |
| 249 | 282 |
| 250 uint16_t* data_position = reinterpret_cast<uint16_t*>(codeUnits.DataAddr(0)); | 283 uint16_t* data_position = reinterpret_cast<uint16_t*>(codeUnits.DataAddr(0)); |
| 251 String::Copy(result, 0, data_position, length_value); | 284 String::Copy(result, 0, data_position, length_value); |
| 252 return result.raw(); | 285 return result.raw(); |
| 253 } | 286 } |
| 254 | 287 |
| 255 } // namespace dart | 288 } // namespace dart |
| OLD | NEW |