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 |