| 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 |