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

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

Issue 22640019: Fix for running with --throw_on_javascript_int_overflow: recognize pattern (a << b) & mask and test… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 4 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
« no previous file with comments | « no previous file | runtime/lib/integers.dart » ('j') | runtime/vm/flow_graph_builder.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 return Integer::New(temp); 216 return Integer::New(temp);
217 } 217 }
218 218
219 const Array& args = Array::Handle(Array::New(1)); 219 const Array& args = Array::Handle(Array::New(1));
220 args.SetAt(0, value); 220 args.SetAt(0, value);
221 Exceptions::ThrowByType(Exceptions::kFormat, args); 221 Exceptions::ThrowByType(Exceptions::kFormat, args);
222 return Object::null(); 222 return Object::null();
223 } 223 }
224 224
225 225
226 // Passing true for 'silent' prevents throwing JavascriptIntegerOverflow.
226 static RawInteger* ShiftOperationHelper(Token::Kind kind, 227 static RawInteger* ShiftOperationHelper(Token::Kind kind,
227 const Integer& value, 228 const Integer& value,
228 const Smi& amount) { 229 const Smi& amount,
230 const bool silent = false) {
229 if (amount.Value() < 0) { 231 if (amount.Value() < 0) {
230 const Array& args = Array::Handle(Array::New(1)); 232 const Array& args = Array::Handle(Array::New(1));
231 args.SetAt(0, amount); 233 args.SetAt(0, amount);
232 Exceptions::ThrowByType(Exceptions::kArgument, args); 234 Exceptions::ThrowByType(Exceptions::kArgument, args);
233 } 235 }
234 if (value.IsSmi()) { 236 if (value.IsSmi()) {
235 const Smi& smi_value = Smi::Cast(value); 237 const Smi& smi_value = Smi::Cast(value);
236 return smi_value.ShiftOp(kind, amount); 238 return smi_value.ShiftOp(kind, amount, silent);
237 } 239 }
238 Bigint& big_value = Bigint::Handle(); 240 Bigint& big_value = Bigint::Handle();
239 if (value.IsMint()) { 241 if (value.IsMint()) {
240 const int64_t mint_value = value.AsInt64Value(); 242 const int64_t mint_value = value.AsInt64Value();
241 const int count = Utils::HighestBit(mint_value); 243 const int count = Utils::HighestBit(mint_value);
242 if ((count + amount.Value()) < Mint::kBits) { 244 if ((count + amount.Value()) < Mint::kBits) {
243 switch (kind) { 245 switch (kind) {
244 case Token::kSHL: 246 case Token::kSHL:
245 return Integer::New(mint_value << amount.Value()); 247 return Integer::New(mint_value << amount.Value(), Heap::kNew, silent);
246 case Token::kSHR: 248 case Token::kSHR:
247 return Integer::New(mint_value >> amount.Value()); 249 return Integer::New(mint_value >> amount.Value(), Heap::kNew, silent);
248 default: 250 default:
249 UNIMPLEMENTED(); 251 UNIMPLEMENTED();
250 } 252 }
251 } else { 253 } else {
252 // Overflow in shift, use Bigints 254 // Overflow in shift, use Bigints
253 big_value = BigintOperations::NewFromInt64(mint_value); 255 big_value = BigintOperations::NewFromInt64(mint_value);
254 } 256 }
255 } else { 257 } else {
256 ASSERT(value.IsBigint()); 258 ASSERT(value.IsBigint());
257 big_value = Bigint::Cast(value).raw(); 259 big_value = Bigint::Cast(value).raw();
258 } 260 }
259 switch (kind) { 261 switch (kind) {
260 case Token::kSHL: 262 case Token::kSHL:
261 return BigintOperations::ShiftLeft(big_value, amount.Value()); 263 return BigintOperations::ShiftLeft(big_value, amount.Value());
262 case Token::kSHR: 264 case Token::kSHR:
263 return BigintOperations::ShiftRight(big_value, amount.Value()); 265 return BigintOperations::ShiftRight(big_value, amount.Value());
264 default: 266 default:
265 UNIMPLEMENTED(); 267 UNIMPLEMENTED();
266 } 268 }
267 return Integer::null(); 269 return Integer::null();
268 } 270 }
269 271
270 272
273 DEFINE_NATIVE_ENTRY(Integer_leftShiftWithMask32, 3) {
274 const Integer& value = Integer::CheckedHandle(arguments->NativeArgAt(0));
275 GET_NON_NULL_NATIVE_ARGUMENT(Integer, shift_count, arguments->NativeArgAt(1));
276 GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(2));
277 ASSERT(CheckInteger(value));
278 ASSERT(CheckInteger(shift_count));
279 ASSERT(CheckInteger(mask));
280 if (!shift_count.IsSmi()) {
281 // Shift count is too large..
282 const Instance& exception =
283 Instance::Handle(isolate->object_store()->out_of_memory());
284 Exceptions::Throw(exception);
285 }
286 const Smi& smi_shift_count = Smi::Cast(shift_count);
287 const Integer& shift_result = Integer::Handle(
288 ShiftOperationHelper(Token::kSHL, value, smi_shift_count, true));
289 const Integer& result =
290 Integer::Handle(shift_result.BitOp(Token::kBIT_AND, mask));
291 return result.AsValidInteger();
292 }
293
294
271 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) { 295 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) {
272 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); 296 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0));
273 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); 297 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1));
274 ASSERT(CheckInteger(amount)); 298 ASSERT(CheckInteger(amount));
275 ASSERT(CheckInteger(value)); 299 ASSERT(CheckInteger(value));
276 const Integer& result = Integer::Handle( 300 const Integer& result = Integer::Handle(
277 ShiftOperationHelper(Token::kSHR, value, amount)); 301 ShiftOperationHelper(Token::kSHR, value, amount));
278 return result.AsValidInteger(); 302 return result.AsValidInteger();
279 } 303 }
280 304
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 // Use the preallocated out of memory exception to avoid calling 369 // Use the preallocated out of memory exception to avoid calling
346 // into dart code or allocating any code. 370 // into dart code or allocating any code.
347 const Instance& exception = 371 const Instance& exception =
348 Instance::Handle(isolate->object_store()->out_of_memory()); 372 Instance::Handle(isolate->object_store()->out_of_memory());
349 Exceptions::Throw(exception); 373 Exceptions::Throw(exception);
350 UNREACHABLE(); 374 UNREACHABLE();
351 return 0; 375 return 0;
352 } 376 }
353 377
354 } // namespace dart 378 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/lib/integers.dart » ('j') | runtime/vm/flow_graph_builder.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698