Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(682)

Side by Side Diff: runtime/lib/object.cc

Issue 260713008: Add support for javascript incompatibility warnings. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698