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 "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 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 const Integer& right = Integer::CheckedHandle(arguments->At(0)); | 145 const Integer& right = Integer::CheckedHandle(arguments->At(0)); |
146 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); | 146 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); |
147 ASSERT(CheckInteger(right)); | 147 ASSERT(CheckInteger(right)); |
148 ASSERT(CheckInteger(left)); | 148 ASSERT(CheckInteger(left)); |
149 if (FLAG_trace_intrinsified_natives) { | 149 if (FLAG_trace_intrinsified_natives) { |
150 OS::Print("Integer_bitAndFromInteger %s & %s\n", | 150 OS::Print("Integer_bitAndFromInteger %s & %s\n", |
151 right.ToCString(), left.ToCString()); | 151 right.ToCString(), left.ToCString()); |
152 } | 152 } |
153 Integer& result = Integer::Handle( | 153 Integer& result = Integer::Handle( |
154 IntegerBitOperation(Token::kBIT_AND, left, right)); | 154 IntegerBitOperation(Token::kBIT_AND, left, right)); |
155 arguments->SetReturn(Integer::Handle(AsInteger(result))); | 155 return AsInteger(result); |
156 } | 156 } |
157 | 157 |
158 | 158 |
159 DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 2) { | 159 DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 2) { |
160 const Integer& right = Integer::CheckedHandle(arguments->At(0)); | 160 const Integer& right = Integer::CheckedHandle(arguments->At(0)); |
161 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); | 161 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); |
162 ASSERT(CheckInteger(right)); | 162 ASSERT(CheckInteger(right)); |
163 ASSERT(CheckInteger(left)); | 163 ASSERT(CheckInteger(left)); |
164 if (FLAG_trace_intrinsified_natives) { | 164 if (FLAG_trace_intrinsified_natives) { |
165 OS::Print("Integer_bitOrFromInteger %s | %s\n", | 165 OS::Print("Integer_bitOrFromInteger %s | %s\n", |
166 left.ToCString(), right.ToCString()); | 166 left.ToCString(), right.ToCString()); |
167 } | 167 } |
168 Integer& result = Integer::Handle( | 168 Integer& result = Integer::Handle( |
169 IntegerBitOperation(Token::kBIT_OR, left, right)); | 169 IntegerBitOperation(Token::kBIT_OR, left, right)); |
170 arguments->SetReturn(Integer::Handle(AsInteger(result))); | 170 return AsInteger(result); |
171 } | 171 } |
172 | 172 |
173 | 173 |
174 DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 2) { | 174 DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 2) { |
175 const Integer& right = Integer::CheckedHandle(arguments->At(0)); | 175 const Integer& right = Integer::CheckedHandle(arguments->At(0)); |
176 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); | 176 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); |
177 ASSERT(CheckInteger(right)); | 177 ASSERT(CheckInteger(right)); |
178 ASSERT(CheckInteger(left)); | 178 ASSERT(CheckInteger(left)); |
179 if (FLAG_trace_intrinsified_natives) { | 179 if (FLAG_trace_intrinsified_natives) { |
180 OS::Print("Integer_bitXorFromInteger %s ^ %s\n", | 180 OS::Print("Integer_bitXorFromInteger %s ^ %s\n", |
181 left.ToCString(), right.ToCString()); | 181 left.ToCString(), right.ToCString()); |
182 } | 182 } |
183 Integer& result = Integer::Handle( | 183 Integer& result = Integer::Handle( |
184 IntegerBitOperation(Token::kBIT_XOR, left, right)); | 184 IntegerBitOperation(Token::kBIT_XOR, left, right)); |
185 arguments->SetReturn(Integer::Handle(AsInteger(result))); | 185 return AsInteger(result); |
186 } | 186 } |
187 | 187 |
188 | 188 |
189 static RawBigint* BinaryOpWithTwoBigints(Token::Kind operation, | 189 static RawBigint* BinaryOpWithTwoBigints(Token::Kind operation, |
190 const Bigint& left, | 190 const Bigint& left, |
191 const Bigint& right) { | 191 const Bigint& right) { |
192 switch (operation) { | 192 switch (operation) { |
193 case Token::kADD: | 193 case Token::kADD: |
194 return BigintOperations::Add(left, right); | 194 return BigintOperations::Add(left, right); |
195 case Token::kSUB: | 195 case Token::kSUB: |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 | 309 |
310 DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 2) { | 310 DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 2) { |
311 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); | 311 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); |
312 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); | 312 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); |
313 ASSERT(CheckInteger(right_int)); | 313 ASSERT(CheckInteger(right_int)); |
314 ASSERT(CheckInteger(left_int)); | 314 ASSERT(CheckInteger(left_int)); |
315 if (FLAG_trace_intrinsified_natives) { | 315 if (FLAG_trace_intrinsified_natives) { |
316 OS::Print("Integer_addFromInteger %s + %s\n", | 316 OS::Print("Integer_addFromInteger %s + %s\n", |
317 left_int.ToCString(), right_int.ToCString()); | 317 left_int.ToCString(), right_int.ToCString()); |
318 } | 318 } |
319 const Integer& result = | 319 return IntegerBinopHelper(Token::kADD, left_int, right_int); |
320 Integer::Handle(IntegerBinopHelper(Token::kADD, left_int, right_int)); | |
321 arguments->SetReturn(result); | |
322 } | 320 } |
323 | 321 |
324 | 322 |
325 DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 2) { | 323 DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 2) { |
326 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); | 324 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); |
327 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); | 325 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); |
328 ASSERT(CheckInteger(right_int)); | 326 ASSERT(CheckInteger(right_int)); |
329 ASSERT(CheckInteger(left_int)); | 327 ASSERT(CheckInteger(left_int)); |
330 if (FLAG_trace_intrinsified_natives) { | 328 if (FLAG_trace_intrinsified_natives) { |
331 OS::Print("Integer_subFromInteger %s - %s\n", | 329 OS::Print("Integer_subFromInteger %s - %s\n", |
332 left_int.ToCString(), right_int.ToCString()); | 330 left_int.ToCString(), right_int.ToCString()); |
333 } | 331 } |
334 const Integer& result = | 332 return IntegerBinopHelper(Token::kSUB, left_int, right_int); |
335 Integer::Handle(IntegerBinopHelper(Token::kSUB, left_int, right_int)); | |
336 arguments->SetReturn(result); | |
337 } | 333 } |
338 | 334 |
339 | 335 |
340 DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 2) { | 336 DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 2) { |
341 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); | 337 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); |
342 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); | 338 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); |
343 ASSERT(CheckInteger(right_int)); | 339 ASSERT(CheckInteger(right_int)); |
344 ASSERT(CheckInteger(left_int)); | 340 ASSERT(CheckInteger(left_int)); |
345 if (FLAG_trace_intrinsified_natives) { | 341 if (FLAG_trace_intrinsified_natives) { |
346 OS::Print("Integer_mulFromInteger %s * %s\n", | 342 OS::Print("Integer_mulFromInteger %s * %s\n", |
347 left_int.ToCString(), right_int.ToCString()); | 343 left_int.ToCString(), right_int.ToCString()); |
348 } | 344 } |
349 const Integer& result = | 345 return IntegerBinopHelper(Token::kMUL, left_int, right_int); |
350 Integer::Handle(IntegerBinopHelper(Token::kMUL, left_int, right_int)); | |
351 arguments->SetReturn(result); | |
352 } | 346 } |
353 | 347 |
354 | 348 |
355 DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 2) { | 349 DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 2) { |
356 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); | 350 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); |
357 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); | 351 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); |
358 ASSERT(CheckInteger(right_int)); | 352 ASSERT(CheckInteger(right_int)); |
359 ASSERT(CheckInteger(left_int)); | 353 ASSERT(CheckInteger(left_int)); |
360 ASSERT(!right_int.IsZero()); | 354 ASSERT(!right_int.IsZero()); |
361 const Integer& result = Integer::Handle( | 355 return IntegerBinopHelper(Token::kTRUNCDIV, left_int, right_int); |
362 IntegerBinopHelper(Token::kTRUNCDIV, left_int, right_int)); | |
363 arguments->SetReturn(result); | |
364 } | 356 } |
365 | 357 |
366 | 358 |
367 DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 2) { | 359 DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 2) { |
368 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); | 360 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); |
369 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); | 361 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); |
370 ASSERT(CheckInteger(right_int)); | 362 ASSERT(CheckInteger(right_int)); |
371 ASSERT(CheckInteger(right_int)); | 363 ASSERT(CheckInteger(right_int)); |
372 if (FLAG_trace_intrinsified_natives) { | 364 if (FLAG_trace_intrinsified_natives) { |
373 OS::Print("Integer_moduloFromInteger %s mod %s\n", | 365 OS::Print("Integer_moduloFromInteger %s mod %s\n", |
374 left_int.ToCString(), right_int.ToCString()); | 366 left_int.ToCString(), right_int.ToCString()); |
375 } | 367 } |
376 if (right_int.IsZero()) { | 368 if (right_int.IsZero()) { |
377 // Should have been caught before calling into runtime. | 369 // Should have been caught before calling into runtime. |
378 UNIMPLEMENTED(); | 370 UNIMPLEMENTED(); |
379 } | 371 } |
380 const Integer& result = | 372 return IntegerBinopHelper(Token::kMOD, left_int, right_int); |
381 Integer::Handle(IntegerBinopHelper(Token::kMOD, left_int, right_int)); | |
382 arguments->SetReturn(result); | |
383 } | 373 } |
384 | 374 |
385 | 375 |
386 DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 2) { | 376 DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 2) { |
387 const Integer& right = Integer::CheckedHandle(arguments->At(0)); | 377 const Integer& right = Integer::CheckedHandle(arguments->At(0)); |
388 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); | 378 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); |
389 ASSERT(CheckInteger(right)); | 379 ASSERT(CheckInteger(right)); |
390 ASSERT(CheckInteger(left)); | 380 ASSERT(CheckInteger(left)); |
391 if (FLAG_trace_intrinsified_natives) { | 381 if (FLAG_trace_intrinsified_natives) { |
392 OS::Print("Integer_greaterThanFromInteger %s > %s\n", | 382 OS::Print("Integer_greaterThanFromInteger %s > %s\n", |
393 left.ToCString(), right.ToCString()); | 383 left.ToCString(), right.ToCString()); |
394 } | 384 } |
395 const Bool& result = Bool::Handle(Bool::Get(left.CompareWith(right) == 1)); | 385 return Bool::Get(left.CompareWith(right) == 1); |
396 arguments->SetReturn(result); | |
397 } | 386 } |
398 | 387 |
399 | 388 |
400 DEFINE_NATIVE_ENTRY(Integer_equalToInteger, 2) { | 389 DEFINE_NATIVE_ENTRY(Integer_equalToInteger, 2) { |
401 const Integer& left = Integer::CheckedHandle(arguments->At(0)); | 390 const Integer& left = Integer::CheckedHandle(arguments->At(0)); |
402 GET_NATIVE_ARGUMENT(Integer, right, arguments->At(1)); | 391 GET_NATIVE_ARGUMENT(Integer, right, arguments->At(1)); |
403 ASSERT(CheckInteger(left)); | 392 ASSERT(CheckInteger(left)); |
404 ASSERT(CheckInteger(right)); | 393 ASSERT(CheckInteger(right)); |
405 if (FLAG_trace_intrinsified_natives) { | 394 if (FLAG_trace_intrinsified_natives) { |
406 OS::Print("Integer_equalToInteger %s == %s\n", | 395 OS::Print("Integer_equalToInteger %s == %s\n", |
407 left.ToCString(), right.ToCString()); | 396 left.ToCString(), right.ToCString()); |
408 } | 397 } |
409 const Bool& result = Bool::Handle(Bool::Get(left.CompareWith(right) == 0)); | 398 return Bool::Get(left.CompareWith(right) == 0); |
410 arguments->SetReturn(result); | |
411 } | 399 } |
412 | 400 |
413 | 401 |
414 static int HighestBit(int64_t v) { | 402 static int HighestBit(int64_t v) { |
415 uint64_t t = static_cast<uint64_t>((v > 0) ? v : -v); | 403 uint64_t t = static_cast<uint64_t>((v > 0) ? v : -v); |
416 int count = 0; | 404 int count = 0; |
417 while ((t >>= 1) != 0) { | 405 while ((t >>= 1) != 0) { |
418 count++; | 406 count++; |
419 } | 407 } |
420 return count; | 408 return count; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 } | 497 } |
510 | 498 |
511 | 499 |
512 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) { | 500 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) { |
513 const Smi& amount = Smi::CheckedHandle(arguments->At(0)); | 501 const Smi& amount = Smi::CheckedHandle(arguments->At(0)); |
514 GET_NATIVE_ARGUMENT(Integer, value, arguments->At(1)); | 502 GET_NATIVE_ARGUMENT(Integer, value, arguments->At(1)); |
515 ASSERT(CheckInteger(amount)); | 503 ASSERT(CheckInteger(amount)); |
516 ASSERT(CheckInteger(value)); | 504 ASSERT(CheckInteger(value)); |
517 Integer& result = Integer::Handle( | 505 Integer& result = Integer::Handle( |
518 ShiftOperationHelper(Token::kSHR, value, amount)); | 506 ShiftOperationHelper(Token::kSHR, value, amount)); |
519 arguments->SetReturn(Integer::Handle(AsInteger(result))); | 507 return AsInteger(result); |
520 } | 508 } |
521 | 509 |
522 | 510 |
523 | 511 |
524 DEFINE_NATIVE_ENTRY(Smi_shlFromInt, 2) { | 512 DEFINE_NATIVE_ENTRY(Smi_shlFromInt, 2) { |
525 const Smi& amount = Smi::CheckedHandle(arguments->At(0)); | 513 const Smi& amount = Smi::CheckedHandle(arguments->At(0)); |
526 GET_NATIVE_ARGUMENT(Integer, value, arguments->At(1)); | 514 GET_NATIVE_ARGUMENT(Integer, value, arguments->At(1)); |
527 ASSERT(CheckInteger(amount)); | 515 ASSERT(CheckInteger(amount)); |
528 ASSERT(CheckInteger(value)); | 516 ASSERT(CheckInteger(value)); |
529 if (FLAG_trace_intrinsified_natives) { | 517 if (FLAG_trace_intrinsified_natives) { |
530 OS::Print("Smi_shlFromInt: %s << %s\n", | 518 OS::Print("Smi_shlFromInt: %s << %s\n", |
531 value.ToCString(), amount.ToCString()); | 519 value.ToCString(), amount.ToCString()); |
532 } | 520 } |
533 Integer& result = Integer::Handle( | 521 Integer& result = Integer::Handle( |
534 ShiftOperationHelper(Token::kSHL, value, amount)); | 522 ShiftOperationHelper(Token::kSHL, value, amount)); |
535 arguments->SetReturn(Integer::Handle(AsInteger(result))); | 523 return AsInteger(result); |
536 } | 524 } |
537 | 525 |
538 | 526 |
539 DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) { | 527 DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) { |
540 const Smi& operand = Smi::CheckedHandle(arguments->At(0)); | 528 const Smi& operand = Smi::CheckedHandle(arguments->At(0)); |
541 if (FLAG_trace_intrinsified_natives) { | 529 if (FLAG_trace_intrinsified_natives) { |
542 OS::Print("Smi_bitNegate: %s\n", operand.ToCString()); | 530 OS::Print("Smi_bitNegate: %s\n", operand.ToCString()); |
543 } | 531 } |
544 intptr_t result = ~operand.Value(); | 532 intptr_t result = ~operand.Value(); |
545 ASSERT(Smi::IsValid(result)); | 533 ASSERT(Smi::IsValid(result)); |
546 arguments->SetReturn(Smi::Handle(Smi::New(result))); | 534 return Smi::New(result); |
547 } | 535 } |
548 | 536 |
549 // Mint natives. | 537 // Mint natives. |
550 | 538 |
551 DEFINE_NATIVE_ENTRY(Mint_bitNegate, 1) { | 539 DEFINE_NATIVE_ENTRY(Mint_bitNegate, 1) { |
552 const Mint& operand = Mint::CheckedHandle(arguments->At(0)); | 540 const Mint& operand = Mint::CheckedHandle(arguments->At(0)); |
553 ASSERT(CheckInteger(operand)); | 541 ASSERT(CheckInteger(operand)); |
554 if (FLAG_trace_intrinsified_natives) { | 542 if (FLAG_trace_intrinsified_natives) { |
555 OS::Print("Mint_bitNegate: %s\n", operand.ToCString()); | 543 OS::Print("Mint_bitNegate: %s\n", operand.ToCString()); |
556 } | 544 } |
557 int64_t result = ~operand.value(); | 545 int64_t result = ~operand.value(); |
558 arguments->SetReturn(Integer::Handle(Integer::New(result))); | 546 return Integer::New(result); |
559 } | 547 } |
560 | 548 |
561 // Bigint natives. | 549 // Bigint natives. |
562 | 550 |
563 DEFINE_NATIVE_ENTRY(Bigint_bitNegate, 1) { | 551 DEFINE_NATIVE_ENTRY(Bigint_bitNegate, 1) { |
564 const Bigint& value = Bigint::CheckedHandle(arguments->At(0)); | 552 const Bigint& value = Bigint::CheckedHandle(arguments->At(0)); |
565 const Bigint& result = Bigint::Handle(BigintOperations::BitNot(value)); | 553 const Bigint& result = Bigint::Handle(BigintOperations::BitNot(value)); |
566 ASSERT(CheckInteger(value)); | 554 ASSERT(CheckInteger(value)); |
567 ASSERT(CheckInteger(result)); | 555 ASSERT(CheckInteger(result)); |
568 arguments->SetReturn(Integer::Handle(AsInteger(result))); | 556 return AsInteger(result); |
569 } | 557 } |
570 | 558 |
571 } // namespace dart | 559 } // namespace dart |
OLD | NEW |