| 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/code_patcher.h" | 
| 8 #include "vm/exceptions.h" | 9 #include "vm/exceptions.h" | 
| 9 #include "vm/heap.h" | 10 #include "vm/heap.h" | 
| 10 #include "vm/native_entry.h" | 11 #include "vm/native_entry.h" | 
| 11 #include "vm/object.h" | 12 #include "vm/object.h" | 
| 12 #include "vm/stack_frame.h" | 13 #include "vm/stack_frame.h" | 
| 13 #include "vm/symbols.h" | 14 #include "vm/symbols.h" | 
| 14 | 15 | 
| 15 namespace dart { | 16 namespace dart { | 
| 16 | 17 | 
| 17 DECLARE_FLAG(bool, enable_type_checks); | 18 DECLARE_FLAG(bool, enable_type_checks); | 
| 18 DECLARE_FLAG(bool, trace_type_checks); | 19 DECLARE_FLAG(bool, trace_type_checks); | 
|  | 20 DECLARE_FLAG(bool, warn_on_javascript_compatibility); | 
| 19 | 21 | 
| 20 | 22 | 
| 21 DEFINE_NATIVE_ENTRY(Object_equals, 1) { | 23 DEFINE_NATIVE_ENTRY(Object_equals, 1) { | 
| 22   // Implemented in the flow graph builder. | 24   // Implemented in the flow graph builder. | 
| 23   UNREACHABLE(); | 25   UNREACHABLE(); | 
| 24   return Object::null(); | 26   return Object::null(); | 
| 25 } | 27 } | 
| 26 | 28 | 
| 27 | 29 | 
| 28 DEFINE_NATIVE_ENTRY(Object_cid, 1) { | 30 DEFINE_NATIVE_ENTRY(Object_cid, 1) { | 
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 102 | 104 | 
| 103 | 105 | 
| 104 DEFINE_NATIVE_ENTRY(Object_runtimeType, 1) { | 106 DEFINE_NATIVE_ENTRY(Object_runtimeType, 1) { | 
| 105   const Instance& instance = Instance::CheckedHandle(arguments->NativeArgAt(0)); | 107   const Instance& instance = Instance::CheckedHandle(arguments->NativeArgAt(0)); | 
| 106   // Special handling for following types outside this native. | 108   // Special handling for following types outside this native. | 
| 107   ASSERT(!instance.IsString() && !instance.IsInteger() && !instance.IsDouble()); | 109   ASSERT(!instance.IsString() && !instance.IsInteger() && !instance.IsDouble()); | 
| 108   return instance.GetType(); | 110   return instance.GetType(); | 
| 109 } | 111 } | 
| 110 | 112 | 
| 111 | 113 | 
|  | 114 static void JSWarning(const char* msg) { | 
|  | 115   DartFrameIterator iterator; | 
|  | 116   iterator.NextFrame();  // Skip native call. | 
|  | 117   StackFrame* caller_frame = iterator.NextFrame(); | 
|  | 118   ASSERT(caller_frame != NULL); | 
|  | 119   const Code& caller_code = Code::Handle(caller_frame->LookupDartCode()); | 
|  | 120   ASSERT(!caller_code.IsNull()); | 
|  | 121   const uword caller_pc = caller_frame->pc(); | 
|  | 122   // Assume an instance call. | 
|  | 123   ICData& ic_data = ICData::Handle(); | 
|  | 124   CodePatcher::GetInstanceCallAt(caller_pc, caller_code, &ic_data); | 
|  | 125   ASSERT(!ic_data.IsNull()); | 
|  | 126   // Report warning only if not already reported at this location. | 
|  | 127   if (!ic_data.IssuedJSWarning()) { | 
|  | 128     ic_data.SetIssuedJSWarning(); | 
|  | 129     Exceptions::JSWarning(caller_frame, "%s", msg); | 
|  | 130   } | 
|  | 131 } | 
|  | 132 | 
|  | 133 | 
|  | 134 static void WarnOnJSIntegralNumTypeTest( | 
|  | 135     const Instance& instance, | 
|  | 136     const TypeArguments& instantiator_type_arguments, | 
|  | 137     const AbstractType& type) { | 
|  | 138   const bool instance_is_int = instance.IsInteger(); | 
|  | 139   const bool instance_is_double = instance.IsDouble(); | 
|  | 140   if (!(instance_is_int || instance_is_double)) { | 
|  | 141     return; | 
|  | 142   } | 
|  | 143   AbstractType& instantiated_type = AbstractType::Handle(type.raw()); | 
|  | 144   if (!type.IsInstantiated()) { | 
|  | 145     instantiated_type = type.InstantiateFrom(instantiator_type_arguments, NULL); | 
|  | 146   } | 
|  | 147   if (instance_is_double) { | 
|  | 148     if (instantiated_type.IsIntType()) { | 
|  | 149       const double value = Double::Cast(instance).value(); | 
|  | 150       if (floor(value) == value) { | 
|  | 151         JSWarning("integral value of type 'double' is also considered to be " | 
|  | 152                   "of type 'int'"); | 
|  | 153       } | 
|  | 154     } | 
|  | 155   } else { | 
|  | 156     ASSERT(instance_is_int); | 
|  | 157     if (instantiated_type.IsDoubleType()) { | 
|  | 158       JSWarning("integer value is also considered to be of type 'double'"); | 
|  | 159     } | 
|  | 160   } | 
|  | 161 } | 
|  | 162 | 
|  | 163 | 
| 112 DEFINE_NATIVE_ENTRY(Object_instanceOf, 5) { | 164 DEFINE_NATIVE_ENTRY(Object_instanceOf, 5) { | 
| 113   const Instance& instance = Instance::CheckedHandle(arguments->NativeArgAt(0)); | 165   const Instance& instance = Instance::CheckedHandle(arguments->NativeArgAt(0)); | 
| 114   // Instantiator at position 1 is not used. It is passed along so that the call | 166   // 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 | 167   // can be easily converted to an optimized implementation. Instantiator is | 
| 116   // used to populate the subtype cache. | 168   // used to populate the subtype cache. | 
| 117   const TypeArguments& instantiator_type_arguments = | 169   const TypeArguments& instantiator_type_arguments = | 
| 118       TypeArguments::CheckedHandle(arguments->NativeArgAt(2)); | 170       TypeArguments::CheckedHandle(arguments->NativeArgAt(2)); | 
| 119   const AbstractType& type = | 171   const AbstractType& type = | 
| 120       AbstractType::CheckedHandle(arguments->NativeArgAt(3)); | 172       AbstractType::CheckedHandle(arguments->NativeArgAt(3)); | 
| 121   const Bool& negate = Bool::CheckedHandle(arguments->NativeArgAt(4)); | 173   const Bool& negate = Bool::CheckedHandle(arguments->NativeArgAt(4)); | 
| 122   ASSERT(type.IsFinalized()); | 174   ASSERT(type.IsFinalized()); | 
| 123   ASSERT(!type.IsMalformed()); | 175   ASSERT(!type.IsMalformed()); | 
| 124   ASSERT(!type.IsMalbounded()); | 176   ASSERT(!type.IsMalbounded()); | 
|  | 177 | 
|  | 178   // Check for javascript compatibility. | 
|  | 179   if (FLAG_warn_on_javascript_compatibility) { | 
|  | 180     WarnOnJSIntegralNumTypeTest(instance, instantiator_type_arguments, type); | 
|  | 181   } | 
|  | 182 | 
| 125   Error& bound_error = Error::Handle(); | 183   Error& bound_error = Error::Handle(); | 
| 126   const bool is_instance_of = instance.IsInstanceOf(type, | 184   const bool is_instance_of = instance.IsInstanceOf(type, | 
| 127                                                     instantiator_type_arguments, | 185                                                     instantiator_type_arguments, | 
| 128                                                     &bound_error); | 186                                                     &bound_error); | 
| 129   if (FLAG_trace_type_checks) { | 187   if (FLAG_trace_type_checks) { | 
| 130     const char* result_str = is_instance_of ? "true" : "false"; | 188     const char* result_str = is_instance_of ? "true" : "false"; | 
| 131     OS::Print("Native Object.instanceOf: result %s\n", result_str); | 189     OS::Print("Native Object.instanceOf: result %s\n", result_str); | 
| 132     const Type& instance_type = Type::Handle(instance.GetType()); | 190     const Type& instance_type = Type::Handle(instance.GetType()); | 
| 133     OS::Print("  instance type: %s\n", | 191     OS::Print("  instance type: %s\n", | 
| 134               String::Handle(instance_type.Name()).ToCString()); | 192               String::Handle(instance_type.Name()).ToCString()); | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
| 163       TypeArguments::CheckedHandle(arguments->NativeArgAt(2)); | 221       TypeArguments::CheckedHandle(arguments->NativeArgAt(2)); | 
| 164   const AbstractType& type = | 222   const AbstractType& type = | 
| 165       AbstractType::CheckedHandle(arguments->NativeArgAt(3)); | 223       AbstractType::CheckedHandle(arguments->NativeArgAt(3)); | 
| 166   ASSERT(type.IsFinalized()); | 224   ASSERT(type.IsFinalized()); | 
| 167   ASSERT(!type.IsMalformed()); | 225   ASSERT(!type.IsMalformed()); | 
| 168   ASSERT(!type.IsMalbounded()); | 226   ASSERT(!type.IsMalbounded()); | 
| 169   Error& bound_error = Error::Handle(); | 227   Error& bound_error = Error::Handle(); | 
| 170   if (instance.IsNull()) { | 228   if (instance.IsNull()) { | 
| 171     return instance.raw(); | 229     return instance.raw(); | 
| 172   } | 230   } | 
|  | 231 | 
|  | 232   // Check for javascript compatibility. | 
|  | 233   if (FLAG_warn_on_javascript_compatibility) { | 
|  | 234     WarnOnJSIntegralNumTypeTest(instance, instantiator_type_arguments, type); | 
|  | 235   } | 
|  | 236 | 
| 173   const bool is_instance_of = instance.IsInstanceOf(type, | 237   const bool is_instance_of = instance.IsInstanceOf(type, | 
| 174                                                     instantiator_type_arguments, | 238                                                     instantiator_type_arguments, | 
| 175                                                     &bound_error); | 239                                                     &bound_error); | 
| 176   if (FLAG_trace_type_checks) { | 240   if (FLAG_trace_type_checks) { | 
| 177     const char* result_str = is_instance_of ? "true" : "false"; | 241     const char* result_str = is_instance_of ? "true" : "false"; | 
| 178     OS::Print("Object.as: result %s\n", result_str); | 242     OS::Print("Object.as: result %s\n", result_str); | 
| 179     const Type& instance_type = Type::Handle(instance.GetType()); | 243     const Type& instance_type = Type::Handle(instance.GetType()); | 
| 180     OS::Print("  instance type: %s\n", | 244     OS::Print("  instance type: %s\n", | 
| 181               String::Handle(instance_type.Name()).ToCString()); | 245               String::Handle(instance_type.Name()).ToCString()); | 
| 182     OS::Print("  cast type: %s\n", String::Handle(type.Name()).ToCString()); | 246     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 | 296 | 
| 233 | 297 | 
| 234 DEFINE_NATIVE_ENTRY(LibraryPrefix_load, 1) { | 298 DEFINE_NATIVE_ENTRY(LibraryPrefix_load, 1) { | 
| 235   const LibraryPrefix& prefix = | 299   const LibraryPrefix& prefix = | 
| 236       LibraryPrefix::CheckedHandle(arguments->NativeArgAt(0)); | 300       LibraryPrefix::CheckedHandle(arguments->NativeArgAt(0)); | 
| 237   prefix.LoadLibrary(); | 301   prefix.LoadLibrary(); | 
| 238   return Bool::Get(true).raw(); | 302   return Bool::Get(true).raw(); | 
| 239 } | 303 } | 
| 240 | 304 | 
| 241 }  // namespace dart | 305 }  // namespace dart | 
| OLD | NEW | 
|---|