Chromium Code Reviews| 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 |