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/code_generator.h" | 5 #include "vm/code_generator.h" |
6 | 6 |
7 #include "vm/assembler_macros.h" | 7 #include "vm/assembler_macros.h" |
8 #include "vm/ast.h" | 8 #include "vm/ast.h" |
9 #include "vm/code_patcher.h" | 9 #include "vm/code_patcher.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 1172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1183 } | 1183 } |
1184 if (!result.IsSmi()) { | 1184 if (!result.IsSmi()) { |
1185 const Class& cls = Class::Handle(result.clazz()); | 1185 const Class& cls = Class::Handle(result.clazz()); |
1186 ASSERT(!cls.IsNull()); | 1186 ASSERT(!cls.IsNull()); |
1187 function = cls.signature_function(); | 1187 function = cls.signature_function(); |
1188 if (!function.IsNull()) { | 1188 if (!function.IsNull()) { |
1189 arguments.SetReturn(result); | 1189 arguments.SetReturn(result); |
1190 return; // Return closure object. | 1190 return; // Return closure object. |
1191 } | 1191 } |
1192 } | 1192 } |
1193 Exceptions::ThrowByType(Exceptions::kObjectNotClosure, invoke_arguments); | 1193 // The result instance is not a closure, try to invoke method "call" before |
| 1194 // throwing a NoSuchMethodError. |
| 1195 |
| 1196 // TODO(regis): Factorize the following code. |
| 1197 |
| 1198 // TODO(regis): Args should be passed. |
| 1199 const Array& function_args = Array::Handle(); |
| 1200 const String& function_name = String::Handle(Symbols::Call()); |
| 1201 GrowableArray<const Object*> dart_arguments(5); |
| 1202 |
| 1203 // TODO(regis): Resolve and invoke "call" method, if existing. |
| 1204 |
| 1205 const Object& null_object = Object::Handle(); |
| 1206 dart_arguments.Add(&result); |
| 1207 dart_arguments.Add(&function_name); |
| 1208 dart_arguments.Add(&function_args); |
| 1209 dart_arguments.Add(&null_object); |
| 1210 |
| 1211 // Report if a function "call" with different arguments has been found. |
| 1212 { |
| 1213 Class& instance_class = Class::Handle(result.clazz()); |
| 1214 Function& function = |
| 1215 Function::Handle(instance_class.LookupDynamicFunction(function_name)); |
| 1216 while (function.IsNull()) { |
| 1217 instance_class = instance_class.SuperClass(); |
| 1218 if (instance_class.IsNull()) break; |
| 1219 function = instance_class.LookupDynamicFunction(function_name); |
| 1220 } |
| 1221 if (!function.IsNull()) { |
| 1222 const int total_num_parameters = function.NumParameters(); |
| 1223 const Array& array = Array::Handle(Array::New(total_num_parameters - 1)); |
| 1224 // Skip receiver. |
| 1225 for (int i = 1; i < total_num_parameters; i++) { |
| 1226 array.SetAt(i - 1, String::Handle(function.ParameterNameAt(i))); |
| 1227 } |
| 1228 dart_arguments.Add(&array); |
| 1229 } |
| 1230 } |
| 1231 Exceptions::ThrowByType(Exceptions::kNoSuchMethod, dart_arguments); |
| 1232 UNREACHABLE(); |
1194 } | 1233 } |
1195 | 1234 |
1196 | 1235 |
1197 // Invoke Implicit Closure function. | 1236 // Invoke Implicit Closure function. |
1198 // Arg0: closure object. | 1237 // Arg0: closure object. |
1199 // Arg1: arguments descriptor (originally passed as dart instance invocation). | 1238 // Arg1: arguments descriptor (originally passed as dart instance invocation). |
1200 // Arg2: arguments array (originally passed to dart instance invocation). | 1239 // Arg2: arguments array (originally passed to dart instance invocation). |
1201 DEFINE_RUNTIME_ENTRY(InvokeImplicitClosureFunction, 3) { | 1240 DEFINE_RUNTIME_ENTRY(InvokeImplicitClosureFunction, 3) { |
1202 ASSERT(arguments.Count() == | 1241 ASSERT(arguments.Count() == |
1203 kInvokeImplicitClosureFunctionRuntimeEntry.argument_count()); | 1242 kInvokeImplicitClosureFunctionRuntimeEntry.argument_count()); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1237 Smi& named_arg_pos = Smi::Handle(); | 1276 Smi& named_arg_pos = Smi::Handle(); |
1238 for (intptr_t i = 0; i < num_named_args; i++) { | 1277 for (intptr_t i = 0; i < num_named_args; i++) { |
1239 const int index = 2 + (2 * i); | 1278 const int index = 2 + (2 * i); |
1240 named_arg_name ^= arg_descriptor.At(index); | 1279 named_arg_name ^= arg_descriptor.At(index); |
1241 ASSERT(named_arg_name.IsSymbol()); | 1280 ASSERT(named_arg_name.IsSymbol()); |
1242 adjusted_arg_descriptor.SetAt(index, named_arg_name); | 1281 adjusted_arg_descriptor.SetAt(index, named_arg_name); |
1243 named_arg_pos ^= arg_descriptor.At(index + 1); | 1282 named_arg_pos ^= arg_descriptor.At(index + 1); |
1244 named_arg_pos = Smi::New(named_arg_pos.Value() - 1); | 1283 named_arg_pos = Smi::New(named_arg_pos.Value() - 1); |
1245 adjusted_arg_descriptor.SetAt(index + 1, named_arg_pos); | 1284 adjusted_arg_descriptor.SetAt(index + 1, named_arg_pos); |
1246 } | 1285 } |
1247 adjusted_arg_descriptor.SetAt(len - 1, Object::Handle(Object::null())); | 1286 adjusted_arg_descriptor.SetAt(len - 1, Object::Handle()); |
1248 // It is too late to share the descriptor by canonicalizing it. However, it is | 1287 // It is too late to share the descriptor by canonicalizing it. However, it is |
1249 // important that the argument names are canonicalized (i.e. are symbols). | 1288 // important that the argument names are canonicalized (i.e. are symbols). |
1250 | 1289 |
1251 // Receiver parameter has already been skipped by caller. | 1290 // Receiver parameter has already been skipped by caller. |
1252 GrowableArray<const Object*> invoke_arguments(0); | 1291 GrowableArray<const Object*> invoke_arguments(0); |
1253 for (intptr_t i = 0; i < func_arguments.Length(); i++) { | 1292 for (intptr_t i = 0; i < func_arguments.Length(); i++) { |
1254 const Object& value = Object::Handle(func_arguments.At(i)); | 1293 const Object& value = Object::Handle(func_arguments.At(i)); |
1255 invoke_arguments.Add(&value); | 1294 invoke_arguments.Add(&value); |
1256 } | 1295 } |
1257 | 1296 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1322 const Object& result = Object::Handle( | 1361 const Object& result = Object::Handle( |
1323 DartEntry::InvokeDynamic(receiver, | 1362 DartEntry::InvokeDynamic(receiver, |
1324 function, | 1363 function, |
1325 invoke_arguments, | 1364 invoke_arguments, |
1326 kNoArgumentNames)); | 1365 kNoArgumentNames)); |
1327 CheckResultError(result); | 1366 CheckResultError(result); |
1328 arguments.SetReturn(result); | 1367 arguments.SetReturn(result); |
1329 } | 1368 } |
1330 | 1369 |
1331 | 1370 |
1332 // Report that an object is not a closure. | 1371 // A non-closure object was invoked as a closure, so call the "call" method |
| 1372 // on it. |
1333 // Arg0: non-closure object. | 1373 // Arg0: non-closure object. |
1334 // Arg1: arguments array. | 1374 // Arg1: arguments array. |
| 1375 // TODO(regis): Rename this entry? |
1335 DEFINE_RUNTIME_ENTRY(ReportObjectNotClosure, 2) { | 1376 DEFINE_RUNTIME_ENTRY(ReportObjectNotClosure, 2) { |
1336 ASSERT(arguments.Count() == | 1377 ASSERT(arguments.Count() == |
1337 kReportObjectNotClosureRuntimeEntry.argument_count()); | 1378 kReportObjectNotClosureRuntimeEntry.argument_count()); |
1338 const Instance& bad_closure = Instance::CheckedHandle(arguments.At(0)); | 1379 const Instance& instance = Instance::CheckedHandle(arguments.At(0)); |
1339 if (bad_closure.IsNull()) { | 1380 const Array& function_args = Array::CheckedHandle(arguments.At(1)); |
1340 GrowableArray<const Object*> args; | 1381 const String& function_name = String::Handle(Symbols::Call()); |
1341 Exceptions::ThrowByType(Exceptions::kObjectNotClosure, args); | 1382 GrowableArray<const Object*> dart_arguments(5); |
| 1383 if (instance.IsNull()) { |
| 1384 dart_arguments.Add(&function_name); |
| 1385 dart_arguments.Add(&function_args); |
| 1386 Exceptions::ThrowByType(Exceptions::kNullPointer, dart_arguments); |
| 1387 UNREACHABLE(); |
1342 } | 1388 } |
1343 GrowableArray<const Object*> args; | 1389 |
1344 Exceptions::ThrowByType(Exceptions::kObjectNotClosure, args); | 1390 // TODO(regis): Resolve and invoke "call" method, if existing. |
| 1391 |
| 1392 const Object& null_object = Object::Handle(); |
| 1393 dart_arguments.Add(&instance); |
| 1394 dart_arguments.Add(&function_name); |
| 1395 dart_arguments.Add(&function_args); |
| 1396 dart_arguments.Add(&null_object); |
| 1397 |
| 1398 // Report if a function "call" with different arguments has been found. |
| 1399 Class& instance_class = Class::Handle(instance.clazz()); |
| 1400 Function& function = |
| 1401 Function::Handle(instance_class.LookupDynamicFunction(function_name)); |
| 1402 while (function.IsNull()) { |
| 1403 instance_class = instance_class.SuperClass(); |
| 1404 if (instance_class.IsNull()) break; |
| 1405 function = instance_class.LookupDynamicFunction(function_name); |
| 1406 } |
| 1407 if (!function.IsNull()) { |
| 1408 const int total_num_parameters = function.NumParameters(); |
| 1409 const Array& array = Array::Handle(Array::New(total_num_parameters - 1)); |
| 1410 // Skip receiver. |
| 1411 for (int i = 1; i < total_num_parameters; i++) { |
| 1412 array.SetAt(i - 1, String::Handle(function.ParameterNameAt(i))); |
| 1413 } |
| 1414 dart_arguments.Add(&array); |
| 1415 } |
| 1416 Exceptions::ThrowByType(Exceptions::kNoSuchMethod, dart_arguments); |
| 1417 UNREACHABLE(); |
1345 } | 1418 } |
1346 | 1419 |
1347 | 1420 |
| 1421 // A closure object was invoked with incompatible arguments. |
| 1422 // TODO(regis): Deprecated. This case should be handled by a noSuchMethod call. |
1348 DEFINE_RUNTIME_ENTRY(ClosureArgumentMismatch, 0) { | 1423 DEFINE_RUNTIME_ENTRY(ClosureArgumentMismatch, 0) { |
1349 ASSERT(arguments.Count() == | 1424 ASSERT(arguments.Count() == |
1350 kClosureArgumentMismatchRuntimeEntry.argument_count()); | 1425 kClosureArgumentMismatchRuntimeEntry.argument_count()); |
1351 GrowableArray<const Object*> args; | 1426 const Instance& instance = Instance::Handle(); // Incorrect. OK for now. |
1352 Exceptions::ThrowByType(Exceptions::kClosureArgumentMismatch, args); | 1427 const Array& function_args = Array::Handle(); // Incorrect. OK for now. |
| 1428 const String& function_name = String::Handle(Symbols::Call()); |
| 1429 GrowableArray<const Object*> dart_arguments(5); |
| 1430 |
| 1431 const Object& null_object = Object::Handle(); |
| 1432 dart_arguments.Add(&instance); |
| 1433 dart_arguments.Add(&function_name); |
| 1434 dart_arguments.Add(&function_args); |
| 1435 dart_arguments.Add(&null_object); |
| 1436 Exceptions::ThrowByType(Exceptions::kNoSuchMethod, dart_arguments); |
| 1437 UNREACHABLE(); |
1353 } | 1438 } |
1354 | 1439 |
1355 | 1440 |
1356 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { | 1441 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { |
1357 ASSERT(arguments.Count() == | 1442 ASSERT(arguments.Count() == |
1358 kStackOverflowRuntimeEntry.argument_count()); | 1443 kStackOverflowRuntimeEntry.argument_count()); |
1359 uword stack_pos = reinterpret_cast<uword>(&arguments); | 1444 uword stack_pos = reinterpret_cast<uword>(&arguments); |
1360 | 1445 |
1361 // If an interrupt happens at the same time as a stack overflow, we | 1446 // If an interrupt happens at the same time as a stack overflow, we |
1362 // process the stack overflow first. | 1447 // process the stack overflow first. |
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1823 intptr_t line, column; | 1908 intptr_t line, column; |
1824 script.GetTokenLocation(token_pos, &line, &column); | 1909 script.GetTokenLocation(token_pos, &line, &column); |
1825 String& line_string = String::Handle(script.GetLine(line)); | 1910 String& line_string = String::Handle(script.GetLine(line)); |
1826 OS::Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); | 1911 OS::Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); |
1827 OS::Print(" Line %"Pd": '%s'\n", line, line_string.ToCString()); | 1912 OS::Print(" Line %"Pd": '%s'\n", line, line_string.ToCString()); |
1828 } | 1913 } |
1829 } | 1914 } |
1830 | 1915 |
1831 | 1916 |
1832 } // namespace dart | 1917 } // namespace dart |
OLD | NEW |