OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
10 #include "vm/dart_api_impl.h" | 10 #include "vm/dart_api_impl.h" |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
184 ASSERT(CheckInteger(left)); | 184 ASSERT(CheckInteger(left)); |
185 ASSERT(CheckInteger(right)); | 185 ASSERT(CheckInteger(right)); |
186 if (FLAG_trace_intrinsified_natives) { | 186 if (FLAG_trace_intrinsified_natives) { |
187 OS::Print("Integer_equalToInteger %s == %s\n", | 187 OS::Print("Integer_equalToInteger %s == %s\n", |
188 left.ToCString(), right.ToCString()); | 188 left.ToCString(), right.ToCString()); |
189 } | 189 } |
190 return Bool::Get(left.CompareWith(right) == 0).raw(); | 190 return Bool::Get(left.CompareWith(right) == 0).raw(); |
191 } | 191 } |
192 | 192 |
193 | 193 |
194 DEFINE_NATIVE_ENTRY(Integer_parse, 1) { | 194 static RawInteger* ParseInteger(const String& value) { |
195 GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0)); | 195 // Used by both Integer_parse and Integer_fromEnvironment. |
196 if (value.IsOneByteString()) { | 196 if (value.IsOneByteString()) { |
197 // Quick conversion for unpadded integers in strings. | 197 // Quick conversion for unpadded integers in strings. |
198 const intptr_t len = value.Length(); | 198 const intptr_t len = value.Length(); |
199 if (len > 0) { | 199 if (len > 0) { |
200 const char* cstr = value.ToCString(); | 200 const char* cstr = value.ToCString(); |
201 ASSERT(cstr != NULL); | 201 ASSERT(cstr != NULL); |
202 char* p_end = NULL; | 202 char* p_end = NULL; |
203 const int64_t int_value = strtoll(cstr, &p_end, 10); | 203 const int64_t int_value = strtoll(cstr, &p_end, 10); |
204 if (p_end == (cstr + len)) { | 204 if (p_end == (cstr + len)) { |
205 if ((int_value != LLONG_MIN) && (int_value != LLONG_MAX)) { | 205 if ((int_value != LLONG_MIN) && (int_value != LLONG_MAX)) { |
(...skipping 12 matching lines...) Expand all Loading... | |
218 &is_positive, | 218 &is_positive, |
219 &int_string)) { | 219 &int_string)) { |
220 if (is_positive) { | 220 if (is_positive) { |
221 return Integer::New(*int_string); | 221 return Integer::New(*int_string); |
222 } | 222 } |
223 String& temp = String::Handle(); | 223 String& temp = String::Handle(); |
224 temp = String::Concat(Symbols::Dash(), *int_string); | 224 temp = String::Concat(Symbols::Dash(), *int_string); |
225 return Integer::New(temp); | 225 return Integer::New(temp); |
226 } | 226 } |
227 | 227 |
228 return Object::null(); | 228 return Integer::null(); |
229 } | 229 } |
230 | 230 |
231 | 231 |
232 DEFINE_NATIVE_ENTRY(Integer_parse, 1) { | |
233 GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0)); | |
234 return ParseInteger(value); | |
235 } | |
236 | |
237 | |
232 DEFINE_NATIVE_ENTRY(Integer_fromEnvironment, 3) { | 238 DEFINE_NATIVE_ENTRY(Integer_fromEnvironment, 3) { |
233 GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(1)); | 239 GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(1)); |
234 GET_NATIVE_ARGUMENT(Integer, default_value, arguments->NativeArgAt(2)); | 240 GET_NATIVE_ARGUMENT(Integer, default_value, arguments->NativeArgAt(2)); |
235 // Call the embedder to supply us with the environment. | 241 // Call the embedder to supply us with the environment. |
236 Dart_EnvironmentCallback callback = isolate->environment_callback(); | 242 Dart_EnvironmentCallback callback = isolate->environment_callback(); |
237 if (callback != NULL) { | 243 if (callback != NULL) { |
238 Dart_Handle result = callback(Api::NewHandle(isolate, name.raw())); | 244 Dart_Handle response = callback(Api::NewHandle(isolate, name.raw())); |
239 if (Dart_IsError(result)) { | 245 if (Dart_IsString(response)) { |
246 const String& value = String::Cast( | |
247 Object::Handle(isolate, Api::UnwrapHandle(response))); | |
248 const Integer& result = Integer::Handle(ParseInteger(value)); | |
249 if (!result.IsNull()) { | |
250 if (result.IsSmi()) return result.raw(); | |
Ivan Posva
2013/10/31 16:08:18
{
return result.raw();
}
| |
251 return Integer::NewCanonical(String::Handle( | |
252 String::New(result.ToCString()))); | |
Lasse Reichstein Nielsen
2013/10/31 13:45:24
Ivan, we can't decide if this canonicalization is
Ivan Posva
2013/10/31 16:08:18
Yes, it is necessary. You could of course do
retu
| |
253 } | |
254 } else if (Dart_IsError(response)) { | |
240 const Object& error = | 255 const Object& error = |
241 Object::Handle(isolate, Api::UnwrapHandle(result)); | 256 Object::Handle(isolate, Api::UnwrapHandle(response)); |
242 Exceptions::ThrowArgumentError( | 257 Exceptions::ThrowArgumentError( |
243 String::Handle( | 258 String::Handle( |
244 String::New(Error::Cast(error).ToErrorCString()))); | 259 String::New(Error::Cast(error).ToErrorCString()))); |
245 } else if (Dart_IsString(result)) { | 260 } else if (!Dart_IsNull(response)) { |
246 uint8_t* digits; | |
247 intptr_t digits_len; | |
248 Dart_StringToUTF8(result, &digits, &digits_len); | |
249 if (digits_len > 0) { | |
250 // Check for valid integer literal before constructing integer object. | |
251 // Skip leading minus if present. | |
252 if (digits[0] == '-') { | |
253 digits++; | |
254 digits_len--; | |
255 } | |
256 // Check remaining string for decimal or hex-decimal literal. | |
257 bool is_number = true; | |
258 if (digits_len > 2 && | |
259 digits[0] == '0' && | |
260 (digits[1] == 'x' || digits[1] == 'X')) { | |
261 for (int i = 2; i < digits_len && is_number; i++) { | |
262 is_number = ('0' <= digits[i] && digits[i] <= '9') || | |
263 ('A' <= digits[i] && digits[i] <= 'F') || | |
264 ('a' <= digits[i] && digits[i] <= 'f'); | |
265 } | |
266 } else { | |
267 for (int i = 0; i < digits_len && is_number; i++) { | |
268 is_number = '0' <= digits[i] && digits[i] <= '9'; | |
269 } | |
270 } | |
271 if (digits_len > 0 && is_number) { | |
272 const Object& value = | |
273 Object::Handle(isolate, Api::UnwrapHandle(result)); | |
274 ASSERT(value.IsString()); | |
275 return Integer::NewCanonical(String::Cast(value)); | |
276 } | |
277 } | |
278 } else if (!Dart_IsNull(result)) { | |
279 Exceptions::ThrowArgumentError( | 261 Exceptions::ThrowArgumentError( |
280 String::Handle(String::New("Illegal environment value"))); | 262 String::Handle(String::New("Illegal environment value"))); |
281 } | 263 } |
282 } | 264 } |
283 return default_value.raw(); | 265 return default_value.raw(); |
284 } | 266 } |
285 | 267 |
286 | 268 |
287 // Passing true for 'silent' prevents throwing JavascriptIntegerOverflow. | 269 // Passing true for 'silent' prevents throwing JavascriptIntegerOverflow. |
288 static RawInteger* ShiftOperationHelper(Token::Kind kind, | 270 static RawInteger* ShiftOperationHelper(Token::Kind kind, |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
459 // Use the preallocated out of memory exception to avoid calling | 441 // Use the preallocated out of memory exception to avoid calling |
460 // into dart code or allocating any code. | 442 // into dart code or allocating any code. |
461 const Instance& exception = | 443 const Instance& exception = |
462 Instance::Handle(isolate->object_store()->out_of_memory()); | 444 Instance::Handle(isolate->object_store()->out_of_memory()); |
463 Exceptions::Throw(exception); | 445 Exceptions::Throw(exception); |
464 UNREACHABLE(); | 446 UNREACHABLE(); |
465 return 0; | 447 return 0; |
466 } | 448 } |
467 | 449 |
468 } // namespace dart | 450 } // namespace dart |
OLD | NEW |