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

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

Issue 15743017: Adds a flag to the standalone vm to throw an exception on 53-bit integer overflow. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 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 "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/dart_entry.h" 8 #include "vm/dart_entry.h"
9 #include "vm/exceptions.h" 9 #include "vm/exceptions.h"
10 #include "vm/native_entry.h" 10 #include "vm/native_entry.h"
11 #include "vm/object.h" 11 #include "vm/object.h"
12 #include "vm/symbols.h" 12 #include "vm/symbols.h"
13 13
14 namespace dart { 14 namespace dart {
15 15
16 DEFINE_FLAG(bool, throw_on_53bit_overflow, false,
17 "Throw an exception when integer arithmetic exceeds 53 bits.");
18
16 DEFINE_FLAG(bool, trace_intrinsified_natives, false, 19 DEFINE_FLAG(bool, trace_intrinsified_natives, false,
17 "Report if any of the intrinsified natives are called"); 20 "Report if any of the intrinsified natives are called");
18 21
19 // Smi natives. 22 // Smi natives.
20 23
21 // 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
22 // when it could have been a Smi. 25 // when it could have been a Smi.
23 static bool CheckInteger(const Integer& i) { 26 static bool CheckInteger(const Integer& i) {
24 if (i.IsBigint()) { 27 if (i.IsBigint()) {
25 const Bigint& bigint = Bigint::Cast(i); 28 const Bigint& bigint = Bigint::Cast(i);
26 return !BigintOperations::FitsIntoSmi(bigint) && 29 return !BigintOperations::FitsIntoSmi(bigint) &&
27 !BigintOperations::FitsIntoInt64(bigint); 30 !BigintOperations::FitsIntoInt64(bigint);
28 } 31 }
29 if (i.IsMint()) { 32 if (i.IsMint()) {
30 const Mint& mint = Mint::Cast(i); 33 const Mint& mint = Mint::Cast(i);
31 return !Smi::IsValid64(mint.value()); 34 return !Smi::IsValid64(mint.value());
32 } 35 }
33 return true; 36 return true;
34 } 37 }
35 38
36 39
40 // Throw kFiftyThreeBitOverflow if the result of an operation overflows
41 // 53 bits.
42 static void ThrowExceptionOnOverflow(const Integer& i, const char* msg) {
siva 2013/05/23 01:28:22 The name ThrowExceptionOnOverflow seems like a gen
zra 2013/05/23 15:59:07 Done.
43 if (i.FitsIn53Bits()) return;
44 const Array& exc_args = Array::Handle(Array::New(1));
45 exc_args.SetAt(0, Object::Handle(String::New(msg)));
46 Exceptions::ThrowByType(Exceptions::kFiftyThreeBitOverflowError, exc_args);
47 return;
48 }
49
50
37 DEFINE_NATIVE_ENTRY(Integer_bitAndFromInteger, 2) { 51 DEFINE_NATIVE_ENTRY(Integer_bitAndFromInteger, 2) {
38 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); 52 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0));
39 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); 53 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1));
40 ASSERT(CheckInteger(right)); 54 ASSERT(CheckInteger(right));
41 ASSERT(CheckInteger(left)); 55 ASSERT(CheckInteger(left));
42 if (FLAG_trace_intrinsified_natives) { 56 if (FLAG_trace_intrinsified_natives) {
43 OS::Print("Integer_bitAndFromInteger %s & %s\n", 57 OS::Print("Integer_bitAndFromInteger %s & %s\n",
44 right.ToCString(), left.ToCString()); 58 right.ToCString(), left.ToCString());
45 } 59 }
46 const Integer& result = 60 const Integer& result =
47 Integer::Handle(left.BitOp(Token::kBIT_AND, right)); 61 Integer::Handle(left.BitOp(Token::kBIT_AND, right));
62 if (FLAG_throw_on_53bit_overflow) {
63 ThrowExceptionOnOverflow(result, "Integer_bitAndFromInteger");
64 }
48 return result.AsValidInteger(); 65 return result.AsValidInteger();
49 } 66 }
50 67
51 68
52 DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 2) { 69 DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 2) {
53 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); 70 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0));
54 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); 71 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1));
55 ASSERT(CheckInteger(right)); 72 ASSERT(CheckInteger(right));
56 ASSERT(CheckInteger(left)); 73 ASSERT(CheckInteger(left));
57 if (FLAG_trace_intrinsified_natives) { 74 if (FLAG_trace_intrinsified_natives) {
58 OS::Print("Integer_bitOrFromInteger %s | %s\n", 75 OS::Print("Integer_bitOrFromInteger %s | %s\n",
59 left.ToCString(), right.ToCString()); 76 left.ToCString(), right.ToCString());
60 } 77 }
61 const Integer& result = 78 const Integer& result =
62 Integer::Handle(left.BitOp(Token::kBIT_OR, right)); 79 Integer::Handle(left.BitOp(Token::kBIT_OR, right));
80 if (FLAG_throw_on_53bit_overflow) {
81 ThrowExceptionOnOverflow(result, "Integer_bitOrFromInteger");
82 }
63 return result.AsValidInteger(); 83 return result.AsValidInteger();
64 } 84 }
65 85
66 86
67 DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 2) { 87 DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 2) {
68 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); 88 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0));
69 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); 89 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1));
70 ASSERT(CheckInteger(right)); 90 ASSERT(CheckInteger(right));
71 ASSERT(CheckInteger(left)); 91 ASSERT(CheckInteger(left));
72 if (FLAG_trace_intrinsified_natives) { 92 if (FLAG_trace_intrinsified_natives) {
73 OS::Print("Integer_bitXorFromInteger %s ^ %s\n", 93 OS::Print("Integer_bitXorFromInteger %s ^ %s\n",
74 left.ToCString(), right.ToCString()); 94 left.ToCString(), right.ToCString());
75 } 95 }
76 const Integer& result = 96 const Integer& result =
77 Integer::Handle(left.BitOp(Token::kBIT_XOR, right)); 97 Integer::Handle(left.BitOp(Token::kBIT_XOR, right));
98 if (FLAG_throw_on_53bit_overflow) {
99 ThrowExceptionOnOverflow(result, "Integer_bitXorFromInteger");
100 }
78 return result.AsValidInteger(); 101 return result.AsValidInteger();
79 } 102 }
80 103
81 104
82 DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 2) { 105 DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 2) {
83 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); 106 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0));
84 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); 107 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1));
85 ASSERT(CheckInteger(right_int)); 108 ASSERT(CheckInteger(right_int));
86 ASSERT(CheckInteger(left_int)); 109 ASSERT(CheckInteger(left_int));
87 if (FLAG_trace_intrinsified_natives) { 110 if (FLAG_trace_intrinsified_natives) {
88 OS::Print("Integer_addFromInteger %s + %s\n", 111 OS::Print("Integer_addFromInteger %s + %s\n",
89 left_int.ToCString(), right_int.ToCString()); 112 left_int.ToCString(), right_int.ToCString());
90 } 113 }
91 const Integer& result = 114 const Integer& result =
92 Integer::Handle(left_int.ArithmeticOp(Token::kADD, right_int)); 115 Integer::Handle(left_int.ArithmeticOp(Token::kADD, right_int));
116 if (FLAG_throw_on_53bit_overflow) {
117 ThrowExceptionOnOverflow(result, "Integer_addFromInteger");
118 }
93 return result.AsValidInteger(); 119 return result.AsValidInteger();
94 } 120 }
95 121
96 122
97 DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 2) { 123 DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 2) {
98 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); 124 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0));
99 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); 125 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1));
100 ASSERT(CheckInteger(right_int)); 126 ASSERT(CheckInteger(right_int));
101 ASSERT(CheckInteger(left_int)); 127 ASSERT(CheckInteger(left_int));
102 if (FLAG_trace_intrinsified_natives) { 128 if (FLAG_trace_intrinsified_natives) {
103 OS::Print("Integer_subFromInteger %s - %s\n", 129 OS::Print("Integer_subFromInteger %s - %s\n",
104 left_int.ToCString(), right_int.ToCString()); 130 left_int.ToCString(), right_int.ToCString());
105 } 131 }
106 const Integer& result = 132 const Integer& result =
107 Integer::Handle(left_int.ArithmeticOp(Token::kSUB, right_int)); 133 Integer::Handle(left_int.ArithmeticOp(Token::kSUB, right_int));
134 if (FLAG_throw_on_53bit_overflow) {
135 ThrowExceptionOnOverflow(result, "Integer_subFromInteger");
136 }
108 return result.AsValidInteger(); 137 return result.AsValidInteger();
109 } 138 }
110 139
111 140
112 DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 2) { 141 DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 2) {
113 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); 142 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0));
114 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); 143 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1));
115 ASSERT(CheckInteger(right_int)); 144 ASSERT(CheckInteger(right_int));
116 ASSERT(CheckInteger(left_int)); 145 ASSERT(CheckInteger(left_int));
117 if (FLAG_trace_intrinsified_natives) { 146 if (FLAG_trace_intrinsified_natives) {
118 OS::Print("Integer_mulFromInteger %s * %s\n", 147 OS::Print("Integer_mulFromInteger %s * %s\n",
119 left_int.ToCString(), right_int.ToCString()); 148 left_int.ToCString(), right_int.ToCString());
120 } 149 }
121 const Integer& result = 150 const Integer& result =
122 Integer::Handle(left_int.ArithmeticOp(Token::kMUL, right_int)); 151 Integer::Handle(left_int.ArithmeticOp(Token::kMUL, right_int));
152 if (FLAG_throw_on_53bit_overflow) {
153 ThrowExceptionOnOverflow(result, "Integer_mulFromInteger");
154 }
123 return result.AsValidInteger(); 155 return result.AsValidInteger();
124 } 156 }
125 157
126 158
127 DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 2) { 159 DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 2) {
128 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); 160 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0));
129 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); 161 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1));
130 ASSERT(CheckInteger(right_int)); 162 ASSERT(CheckInteger(right_int));
131 ASSERT(CheckInteger(left_int)); 163 ASSERT(CheckInteger(left_int));
132 ASSERT(!right_int.IsZero()); 164 ASSERT(!right_int.IsZero());
133 const Integer& result = 165 const Integer& result =
134 Integer::Handle(left_int.ArithmeticOp(Token::kTRUNCDIV, right_int)); 166 Integer::Handle(left_int.ArithmeticOp(Token::kTRUNCDIV, right_int));
167 if (FLAG_throw_on_53bit_overflow) {
168 ThrowExceptionOnOverflow(result, "Integer_trucDivFromInteger");
169 }
135 return result.AsValidInteger(); 170 return result.AsValidInteger();
136 } 171 }
137 172
138 173
139 DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 2) { 174 DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 2) {
140 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); 175 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0));
141 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); 176 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1));
142 ASSERT(CheckInteger(right_int)); 177 ASSERT(CheckInteger(right_int));
143 ASSERT(CheckInteger(right_int)); 178 ASSERT(CheckInteger(right_int));
144 if (FLAG_trace_intrinsified_natives) { 179 if (FLAG_trace_intrinsified_natives) {
145 OS::Print("Integer_moduloFromInteger %s mod %s\n", 180 OS::Print("Integer_moduloFromInteger %s mod %s\n",
146 left_int.ToCString(), right_int.ToCString()); 181 left_int.ToCString(), right_int.ToCString());
147 } 182 }
148 if (right_int.IsZero()) { 183 if (right_int.IsZero()) {
149 // Should have been caught before calling into runtime. 184 // Should have been caught before calling into runtime.
150 UNIMPLEMENTED(); 185 UNIMPLEMENTED();
151 } 186 }
152 const Integer& result = 187 const Integer& result =
153 Integer::Handle(left_int.ArithmeticOp(Token::kMOD, right_int)); 188 Integer::Handle(left_int.ArithmeticOp(Token::kMOD, right_int));
189 if (FLAG_throw_on_53bit_overflow) {
190 ThrowExceptionOnOverflow(result, "Integer_moduloFromInteger");
191 }
154 return result.AsValidInteger(); 192 return result.AsValidInteger();
155 } 193 }
156 194
157 195
158 DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 2) { 196 DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 2) {
159 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); 197 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0));
160 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); 198 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1));
161 ASSERT(CheckInteger(right)); 199 ASSERT(CheckInteger(right));
162 ASSERT(CheckInteger(left)); 200 ASSERT(CheckInteger(left));
163 if (FLAG_trace_intrinsified_natives) { 201 if (FLAG_trace_intrinsified_natives) {
(...skipping 22 matching lines...) Expand all
186 if (value.IsOneByteString()) { 224 if (value.IsOneByteString()) {
187 // Quick conversion for unpadded integers in strings. 225 // Quick conversion for unpadded integers in strings.
188 const intptr_t len = value.Length(); 226 const intptr_t len = value.Length();
189 if (len > 0) { 227 if (len > 0) {
190 const char* cstr = value.ToCString(); 228 const char* cstr = value.ToCString();
191 ASSERT(cstr != NULL); 229 ASSERT(cstr != NULL);
192 char* p_end = NULL; 230 char* p_end = NULL;
193 const int64_t int_value = strtoll(cstr, &p_end, 10); 231 const int64_t int_value = strtoll(cstr, &p_end, 10);
194 if (p_end == (cstr + len)) { 232 if (p_end == (cstr + len)) {
195 if ((int_value != LLONG_MIN) && (int_value != LLONG_MAX)) { 233 if ((int_value != LLONG_MIN) && (int_value != LLONG_MAX)) {
196 return Integer::New(int_value); 234 const Integer& i = Integer::Handle(Integer::New(int_value));
235 if (FLAG_throw_on_53bit_overflow) {
236 ThrowExceptionOnOverflow(i, "Integer_parse");
237 }
238 return i.AsValidInteger();
197 } 239 }
198 } 240 }
199 } 241 }
200 } 242 }
201 243
202 Scanner scanner(value, Symbols::Empty()); 244 Scanner scanner(value, Symbols::Empty());
203 const Scanner::GrowableTokenStream& tokens = scanner.GetStream(); 245 const Scanner::GrowableTokenStream& tokens = scanner.GetStream();
204 String* int_string; 246 String* int_string;
205 bool is_positive; 247 bool is_positive;
206 if (Scanner::IsValidLiteral(tokens, 248 if (Scanner::IsValidLiteral(tokens,
207 Token::kINTEGER, 249 Token::kINTEGER,
208 &is_positive, 250 &is_positive,
209 &int_string)) { 251 &int_string)) {
210 if (is_positive) { 252 if (is_positive) {
211 return Integer::New(*int_string); 253 return Integer::New(*int_string);
212 } 254 }
213 String& temp = String::Handle(); 255 String& temp = String::Handle();
214 temp = String::Concat(Symbols::Dash(), *int_string); 256 temp = String::Concat(Symbols::Dash(), *int_string);
215 return Integer::New(temp); 257 const Integer& i = Integer::Handle(Integer::New(temp));
258 if (FLAG_throw_on_53bit_overflow) {
259 ThrowExceptionOnOverflow(i, "Integer_parse");
260 }
261 return i.AsValidInteger();
216 } 262 }
217 263
218 const Array& args = Array::Handle(Array::New(1)); 264 const Array& args = Array::Handle(Array::New(1));
219 args.SetAt(0, value); 265 args.SetAt(0, value);
220 Exceptions::ThrowByType(Exceptions::kFormat, args); 266 Exceptions::ThrowByType(Exceptions::kFormat, args);
221 return Object::null(); 267 return Object::null();
222 } 268 }
223 269
224 270
225 static RawInteger* ShiftOperationHelper(Token::Kind kind, 271 static RawInteger* ShiftOperationHelper(Token::Kind kind,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 } 313 }
268 314
269 315
270 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) { 316 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) {
271 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); 317 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0));
272 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); 318 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1));
273 ASSERT(CheckInteger(amount)); 319 ASSERT(CheckInteger(amount));
274 ASSERT(CheckInteger(value)); 320 ASSERT(CheckInteger(value));
275 const Integer& result = Integer::Handle( 321 const Integer& result = Integer::Handle(
276 ShiftOperationHelper(Token::kSHR, value, amount)); 322 ShiftOperationHelper(Token::kSHR, value, amount));
323 if (FLAG_throw_on_53bit_overflow) {
324 ThrowExceptionOnOverflow(result, "Smi_shrFromInt");
325 }
277 return result.AsValidInteger(); 326 return result.AsValidInteger();
278 } 327 }
279 328
280 329
281 330
282 DEFINE_NATIVE_ENTRY(Smi_shlFromInt, 2) { 331 DEFINE_NATIVE_ENTRY(Smi_shlFromInt, 2) {
283 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); 332 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0));
284 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); 333 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1));
285 ASSERT(CheckInteger(amount)); 334 ASSERT(CheckInteger(amount));
286 ASSERT(CheckInteger(value)); 335 ASSERT(CheckInteger(value));
287 if (FLAG_trace_intrinsified_natives) { 336 if (FLAG_trace_intrinsified_natives) {
288 OS::Print("Smi_shlFromInt: %s << %s\n", 337 OS::Print("Smi_shlFromInt: %s << %s\n",
289 value.ToCString(), amount.ToCString()); 338 value.ToCString(), amount.ToCString());
290 } 339 }
291 const Integer& result = Integer::Handle( 340 const Integer& result = Integer::Handle(
292 ShiftOperationHelper(Token::kSHL, value, amount)); 341 ShiftOperationHelper(Token::kSHL, value, amount));
342 if (FLAG_throw_on_53bit_overflow) {
343 ThrowExceptionOnOverflow(result, "Smi_shlFromInt");
344 }
293 return result.AsValidInteger(); 345 return result.AsValidInteger();
294 } 346 }
295 347
296 348
297 DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) { 349 DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) {
298 const Smi& operand = Smi::CheckedHandle(arguments->NativeArgAt(0)); 350 const Smi& operand = Smi::CheckedHandle(arguments->NativeArgAt(0));
299 if (FLAG_trace_intrinsified_natives) { 351 if (FLAG_trace_intrinsified_natives) {
300 OS::Print("Smi_bitNegate: %s\n", operand.ToCString()); 352 OS::Print("Smi_bitNegate: %s\n", operand.ToCString());
301 } 353 }
302 intptr_t result = ~operand.Value(); 354 intptr_t result = ~operand.Value();
303 ASSERT(Smi::IsValid(result)); 355 ASSERT(Smi::IsValid(result));
304 return Smi::New(result); 356 return Smi::New(result);
305 } 357 }
306 358
307 // Mint natives. 359 // Mint natives.
308 360
309 DEFINE_NATIVE_ENTRY(Mint_bitNegate, 1) { 361 DEFINE_NATIVE_ENTRY(Mint_bitNegate, 1) {
310 const Mint& operand = Mint::CheckedHandle(arguments->NativeArgAt(0)); 362 const Mint& operand = Mint::CheckedHandle(arguments->NativeArgAt(0));
311 ASSERT(CheckInteger(operand)); 363 ASSERT(CheckInteger(operand));
312 if (FLAG_trace_intrinsified_natives) { 364 if (FLAG_trace_intrinsified_natives) {
313 OS::Print("Mint_bitNegate: %s\n", operand.ToCString()); 365 OS::Print("Mint_bitNegate: %s\n", operand.ToCString());
314 } 366 }
315 int64_t result = ~operand.value(); 367 int64_t result = ~operand.value();
316 return Integer::New(result); 368 const Integer& i = Integer::Handle(Integer::New(result));
369 if (FLAG_throw_on_53bit_overflow) {
370 ThrowExceptionOnOverflow(i, "Integer_bitAndFromInteger");
371 }
372 return i.AsValidInteger();
siva 2013/05/23 01:28:22 Ditto question about the need for AsValidInteger.
zra 2013/05/23 15:59:07 Done.
317 } 373 }
318 374
319 // Bigint natives. 375 // Bigint natives.
320 376
321 DEFINE_NATIVE_ENTRY(Bigint_bitNegate, 1) { 377 DEFINE_NATIVE_ENTRY(Bigint_bitNegate, 1) {
322 const Bigint& value = Bigint::CheckedHandle(arguments->NativeArgAt(0)); 378 const Bigint& value = Bigint::CheckedHandle(arguments->NativeArgAt(0));
323 const Bigint& result = Bigint::Handle(BigintOperations::BitNot(value)); 379 const Bigint& result = Bigint::Handle(BigintOperations::BitNot(value));
324 ASSERT(CheckInteger(value)); 380 ASSERT(CheckInteger(value));
325 ASSERT(CheckInteger(result)); 381 ASSERT(CheckInteger(result));
326 return result.AsValidInteger(); 382 return result.AsValidInteger();
327 } 383 }
328 384
329 } // namespace dart 385 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698