| 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 case Token::kBIT_AND: | 53 case Token::kBIT_AND: |
| 54 return Integer::New(a & b); | 54 return Integer::New(a & b); |
| 55 case Token::kBIT_OR: | 55 case Token::kBIT_OR: |
| 56 return Integer::New(a | b); | 56 return Integer::New(a | b); |
| 57 case Token::kBIT_XOR: | 57 case Token::kBIT_XOR: |
| 58 return Integer::New(a ^ b); | 58 return Integer::New(a ^ b); |
| 59 default: | 59 default: |
| 60 UNIMPLEMENTED(); | 60 UNIMPLEMENTED(); |
| 61 } | 61 } |
| 62 } else { | 62 } else { |
| 63 Bigint& op1 = Bigint::Handle(Bigint::AsBigint(op1_int)); | 63 Bigint& op1 = Bigint::Handle(op1_int.AsBigint()); |
| 64 Bigint& op2 = Bigint::Handle(Bigint::AsBigint(op2_int)); | 64 Bigint& op2 = Bigint::Handle(op2_int.AsBigint()); |
| 65 switch (kind) { | 65 switch (kind) { |
| 66 case Token::kBIT_AND: | 66 case Token::kBIT_AND: |
| 67 return BigintOperations::BitAnd(op1, op2); | 67 return BigintOperations::BitAnd(op1, op2); |
| 68 case Token::kBIT_OR: | 68 case Token::kBIT_OR: |
| 69 return BigintOperations::BitOr(op1, op2); | 69 return BigintOperations::BitOr(op1, op2); |
| 70 case Token::kBIT_XOR: | 70 case Token::kBIT_XOR: |
| 71 return BigintOperations::BitXor(op1, op2); | 71 return BigintOperations::BitXor(op1, op2); |
| 72 default: | 72 default: |
| 73 UNIMPLEMENTED(); | 73 UNIMPLEMENTED(); |
| 74 } | 74 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 99 const Integer& right = Integer::CheckedHandle(arguments->At(0)); | 99 const Integer& right = Integer::CheckedHandle(arguments->At(0)); |
| 100 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); | 100 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); |
| 101 ASSERT(CheckInteger(right)); | 101 ASSERT(CheckInteger(right)); |
| 102 ASSERT(CheckInteger(left)); | 102 ASSERT(CheckInteger(left)); |
| 103 if (FLAG_trace_intrinsified_natives) { | 103 if (FLAG_trace_intrinsified_natives) { |
| 104 OS::Print("Integer_bitAndFromInteger %s & %s\n", | 104 OS::Print("Integer_bitAndFromInteger %s & %s\n", |
| 105 right.ToCString(), left.ToCString()); | 105 right.ToCString(), left.ToCString()); |
| 106 } | 106 } |
| 107 Integer& result = Integer::Handle( | 107 Integer& result = Integer::Handle( |
| 108 IntegerBitOperation(Token::kBIT_AND, left, right)); | 108 IntegerBitOperation(Token::kBIT_AND, left, right)); |
| 109 return Integer::AsInteger(result); | 109 return result.AsInteger(); |
| 110 } | 110 } |
| 111 | 111 |
| 112 | 112 |
| 113 DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 2) { | 113 DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 2) { |
| 114 const Integer& right = Integer::CheckedHandle(arguments->At(0)); | 114 const Integer& right = Integer::CheckedHandle(arguments->At(0)); |
| 115 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); | 115 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); |
| 116 ASSERT(CheckInteger(right)); | 116 ASSERT(CheckInteger(right)); |
| 117 ASSERT(CheckInteger(left)); | 117 ASSERT(CheckInteger(left)); |
| 118 if (FLAG_trace_intrinsified_natives) { | 118 if (FLAG_trace_intrinsified_natives) { |
| 119 OS::Print("Integer_bitOrFromInteger %s | %s\n", | 119 OS::Print("Integer_bitOrFromInteger %s | %s\n", |
| 120 left.ToCString(), right.ToCString()); | 120 left.ToCString(), right.ToCString()); |
| 121 } | 121 } |
| 122 Integer& result = Integer::Handle( | 122 Integer& result = Integer::Handle( |
| 123 IntegerBitOperation(Token::kBIT_OR, left, right)); | 123 IntegerBitOperation(Token::kBIT_OR, left, right)); |
| 124 return Integer::AsInteger(result); | 124 return result.AsInteger(); |
| 125 } | 125 } |
| 126 | 126 |
| 127 | 127 |
| 128 DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 2) { | 128 DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 2) { |
| 129 const Integer& right = Integer::CheckedHandle(arguments->At(0)); | 129 const Integer& right = Integer::CheckedHandle(arguments->At(0)); |
| 130 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); | 130 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); |
| 131 ASSERT(CheckInteger(right)); | 131 ASSERT(CheckInteger(right)); |
| 132 ASSERT(CheckInteger(left)); | 132 ASSERT(CheckInteger(left)); |
| 133 if (FLAG_trace_intrinsified_natives) { | 133 if (FLAG_trace_intrinsified_natives) { |
| 134 OS::Print("Integer_bitXorFromInteger %s ^ %s\n", | 134 OS::Print("Integer_bitXorFromInteger %s ^ %s\n", |
| 135 left.ToCString(), right.ToCString()); | 135 left.ToCString(), right.ToCString()); |
| 136 } | 136 } |
| 137 Integer& result = Integer::Handle( | 137 Integer& result = Integer::Handle( |
| 138 IntegerBitOperation(Token::kBIT_XOR, left, right)); | 138 IntegerBitOperation(Token::kBIT_XOR, left, right)); |
| 139 return Integer::AsInteger(result); | 139 return result.AsInteger(); |
| 140 } | 140 } |
| 141 | 141 |
| 142 | 142 |
| 143 DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 2) { | 143 DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 2) { |
| 144 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); | 144 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); |
| 145 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); | 145 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); |
| 146 ASSERT(CheckInteger(right_int)); | 146 ASSERT(CheckInteger(right_int)); |
| 147 ASSERT(CheckInteger(left_int)); | 147 ASSERT(CheckInteger(left_int)); |
| 148 if (FLAG_trace_intrinsified_natives) { | 148 if (FLAG_trace_intrinsified_natives) { |
| 149 OS::Print("Integer_addFromInteger %s + %s\n", | 149 OS::Print("Integer_addFromInteger %s + %s\n", |
| 150 left_int.ToCString(), right_int.ToCString()); | 150 left_int.ToCString(), right_int.ToCString()); |
| 151 } | 151 } |
| 152 return Integer::BinaryOp(Token::kADD, left_int, right_int); | 152 return left_int.BinaryOp(Token::kADD, right_int); |
| 153 } | 153 } |
| 154 | 154 |
| 155 | 155 |
| 156 DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 2) { | 156 DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 2) { |
| 157 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); | 157 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); |
| 158 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); | 158 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); |
| 159 ASSERT(CheckInteger(right_int)); | 159 ASSERT(CheckInteger(right_int)); |
| 160 ASSERT(CheckInteger(left_int)); | 160 ASSERT(CheckInteger(left_int)); |
| 161 if (FLAG_trace_intrinsified_natives) { | 161 if (FLAG_trace_intrinsified_natives) { |
| 162 OS::Print("Integer_subFromInteger %s - %s\n", | 162 OS::Print("Integer_subFromInteger %s - %s\n", |
| 163 left_int.ToCString(), right_int.ToCString()); | 163 left_int.ToCString(), right_int.ToCString()); |
| 164 } | 164 } |
| 165 return Integer::BinaryOp(Token::kSUB, left_int, right_int); | 165 return left_int.BinaryOp(Token::kSUB, right_int); |
| 166 } | 166 } |
| 167 | 167 |
| 168 | 168 |
| 169 DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 2) { | 169 DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 2) { |
| 170 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); | 170 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); |
| 171 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); | 171 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); |
| 172 ASSERT(CheckInteger(right_int)); | 172 ASSERT(CheckInteger(right_int)); |
| 173 ASSERT(CheckInteger(left_int)); | 173 ASSERT(CheckInteger(left_int)); |
| 174 if (FLAG_trace_intrinsified_natives) { | 174 if (FLAG_trace_intrinsified_natives) { |
| 175 OS::Print("Integer_mulFromInteger %s * %s\n", | 175 OS::Print("Integer_mulFromInteger %s * %s\n", |
| 176 left_int.ToCString(), right_int.ToCString()); | 176 left_int.ToCString(), right_int.ToCString()); |
| 177 } | 177 } |
| 178 return Integer::BinaryOp(Token::kMUL, left_int, right_int); | 178 return left_int.BinaryOp(Token::kMUL, right_int); |
| 179 } | 179 } |
| 180 | 180 |
| 181 | 181 |
| 182 DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 2) { | 182 DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 2) { |
| 183 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); | 183 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); |
| 184 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); | 184 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); |
| 185 ASSERT(CheckInteger(right_int)); | 185 ASSERT(CheckInteger(right_int)); |
| 186 ASSERT(CheckInteger(left_int)); | 186 ASSERT(CheckInteger(left_int)); |
| 187 ASSERT(!right_int.IsZero()); | 187 ASSERT(!right_int.IsZero()); |
| 188 return Integer::BinaryOp(Token::kTRUNCDIV, left_int, right_int); | 188 return left_int.BinaryOp(Token::kTRUNCDIV, right_int); |
| 189 } | 189 } |
| 190 | 190 |
| 191 | 191 |
| 192 DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 2) { | 192 DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 2) { |
| 193 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); | 193 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); |
| 194 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); | 194 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); |
| 195 ASSERT(CheckInteger(right_int)); | 195 ASSERT(CheckInteger(right_int)); |
| 196 ASSERT(CheckInteger(right_int)); | 196 ASSERT(CheckInteger(right_int)); |
| 197 if (FLAG_trace_intrinsified_natives) { | 197 if (FLAG_trace_intrinsified_natives) { |
| 198 OS::Print("Integer_moduloFromInteger %s mod %s\n", | 198 OS::Print("Integer_moduloFromInteger %s mod %s\n", |
| 199 left_int.ToCString(), right_int.ToCString()); | 199 left_int.ToCString(), right_int.ToCString()); |
| 200 } | 200 } |
| 201 if (right_int.IsZero()) { | 201 if (right_int.IsZero()) { |
| 202 // Should have been caught before calling into runtime. | 202 // Should have been caught before calling into runtime. |
| 203 UNIMPLEMENTED(); | 203 UNIMPLEMENTED(); |
| 204 } | 204 } |
| 205 return Integer::BinaryOp(Token::kMOD, left_int, right_int); | 205 return left_int.BinaryOp(Token::kMOD, right_int); |
| 206 } | 206 } |
| 207 | 207 |
| 208 | 208 |
| 209 DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 2) { | 209 DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 2) { |
| 210 const Integer& right = Integer::CheckedHandle(arguments->At(0)); | 210 const Integer& right = Integer::CheckedHandle(arguments->At(0)); |
| 211 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); | 211 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); |
| 212 ASSERT(CheckInteger(right)); | 212 ASSERT(CheckInteger(right)); |
| 213 ASSERT(CheckInteger(left)); | 213 ASSERT(CheckInteger(left)); |
| 214 if (FLAG_trace_intrinsified_natives) { | 214 if (FLAG_trace_intrinsified_natives) { |
| 215 OS::Print("Integer_greaterThanFromInteger %s > %s\n", | 215 OS::Print("Integer_greaterThanFromInteger %s > %s\n", |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 switch (kind) { | 253 switch (kind) { |
| 254 case Token::kSHL: { | 254 case Token::kSHL: { |
| 255 if ((left_value == 0) || (right_value == 0)) { | 255 if ((left_value == 0) || (right_value == 0)) { |
| 256 return left.raw(); | 256 return left.raw(); |
| 257 } | 257 } |
| 258 { // Check for overflow. | 258 { // Check for overflow. |
| 259 int cnt = HighestBit(left_value); | 259 int cnt = HighestBit(left_value); |
| 260 if ((cnt + right_value) >= Smi::kBits) { | 260 if ((cnt + right_value) >= Smi::kBits) { |
| 261 if ((cnt + right_value) >= Mint::kBits) { | 261 if ((cnt + right_value) >= Mint::kBits) { |
| 262 return BigintOperations::ShiftLeft( | 262 return BigintOperations::ShiftLeft( |
| 263 Bigint::Handle(Bigint::AsBigint(left)), right_value); | 263 Bigint::Handle(left.AsBigint()), right_value); |
| 264 } else { | 264 } else { |
| 265 int64_t left_64 = left_value; | 265 int64_t left_64 = left_value; |
| 266 return Integer::New(left_64 << right_value); | 266 return Integer::New(left_64 << right_value); |
| 267 } | 267 } |
| 268 } | 268 } |
| 269 } | 269 } |
| 270 result = left_value << right_value; | 270 result = left_value << right_value; |
| 271 break; | 271 break; |
| 272 } | 272 } |
| 273 case Token::kSHR: { | 273 case Token::kSHR: { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 } | 330 } |
| 331 | 331 |
| 332 | 332 |
| 333 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) { | 333 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) { |
| 334 const Smi& amount = Smi::CheckedHandle(arguments->At(0)); | 334 const Smi& amount = Smi::CheckedHandle(arguments->At(0)); |
| 335 GET_NATIVE_ARGUMENT(Integer, value, arguments->At(1)); | 335 GET_NATIVE_ARGUMENT(Integer, value, arguments->At(1)); |
| 336 ASSERT(CheckInteger(amount)); | 336 ASSERT(CheckInteger(amount)); |
| 337 ASSERT(CheckInteger(value)); | 337 ASSERT(CheckInteger(value)); |
| 338 Integer& result = Integer::Handle( | 338 Integer& result = Integer::Handle( |
| 339 ShiftOperationHelper(Token::kSHR, value, amount)); | 339 ShiftOperationHelper(Token::kSHR, value, amount)); |
| 340 return Integer::AsInteger(result); | 340 return result.AsInteger(); |
| 341 } | 341 } |
| 342 | 342 |
| 343 | 343 |
| 344 | 344 |
| 345 DEFINE_NATIVE_ENTRY(Smi_shlFromInt, 2) { | 345 DEFINE_NATIVE_ENTRY(Smi_shlFromInt, 2) { |
| 346 const Smi& amount = Smi::CheckedHandle(arguments->At(0)); | 346 const Smi& amount = Smi::CheckedHandle(arguments->At(0)); |
| 347 GET_NATIVE_ARGUMENT(Integer, value, arguments->At(1)); | 347 GET_NATIVE_ARGUMENT(Integer, value, arguments->At(1)); |
| 348 ASSERT(CheckInteger(amount)); | 348 ASSERT(CheckInteger(amount)); |
| 349 ASSERT(CheckInteger(value)); | 349 ASSERT(CheckInteger(value)); |
| 350 if (FLAG_trace_intrinsified_natives) { | 350 if (FLAG_trace_intrinsified_natives) { |
| 351 OS::Print("Smi_shlFromInt: %s << %s\n", | 351 OS::Print("Smi_shlFromInt: %s << %s\n", |
| 352 value.ToCString(), amount.ToCString()); | 352 value.ToCString(), amount.ToCString()); |
| 353 } | 353 } |
| 354 Integer& result = Integer::Handle( | 354 Integer& result = Integer::Handle( |
| 355 ShiftOperationHelper(Token::kSHL, value, amount)); | 355 ShiftOperationHelper(Token::kSHL, value, amount)); |
| 356 return Integer::AsInteger(result); | 356 return result.AsInteger(); |
| 357 } | 357 } |
| 358 | 358 |
| 359 | 359 |
| 360 DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) { | 360 DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) { |
| 361 const Smi& operand = Smi::CheckedHandle(arguments->At(0)); | 361 const Smi& operand = Smi::CheckedHandle(arguments->At(0)); |
| 362 if (FLAG_trace_intrinsified_natives) { | 362 if (FLAG_trace_intrinsified_natives) { |
| 363 OS::Print("Smi_bitNegate: %s\n", operand.ToCString()); | 363 OS::Print("Smi_bitNegate: %s\n", operand.ToCString()); |
| 364 } | 364 } |
| 365 intptr_t result = ~operand.Value(); | 365 intptr_t result = ~operand.Value(); |
| 366 ASSERT(Smi::IsValid(result)); | 366 ASSERT(Smi::IsValid(result)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 379 return Integer::New(result); | 379 return Integer::New(result); |
| 380 } | 380 } |
| 381 | 381 |
| 382 // Bigint natives. | 382 // Bigint natives. |
| 383 | 383 |
| 384 DEFINE_NATIVE_ENTRY(Bigint_bitNegate, 1) { | 384 DEFINE_NATIVE_ENTRY(Bigint_bitNegate, 1) { |
| 385 const Bigint& value = Bigint::CheckedHandle(arguments->At(0)); | 385 const Bigint& value = Bigint::CheckedHandle(arguments->At(0)); |
| 386 const Bigint& result = Bigint::Handle(BigintOperations::BitNot(value)); | 386 const Bigint& result = Bigint::Handle(BigintOperations::BitNot(value)); |
| 387 ASSERT(CheckInteger(value)); | 387 ASSERT(CheckInteger(value)); |
| 388 ASSERT(CheckInteger(result)); | 388 ASSERT(CheckInteger(result)); |
| 389 return Integer::AsInteger(result); | 389 return result.AsInteger(); |
| 390 } | 390 } |
| 391 | 391 |
| 392 } // namespace dart | 392 } // namespace dart |
| OLD | NEW |