| 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 "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 #include "vm/dart_api_impl.h" |
| 8 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 9 #include "vm/dart_api_impl.h" | |
| 10 #include "vm/exceptions.h" | 10 #include "vm/exceptions.h" |
| 11 #include "vm/isolate.h" | 11 #include "vm/isolate.h" |
| 12 #include "vm/native_entry.h" | 12 #include "vm/native_entry.h" |
| 13 #include "vm/object.h" | 13 #include "vm/object.h" |
| 14 #include "vm/object_store.h" | 14 #include "vm/object_store.h" |
| 15 #include "vm/symbols.h" | 15 #include "vm/symbols.h" |
| 16 | 16 |
| 17 namespace dart { | 17 namespace dart { |
| 18 | 18 |
| 19 DEFINE_FLAG(bool, | 19 DEFINE_FLAG(bool, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 31 const Bigint& bigint = Bigint::Cast(i); | 31 const Bigint& bigint = Bigint::Cast(i); |
| 32 return !bigint.FitsIntoSmi() && !bigint.FitsIntoInt64(); | 32 return !bigint.FitsIntoSmi() && !bigint.FitsIntoInt64(); |
| 33 } | 33 } |
| 34 if (i.IsMint()) { | 34 if (i.IsMint()) { |
| 35 const Mint& mint = Mint::Cast(i); | 35 const Mint& mint = Mint::Cast(i); |
| 36 return !Smi::IsValid(mint.value()); | 36 return !Smi::IsValid(mint.value()); |
| 37 } | 37 } |
| 38 return true; | 38 return true; |
| 39 } | 39 } |
| 40 | 40 |
| 41 | |
| 42 DEFINE_NATIVE_ENTRY(Integer_bitAndFromInteger, 2) { | 41 DEFINE_NATIVE_ENTRY(Integer_bitAndFromInteger, 2) { |
| 43 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 42 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 44 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); | 43 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); |
| 45 ASSERT(CheckInteger(right)); | 44 ASSERT(CheckInteger(right)); |
| 46 ASSERT(CheckInteger(left)); | 45 ASSERT(CheckInteger(left)); |
| 47 if (FLAG_trace_intrinsified_natives) { | 46 if (FLAG_trace_intrinsified_natives) { |
| 48 OS::Print("Integer_bitAndFromInteger %s & %s\n", right.ToCString(), | 47 OS::Print("Integer_bitAndFromInteger %s & %s\n", right.ToCString(), |
| 49 left.ToCString()); | 48 left.ToCString()); |
| 50 } | 49 } |
| 51 const Integer& result = Integer::Handle(left.BitOp(Token::kBIT_AND, right)); | 50 const Integer& result = Integer::Handle(left.BitOp(Token::kBIT_AND, right)); |
| 52 // A null result indicates that a bigint operation is required. | 51 // A null result indicates that a bigint operation is required. |
| 53 return result.IsNull() ? result.raw() : result.AsValidInteger(); | 52 return result.IsNull() ? result.raw() : result.AsValidInteger(); |
| 54 } | 53 } |
| 55 | 54 |
| 56 | |
| 57 DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 2) { | 55 DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 2) { |
| 58 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 56 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 59 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); | 57 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); |
| 60 ASSERT(CheckInteger(right)); | 58 ASSERT(CheckInteger(right)); |
| 61 ASSERT(CheckInteger(left)); | 59 ASSERT(CheckInteger(left)); |
| 62 if (FLAG_trace_intrinsified_natives) { | 60 if (FLAG_trace_intrinsified_natives) { |
| 63 OS::Print("Integer_bitOrFromInteger %s | %s\n", left.ToCString(), | 61 OS::Print("Integer_bitOrFromInteger %s | %s\n", left.ToCString(), |
| 64 right.ToCString()); | 62 right.ToCString()); |
| 65 } | 63 } |
| 66 const Integer& result = Integer::Handle(left.BitOp(Token::kBIT_OR, right)); | 64 const Integer& result = Integer::Handle(left.BitOp(Token::kBIT_OR, right)); |
| 67 // A null result indicates that a bigint operation is required. | 65 // A null result indicates that a bigint operation is required. |
| 68 return result.IsNull() ? result.raw() : result.AsValidInteger(); | 66 return result.IsNull() ? result.raw() : result.AsValidInteger(); |
| 69 } | 67 } |
| 70 | 68 |
| 71 | |
| 72 DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 2) { | 69 DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 2) { |
| 73 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 70 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 74 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); | 71 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); |
| 75 ASSERT(CheckInteger(right)); | 72 ASSERT(CheckInteger(right)); |
| 76 ASSERT(CheckInteger(left)); | 73 ASSERT(CheckInteger(left)); |
| 77 if (FLAG_trace_intrinsified_natives) { | 74 if (FLAG_trace_intrinsified_natives) { |
| 78 OS::Print("Integer_bitXorFromInteger %s ^ %s\n", left.ToCString(), | 75 OS::Print("Integer_bitXorFromInteger %s ^ %s\n", left.ToCString(), |
| 79 right.ToCString()); | 76 right.ToCString()); |
| 80 } | 77 } |
| 81 const Integer& result = Integer::Handle(left.BitOp(Token::kBIT_XOR, right)); | 78 const Integer& result = Integer::Handle(left.BitOp(Token::kBIT_XOR, right)); |
| 82 // A null result indicates that a bigint operation is required. | 79 // A null result indicates that a bigint operation is required. |
| 83 return result.IsNull() ? result.raw() : result.AsValidInteger(); | 80 return result.IsNull() ? result.raw() : result.AsValidInteger(); |
| 84 } | 81 } |
| 85 | 82 |
| 86 | |
| 87 DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 2) { | 83 DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 2) { |
| 88 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 84 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 89 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); | 85 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
| 90 ASSERT(CheckInteger(right_int)); | 86 ASSERT(CheckInteger(right_int)); |
| 91 ASSERT(CheckInteger(left_int)); | 87 ASSERT(CheckInteger(left_int)); |
| 92 if (FLAG_trace_intrinsified_natives) { | 88 if (FLAG_trace_intrinsified_natives) { |
| 93 OS::Print("Integer_addFromInteger %s + %s\n", left_int.ToCString(), | 89 OS::Print("Integer_addFromInteger %s + %s\n", left_int.ToCString(), |
| 94 right_int.ToCString()); | 90 right_int.ToCString()); |
| 95 } | 91 } |
| 96 const Integer& result = | 92 const Integer& result = |
| 97 Integer::Handle(left_int.ArithmeticOp(Token::kADD, right_int)); | 93 Integer::Handle(left_int.ArithmeticOp(Token::kADD, right_int)); |
| 98 // A null result indicates that a bigint operation is required. | 94 // A null result indicates that a bigint operation is required. |
| 99 return result.IsNull() ? result.raw() : result.AsValidInteger(); | 95 return result.IsNull() ? result.raw() : result.AsValidInteger(); |
| 100 } | 96 } |
| 101 | 97 |
| 102 | |
| 103 DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 2) { | 98 DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 2) { |
| 104 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 99 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 105 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); | 100 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
| 106 ASSERT(CheckInteger(right_int)); | 101 ASSERT(CheckInteger(right_int)); |
| 107 ASSERT(CheckInteger(left_int)); | 102 ASSERT(CheckInteger(left_int)); |
| 108 if (FLAG_trace_intrinsified_natives) { | 103 if (FLAG_trace_intrinsified_natives) { |
| 109 OS::Print("Integer_subFromInteger %s - %s\n", left_int.ToCString(), | 104 OS::Print("Integer_subFromInteger %s - %s\n", left_int.ToCString(), |
| 110 right_int.ToCString()); | 105 right_int.ToCString()); |
| 111 } | 106 } |
| 112 const Integer& result = | 107 const Integer& result = |
| 113 Integer::Handle(left_int.ArithmeticOp(Token::kSUB, right_int)); | 108 Integer::Handle(left_int.ArithmeticOp(Token::kSUB, right_int)); |
| 114 // A null result indicates that a bigint operation is required. | 109 // A null result indicates that a bigint operation is required. |
| 115 return result.IsNull() ? result.raw() : result.AsValidInteger(); | 110 return result.IsNull() ? result.raw() : result.AsValidInteger(); |
| 116 } | 111 } |
| 117 | 112 |
| 118 | |
| 119 DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 2) { | 113 DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 2) { |
| 120 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 114 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 121 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); | 115 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
| 122 ASSERT(CheckInteger(right_int)); | 116 ASSERT(CheckInteger(right_int)); |
| 123 ASSERT(CheckInteger(left_int)); | 117 ASSERT(CheckInteger(left_int)); |
| 124 if (FLAG_trace_intrinsified_natives) { | 118 if (FLAG_trace_intrinsified_natives) { |
| 125 OS::Print("Integer_mulFromInteger %s * %s\n", left_int.ToCString(), | 119 OS::Print("Integer_mulFromInteger %s * %s\n", left_int.ToCString(), |
| 126 right_int.ToCString()); | 120 right_int.ToCString()); |
| 127 } | 121 } |
| 128 const Integer& result = | 122 const Integer& result = |
| 129 Integer::Handle(left_int.ArithmeticOp(Token::kMUL, right_int)); | 123 Integer::Handle(left_int.ArithmeticOp(Token::kMUL, right_int)); |
| 130 // A null result indicates that a bigint operation is required. | 124 // A null result indicates that a bigint operation is required. |
| 131 return result.IsNull() ? result.raw() : result.AsValidInteger(); | 125 return result.IsNull() ? result.raw() : result.AsValidInteger(); |
| 132 } | 126 } |
| 133 | 127 |
| 134 | |
| 135 DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 2) { | 128 DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 2) { |
| 136 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 129 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 137 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); | 130 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
| 138 ASSERT(CheckInteger(right_int)); | 131 ASSERT(CheckInteger(right_int)); |
| 139 ASSERT(CheckInteger(left_int)); | 132 ASSERT(CheckInteger(left_int)); |
| 140 ASSERT(!right_int.IsZero()); | 133 ASSERT(!right_int.IsZero()); |
| 141 const Integer& result = | 134 const Integer& result = |
| 142 Integer::Handle(left_int.ArithmeticOp(Token::kTRUNCDIV, right_int)); | 135 Integer::Handle(left_int.ArithmeticOp(Token::kTRUNCDIV, right_int)); |
| 143 // A null result indicates that a bigint operation is required. | 136 // A null result indicates that a bigint operation is required. |
| 144 return result.IsNull() ? result.raw() : result.AsValidInteger(); | 137 return result.IsNull() ? result.raw() : result.AsValidInteger(); |
| 145 } | 138 } |
| 146 | 139 |
| 147 | |
| 148 DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 2) { | 140 DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 2) { |
| 149 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 141 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 150 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); | 142 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
| 151 ASSERT(CheckInteger(right_int)); | 143 ASSERT(CheckInteger(right_int)); |
| 152 ASSERT(CheckInteger(left_int)); | 144 ASSERT(CheckInteger(left_int)); |
| 153 if (FLAG_trace_intrinsified_natives) { | 145 if (FLAG_trace_intrinsified_natives) { |
| 154 OS::Print("Integer_moduloFromInteger %s mod %s\n", left_int.ToCString(), | 146 OS::Print("Integer_moduloFromInteger %s mod %s\n", left_int.ToCString(), |
| 155 right_int.ToCString()); | 147 right_int.ToCString()); |
| 156 } | 148 } |
| 157 if (right_int.IsZero()) { | 149 if (right_int.IsZero()) { |
| 158 // Should have been caught before calling into runtime. | 150 // Should have been caught before calling into runtime. |
| 159 UNIMPLEMENTED(); | 151 UNIMPLEMENTED(); |
| 160 } | 152 } |
| 161 const Integer& result = | 153 const Integer& result = |
| 162 Integer::Handle(left_int.ArithmeticOp(Token::kMOD, right_int)); | 154 Integer::Handle(left_int.ArithmeticOp(Token::kMOD, right_int)); |
| 163 // A null result indicates that a bigint operation is required. | 155 // A null result indicates that a bigint operation is required. |
| 164 return result.IsNull() ? result.raw() : result.AsValidInteger(); | 156 return result.IsNull() ? result.raw() : result.AsValidInteger(); |
| 165 } | 157 } |
| 166 | 158 |
| 167 | |
| 168 DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 2) { | 159 DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 2) { |
| 169 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 160 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 170 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); | 161 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); |
| 171 ASSERT(CheckInteger(right)); | 162 ASSERT(CheckInteger(right)); |
| 172 ASSERT(CheckInteger(left)); | 163 ASSERT(CheckInteger(left)); |
| 173 if (FLAG_trace_intrinsified_natives) { | 164 if (FLAG_trace_intrinsified_natives) { |
| 174 OS::Print("Integer_greaterThanFromInteger %s > %s\n", left.ToCString(), | 165 OS::Print("Integer_greaterThanFromInteger %s > %s\n", left.ToCString(), |
| 175 right.ToCString()); | 166 right.ToCString()); |
| 176 } | 167 } |
| 177 return Bool::Get(left.CompareWith(right) == 1).raw(); | 168 return Bool::Get(left.CompareWith(right) == 1).raw(); |
| 178 } | 169 } |
| 179 | 170 |
| 180 | |
| 181 DEFINE_NATIVE_ENTRY(Integer_equalToInteger, 2) { | 171 DEFINE_NATIVE_ENTRY(Integer_equalToInteger, 2) { |
| 182 const Integer& left = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 172 const Integer& left = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 183 GET_NON_NULL_NATIVE_ARGUMENT(Integer, right, arguments->NativeArgAt(1)); | 173 GET_NON_NULL_NATIVE_ARGUMENT(Integer, right, arguments->NativeArgAt(1)); |
| 184 ASSERT(CheckInteger(left)); | 174 ASSERT(CheckInteger(left)); |
| 185 ASSERT(CheckInteger(right)); | 175 ASSERT(CheckInteger(right)); |
| 186 if (FLAG_trace_intrinsified_natives) { | 176 if (FLAG_trace_intrinsified_natives) { |
| 187 OS::Print("Integer_equalToInteger %s == %s\n", left.ToCString(), | 177 OS::Print("Integer_equalToInteger %s == %s\n", left.ToCString(), |
| 188 right.ToCString()); | 178 right.ToCString()); |
| 189 } | 179 } |
| 190 return Bool::Get(left.CompareWith(right) == 0).raw(); | 180 return Bool::Get(left.CompareWith(right) == 0).raw(); |
| 191 } | 181 } |
| 192 | 182 |
| 193 | |
| 194 static RawInteger* ParseInteger(const String& value) { | 183 static RawInteger* ParseInteger(const String& value) { |
| 195 // Used by both Integer_parse and Integer_fromEnvironment. | 184 // Used by both Integer_parse and Integer_fromEnvironment. |
| 196 if (value.IsOneByteString()) { | 185 if (value.IsOneByteString()) { |
| 197 // Quick conversion for unpadded integers in strings. | 186 // Quick conversion for unpadded integers in strings. |
| 198 const intptr_t len = value.Length(); | 187 const intptr_t len = value.Length(); |
| 199 if (len > 0) { | 188 if (len > 0) { |
| 200 const char* cstr = value.ToCString(); | 189 const char* cstr = value.ToCString(); |
| 201 ASSERT(cstr != NULL); | 190 ASSERT(cstr != NULL); |
| 202 char* p_end = NULL; | 191 char* p_end = NULL; |
| 203 const int64_t int_value = strtoll(cstr, &p_end, 10); | 192 const int64_t int_value = strtoll(cstr, &p_end, 10); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 216 return Integer::New(*int_string); | 205 return Integer::New(*int_string); |
| 217 } | 206 } |
| 218 String& temp = String::Handle(); | 207 String& temp = String::Handle(); |
| 219 temp = String::Concat(Symbols::Dash(), *int_string); | 208 temp = String::Concat(Symbols::Dash(), *int_string); |
| 220 return Integer::New(temp); | 209 return Integer::New(temp); |
| 221 } | 210 } |
| 222 | 211 |
| 223 return Integer::null(); | 212 return Integer::null(); |
| 224 } | 213 } |
| 225 | 214 |
| 226 | |
| 227 DEFINE_NATIVE_ENTRY(Integer_parse, 1) { | 215 DEFINE_NATIVE_ENTRY(Integer_parse, 1) { |
| 228 GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0)); | 216 GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0)); |
| 229 return ParseInteger(value); | 217 return ParseInteger(value); |
| 230 } | 218 } |
| 231 | 219 |
| 232 | |
| 233 DEFINE_NATIVE_ENTRY(Integer_fromEnvironment, 3) { | 220 DEFINE_NATIVE_ENTRY(Integer_fromEnvironment, 3) { |
| 234 GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(1)); | 221 GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(1)); |
| 235 GET_NATIVE_ARGUMENT(Integer, default_value, arguments->NativeArgAt(2)); | 222 GET_NATIVE_ARGUMENT(Integer, default_value, arguments->NativeArgAt(2)); |
| 236 // Call the embedder to supply us with the environment. | 223 // Call the embedder to supply us with the environment. |
| 237 const String& env_value = | 224 const String& env_value = |
| 238 String::Handle(Api::GetEnvironmentValue(thread, name)); | 225 String::Handle(Api::GetEnvironmentValue(thread, name)); |
| 239 if (!env_value.IsNull()) { | 226 if (!env_value.IsNull()) { |
| 240 const Integer& result = Integer::Handle(ParseInteger(env_value)); | 227 const Integer& result = Integer::Handle(ParseInteger(env_value)); |
| 241 if (!result.IsNull()) { | 228 if (!result.IsNull()) { |
| 242 if (result.IsSmi()) { | 229 if (result.IsSmi()) { |
| 243 return result.raw(); | 230 return result.raw(); |
| 244 } | 231 } |
| 245 return result.CheckAndCanonicalize(thread, NULL); | 232 return result.CheckAndCanonicalize(thread, NULL); |
| 246 } | 233 } |
| 247 } | 234 } |
| 248 return default_value.raw(); | 235 return default_value.raw(); |
| 249 } | 236 } |
| 250 | 237 |
| 251 | |
| 252 static RawInteger* ShiftOperationHelper(Token::Kind kind, | 238 static RawInteger* ShiftOperationHelper(Token::Kind kind, |
| 253 const Integer& value, | 239 const Integer& value, |
| 254 const Smi& amount) { | 240 const Smi& amount) { |
| 255 if (amount.Value() < 0) { | 241 if (amount.Value() < 0) { |
| 256 Exceptions::ThrowArgumentError(amount); | 242 Exceptions::ThrowArgumentError(amount); |
| 257 } | 243 } |
| 258 if (value.IsSmi()) { | 244 if (value.IsSmi()) { |
| 259 const Smi& smi_value = Smi::Cast(value); | 245 const Smi& smi_value = Smi::Cast(value); |
| 260 return smi_value.ShiftOp(kind, amount, Heap::kNew); | 246 return smi_value.ShiftOp(kind, amount, Heap::kNew); |
| 261 } | 247 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 283 default: | 269 default: |
| 284 UNIMPLEMENTED(); | 270 UNIMPLEMENTED(); |
| 285 } | 271 } |
| 286 } else { | 272 } else { |
| 287 ASSERT(value.IsBigint()); | 273 ASSERT(value.IsBigint()); |
| 288 } | 274 } |
| 289 ASSERT(!FLAG_limit_ints_to_64_bits); | 275 ASSERT(!FLAG_limit_ints_to_64_bits); |
| 290 return Integer::null(); | 276 return Integer::null(); |
| 291 } | 277 } |
| 292 | 278 |
| 293 | |
| 294 DEFINE_NATIVE_ENTRY(Smi_bitAndFromSmi, 2) { | 279 DEFINE_NATIVE_ENTRY(Smi_bitAndFromSmi, 2) { |
| 295 const Smi& left = Smi::CheckedHandle(arguments->NativeArgAt(0)); | 280 const Smi& left = Smi::CheckedHandle(arguments->NativeArgAt(0)); |
| 296 GET_NON_NULL_NATIVE_ARGUMENT(Smi, right, arguments->NativeArgAt(1)); | 281 GET_NON_NULL_NATIVE_ARGUMENT(Smi, right, arguments->NativeArgAt(1)); |
| 297 if (FLAG_trace_intrinsified_natives) { | 282 if (FLAG_trace_intrinsified_natives) { |
| 298 OS::Print("Smi_bitAndFromSmi %s & %s\n", left.ToCString(), | 283 OS::Print("Smi_bitAndFromSmi %s & %s\n", left.ToCString(), |
| 299 right.ToCString()); | 284 right.ToCString()); |
| 300 } | 285 } |
| 301 const Smi& left_value = Smi::Cast(left); | 286 const Smi& left_value = Smi::Cast(left); |
| 302 const Smi& right_value = Smi::Cast(right); | 287 const Smi& right_value = Smi::Cast(right); |
| 303 return Smi::New(left_value.Value() & right_value.Value()); | 288 return Smi::New(left_value.Value() & right_value.Value()); |
| 304 } | 289 } |
| 305 | 290 |
| 306 | |
| 307 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) { | 291 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) { |
| 308 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); | 292 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); |
| 309 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); | 293 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); |
| 310 ASSERT(CheckInteger(amount)); | 294 ASSERT(CheckInteger(amount)); |
| 311 ASSERT(CheckInteger(value)); | 295 ASSERT(CheckInteger(value)); |
| 312 const Integer& result = | 296 const Integer& result = |
| 313 Integer::Handle(ShiftOperationHelper(Token::kSHR, value, amount)); | 297 Integer::Handle(ShiftOperationHelper(Token::kSHR, value, amount)); |
| 314 // A null result indicates that a bigint operation is required. | 298 // A null result indicates that a bigint operation is required. |
| 315 return result.IsNull() ? result.raw() : result.AsValidInteger(); | 299 return result.IsNull() ? result.raw() : result.AsValidInteger(); |
| 316 } | 300 } |
| 317 | 301 |
| 318 | |
| 319 DEFINE_NATIVE_ENTRY(Smi_shlFromInt, 2) { | 302 DEFINE_NATIVE_ENTRY(Smi_shlFromInt, 2) { |
| 320 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); | 303 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); |
| 321 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); | 304 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); |
| 322 ASSERT(CheckInteger(amount)); | 305 ASSERT(CheckInteger(amount)); |
| 323 ASSERT(CheckInteger(value)); | 306 ASSERT(CheckInteger(value)); |
| 324 if (FLAG_trace_intrinsified_natives) { | 307 if (FLAG_trace_intrinsified_natives) { |
| 325 OS::Print("Smi_shlFromInt: %s << %s\n", value.ToCString(), | 308 OS::Print("Smi_shlFromInt: %s << %s\n", value.ToCString(), |
| 326 amount.ToCString()); | 309 amount.ToCString()); |
| 327 } | 310 } |
| 328 const Integer& result = | 311 const Integer& result = |
| 329 Integer::Handle(ShiftOperationHelper(Token::kSHL, value, amount)); | 312 Integer::Handle(ShiftOperationHelper(Token::kSHL, value, amount)); |
| 330 // A null result indicates that a bigint operation is required. | 313 // A null result indicates that a bigint operation is required. |
| 331 return result.IsNull() ? result.raw() : result.AsValidInteger(); | 314 return result.IsNull() ? result.raw() : result.AsValidInteger(); |
| 332 } | 315 } |
| 333 | 316 |
| 334 | |
| 335 DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) { | 317 DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) { |
| 336 const Smi& operand = Smi::CheckedHandle(arguments->NativeArgAt(0)); | 318 const Smi& operand = Smi::CheckedHandle(arguments->NativeArgAt(0)); |
| 337 if (FLAG_trace_intrinsified_natives) { | 319 if (FLAG_trace_intrinsified_natives) { |
| 338 OS::Print("Smi_bitNegate: %s\n", operand.ToCString()); | 320 OS::Print("Smi_bitNegate: %s\n", operand.ToCString()); |
| 339 } | 321 } |
| 340 intptr_t result = ~operand.Value(); | 322 intptr_t result = ~operand.Value(); |
| 341 ASSERT(Smi::IsValid(result)); | 323 ASSERT(Smi::IsValid(result)); |
| 342 return Smi::New(result); | 324 return Smi::New(result); |
| 343 } | 325 } |
| 344 | 326 |
| 345 | |
| 346 DEFINE_NATIVE_ENTRY(Smi_bitLength, 1) { | 327 DEFINE_NATIVE_ENTRY(Smi_bitLength, 1) { |
| 347 const Smi& operand = Smi::CheckedHandle(arguments->NativeArgAt(0)); | 328 const Smi& operand = Smi::CheckedHandle(arguments->NativeArgAt(0)); |
| 348 if (FLAG_trace_intrinsified_natives) { | 329 if (FLAG_trace_intrinsified_natives) { |
| 349 OS::Print("Smi_bitLength: %s\n", operand.ToCString()); | 330 OS::Print("Smi_bitLength: %s\n", operand.ToCString()); |
| 350 } | 331 } |
| 351 int64_t value = operand.AsInt64Value(); | 332 int64_t value = operand.AsInt64Value(); |
| 352 intptr_t result = Utils::BitLength(value); | 333 intptr_t result = Utils::BitLength(value); |
| 353 ASSERT(Smi::IsValid(result)); | 334 ASSERT(Smi::IsValid(result)); |
| 354 return Smi::New(result); | 335 return Smi::New(result); |
| 355 } | 336 } |
| 356 | 337 |
| 357 | |
| 358 // Mint natives. | 338 // Mint natives. |
| 359 | 339 |
| 360 DEFINE_NATIVE_ENTRY(Mint_bitNegate, 1) { | 340 DEFINE_NATIVE_ENTRY(Mint_bitNegate, 1) { |
| 361 const Mint& operand = Mint::CheckedHandle(arguments->NativeArgAt(0)); | 341 const Mint& operand = Mint::CheckedHandle(arguments->NativeArgAt(0)); |
| 362 ASSERT(CheckInteger(operand)); | 342 ASSERT(CheckInteger(operand)); |
| 363 if (FLAG_trace_intrinsified_natives) { | 343 if (FLAG_trace_intrinsified_natives) { |
| 364 OS::Print("Mint_bitNegate: %s\n", operand.ToCString()); | 344 OS::Print("Mint_bitNegate: %s\n", operand.ToCString()); |
| 365 } | 345 } |
| 366 int64_t result = ~operand.value(); | 346 int64_t result = ~operand.value(); |
| 367 return Integer::New(result); | 347 return Integer::New(result); |
| 368 } | 348 } |
| 369 | 349 |
| 370 | |
| 371 DEFINE_NATIVE_ENTRY(Mint_bitLength, 1) { | 350 DEFINE_NATIVE_ENTRY(Mint_bitLength, 1) { |
| 372 const Mint& operand = Mint::CheckedHandle(arguments->NativeArgAt(0)); | 351 const Mint& operand = Mint::CheckedHandle(arguments->NativeArgAt(0)); |
| 373 ASSERT(CheckInteger(operand)); | 352 ASSERT(CheckInteger(operand)); |
| 374 if (FLAG_trace_intrinsified_natives) { | 353 if (FLAG_trace_intrinsified_natives) { |
| 375 OS::Print("Mint_bitLength: %s\n", operand.ToCString()); | 354 OS::Print("Mint_bitLength: %s\n", operand.ToCString()); |
| 376 } | 355 } |
| 377 int64_t value = operand.AsInt64Value(); | 356 int64_t value = operand.AsInt64Value(); |
| 378 intptr_t result = Utils::BitLength(value); | 357 intptr_t result = Utils::BitLength(value); |
| 379 ASSERT(Smi::IsValid(result)); | 358 ASSERT(Smi::IsValid(result)); |
| 380 return Smi::New(result); | 359 return Smi::New(result); |
| 381 } | 360 } |
| 382 | 361 |
| 383 | |
| 384 DEFINE_NATIVE_ENTRY(Mint_shlFromInt, 2) { | 362 DEFINE_NATIVE_ENTRY(Mint_shlFromInt, 2) { |
| 385 // Use the preallocated out of memory exception to avoid calling | 363 // Use the preallocated out of memory exception to avoid calling |
| 386 // into dart code or allocating any code. | 364 // into dart code or allocating any code. |
| 387 const Instance& exception = | 365 const Instance& exception = |
| 388 Instance::Handle(isolate->object_store()->out_of_memory()); | 366 Instance::Handle(isolate->object_store()->out_of_memory()); |
| 389 Exceptions::Throw(thread, exception); | 367 Exceptions::Throw(thread, exception); |
| 390 UNREACHABLE(); | 368 UNREACHABLE(); |
| 391 return 0; | 369 return 0; |
| 392 } | 370 } |
| 393 | 371 |
| 394 | |
| 395 // Bigint natives. | 372 // Bigint natives. |
| 396 | 373 |
| 397 DEFINE_NATIVE_ENTRY(Bigint_getNeg, 1) { | 374 DEFINE_NATIVE_ENTRY(Bigint_getNeg, 1) { |
| 398 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); | 375 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
| 399 return bigint.neg(); | 376 return bigint.neg(); |
| 400 } | 377 } |
| 401 | 378 |
| 402 | |
| 403 DEFINE_NATIVE_ENTRY(Bigint_getUsed, 1) { | 379 DEFINE_NATIVE_ENTRY(Bigint_getUsed, 1) { |
| 404 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); | 380 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
| 405 return bigint.used(); | 381 return bigint.used(); |
| 406 } | 382 } |
| 407 | 383 |
| 408 | |
| 409 DEFINE_NATIVE_ENTRY(Bigint_getDigits, 1) { | 384 DEFINE_NATIVE_ENTRY(Bigint_getDigits, 1) { |
| 410 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); | 385 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
| 411 return bigint.digits(); | 386 return bigint.digits(); |
| 412 } | 387 } |
| 413 | 388 |
| 414 | |
| 415 DEFINE_NATIVE_ENTRY(Bigint_allocate, 4) { | 389 DEFINE_NATIVE_ENTRY(Bigint_allocate, 4) { |
| 416 // TODO(alexmarkov): Revise this assertion if this native method can be used | 390 // TODO(alexmarkov): Revise this assertion if this native method can be used |
| 417 // to explicitly allocate Bigint objects in --limit-ints-to-64-bits mode. | 391 // to explicitly allocate Bigint objects in --limit-ints-to-64-bits mode. |
| 418 ASSERT(!FLAG_limit_ints_to_64_bits); | 392 ASSERT(!FLAG_limit_ints_to_64_bits); |
| 419 // First arg is null type arguments, since class Bigint is not parameterized. | 393 // First arg is null type arguments, since class Bigint is not parameterized. |
| 420 const Bool& neg = Bool::CheckedHandle(arguments->NativeArgAt(1)); | 394 const Bool& neg = Bool::CheckedHandle(arguments->NativeArgAt(1)); |
| 421 const Smi& used = Smi::CheckedHandle(arguments->NativeArgAt(2)); | 395 const Smi& used = Smi::CheckedHandle(arguments->NativeArgAt(2)); |
| 422 const TypedData& digits = TypedData::CheckedHandle(arguments->NativeArgAt(3)); | 396 const TypedData& digits = TypedData::CheckedHandle(arguments->NativeArgAt(3)); |
| 423 ASSERT(!digits.IsNull()); | 397 ASSERT(!digits.IsNull()); |
| 424 return Bigint::New(neg.value(), used.Value(), digits); | 398 return Bigint::New(neg.value(), used.Value(), digits); |
| 425 } | 399 } |
| 426 | 400 |
| 427 } // namespace dart | 401 } // namespace dart |
| OLD | NEW |