Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(509)

Side by Side Diff: runtime/lib/integers.cc

Issue 509153003: New bigint implementation in the vm. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 = Integer::Handle(left.BitOp(Token::kBIT_AND, right));
57 Integer::Handle(left.BitOp(Token::kBIT_AND, right)); 56 // A null result indicates that a bigint operation is required.
58 return result.AsValidInteger(); 57 return result.IsNull() ? result.raw() : result.AsValidInteger();
59 } 58 }
60 59
61 60
62 DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 2) { 61 DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 2) {
63 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); 62 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0));
64 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); 63 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1));
65 ASSERT(CheckInteger(right)); 64 ASSERT(CheckInteger(right));
66 ASSERT(CheckInteger(left)); 65 ASSERT(CheckInteger(left));
67 if (FLAG_trace_intrinsified_natives) { 66 if (FLAG_trace_intrinsified_natives) {
68 OS::Print("Integer_bitOrFromInteger %s | %s\n", 67 OS::Print("Integer_bitOrFromInteger %s | %s\n",
69 left.ToCString(), right.ToCString()); 68 left.ToCString(), right.ToCString());
70 } 69 }
71 const Integer& result = 70 const Integer& result = Integer::Handle(left.BitOp(Token::kBIT_OR, right));
72 Integer::Handle(left.BitOp(Token::kBIT_OR, right)); 71 // A null result indicates that a bigint operation is required.
73 return result.AsValidInteger(); 72 return result.IsNull() ? result.raw() : result.AsValidInteger();
74 } 73 }
75 74
76 75
77 DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 2) { 76 DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 2) {
78 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); 77 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0));
79 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); 78 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1));
80 ASSERT(CheckInteger(right)); 79 ASSERT(CheckInteger(right));
81 ASSERT(CheckInteger(left)); 80 ASSERT(CheckInteger(left));
82 if (FLAG_trace_intrinsified_natives) { 81 if (FLAG_trace_intrinsified_natives) {
83 OS::Print("Integer_bitXorFromInteger %s ^ %s\n", 82 OS::Print("Integer_bitXorFromInteger %s ^ %s\n",
84 left.ToCString(), right.ToCString()); 83 left.ToCString(), right.ToCString());
85 } 84 }
86 const Integer& result = 85 const Integer& result = Integer::Handle(left.BitOp(Token::kBIT_XOR, right));
87 Integer::Handle(left.BitOp(Token::kBIT_XOR, right)); 86 // A null result indicates that a bigint operation is required.
88 return result.AsValidInteger(); 87 return result.IsNull() ? result.raw() : result.AsValidInteger();
89 } 88 }
90 89
91 90
92 DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 2) { 91 DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 2) {
93 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); 92 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0));
94 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); 93 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1));
95 ASSERT(CheckInteger(right_int)); 94 ASSERT(CheckInteger(right_int));
96 ASSERT(CheckInteger(left_int)); 95 ASSERT(CheckInteger(left_int));
97 if (FLAG_trace_intrinsified_natives) { 96 if (FLAG_trace_intrinsified_natives) {
98 OS::Print("Integer_addFromInteger %s + %s\n", 97 OS::Print("Integer_addFromInteger %s + %s\n",
99 left_int.ToCString(), right_int.ToCString()); 98 left_int.ToCString(), right_int.ToCString());
100 } 99 }
101 const Integer& result = 100 const Integer& result =
102 Integer::Handle(left_int.ArithmeticOp(Token::kADD, right_int)); 101 Integer::Handle(left_int.ArithmeticOp(Token::kADD, right_int));
103 return result.AsValidInteger(); 102 // A null result indicates that a bigint operation is required.
103 return result.IsNull() ? result.raw() : result.AsValidInteger();
104 } 104 }
105 105
106 106
107 DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 2) { 107 DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 2) {
108 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); 108 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0));
109 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); 109 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1));
110 ASSERT(CheckInteger(right_int)); 110 ASSERT(CheckInteger(right_int));
111 ASSERT(CheckInteger(left_int)); 111 ASSERT(CheckInteger(left_int));
112 if (FLAG_trace_intrinsified_natives) { 112 if (FLAG_trace_intrinsified_natives) {
113 OS::Print("Integer_subFromInteger %s - %s\n", 113 OS::Print("Integer_subFromInteger %s - %s\n",
114 left_int.ToCString(), right_int.ToCString()); 114 left_int.ToCString(), right_int.ToCString());
115 } 115 }
116 const Integer& result = 116 const Integer& result =
117 Integer::Handle(left_int.ArithmeticOp(Token::kSUB, right_int)); 117 Integer::Handle(left_int.ArithmeticOp(Token::kSUB, right_int));
118 return result.AsValidInteger(); 118 // A null result indicates that a bigint operation is required.
119 return result.IsNull() ? result.raw() : result.AsValidInteger();
119 } 120 }
120 121
121 122
122 DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 2) { 123 DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 2) {
123 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); 124 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0));
124 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); 125 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1));
125 ASSERT(CheckInteger(right_int)); 126 ASSERT(CheckInteger(right_int));
126 ASSERT(CheckInteger(left_int)); 127 ASSERT(CheckInteger(left_int));
127 if (FLAG_trace_intrinsified_natives) { 128 if (FLAG_trace_intrinsified_natives) {
128 OS::Print("Integer_mulFromInteger %s * %s\n", 129 OS::Print("Integer_mulFromInteger %s * %s\n",
129 left_int.ToCString(), right_int.ToCString()); 130 left_int.ToCString(), right_int.ToCString());
130 } 131 }
131 const Integer& result = 132 const Integer& result =
132 Integer::Handle(left_int.ArithmeticOp(Token::kMUL, right_int)); 133 Integer::Handle(left_int.ArithmeticOp(Token::kMUL, right_int));
133 return result.AsValidInteger(); 134 // A null result indicates that a bigint operation is required.
135 return result.IsNull() ? result.raw() : result.AsValidInteger();
134 } 136 }
135 137
136 138
137 DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 2) { 139 DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 2) {
138 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); 140 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0));
139 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); 141 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1));
140 ASSERT(CheckInteger(right_int)); 142 ASSERT(CheckInteger(right_int));
141 ASSERT(CheckInteger(left_int)); 143 ASSERT(CheckInteger(left_int));
142 ASSERT(!right_int.IsZero()); 144 ASSERT(!right_int.IsZero());
143 const Integer& result = 145 const Integer& result =
144 Integer::Handle(left_int.ArithmeticOp(Token::kTRUNCDIV, right_int)); 146 Integer::Handle(left_int.ArithmeticOp(Token::kTRUNCDIV, right_int));
145 return result.AsValidInteger(); 147 // A null result indicates that a bigint operation is required.
148 return result.IsNull() ? result.raw() : result.AsValidInteger();
146 } 149 }
147 150
148 151
149 DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 2) { 152 DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 2) {
150 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); 153 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0));
151 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); 154 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1));
152 ASSERT(CheckInteger(right_int)); 155 ASSERT(CheckInteger(right_int));
153 ASSERT(CheckInteger(right_int)); 156 ASSERT(CheckInteger(right_int));
154 if (FLAG_trace_intrinsified_natives) { 157 if (FLAG_trace_intrinsified_natives) {
155 OS::Print("Integer_moduloFromInteger %s mod %s\n", 158 OS::Print("Integer_moduloFromInteger %s mod %s\n",
156 left_int.ToCString(), right_int.ToCString()); 159 left_int.ToCString(), right_int.ToCString());
157 } 160 }
158 if (right_int.IsZero()) { 161 if (right_int.IsZero()) {
159 // Should have been caught before calling into runtime. 162 // Should have been caught before calling into runtime.
160 UNIMPLEMENTED(); 163 UNIMPLEMENTED();
161 } 164 }
162 const Integer& result = 165 const Integer& result =
163 Integer::Handle(left_int.ArithmeticOp(Token::kMOD, right_int)); 166 Integer::Handle(left_int.ArithmeticOp(Token::kMOD, right_int));
164 return result.AsValidInteger(); 167 // A null result indicates that a bigint operation is required.
168 return result.IsNull() ? result.raw() : result.AsValidInteger();
165 } 169 }
166 170
167 171
168 DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 2) { 172 DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 2) {
169 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); 173 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0));
170 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); 174 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1));
171 ASSERT(CheckInteger(right)); 175 ASSERT(CheckInteger(right));
172 ASSERT(CheckInteger(left)); 176 ASSERT(CheckInteger(left));
173 if (FLAG_trace_intrinsified_natives) { 177 if (FLAG_trace_intrinsified_natives) {
174 OS::Print("Integer_greaterThanFromInteger %s > %s\n", 178 OS::Print("Integer_greaterThanFromInteger %s > %s\n",
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 const Integer& value, 263 const Integer& value,
260 const Smi& amount, 264 const Smi& amount,
261 const bool silent = false) { 265 const bool silent = false) {
262 if (amount.Value() < 0) { 266 if (amount.Value() < 0) {
263 Exceptions::ThrowArgumentError(amount); 267 Exceptions::ThrowArgumentError(amount);
264 } 268 }
265 if (value.IsSmi()) { 269 if (value.IsSmi()) {
266 const Smi& smi_value = Smi::Cast(value); 270 const Smi& smi_value = Smi::Cast(value);
267 return smi_value.ShiftOp(kind, amount, silent); 271 return smi_value.ShiftOp(kind, amount, silent);
268 } 272 }
269 Bigint& big_value = Bigint::Handle();
270 if (value.IsMint()) { 273 if (value.IsMint()) {
271 const int64_t mint_value = value.AsInt64Value(); 274 const int64_t mint_value = value.AsInt64Value();
272 const int count = Utils::HighestBit(mint_value); 275 const int count = Utils::HighestBit(mint_value);
273 intptr_t shift_count = amount.Value(); 276 intptr_t shift_count = amount.Value();
274 if (kind == Token::kSHR) { 277 if (kind == Token::kSHR) {
275 shift_count = -shift_count; 278 shift_count = -shift_count;
276 } 279 }
277 if ((count + shift_count) < Mint::kBits) { 280 if ((count + shift_count) < Mint::kBits) {
278 switch (kind) { 281 switch (kind) {
279 case Token::kSHL: 282 case Token::kSHL:
280 return Integer::New(mint_value << shift_count, Heap::kNew, silent); 283 return Integer::New(mint_value << shift_count, Heap::kNew, silent);
281 case Token::kSHR: 284 case Token::kSHR:
282 return Integer::New(mint_value >> -shift_count, Heap::kNew, silent); 285 return Integer::New(mint_value >> -shift_count, Heap::kNew, silent);
283 default: 286 default:
284 UNIMPLEMENTED(); 287 UNIMPLEMENTED();
285 } 288 }
286 } else { 289 } else {
287 // Overflow in shift, use Bigints 290 // Overflow in shift, use Bigints
288 big_value = BigintOperations::NewFromInt64(mint_value); 291 return Integer::null();
289 } 292 }
290 } else { 293 } else {
291 ASSERT(value.IsBigint()); 294 ASSERT(value.IsBigint());
292 big_value = Bigint::Cast(value).raw();
293 }
294 switch (kind) {
295 case Token::kSHL:
296 return BigintOperations::ShiftLeft(big_value, amount.Value());
297 case Token::kSHR:
298 return BigintOperations::ShiftRight(big_value, amount.Value());
299 default:
300 UNIMPLEMENTED();
301 } 295 }
302 return Integer::null(); 296 return Integer::null();
303 } 297 }
304 298
305 299
306 DEFINE_NATIVE_ENTRY(Integer_leftShiftWithMask32, 3) { 300 DEFINE_NATIVE_ENTRY(Integer_leftShiftWithMask32, 3) {
307 const Integer& value = Integer::CheckedHandle(arguments->NativeArgAt(0)); 301 const Integer& value = Integer::CheckedHandle(arguments->NativeArgAt(0));
308 GET_NON_NULL_NATIVE_ARGUMENT(Integer, shift_count, arguments->NativeArgAt(1)); 302 GET_NON_NULL_NATIVE_ARGUMENT(Integer, shift_count, arguments->NativeArgAt(1));
309 GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(2)); 303 GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(2));
310 ASSERT(CheckInteger(value)); 304 ASSERT(CheckInteger(value));
(...skipping 14 matching lines...) Expand all
325 } 319 }
326 320
327 321
328 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) { 322 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) {
329 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); 323 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0));
330 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); 324 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1));
331 ASSERT(CheckInteger(amount)); 325 ASSERT(CheckInteger(amount));
332 ASSERT(CheckInteger(value)); 326 ASSERT(CheckInteger(value));
333 const Integer& result = Integer::Handle( 327 const Integer& result = Integer::Handle(
334 ShiftOperationHelper(Token::kSHR, value, amount)); 328 ShiftOperationHelper(Token::kSHR, value, amount));
335 return result.AsValidInteger(); 329 // A null result indicates that a bigint operation is required.
330 return result.IsNull() ? result.raw() : result.AsValidInteger();
336 } 331 }
337 332
338 333
339 334
340 DEFINE_NATIVE_ENTRY(Smi_shlFromInt, 2) { 335 DEFINE_NATIVE_ENTRY(Smi_shlFromInt, 2) {
341 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); 336 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0));
342 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); 337 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1));
343 ASSERT(CheckInteger(amount)); 338 ASSERT(CheckInteger(amount));
344 ASSERT(CheckInteger(value)); 339 ASSERT(CheckInteger(value));
345 if (FLAG_trace_intrinsified_natives) { 340 if (FLAG_trace_intrinsified_natives) {
346 OS::Print("Smi_shlFromInt: %s << %s\n", 341 OS::Print("Smi_shlFromInt: %s << %s\n",
347 value.ToCString(), amount.ToCString()); 342 value.ToCString(), amount.ToCString());
348 } 343 }
349 const Integer& result = Integer::Handle( 344 const Integer& result = Integer::Handle(
350 ShiftOperationHelper(Token::kSHL, value, amount)); 345 ShiftOperationHelper(Token::kSHL, value, amount));
351 return result.AsValidInteger(); 346 // A null result indicates that a bigint operation is required.
347 return result.IsNull() ? result.raw() : result.AsValidInteger();
352 } 348 }
353 349
354 350
355 DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) { 351 DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) {
356 const Smi& operand = Smi::CheckedHandle(arguments->NativeArgAt(0)); 352 const Smi& operand = Smi::CheckedHandle(arguments->NativeArgAt(0));
357 if (FLAG_trace_intrinsified_natives) { 353 if (FLAG_trace_intrinsified_natives) {
358 OS::Print("Smi_bitNegate: %s\n", operand.ToCString()); 354 OS::Print("Smi_bitNegate: %s\n", operand.ToCString());
359 } 355 }
360 intptr_t result = ~operand.Value(); 356 intptr_t result = ~operand.Value();
361 ASSERT(Smi::IsValid(result)); 357 ASSERT(Smi::IsValid(result));
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 const Instance& exception = 403 const Instance& exception =
408 Instance::Handle(isolate->object_store()->out_of_memory()); 404 Instance::Handle(isolate->object_store()->out_of_memory());
409 Exceptions::Throw(isolate, exception); 405 Exceptions::Throw(isolate, exception);
410 UNREACHABLE(); 406 UNREACHABLE();
411 return 0; 407 return 0;
412 } 408 }
413 409
414 410
415 // Bigint natives. 411 // Bigint natives.
416 412
417 DEFINE_NATIVE_ENTRY(Bigint_bitNegate, 1) { 413 DEFINE_NATIVE_ENTRY(Bigint_getNeg, 1) {
418 const Bigint& value = Bigint::CheckedHandle(arguments->NativeArgAt(0)); 414 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0));
419 const Bigint& result = Bigint::Handle(BigintOperations::BitNot(value)); 415 return bigint.neg();
420 ASSERT(CheckInteger(value));
421 ASSERT(CheckInteger(result));
422 return result.AsValidInteger();
423 } 416 }
424 417
425 418
426 DEFINE_NATIVE_ENTRY(Bigint_bitLength, 1) { 419 DEFINE_NATIVE_ENTRY(Bigint_setNeg, 2) {
427 const Bigint& value = Bigint::CheckedHandle(arguments->NativeArgAt(0)); 420 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0));
428 return Integer::New(BigintOperations::BitLength(value)); 421 const Bool& neg = Bool::CheckedHandle(arguments->NativeArgAt(1));
422 bigint.set_neg(neg);
423 return Object::null();
429 } 424 }
430 425
431 426
432 DEFINE_NATIVE_ENTRY(Bigint_shlFromInt, 2) { 427 DEFINE_NATIVE_ENTRY(Bigint_getUsed, 1) {
433 // Use the preallocated out of memory exception to avoid calling 428 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0));
434 // into dart code or allocating any code. 429 return bigint.used();
435 const Instance& exception = 430 }
436 Instance::Handle(isolate->object_store()->out_of_memory()); 431
437 Exceptions::Throw(isolate, exception); 432
438 UNREACHABLE(); 433 DEFINE_NATIVE_ENTRY(Bigint_setUsed, 2) {
439 return 0; 434 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0));
435 const Smi& used = Smi::CheckedHandle(arguments->NativeArgAt(1));
436 bigint.set_used(used);
437 return Object::null();
438 }
439
440
441 DEFINE_NATIVE_ENTRY(Bigint_getDigits, 1) {
442 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0));
443 return bigint.digits();
444 }
445
446
447 DEFINE_NATIVE_ENTRY(Bigint_setDigits, 2) {
448 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0));
449 const TypedData& digits = TypedData::CheckedHandle(arguments->NativeArgAt(1));
450 bigint.set_digits(digits);
451 return Object::null();
452 }
453
454
455 DEFINE_NATIVE_ENTRY(Bigint_allocate, 1) {
456 // Argument is null type arguments, since class Bigint is not parameterized.
457 return Bigint::New();
440 } 458 }
441 459
442 } // namespace dart 460 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698