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" | |
9 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
10 #include "vm/dart_api_impl.h" | 9 #include "vm/dart_api_impl.h" |
11 #include "vm/exceptions.h" | 10 #include "vm/exceptions.h" |
12 #include "vm/isolate.h" | 11 #include "vm/isolate.h" |
13 #include "vm/native_entry.h" | 12 #include "vm/native_entry.h" |
14 #include "vm/object.h" | 13 #include "vm/object.h" |
15 #include "vm/object_store.h" | 14 #include "vm/object_store.h" |
16 #include "vm/symbols.h" | 15 #include "vm/symbols.h" |
17 | 16 |
18 namespace dart { | 17 namespace dart { |
19 | 18 |
20 DEFINE_FLAG(bool, trace_intrinsified_natives, false, | 19 DEFINE_FLAG(bool, trace_intrinsified_natives, false, |
21 "Report if any of the intrinsified natives are called"); | 20 "Report if any of the intrinsified natives are called"); |
22 | 21 |
23 // Smi natives. | 22 // Smi natives. |
24 | 23 |
25 // Returns false if integer is in wrong representation, e.g., as is a Bigint | 24 // Returns false if integer is in wrong representation, e.g., as is a Bigint |
26 // when it could have been a Smi. | 25 // when it could have been a Smi. |
27 static bool CheckInteger(const Integer& i) { | 26 static bool CheckInteger(const Integer& i) { |
28 if (i.IsBigint()) { | 27 if (i.IsBigint()) { |
29 const Bigint& bigint = Bigint::Cast(i); | 28 const Bigint& bigint = Bigint::Cast(i); |
30 return !BigintOperations::FitsIntoSmi(bigint) && | 29 return !bigint.FitsIntoSmi() && !bigint.FitsIntoInt64(); |
31 !BigintOperations::FitsIntoInt64(bigint); | |
32 } | 30 } |
33 if (i.IsMint()) { | 31 if (i.IsMint()) { |
34 const Mint& mint = Mint::Cast(i); | 32 const Mint& mint = Mint::Cast(i); |
35 return !Smi::IsValid(mint.value()); | 33 return !Smi::IsValid(mint.value()); |
36 } | 34 } |
37 return true; | 35 return true; |
38 } | 36 } |
39 | 37 |
40 | 38 |
41 static int BitLengthInt64(int64_t value) { | 39 static int BitLengthInt64(int64_t value) { |
42 value ^= value >> (8 * sizeof(value) - 1); // flip bits if negative. | 40 value ^= value >> (8 * sizeof(value) - 1); // flip bits if negative. |
41 // TODO(regis): Utils::HighestBit handles negative values. Why the above? | |
43 return value == 0 ? 0 : Utils::HighestBit(value) + 1; | 42 return value == 0 ? 0 : Utils::HighestBit(value) + 1; |
44 } | 43 } |
45 | 44 |
46 | 45 |
47 DEFINE_NATIVE_ENTRY(Integer_bitAndFromInteger, 2) { | 46 DEFINE_NATIVE_ENTRY(Integer_bitAndFromInteger, 2) { |
48 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 47 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
49 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); | 48 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); |
50 ASSERT(CheckInteger(right)); | 49 ASSERT(CheckInteger(right)); |
51 ASSERT(CheckInteger(left)); | 50 ASSERT(CheckInteger(left)); |
52 if (FLAG_trace_intrinsified_natives) { | 51 if (FLAG_trace_intrinsified_natives) { |
53 OS::Print("Integer_bitAndFromInteger %s & %s\n", | 52 OS::Print("Integer_bitAndFromInteger %s & %s\n", |
54 right.ToCString(), left.ToCString()); | 53 right.ToCString(), left.ToCString()); |
55 } | 54 } |
56 const Integer& result = | 55 const Integer& result = |
57 Integer::Handle(left.BitOp(Token::kBIT_AND, right)); | 56 Integer::Handle(left.BitOp(Token::kBIT_AND, right)); |
57 if (result.IsNull()) { | |
58 return result.raw(); // A bigint operation is required. | |
59 } | |
58 return result.AsValidInteger(); | 60 return result.AsValidInteger(); |
srdjan
2014/09/08 19:19:49
maybe: result.IsNull() ? result.raw() : result.AsV
regis
2014/09/09 19:18:14
Done.
| |
59 } | 61 } |
60 | 62 |
61 | 63 |
62 DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 2) { | 64 DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 2) { |
63 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 65 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
64 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); | 66 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); |
65 ASSERT(CheckInteger(right)); | 67 ASSERT(CheckInteger(right)); |
66 ASSERT(CheckInteger(left)); | 68 ASSERT(CheckInteger(left)); |
67 if (FLAG_trace_intrinsified_natives) { | 69 if (FLAG_trace_intrinsified_natives) { |
68 OS::Print("Integer_bitOrFromInteger %s | %s\n", | 70 OS::Print("Integer_bitOrFromInteger %s | %s\n", |
69 left.ToCString(), right.ToCString()); | 71 left.ToCString(), right.ToCString()); |
70 } | 72 } |
71 const Integer& result = | 73 const Integer& result = |
72 Integer::Handle(left.BitOp(Token::kBIT_OR, right)); | 74 Integer::Handle(left.BitOp(Token::kBIT_OR, right)); |
75 if (result.IsNull()) { | |
76 return result.raw(); // A bigint operation is required. | |
77 } | |
73 return result.AsValidInteger(); | 78 return result.AsValidInteger(); |
74 } | 79 } |
75 | 80 |
76 | 81 |
77 DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 2) { | 82 DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 2) { |
78 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 83 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
79 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); | 84 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); |
80 ASSERT(CheckInteger(right)); | 85 ASSERT(CheckInteger(right)); |
81 ASSERT(CheckInteger(left)); | 86 ASSERT(CheckInteger(left)); |
82 if (FLAG_trace_intrinsified_natives) { | 87 if (FLAG_trace_intrinsified_natives) { |
83 OS::Print("Integer_bitXorFromInteger %s ^ %s\n", | 88 OS::Print("Integer_bitXorFromInteger %s ^ %s\n", |
84 left.ToCString(), right.ToCString()); | 89 left.ToCString(), right.ToCString()); |
85 } | 90 } |
86 const Integer& result = | 91 const Integer& result = |
87 Integer::Handle(left.BitOp(Token::kBIT_XOR, right)); | 92 Integer::Handle(left.BitOp(Token::kBIT_XOR, right)); |
93 if (result.IsNull()) { | |
94 return result.raw(); // A bigint operation is required. | |
95 } | |
88 return result.AsValidInteger(); | 96 return result.AsValidInteger(); |
89 } | 97 } |
90 | 98 |
91 | 99 |
92 DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 2) { | 100 DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 2) { |
93 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 101 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
94 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); | 102 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
95 ASSERT(CheckInteger(right_int)); | 103 ASSERT(CheckInteger(right_int)); |
96 ASSERT(CheckInteger(left_int)); | 104 ASSERT(CheckInteger(left_int)); |
97 if (FLAG_trace_intrinsified_natives) { | 105 if (FLAG_trace_intrinsified_natives) { |
98 OS::Print("Integer_addFromInteger %s + %s\n", | 106 OS::Print("Integer_addFromInteger %s + %s\n", |
99 left_int.ToCString(), right_int.ToCString()); | 107 left_int.ToCString(), right_int.ToCString()); |
100 } | 108 } |
101 const Integer& result = | 109 const Integer& result = |
102 Integer::Handle(left_int.ArithmeticOp(Token::kADD, right_int)); | 110 Integer::Handle(left_int.ArithmeticOp(Token::kADD, right_int)); |
111 if (result.IsNull()) { | |
112 return result.raw(); // A bigint operation is required. | |
113 } | |
103 return result.AsValidInteger(); | 114 return result.AsValidInteger(); |
104 } | 115 } |
105 | 116 |
106 | 117 |
107 DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 2) { | 118 DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 2) { |
108 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 119 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
109 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); | 120 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
110 ASSERT(CheckInteger(right_int)); | 121 ASSERT(CheckInteger(right_int)); |
111 ASSERT(CheckInteger(left_int)); | 122 ASSERT(CheckInteger(left_int)); |
112 if (FLAG_trace_intrinsified_natives) { | 123 if (FLAG_trace_intrinsified_natives) { |
113 OS::Print("Integer_subFromInteger %s - %s\n", | 124 OS::Print("Integer_subFromInteger %s - %s\n", |
114 left_int.ToCString(), right_int.ToCString()); | 125 left_int.ToCString(), right_int.ToCString()); |
115 } | 126 } |
116 const Integer& result = | 127 const Integer& result = |
117 Integer::Handle(left_int.ArithmeticOp(Token::kSUB, right_int)); | 128 Integer::Handle(left_int.ArithmeticOp(Token::kSUB, right_int)); |
129 if (result.IsNull()) { | |
130 return result.raw(); // A bigint operation is required. | |
131 } | |
118 return result.AsValidInteger(); | 132 return result.AsValidInteger(); |
119 } | 133 } |
120 | 134 |
121 | 135 |
122 DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 2) { | 136 DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 2) { |
123 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 137 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
124 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); | 138 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
125 ASSERT(CheckInteger(right_int)); | 139 ASSERT(CheckInteger(right_int)); |
126 ASSERT(CheckInteger(left_int)); | 140 ASSERT(CheckInteger(left_int)); |
127 if (FLAG_trace_intrinsified_natives) { | 141 if (FLAG_trace_intrinsified_natives) { |
128 OS::Print("Integer_mulFromInteger %s * %s\n", | 142 OS::Print("Integer_mulFromInteger %s * %s\n", |
129 left_int.ToCString(), right_int.ToCString()); | 143 left_int.ToCString(), right_int.ToCString()); |
130 } | 144 } |
131 const Integer& result = | 145 const Integer& result = |
132 Integer::Handle(left_int.ArithmeticOp(Token::kMUL, right_int)); | 146 Integer::Handle(left_int.ArithmeticOp(Token::kMUL, right_int)); |
147 if (result.IsNull()) { | |
148 return result.raw(); // A bigint operation is required. | |
149 } | |
133 return result.AsValidInteger(); | 150 return result.AsValidInteger(); |
134 } | 151 } |
135 | 152 |
136 | 153 |
137 DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 2) { | 154 DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 2) { |
138 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 155 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
139 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); | 156 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
140 ASSERT(CheckInteger(right_int)); | 157 ASSERT(CheckInteger(right_int)); |
141 ASSERT(CheckInteger(left_int)); | 158 ASSERT(CheckInteger(left_int)); |
142 ASSERT(!right_int.IsZero()); | 159 ASSERT(!right_int.IsZero()); |
143 const Integer& result = | 160 const Integer& result = |
144 Integer::Handle(left_int.ArithmeticOp(Token::kTRUNCDIV, right_int)); | 161 Integer::Handle(left_int.ArithmeticOp(Token::kTRUNCDIV, right_int)); |
162 if (result.IsNull()) { | |
163 return result.raw(); // A bigint operation is required. | |
164 } | |
145 return result.AsValidInteger(); | 165 return result.AsValidInteger(); |
146 } | 166 } |
147 | 167 |
148 | 168 |
149 DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 2) { | 169 DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 2) { |
150 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 170 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
151 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); | 171 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
152 ASSERT(CheckInteger(right_int)); | 172 ASSERT(CheckInteger(right_int)); |
153 ASSERT(CheckInteger(right_int)); | 173 ASSERT(CheckInteger(right_int)); |
154 if (FLAG_trace_intrinsified_natives) { | 174 if (FLAG_trace_intrinsified_natives) { |
155 OS::Print("Integer_moduloFromInteger %s mod %s\n", | 175 OS::Print("Integer_moduloFromInteger %s mod %s\n", |
156 left_int.ToCString(), right_int.ToCString()); | 176 left_int.ToCString(), right_int.ToCString()); |
157 } | 177 } |
158 if (right_int.IsZero()) { | 178 if (right_int.IsZero()) { |
159 // Should have been caught before calling into runtime. | 179 // Should have been caught before calling into runtime. |
160 UNIMPLEMENTED(); | 180 UNIMPLEMENTED(); |
161 } | 181 } |
162 const Integer& result = | 182 const Integer& result = |
163 Integer::Handle(left_int.ArithmeticOp(Token::kMOD, right_int)); | 183 Integer::Handle(left_int.ArithmeticOp(Token::kMOD, right_int)); |
184 if (result.IsNull()) { | |
185 return result.raw(); // A bigint operation is required. | |
186 } | |
164 return result.AsValidInteger(); | 187 return result.AsValidInteger(); |
165 } | 188 } |
166 | 189 |
167 | 190 |
168 DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 2) { | 191 DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 2) { |
169 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 192 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
170 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); | 193 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); |
171 ASSERT(CheckInteger(right)); | 194 ASSERT(CheckInteger(right)); |
172 ASSERT(CheckInteger(left)); | 195 ASSERT(CheckInteger(left)); |
173 if (FLAG_trace_intrinsified_natives) { | 196 if (FLAG_trace_intrinsified_natives) { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
271 const Integer& value, | 294 const Integer& value, |
272 const Smi& amount, | 295 const Smi& amount, |
273 const bool silent = false) { | 296 const bool silent = false) { |
274 if (amount.Value() < 0) { | 297 if (amount.Value() < 0) { |
275 Exceptions::ThrowArgumentError(amount); | 298 Exceptions::ThrowArgumentError(amount); |
276 } | 299 } |
277 if (value.IsSmi()) { | 300 if (value.IsSmi()) { |
278 const Smi& smi_value = Smi::Cast(value); | 301 const Smi& smi_value = Smi::Cast(value); |
279 return smi_value.ShiftOp(kind, amount, silent); | 302 return smi_value.ShiftOp(kind, amount, silent); |
280 } | 303 } |
281 Bigint& big_value = Bigint::Handle(); | |
282 if (value.IsMint()) { | 304 if (value.IsMint()) { |
283 const int64_t mint_value = value.AsInt64Value(); | 305 const int64_t mint_value = value.AsInt64Value(); |
284 const int count = Utils::HighestBit(mint_value); | 306 const int count = Utils::HighestBit(mint_value); |
285 intptr_t shift_count = amount.Value(); | 307 intptr_t shift_count = amount.Value(); |
286 if (kind == Token::kSHR) { | 308 if (kind == Token::kSHR) { |
287 shift_count = -shift_count; | 309 shift_count = -shift_count; |
288 } | 310 } |
289 if ((count + shift_count) < Mint::kBits) { | 311 if ((count + shift_count) < Mint::kBits) { |
290 switch (kind) { | 312 switch (kind) { |
291 case Token::kSHL: | 313 case Token::kSHL: |
292 return Integer::New(mint_value << shift_count, Heap::kNew, silent); | 314 return Integer::New(mint_value << shift_count, Heap::kNew, silent); |
293 case Token::kSHR: | 315 case Token::kSHR: |
294 return Integer::New(mint_value >> -shift_count, Heap::kNew, silent); | 316 return Integer::New(mint_value >> -shift_count, Heap::kNew, silent); |
295 default: | 317 default: |
296 UNIMPLEMENTED(); | 318 UNIMPLEMENTED(); |
297 } | 319 } |
298 } else { | 320 } else { |
299 // Overflow in shift, use Bigints | 321 // Overflow in shift, use Bigints |
300 big_value = BigintOperations::NewFromInt64(mint_value); | 322 return Integer::null(); |
301 } | 323 } |
302 } else { | 324 } else { |
303 ASSERT(value.IsBigint()); | 325 ASSERT(value.IsBigint()); |
304 big_value = Bigint::Cast(value).raw(); | |
305 } | |
306 switch (kind) { | |
307 case Token::kSHL: | |
308 return BigintOperations::ShiftLeft(big_value, amount.Value()); | |
309 case Token::kSHR: | |
310 return BigintOperations::ShiftRight(big_value, amount.Value()); | |
311 default: | |
312 UNIMPLEMENTED(); | |
313 } | 326 } |
314 return Integer::null(); | 327 return Integer::null(); |
315 } | 328 } |
316 | 329 |
317 | 330 |
318 DEFINE_NATIVE_ENTRY(Integer_leftShiftWithMask32, 3) { | 331 DEFINE_NATIVE_ENTRY(Integer_leftShiftWithMask32, 3) { |
319 const Integer& value = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 332 const Integer& value = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
320 GET_NON_NULL_NATIVE_ARGUMENT(Integer, shift_count, arguments->NativeArgAt(1)); | 333 GET_NON_NULL_NATIVE_ARGUMENT(Integer, shift_count, arguments->NativeArgAt(1)); |
321 GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(2)); | 334 GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(2)); |
322 ASSERT(CheckInteger(value)); | 335 ASSERT(CheckInteger(value)); |
(...skipping 14 matching lines...) Expand all Loading... | |
337 } | 350 } |
338 | 351 |
339 | 352 |
340 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) { | 353 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) { |
341 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); | 354 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); |
342 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); | 355 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); |
343 ASSERT(CheckInteger(amount)); | 356 ASSERT(CheckInteger(amount)); |
344 ASSERT(CheckInteger(value)); | 357 ASSERT(CheckInteger(value)); |
345 const Integer& result = Integer::Handle( | 358 const Integer& result = Integer::Handle( |
346 ShiftOperationHelper(Token::kSHR, value, amount)); | 359 ShiftOperationHelper(Token::kSHR, value, amount)); |
360 if (result.IsNull()) { | |
361 return result.raw(); // A bigint operation is required. | |
362 } | |
347 return result.AsValidInteger(); | 363 return result.AsValidInteger(); |
348 } | 364 } |
349 | 365 |
350 | 366 |
351 | 367 |
352 DEFINE_NATIVE_ENTRY(Smi_shlFromInt, 2) { | 368 DEFINE_NATIVE_ENTRY(Smi_shlFromInt, 2) { |
353 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); | 369 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); |
354 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); | 370 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); |
355 ASSERT(CheckInteger(amount)); | 371 ASSERT(CheckInteger(amount)); |
356 ASSERT(CheckInteger(value)); | 372 ASSERT(CheckInteger(value)); |
357 if (FLAG_trace_intrinsified_natives) { | 373 if (FLAG_trace_intrinsified_natives) { |
358 OS::Print("Smi_shlFromInt: %s << %s\n", | 374 OS::Print("Smi_shlFromInt: %s << %s\n", |
359 value.ToCString(), amount.ToCString()); | 375 value.ToCString(), amount.ToCString()); |
360 } | 376 } |
361 const Integer& result = Integer::Handle( | 377 const Integer& result = Integer::Handle( |
362 ShiftOperationHelper(Token::kSHL, value, amount)); | 378 ShiftOperationHelper(Token::kSHL, value, amount)); |
379 if (result.IsNull()) { | |
380 return result.raw(); // A bigint operation is required. | |
381 } | |
363 return result.AsValidInteger(); | 382 return result.AsValidInteger(); |
364 } | 383 } |
365 | 384 |
366 | 385 |
367 DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) { | 386 DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) { |
368 const Smi& operand = Smi::CheckedHandle(arguments->NativeArgAt(0)); | 387 const Smi& operand = Smi::CheckedHandle(arguments->NativeArgAt(0)); |
369 if (FLAG_trace_intrinsified_natives) { | 388 if (FLAG_trace_intrinsified_natives) { |
370 OS::Print("Smi_bitNegate: %s\n", operand.ToCString()); | 389 OS::Print("Smi_bitNegate: %s\n", operand.ToCString()); |
371 } | 390 } |
372 intptr_t result = ~operand.Value(); | 391 intptr_t result = ~operand.Value(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
416 DEFINE_NATIVE_ENTRY(Mint_shlFromInt, 2) { | 435 DEFINE_NATIVE_ENTRY(Mint_shlFromInt, 2) { |
417 // Use the preallocated out of memory exception to avoid calling | 436 // Use the preallocated out of memory exception to avoid calling |
418 // into dart code or allocating any code. | 437 // into dart code or allocating any code. |
419 const Instance& exception = | 438 const Instance& exception = |
420 Instance::Handle(isolate->object_store()->out_of_memory()); | 439 Instance::Handle(isolate->object_store()->out_of_memory()); |
421 Exceptions::Throw(isolate, exception); | 440 Exceptions::Throw(isolate, exception); |
422 UNREACHABLE(); | 441 UNREACHABLE(); |
423 return 0; | 442 return 0; |
424 } | 443 } |
425 | 444 |
426 | |
427 // Bigint natives. | 445 // Bigint natives. |
428 | 446 |
429 DEFINE_NATIVE_ENTRY(Bigint_bitNegate, 1) { | 447 DEFINE_NATIVE_ENTRY(Bigint_getNeg, 1) { |
430 const Bigint& value = Bigint::CheckedHandle(arguments->NativeArgAt(0)); | 448 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
431 const Bigint& result = Bigint::Handle(BigintOperations::BitNot(value)); | 449 return bigint.neg(); |
432 ASSERT(CheckInteger(value)); | |
433 ASSERT(CheckInteger(result)); | |
434 return result.AsValidInteger(); | |
435 } | 450 } |
436 | 451 |
437 | 452 |
438 DEFINE_NATIVE_ENTRY(Bigint_bitLength, 1) { | 453 DEFINE_NATIVE_ENTRY(Bigint_setNeg, 2) { |
439 const Bigint& value = Bigint::CheckedHandle(arguments->NativeArgAt(0)); | 454 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
440 return Integer::New(BigintOperations::BitLength(value)); | 455 const Bool& neg = Bool::CheckedHandle(arguments->NativeArgAt(1)); |
456 bigint.set_neg(neg); | |
457 return Object::null(); | |
441 } | 458 } |
442 | 459 |
443 | 460 |
444 DEFINE_NATIVE_ENTRY(Bigint_shlFromInt, 2) { | 461 DEFINE_NATIVE_ENTRY(Bigint_getUsed, 1) { |
445 // Use the preallocated out of memory exception to avoid calling | 462 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
446 // into dart code or allocating any code. | 463 return bigint.used(); |
447 const Instance& exception = | 464 } |
448 Instance::Handle(isolate->object_store()->out_of_memory()); | 465 |
449 Exceptions::Throw(isolate, exception); | 466 |
450 UNREACHABLE(); | 467 DEFINE_NATIVE_ENTRY(Bigint_setUsed, 2) { |
451 return 0; | 468 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
469 const Smi& used = Smi::CheckedHandle(arguments->NativeArgAt(1)); | |
470 bigint.set_used(used); | |
471 return Object::null(); | |
472 } | |
473 | |
474 | |
475 DEFINE_NATIVE_ENTRY(Bigint_getDigits, 1) { | |
476 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); | |
477 return bigint.digits(); | |
478 } | |
479 | |
480 | |
481 DEFINE_NATIVE_ENTRY(Bigint_setDigits, 2) { | |
482 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); | |
483 const TypedData& digits = TypedData::CheckedHandle(arguments->NativeArgAt(1)); | |
484 bigint.set_digits(digits); | |
485 return Object::null(); | |
486 } | |
487 | |
488 | |
489 DEFINE_NATIVE_ENTRY(Bigint_allocate, 1) { | |
srdjan
2014/09/08 19:19:49
Why one argument? type?
regis
2014/09/09 19:18:14
This is the null type arguments, since class Bigin
| |
490 return Bigint::New(); | |
452 } | 491 } |
453 | 492 |
454 } // namespace dart | 493 } // namespace dart |
OLD | NEW |