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

Side by Side Diff: runtime/vm/code_generator.cc

Issue 11316343: Support call operator in the vm. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years 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
« no previous file with comments | « runtime/vm/code_generator.h ('k') | runtime/vm/dart_entry.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/code_generator.h ('k') | runtime/vm/dart_entry.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698