OLD | NEW |
---|---|
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
8 #include "vm/exceptions.h" | 8 #include "vm/exceptions.h" |
9 #include "vm/heap.h" | 9 #include "vm/heap.h" |
10 #include "vm/native_entry.h" | 10 #include "vm/native_entry.h" |
11 #include "vm/object.h" | 11 #include "vm/object.h" |
12 #include "vm/stack_frame.h" | 12 #include "vm/stack_frame.h" |
13 #include "vm/symbols.h" | 13 #include "vm/symbols.h" |
14 | 14 |
15 namespace dart { | 15 namespace dart { |
16 | 16 |
17 DECLARE_FLAG(bool, enable_type_checks); | 17 DECLARE_FLAG(bool, enable_type_checks); |
18 DECLARE_FLAG(bool, trace_type_checks); | 18 DECLARE_FLAG(bool, trace_type_checks); |
19 DECLARE_FLAG(bool, warn_on_javascript_incompatibility); | |
19 | 20 |
20 | 21 |
21 DEFINE_NATIVE_ENTRY(Object_equals, 1) { | 22 DEFINE_NATIVE_ENTRY(Object_equals, 1) { |
22 // Implemented in the flow graph builder. | 23 // Implemented in the flow graph builder. |
23 UNREACHABLE(); | 24 UNREACHABLE(); |
24 return Object::null(); | 25 return Object::null(); |
25 } | 26 } |
26 | 27 |
27 | 28 |
28 DEFINE_NATIVE_ENTRY(Object_cid, 1) { | 29 DEFINE_NATIVE_ENTRY(Object_cid, 1) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
102 | 103 |
103 | 104 |
104 DEFINE_NATIVE_ENTRY(Object_runtimeType, 1) { | 105 DEFINE_NATIVE_ENTRY(Object_runtimeType, 1) { |
105 const Instance& instance = Instance::CheckedHandle(arguments->NativeArgAt(0)); | 106 const Instance& instance = Instance::CheckedHandle(arguments->NativeArgAt(0)); |
106 // Special handling for following types outside this native. | 107 // Special handling for following types outside this native. |
107 ASSERT(!instance.IsString() && !instance.IsInteger() && !instance.IsDouble()); | 108 ASSERT(!instance.IsString() && !instance.IsInteger() && !instance.IsDouble()); |
108 return instance.GetType(); | 109 return instance.GetType(); |
109 } | 110 } |
110 | 111 |
111 | 112 |
113 static void WarnOnJSIntegralNumTypeTest( | |
114 const Instance& instance, | |
115 const TypeArguments& instantiator_type_arguments, | |
116 const AbstractType& type) { | |
117 const bool instance_is_int = | |
118 instance.IsSmi() || instance.IsMint() || instance.IsBigint(); | |
srdjan
2014/05/08 18:11:05
Why not instance.IsInteger()?
regis
2014/05/09 21:03:42
Done.
| |
119 const bool instance_is_double = instance.IsDouble(); | |
120 if (!(instance_is_int || instance_is_double)) { | |
121 return; | |
122 } | |
123 AbstractType& instantiated_type = AbstractType::Handle(type.raw()); | |
124 if (!type.IsInstantiated()) { | |
125 instantiated_type = type.InstantiateFrom(instantiator_type_arguments, NULL); | |
126 } | |
127 if (instance_is_double) { | |
128 if (instantiated_type.IsIntType()) { | |
129 const double value = Double::Cast(instance).value(); | |
130 if (floor(value) == value) { | |
131 Exceptions::JSWarning(ICData::Handle(), // ic_data must be looked up. | |
132 "javascript incompatibility: integral value of " | |
133 "type 'double' is also considered to be of " | |
134 "type 'int'"); | |
135 } | |
136 } | |
137 } else { | |
138 ASSERT(instance_is_int); | |
139 if (instantiated_type.IsDoubleType()) { | |
140 Exceptions::JSWarning(ICData::Handle(), // ic_data must be looked up. | |
141 "javascript incompatibility: integer value is " | |
142 "also considered to be of type 'double'"); | |
143 } | |
144 } | |
145 } | |
146 | |
147 | |
112 DEFINE_NATIVE_ENTRY(Object_instanceOf, 5) { | 148 DEFINE_NATIVE_ENTRY(Object_instanceOf, 5) { |
113 const Instance& instance = Instance::CheckedHandle(arguments->NativeArgAt(0)); | 149 const Instance& instance = Instance::CheckedHandle(arguments->NativeArgAt(0)); |
114 // Instantiator at position 1 is not used. It is passed along so that the call | 150 // Instantiator at position 1 is not used. It is passed along so that the call |
115 // can be easily converted to an optimized implementation. Instantiator is | 151 // can be easily converted to an optimized implementation. Instantiator is |
116 // used to populate the subtype cache. | 152 // used to populate the subtype cache. |
117 const TypeArguments& instantiator_type_arguments = | 153 const TypeArguments& instantiator_type_arguments = |
118 TypeArguments::CheckedHandle(arguments->NativeArgAt(2)); | 154 TypeArguments::CheckedHandle(arguments->NativeArgAt(2)); |
119 const AbstractType& type = | 155 const AbstractType& type = |
120 AbstractType::CheckedHandle(arguments->NativeArgAt(3)); | 156 AbstractType::CheckedHandle(arguments->NativeArgAt(3)); |
121 const Bool& negate = Bool::CheckedHandle(arguments->NativeArgAt(4)); | 157 const Bool& negate = Bool::CheckedHandle(arguments->NativeArgAt(4)); |
122 ASSERT(type.IsFinalized()); | 158 ASSERT(type.IsFinalized()); |
123 ASSERT(!type.IsMalformed()); | 159 ASSERT(!type.IsMalformed()); |
124 ASSERT(!type.IsMalbounded()); | 160 ASSERT(!type.IsMalbounded()); |
161 | |
162 // Check for javascript incompatibility. | |
163 if (FLAG_warn_on_javascript_incompatibility) { | |
164 WarnOnJSIntegralNumTypeTest(instance, instantiator_type_arguments, type); | |
165 } | |
166 | |
125 Error& bound_error = Error::Handle(); | 167 Error& bound_error = Error::Handle(); |
126 const bool is_instance_of = instance.IsInstanceOf(type, | 168 const bool is_instance_of = instance.IsInstanceOf(type, |
127 instantiator_type_arguments, | 169 instantiator_type_arguments, |
128 &bound_error); | 170 &bound_error); |
129 if (FLAG_trace_type_checks) { | 171 if (FLAG_trace_type_checks) { |
130 const char* result_str = is_instance_of ? "true" : "false"; | 172 const char* result_str = is_instance_of ? "true" : "false"; |
131 OS::Print("Native Object.instanceOf: result %s\n", result_str); | 173 OS::Print("Native Object.instanceOf: result %s\n", result_str); |
132 const Type& instance_type = Type::Handle(instance.GetType()); | 174 const Type& instance_type = Type::Handle(instance.GetType()); |
133 OS::Print(" instance type: %s\n", | 175 OS::Print(" instance type: %s\n", |
134 String::Handle(instance_type.Name()).ToCString()); | 176 String::Handle(instance_type.Name()).ToCString()); |
(...skipping 28 matching lines...) Expand all Loading... | |
163 TypeArguments::CheckedHandle(arguments->NativeArgAt(2)); | 205 TypeArguments::CheckedHandle(arguments->NativeArgAt(2)); |
164 const AbstractType& type = | 206 const AbstractType& type = |
165 AbstractType::CheckedHandle(arguments->NativeArgAt(3)); | 207 AbstractType::CheckedHandle(arguments->NativeArgAt(3)); |
166 ASSERT(type.IsFinalized()); | 208 ASSERT(type.IsFinalized()); |
167 ASSERT(!type.IsMalformed()); | 209 ASSERT(!type.IsMalformed()); |
168 ASSERT(!type.IsMalbounded()); | 210 ASSERT(!type.IsMalbounded()); |
169 Error& bound_error = Error::Handle(); | 211 Error& bound_error = Error::Handle(); |
170 if (instance.IsNull()) { | 212 if (instance.IsNull()) { |
171 return instance.raw(); | 213 return instance.raw(); |
172 } | 214 } |
215 | |
216 // Check for javascript incompatibility. | |
217 if (FLAG_warn_on_javascript_incompatibility) { | |
218 WarnOnJSIntegralNumTypeTest(instance, instantiator_type_arguments, type); | |
219 } | |
220 | |
173 const bool is_instance_of = instance.IsInstanceOf(type, | 221 const bool is_instance_of = instance.IsInstanceOf(type, |
174 instantiator_type_arguments, | 222 instantiator_type_arguments, |
175 &bound_error); | 223 &bound_error); |
176 if (FLAG_trace_type_checks) { | 224 if (FLAG_trace_type_checks) { |
177 const char* result_str = is_instance_of ? "true" : "false"; | 225 const char* result_str = is_instance_of ? "true" : "false"; |
178 OS::Print("Object.as: result %s\n", result_str); | 226 OS::Print("Object.as: result %s\n", result_str); |
179 const Type& instance_type = Type::Handle(instance.GetType()); | 227 const Type& instance_type = Type::Handle(instance.GetType()); |
180 OS::Print(" instance type: %s\n", | 228 OS::Print(" instance type: %s\n", |
181 String::Handle(instance_type.Name()).ToCString()); | 229 String::Handle(instance_type.Name()).ToCString()); |
182 OS::Print(" cast type: %s\n", String::Handle(type.Name()).ToCString()); | 230 OS::Print(" cast type: %s\n", String::Handle(type.Name()).ToCString()); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
232 | 280 |
233 | 281 |
234 DEFINE_NATIVE_ENTRY(LibraryPrefix_load, 1) { | 282 DEFINE_NATIVE_ENTRY(LibraryPrefix_load, 1) { |
235 const LibraryPrefix& prefix = | 283 const LibraryPrefix& prefix = |
236 LibraryPrefix::CheckedHandle(arguments->NativeArgAt(0)); | 284 LibraryPrefix::CheckedHandle(arguments->NativeArgAt(0)); |
237 prefix.LoadLibrary(); | 285 prefix.LoadLibrary(); |
238 return Bool::Get(true).raw(); | 286 return Bool::Get(true).raw(); |
239 } | 287 } |
240 | 288 |
241 } // namespace dart | 289 } // namespace dart |
OLD | NEW |