| 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 18 matching lines...) Expand all Loading... |
| 29 if (i.IsMint()) { | 29 if (i.IsMint()) { |
| 30 Mint& mint = Mint::Handle(); | 30 Mint& mint = Mint::Handle(); |
| 31 mint ^= i.raw(); | 31 mint ^= i.raw(); |
| 32 return !Smi::IsValid64(mint.value()); | 32 return !Smi::IsValid64(mint.value()); |
| 33 } | 33 } |
| 34 return true; | 34 return true; |
| 35 } | 35 } |
| 36 | 36 |
| 37 | 37 |
| 38 DEFINE_NATIVE_ENTRY(Integer_bitAndFromInteger, 2) { | 38 DEFINE_NATIVE_ENTRY(Integer_bitAndFromInteger, 2) { |
| 39 const Integer& right = Integer::CheckedHandle(arguments->At(0)); | 39 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 40 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); | 40 GET_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); |
| 41 ASSERT(CheckInteger(right)); | 41 ASSERT(CheckInteger(right)); |
| 42 ASSERT(CheckInteger(left)); | 42 ASSERT(CheckInteger(left)); |
| 43 if (FLAG_trace_intrinsified_natives) { | 43 if (FLAG_trace_intrinsified_natives) { |
| 44 OS::Print("Integer_bitAndFromInteger %s & %s\n", | 44 OS::Print("Integer_bitAndFromInteger %s & %s\n", |
| 45 right.ToCString(), left.ToCString()); | 45 right.ToCString(), left.ToCString()); |
| 46 } | 46 } |
| 47 Integer& result = | 47 Integer& result = |
| 48 Integer::Handle(left.BitOp(Token::kBIT_AND, right)); | 48 Integer::Handle(left.BitOp(Token::kBIT_AND, right)); |
| 49 return result.AsInteger(); | 49 return result.AsInteger(); |
| 50 } | 50 } |
| 51 | 51 |
| 52 | 52 |
| 53 DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 2) { | 53 DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 2) { |
| 54 const Integer& right = Integer::CheckedHandle(arguments->At(0)); | 54 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 55 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); | 55 GET_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); |
| 56 ASSERT(CheckInteger(right)); | 56 ASSERT(CheckInteger(right)); |
| 57 ASSERT(CheckInteger(left)); | 57 ASSERT(CheckInteger(left)); |
| 58 if (FLAG_trace_intrinsified_natives) { | 58 if (FLAG_trace_intrinsified_natives) { |
| 59 OS::Print("Integer_bitOrFromInteger %s | %s\n", | 59 OS::Print("Integer_bitOrFromInteger %s | %s\n", |
| 60 left.ToCString(), right.ToCString()); | 60 left.ToCString(), right.ToCString()); |
| 61 } | 61 } |
| 62 Integer& result = | 62 Integer& result = |
| 63 Integer::Handle(left.BitOp(Token::kBIT_OR, right)); | 63 Integer::Handle(left.BitOp(Token::kBIT_OR, right)); |
| 64 return result.AsInteger(); | 64 return result.AsInteger(); |
| 65 } | 65 } |
| 66 | 66 |
| 67 | 67 |
| 68 DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 2) { | 68 DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 2) { |
| 69 const Integer& right = Integer::CheckedHandle(arguments->At(0)); | 69 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 70 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); | 70 GET_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); |
| 71 ASSERT(CheckInteger(right)); | 71 ASSERT(CheckInteger(right)); |
| 72 ASSERT(CheckInteger(left)); | 72 ASSERT(CheckInteger(left)); |
| 73 if (FLAG_trace_intrinsified_natives) { | 73 if (FLAG_trace_intrinsified_natives) { |
| 74 OS::Print("Integer_bitXorFromInteger %s ^ %s\n", | 74 OS::Print("Integer_bitXorFromInteger %s ^ %s\n", |
| 75 left.ToCString(), right.ToCString()); | 75 left.ToCString(), right.ToCString()); |
| 76 } | 76 } |
| 77 Integer& result = | 77 Integer& result = |
| 78 Integer::Handle(left.BitOp(Token::kBIT_XOR, right)); | 78 Integer::Handle(left.BitOp(Token::kBIT_XOR, right)); |
| 79 return result.AsInteger(); | 79 return result.AsInteger(); |
| 80 } | 80 } |
| 81 | 81 |
| 82 | 82 |
| 83 DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 2) { | 83 DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 2) { |
| 84 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); | 84 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 85 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); | 85 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
| 86 ASSERT(CheckInteger(right_int)); | 86 ASSERT(CheckInteger(right_int)); |
| 87 ASSERT(CheckInteger(left_int)); | 87 ASSERT(CheckInteger(left_int)); |
| 88 if (FLAG_trace_intrinsified_natives) { | 88 if (FLAG_trace_intrinsified_natives) { |
| 89 OS::Print("Integer_addFromInteger %s + %s\n", | 89 OS::Print("Integer_addFromInteger %s + %s\n", |
| 90 left_int.ToCString(), right_int.ToCString()); | 90 left_int.ToCString(), right_int.ToCString()); |
| 91 } | 91 } |
| 92 return left_int.ArithmeticOp(Token::kADD, right_int); | 92 return left_int.ArithmeticOp(Token::kADD, right_int); |
| 93 } | 93 } |
| 94 | 94 |
| 95 | 95 |
| 96 DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 2) { | 96 DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 2) { |
| 97 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); | 97 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 98 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); | 98 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
| 99 ASSERT(CheckInteger(right_int)); | 99 ASSERT(CheckInteger(right_int)); |
| 100 ASSERT(CheckInteger(left_int)); | 100 ASSERT(CheckInteger(left_int)); |
| 101 if (FLAG_trace_intrinsified_natives) { | 101 if (FLAG_trace_intrinsified_natives) { |
| 102 OS::Print("Integer_subFromInteger %s - %s\n", | 102 OS::Print("Integer_subFromInteger %s - %s\n", |
| 103 left_int.ToCString(), right_int.ToCString()); | 103 left_int.ToCString(), right_int.ToCString()); |
| 104 } | 104 } |
| 105 return left_int.ArithmeticOp(Token::kSUB, right_int); | 105 return left_int.ArithmeticOp(Token::kSUB, right_int); |
| 106 } | 106 } |
| 107 | 107 |
| 108 | 108 |
| 109 DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 2) { | 109 DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 2) { |
| 110 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); | 110 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 111 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); | 111 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
| 112 ASSERT(CheckInteger(right_int)); | 112 ASSERT(CheckInteger(right_int)); |
| 113 ASSERT(CheckInteger(left_int)); | 113 ASSERT(CheckInteger(left_int)); |
| 114 if (FLAG_trace_intrinsified_natives) { | 114 if (FLAG_trace_intrinsified_natives) { |
| 115 OS::Print("Integer_mulFromInteger %s * %s\n", | 115 OS::Print("Integer_mulFromInteger %s * %s\n", |
| 116 left_int.ToCString(), right_int.ToCString()); | 116 left_int.ToCString(), right_int.ToCString()); |
| 117 } | 117 } |
| 118 return left_int.ArithmeticOp(Token::kMUL, right_int); | 118 return left_int.ArithmeticOp(Token::kMUL, right_int); |
| 119 } | 119 } |
| 120 | 120 |
| 121 | 121 |
| 122 DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 2) { | 122 DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 2) { |
| 123 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); | 123 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 124 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); | 124 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
| 125 ASSERT(CheckInteger(right_int)); | 125 ASSERT(CheckInteger(right_int)); |
| 126 ASSERT(CheckInteger(left_int)); | 126 ASSERT(CheckInteger(left_int)); |
| 127 ASSERT(!right_int.IsZero()); | 127 ASSERT(!right_int.IsZero()); |
| 128 return left_int.ArithmeticOp(Token::kTRUNCDIV, right_int); | 128 return left_int.ArithmeticOp(Token::kTRUNCDIV, right_int); |
| 129 } | 129 } |
| 130 | 130 |
| 131 | 131 |
| 132 DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 2) { | 132 DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 2) { |
| 133 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); | 133 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 134 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); | 134 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
| 135 ASSERT(CheckInteger(right_int)); | 135 ASSERT(CheckInteger(right_int)); |
| 136 ASSERT(CheckInteger(right_int)); | 136 ASSERT(CheckInteger(right_int)); |
| 137 if (FLAG_trace_intrinsified_natives) { | 137 if (FLAG_trace_intrinsified_natives) { |
| 138 OS::Print("Integer_moduloFromInteger %s mod %s\n", | 138 OS::Print("Integer_moduloFromInteger %s mod %s\n", |
| 139 left_int.ToCString(), right_int.ToCString()); | 139 left_int.ToCString(), right_int.ToCString()); |
| 140 } | 140 } |
| 141 if (right_int.IsZero()) { | 141 if (right_int.IsZero()) { |
| 142 // Should have been caught before calling into runtime. | 142 // Should have been caught before calling into runtime. |
| 143 UNIMPLEMENTED(); | 143 UNIMPLEMENTED(); |
| 144 } | 144 } |
| 145 return left_int.ArithmeticOp(Token::kMOD, right_int); | 145 return left_int.ArithmeticOp(Token::kMOD, right_int); |
| 146 } | 146 } |
| 147 | 147 |
| 148 | 148 |
| 149 DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 2) { | 149 DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 2) { |
| 150 const Integer& right = Integer::CheckedHandle(arguments->At(0)); | 150 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 151 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); | 151 GET_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); |
| 152 ASSERT(CheckInteger(right)); | 152 ASSERT(CheckInteger(right)); |
| 153 ASSERT(CheckInteger(left)); | 153 ASSERT(CheckInteger(left)); |
| 154 if (FLAG_trace_intrinsified_natives) { | 154 if (FLAG_trace_intrinsified_natives) { |
| 155 OS::Print("Integer_greaterThanFromInteger %s > %s\n", | 155 OS::Print("Integer_greaterThanFromInteger %s > %s\n", |
| 156 left.ToCString(), right.ToCString()); | 156 left.ToCString(), right.ToCString()); |
| 157 } | 157 } |
| 158 return Bool::Get(left.CompareWith(right) == 1); | 158 return Bool::Get(left.CompareWith(right) == 1); |
| 159 } | 159 } |
| 160 | 160 |
| 161 | 161 |
| 162 DEFINE_NATIVE_ENTRY(Integer_equalToInteger, 2) { | 162 DEFINE_NATIVE_ENTRY(Integer_equalToInteger, 2) { |
| 163 const Integer& left = Integer::CheckedHandle(arguments->At(0)); | 163 const Integer& left = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 164 GET_NATIVE_ARGUMENT(Integer, right, arguments->At(1)); | 164 GET_NATIVE_ARGUMENT(Integer, right, arguments->NativeArgAt(1)); |
| 165 ASSERT(CheckInteger(left)); | 165 ASSERT(CheckInteger(left)); |
| 166 ASSERT(CheckInteger(right)); | 166 ASSERT(CheckInteger(right)); |
| 167 if (FLAG_trace_intrinsified_natives) { | 167 if (FLAG_trace_intrinsified_natives) { |
| 168 OS::Print("Integer_equalToInteger %s == %s\n", | 168 OS::Print("Integer_equalToInteger %s == %s\n", |
| 169 left.ToCString(), right.ToCString()); | 169 left.ToCString(), right.ToCString()); |
| 170 } | 170 } |
| 171 return Bool::Get(left.CompareWith(right) == 0); | 171 return Bool::Get(left.CompareWith(right) == 0); |
| 172 } | 172 } |
| 173 | 173 |
| 174 | 174 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 case Token::kSHR: | 212 case Token::kSHR: |
| 213 return BigintOperations::ShiftRight(big_value, amount.Value()); | 213 return BigintOperations::ShiftRight(big_value, amount.Value()); |
| 214 default: | 214 default: |
| 215 UNIMPLEMENTED(); | 215 UNIMPLEMENTED(); |
| 216 } | 216 } |
| 217 return Integer::null(); | 217 return Integer::null(); |
| 218 } | 218 } |
| 219 | 219 |
| 220 | 220 |
| 221 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) { | 221 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) { |
| 222 const Smi& amount = Smi::CheckedHandle(arguments->At(0)); | 222 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); |
| 223 GET_NATIVE_ARGUMENT(Integer, value, arguments->At(1)); | 223 GET_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); |
| 224 ASSERT(CheckInteger(amount)); | 224 ASSERT(CheckInteger(amount)); |
| 225 ASSERT(CheckInteger(value)); | 225 ASSERT(CheckInteger(value)); |
| 226 Integer& result = Integer::Handle( | 226 Integer& result = Integer::Handle( |
| 227 ShiftOperationHelper(Token::kSHR, value, amount)); | 227 ShiftOperationHelper(Token::kSHR, value, amount)); |
| 228 return result.AsInteger(); | 228 return result.AsInteger(); |
| 229 } | 229 } |
| 230 | 230 |
| 231 | 231 |
| 232 | 232 |
| 233 DEFINE_NATIVE_ENTRY(Smi_shlFromInt, 2) { | 233 DEFINE_NATIVE_ENTRY(Smi_shlFromInt, 2) { |
| 234 const Smi& amount = Smi::CheckedHandle(arguments->At(0)); | 234 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); |
| 235 GET_NATIVE_ARGUMENT(Integer, value, arguments->At(1)); | 235 GET_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); |
| 236 ASSERT(CheckInteger(amount)); | 236 ASSERT(CheckInteger(amount)); |
| 237 ASSERT(CheckInteger(value)); | 237 ASSERT(CheckInteger(value)); |
| 238 if (FLAG_trace_intrinsified_natives) { | 238 if (FLAG_trace_intrinsified_natives) { |
| 239 OS::Print("Smi_shlFromInt: %s << %s\n", | 239 OS::Print("Smi_shlFromInt: %s << %s\n", |
| 240 value.ToCString(), amount.ToCString()); | 240 value.ToCString(), amount.ToCString()); |
| 241 } | 241 } |
| 242 Integer& result = Integer::Handle( | 242 Integer& result = Integer::Handle( |
| 243 ShiftOperationHelper(Token::kSHL, value, amount)); | 243 ShiftOperationHelper(Token::kSHL, value, amount)); |
| 244 return result.AsInteger(); | 244 return result.AsInteger(); |
| 245 } | 245 } |
| 246 | 246 |
| 247 | 247 |
| 248 DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) { | 248 DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) { |
| 249 const Smi& operand = Smi::CheckedHandle(arguments->At(0)); | 249 const Smi& operand = Smi::CheckedHandle(arguments->NativeArgAt(0)); |
| 250 if (FLAG_trace_intrinsified_natives) { | 250 if (FLAG_trace_intrinsified_natives) { |
| 251 OS::Print("Smi_bitNegate: %s\n", operand.ToCString()); | 251 OS::Print("Smi_bitNegate: %s\n", operand.ToCString()); |
| 252 } | 252 } |
| 253 intptr_t result = ~operand.Value(); | 253 intptr_t result = ~operand.Value(); |
| 254 ASSERT(Smi::IsValid(result)); | 254 ASSERT(Smi::IsValid(result)); |
| 255 return Smi::New(result); | 255 return Smi::New(result); |
| 256 } | 256 } |
| 257 | 257 |
| 258 // Mint natives. | 258 // Mint natives. |
| 259 | 259 |
| 260 DEFINE_NATIVE_ENTRY(Mint_bitNegate, 1) { | 260 DEFINE_NATIVE_ENTRY(Mint_bitNegate, 1) { |
| 261 const Mint& operand = Mint::CheckedHandle(arguments->At(0)); | 261 const Mint& operand = Mint::CheckedHandle(arguments->NativeArgAt(0)); |
| 262 ASSERT(CheckInteger(operand)); | 262 ASSERT(CheckInteger(operand)); |
| 263 if (FLAG_trace_intrinsified_natives) { | 263 if (FLAG_trace_intrinsified_natives) { |
| 264 OS::Print("Mint_bitNegate: %s\n", operand.ToCString()); | 264 OS::Print("Mint_bitNegate: %s\n", operand.ToCString()); |
| 265 } | 265 } |
| 266 int64_t result = ~operand.value(); | 266 int64_t result = ~operand.value(); |
| 267 return Integer::New(result); | 267 return Integer::New(result); |
| 268 } | 268 } |
| 269 | 269 |
| 270 // Bigint natives. | 270 // Bigint natives. |
| 271 | 271 |
| 272 DEFINE_NATIVE_ENTRY(Bigint_bitNegate, 1) { | 272 DEFINE_NATIVE_ENTRY(Bigint_bitNegate, 1) { |
| 273 const Bigint& value = Bigint::CheckedHandle(arguments->At(0)); | 273 const Bigint& value = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
| 274 const Bigint& result = Bigint::Handle(BigintOperations::BitNot(value)); | 274 const Bigint& result = Bigint::Handle(BigintOperations::BitNot(value)); |
| 275 ASSERT(CheckInteger(value)); | 275 ASSERT(CheckInteger(value)); |
| 276 ASSERT(CheckInteger(result)); | 276 ASSERT(CheckInteger(result)); |
| 277 return result.AsInteger(); | 277 return result.AsInteger(); |
| 278 } | 278 } |
| 279 | 279 |
| 280 } // namespace dart | 280 } // namespace dart |
| OLD | NEW |