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/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
10 #include "vm/code_patcher.h" | 10 #include "vm/code_patcher.h" |
(...skipping 1246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1257 | 1257 |
1258 | 1258 |
1259 // Invoke Implicit Closure function. | 1259 // Invoke Implicit Closure function. |
1260 // Arg0: closure object. | 1260 // Arg0: closure object. |
1261 // Arg1: arguments descriptor (originally passed as dart instance invocation). | 1261 // Arg1: arguments descriptor (originally passed as dart instance invocation). |
1262 // Arg2: arguments array (originally passed to dart instance invocation). | 1262 // Arg2: arguments array (originally passed to dart instance invocation). |
1263 DEFINE_RUNTIME_ENTRY(InvokeImplicitClosureFunction, 3) { | 1263 DEFINE_RUNTIME_ENTRY(InvokeImplicitClosureFunction, 3) { |
1264 ASSERT(arguments.ArgCount() == | 1264 ASSERT(arguments.ArgCount() == |
1265 kInvokeImplicitClosureFunctionRuntimeEntry.argument_count()); | 1265 kInvokeImplicitClosureFunctionRuntimeEntry.argument_count()); |
1266 const Instance& closure = Instance::CheckedHandle(arguments.ArgAt(0)); | 1266 const Instance& closure = Instance::CheckedHandle(arguments.ArgAt(0)); |
1267 const Array& arg_descriptor = Array::CheckedHandle(arguments.ArgAt(1)); | 1267 const Array& args_descriptor = Array::CheckedHandle(arguments.ArgAt(1)); |
1268 const Array& func_arguments = Array::CheckedHandle(arguments.ArgAt(2)); | 1268 const Array& func_arguments = Array::CheckedHandle(arguments.ArgAt(2)); |
1269 const Function& function = Function::Handle(Closure::function(closure)); | 1269 const Function& function = Function::Handle(Closure::function(closure)); |
1270 ASSERT(!function.IsNull()); | 1270 ASSERT(!function.IsNull()); |
1271 if (!function.HasCode()) { | 1271 if (!function.HasCode()) { |
1272 const Error& error = Error::Handle(Compiler::CompileFunction(function)); | 1272 const Error& error = Error::Handle(Compiler::CompileFunction(function)); |
1273 if (!error.IsNull()) { | 1273 if (!error.IsNull()) { |
1274 Exceptions::PropagateError(error); | 1274 Exceptions::PropagateError(error); |
1275 } | 1275 } |
1276 } | 1276 } |
1277 const Context& context = Context::Handle(Closure::context(closure)); | 1277 const Context& context = Context::Handle(Closure::context(closure)); |
1278 const Code& code = Code::Handle(function.CurrentCode()); | 1278 const Code& code = Code::Handle(function.CurrentCode()); |
1279 ASSERT(!code.IsNull()); | 1279 ASSERT(!code.IsNull()); |
1280 const Instructions& instrs = Instructions::Handle(code.instructions()); | 1280 const Instructions& instrs = Instructions::Handle(code.instructions()); |
1281 ASSERT(!instrs.IsNull()); | 1281 ASSERT(!instrs.IsNull()); |
1282 | 1282 |
1283 // The closure object is passed as implicit first argument to closure | 1283 // The closure object is passed as implicit first argument to closure |
1284 // functions, since it may be needed to throw a NoSuchMethodError, in case | 1284 // functions, since it may be needed to throw a NoSuchMethodError, in case |
1285 // the wrong number of arguments is passed. | 1285 // the wrong number of arguments is passed. |
1286 // Replace the original receiver in the arguments array by the closure. | 1286 // Replace the original receiver in the arguments array by the closure. |
1287 GrowableArray<const Object*> invoke_arguments(func_arguments.Length()); | 1287 GrowableArray<const Object*> invoke_arguments(func_arguments.Length()); |
1288 invoke_arguments.Add(&closure); | 1288 invoke_arguments.Add(&closure); |
1289 for (intptr_t i = 1; i < func_arguments.Length(); i++) { | 1289 for (intptr_t i = 1; i < func_arguments.Length(); i++) { |
1290 const Object& value = Object::Handle(func_arguments.At(i)); | 1290 const Object& value = Object::Handle(func_arguments.At(i)); |
1291 invoke_arguments.Add(&value); | 1291 invoke_arguments.Add(&value); |
1292 } | 1292 } |
1293 | 1293 |
1294 // Now Call the invoke stub which will invoke the closure. | 1294 // Now call the invoke stub which will invoke the closure. |
1295 DartEntry::invokestub entrypoint = reinterpret_cast<DartEntry::invokestub>( | 1295 DartEntry::invokestub entrypoint = reinterpret_cast<DartEntry::invokestub>( |
1296 StubCode::InvokeDartCodeEntryPoint()); | 1296 StubCode::InvokeDartCodeEntryPoint()); |
1297 ASSERT(context.isolate() == Isolate::Current()); | 1297 ASSERT(context.isolate() == Isolate::Current()); |
1298 const Object& result = Object::Handle( | 1298 const Object& result = Object::Handle( |
1299 entrypoint(instrs.EntryPoint(), | 1299 entrypoint(instrs.EntryPoint(), |
1300 arg_descriptor, | 1300 args_descriptor, |
1301 invoke_arguments.data(), | 1301 invoke_arguments.data(), |
1302 context)); | 1302 context)); |
1303 CheckResultError(result); | 1303 CheckResultError(result); |
1304 arguments.SetReturn(result); | 1304 arguments.SetReturn(result); |
1305 } | 1305 } |
1306 | 1306 |
1307 | 1307 |
1308 // Invoke appropriate noSuchMethod function. | 1308 // Invoke appropriate noSuchMethod function. |
1309 // Arg0: receiver. | 1309 // Arg0: receiver. |
1310 // Arg1: ic-data. | 1310 // Arg1: ic-data. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1359 invoke_arguments, | 1359 invoke_arguments, |
1360 kNoArgumentNames)); | 1360 kNoArgumentNames)); |
1361 CheckResultError(result); | 1361 CheckResultError(result); |
1362 arguments.SetReturn(result); | 1362 arguments.SetReturn(result); |
1363 } | 1363 } |
1364 | 1364 |
1365 | 1365 |
1366 // A non-closure object was invoked as a closure, so call the "call" method | 1366 // A non-closure object was invoked as a closure, so call the "call" method |
1367 // on it. | 1367 // on it. |
1368 // Arg0: non-closure object. | 1368 // Arg0: non-closure object. |
1369 // Arg1: arguments array, including non-closure object. | 1369 // Arg1: arguments descriptor. |
1370 // TODO(regis): Rename this entry? | 1370 // Arg2: arguments array, including non-closure object. |
1371 DEFINE_RUNTIME_ENTRY(ReportObjectNotClosure, 2) { | 1371 DEFINE_RUNTIME_ENTRY(InvokeNonClosure, 3) { |
1372 ASSERT(arguments.ArgCount() == | 1372 ASSERT(arguments.ArgCount() == |
1373 kReportObjectNotClosureRuntimeEntry.argument_count()); | 1373 kInvokeNonClosureRuntimeEntry.argument_count()); |
1374 const Instance& instance = Instance::CheckedHandle(arguments.ArgAt(0)); | 1374 const Instance& instance = Instance::CheckedHandle(arguments.ArgAt(0)); |
1375 const Array& function_args = Array::CheckedHandle(arguments.ArgAt(1)); | 1375 const Array& args_descriptor = Array::CheckedHandle(arguments.ArgAt(1)); |
| 1376 const Array& function_args = Array::CheckedHandle(arguments.ArgAt(2)); |
| 1377 |
| 1378 // Resolve and invoke "call" method, if existing. |
1376 const String& function_name = String::Handle(Symbols::Call()); | 1379 const String& function_name = String::Handle(Symbols::Call()); |
1377 GrowableArray<const Object*> dart_arguments(5); | |
1378 | |
1379 // TODO(regis): Resolve and invoke "call" method, if existing. | |
1380 | |
1381 const Object& null_object = Object::Handle(); | |
1382 dart_arguments.Add(&instance); | |
1383 dart_arguments.Add(&function_name); | |
1384 dart_arguments.Add(&function_args); | |
1385 dart_arguments.Add(&null_object); | |
1386 | |
1387 // Report if a function "call" with different arguments has been found. | |
1388 Class& instance_class = Class::Handle(instance.clazz()); | 1380 Class& instance_class = Class::Handle(instance.clazz()); |
1389 Function& function = | 1381 Function& function = |
1390 Function::Handle(instance_class.LookupDynamicFunction(function_name)); | 1382 Function::Handle(instance_class.LookupDynamicFunction(function_name)); |
1391 while (function.IsNull()) { | 1383 while (function.IsNull()) { |
1392 instance_class = instance_class.SuperClass(); | 1384 instance_class = instance_class.SuperClass(); |
1393 if (instance_class.IsNull()) break; | 1385 if (instance_class.IsNull()) break; |
1394 function = instance_class.LookupDynamicFunction(function_name); | 1386 function = instance_class.LookupDynamicFunction(function_name); |
1395 } | 1387 } |
1396 if (!function.IsNull()) { | 1388 if (!function.IsNull()) { |
1397 const int total_num_parameters = function.NumParameters(); | 1389 if (!function.HasCode()) { |
1398 const Array& array = Array::Handle(Array::New(total_num_parameters - 1)); | 1390 const Error& error = Error::Handle(Compiler::CompileFunction(function)); |
1399 // Skip receiver. | 1391 if (!error.IsNull()) { |
1400 for (int i = 1; i < total_num_parameters; i++) { | 1392 Exceptions::PropagateError(error); |
1401 array.SetAt(i - 1, String::Handle(function.ParameterNameAt(i))); | 1393 } |
1402 } | 1394 } |
1403 dart_arguments.Add(&array); | 1395 const Code& code = Code::Handle(function.CurrentCode()); |
| 1396 ASSERT(!code.IsNull()); |
| 1397 const Instructions& instrs = Instructions::Handle(code.instructions()); |
| 1398 ASSERT(!instrs.IsNull()); |
| 1399 |
| 1400 // The non-closure object is passed as implicit first argument (receiver). |
| 1401 // It is already included in the arguments array. |
| 1402 GrowableArray<const Object*> invoke_arguments(function_args.Length()); |
| 1403 for (intptr_t i = 0; i < function_args.Length(); i++) { |
| 1404 const Object& value = Object::Handle(function_args.At(i)); |
| 1405 invoke_arguments.Add(&value); |
| 1406 } |
| 1407 |
| 1408 // Now call the invoke stub which will invoke the call method. |
| 1409 DartEntry::invokestub entrypoint = reinterpret_cast<DartEntry::invokestub>( |
| 1410 StubCode::InvokeDartCodeEntryPoint()); |
| 1411 const Context& context = Context::ZoneHandle( |
| 1412 Isolate::Current()->object_store()->empty_context()); |
| 1413 const Object& result = Object::Handle( |
| 1414 entrypoint(instrs.EntryPoint(), |
| 1415 args_descriptor, |
| 1416 invoke_arguments.data(), |
| 1417 context)); |
| 1418 CheckResultError(result); |
| 1419 arguments.SetReturn(result); |
| 1420 return; |
1404 } | 1421 } |
| 1422 const Object& null_object = Object::Handle(); |
| 1423 GrowableArray<const Object*> dart_arguments(5); |
| 1424 dart_arguments.Add(&instance); |
| 1425 dart_arguments.Add(&function_name); |
| 1426 dart_arguments.Add(&function_args); |
| 1427 dart_arguments.Add(&null_object); |
| 1428 // If a function "call" with different arguments exists, it will have been |
| 1429 // invoked above, so no need to handle this case here. |
1405 Exceptions::ThrowByType(Exceptions::kNoSuchMethod, dart_arguments); | 1430 Exceptions::ThrowByType(Exceptions::kNoSuchMethod, dart_arguments); |
1406 UNREACHABLE(); | 1431 UNREACHABLE(); |
1407 } | 1432 } |
1408 | 1433 |
1409 | 1434 |
1410 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { | 1435 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { |
1411 ASSERT(arguments.ArgCount() == | 1436 ASSERT(arguments.ArgCount() == |
1412 kStackOverflowRuntimeEntry.argument_count()); | 1437 kStackOverflowRuntimeEntry.argument_count()); |
1413 uword stack_pos = reinterpret_cast<uword>(&arguments); | 1438 uword stack_pos = reinterpret_cast<uword>(&arguments); |
1414 | 1439 |
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1923 Isolate* isolate = Isolate::Current(); | 1948 Isolate* isolate = Isolate::Current(); |
1924 StackZone zone(isolate); | 1949 StackZone zone(isolate); |
1925 HANDLESCOPE(isolate); | 1950 HANDLESCOPE(isolate); |
1926 const Bigint& big_left = Bigint::Handle(left); | 1951 const Bigint& big_left = Bigint::Handle(left); |
1927 const Bigint& big_right = Bigint::Handle(right); | 1952 const Bigint& big_right = Bigint::Handle(right); |
1928 return BigintOperations::Compare(big_left, big_right); | 1953 return BigintOperations::Compare(big_left, big_right); |
1929 } | 1954 } |
1930 END_LEAF_RUNTIME_ENTRY | 1955 END_LEAF_RUNTIME_ENTRY |
1931 | 1956 |
1932 } // namespace dart | 1957 } // namespace dart |
OLD | NEW |