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

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

Issue 11523002: Pass the proper invocation mirror argument to noSuchMethod. (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/bootstrap_natives.h ('k') | runtime/vm/flow_graph_builder.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 1166 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 const String& original_function_name = String::Handle(ic_data.target_name()); 1177 const String& original_function_name = String::Handle(ic_data.target_name());
1178 const int kNumArguments = 1; 1178 const int kNumArguments = 1;
1179 const int kNumNamedArguments = 0; 1179 const int kNumNamedArguments = 0;
1180 const String& getter_function_name = 1180 const String& getter_function_name =
1181 String::Handle(Field::GetterName(original_function_name)); 1181 String::Handle(Field::GetterName(original_function_name));
1182 Function& function = Function::ZoneHandle( 1182 Function& function = Function::ZoneHandle(
1183 Resolver::ResolveDynamic(receiver, 1183 Resolver::ResolveDynamic(receiver,
1184 getter_function_name, 1184 getter_function_name,
1185 kNumArguments, 1185 kNumArguments,
1186 kNumNamedArguments)); 1186 kNumNamedArguments));
1187 Code& code = Code::Handle(); 1187 const Object& null_object = Object::Handle();
1188 if (function.IsNull()) { 1188 if (function.IsNull()) {
1189 arguments.SetReturn(code); 1189 arguments.SetReturn(null_object);
1190 return; // No getter function found so can't be an implicit closure. 1190 return; // No getter function found so can't be an implicit closure.
1191 } 1191 }
1192 GrowableArray<const Object*> invoke_arguments(0); 1192 GrowableArray<const Object*> invoke_arguments(0);
1193 const Array& kNoArgumentNames = Array::Handle(); 1193 const Array& kNoArgumentNames = Array::Handle();
1194 const Object& result = 1194 const Object& result =
1195 Object::Handle(DartEntry::InvokeDynamic(receiver, 1195 Object::Handle(DartEntry::InvokeDynamic(receiver,
1196 function, 1196 function,
1197 invoke_arguments, 1197 invoke_arguments,
1198 kNoArgumentNames)); 1198 kNoArgumentNames));
1199 if (result.IsError()) { 1199 if (result.IsError()) {
1200 if (result.IsUnhandledException()) { 1200 if (result.IsUnhandledException()) {
1201 // If the getter throws an exception, treat as no such method. 1201 // If the getter throws an exception, treat as no such method.
1202 arguments.SetReturn(code); 1202 arguments.SetReturn(null_object);
1203 return; 1203 return;
1204 } else { 1204 } else {
1205 Exceptions::PropagateError(Error::Cast(result)); 1205 Exceptions::PropagateError(Error::Cast(result));
1206 } 1206 }
1207 } 1207 }
1208 if (!result.IsSmi()) { 1208 if (!result.IsSmi()) {
1209 const Class& cls = Class::Handle(result.clazz()); 1209 const Class& cls = Class::Handle(result.clazz());
1210 ASSERT(!cls.IsNull()); 1210 ASSERT(!cls.IsNull());
1211 function = cls.signature_function(); 1211 function = cls.signature_function();
1212 if (!function.IsNull()) { 1212 if (!function.IsNull()) {
1213 arguments.SetReturn(result); 1213 arguments.SetReturn(result);
1214 return; // Return closure object. 1214 return; // Return closure object.
1215 } 1215 }
1216 } 1216 }
1217 // The result instance is not a closure, try to invoke method "call" before 1217 // The result instance is not a closure, try to invoke method "call" before
1218 // throwing a NoSuchMethodError. 1218 // throwing a NoSuchMethodError.
1219 1219
1220 // TODO(regis): Factorize the following code. 1220 // TODO(regis): Factorize the following code.
1221 1221
1222 // TODO(regis): Args should be passed. 1222 // TODO(regis): Args should be passed.
1223 const Array& function_args = Array::Handle(); 1223 const Array& function_args = Array::Handle();
1224 const String& function_name = String::Handle(Symbols::Call()); 1224 const String& function_name = String::Handle(Symbols::Call());
1225 GrowableArray<const Object*> dart_arguments(5); 1225 GrowableArray<const Object*> dart_arguments(5);
1226 1226
1227 // TODO(regis): Resolve and invoke "call" method, if existing. 1227 // TODO(regis): Resolve and invoke "call" method, if existing.
1228 1228
1229 const Object& null_object = Object::Handle();
1230 dart_arguments.Add(&result); 1229 dart_arguments.Add(&result);
1231 dart_arguments.Add(&function_name); 1230 dart_arguments.Add(&function_name);
1232 dart_arguments.Add(&function_args); 1231 dart_arguments.Add(&function_args);
1233 dart_arguments.Add(&null_object); 1232 dart_arguments.Add(&null_object);
1234 1233
1235 // Report if a function "call" with different arguments has been found. 1234 // Report if a function "call" with different arguments has been found.
1236 { 1235 {
1237 Class& instance_class = Class::Handle(result.clazz()); 1236 Class& instance_class = Class::Handle(result.clazz());
1238 Function& function = 1237 Function& function =
1239 Function::Handle(instance_class.LookupDynamicFunction(function_name)); 1238 Function::Handle(instance_class.LookupDynamicFunction(function_name));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1274 if (!error.IsNull()) { 1273 if (!error.IsNull()) {
1275 Exceptions::PropagateError(error); 1274 Exceptions::PropagateError(error);
1276 } 1275 }
1277 } 1276 }
1278 const Context& context = Context::Handle(Closure::context(closure)); 1277 const Context& context = Context::Handle(Closure::context(closure));
1279 const Code& code = Code::Handle(function.CurrentCode()); 1278 const Code& code = Code::Handle(function.CurrentCode());
1280 ASSERT(!code.IsNull()); 1279 ASSERT(!code.IsNull());
1281 const Instructions& instrs = Instructions::Handle(code.instructions()); 1280 const Instructions& instrs = Instructions::Handle(code.instructions());
1282 ASSERT(!instrs.IsNull()); 1281 ASSERT(!instrs.IsNull());
1283 1282
1284 // Receiver parameter has already been skipped by caller.
1285 // The closure object is passed as implicit first argument to closure 1283 // The closure object is passed as implicit first argument to closure
1286 // 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
1287 // the wrong number of arguments is passed. 1285 // the wrong number of arguments is passed.
1288 GrowableArray<const Object*> invoke_arguments(func_arguments.Length() + 1); 1286 // Replace the original receiver in the arguments array by the closure.
1287 GrowableArray<const Object*> invoke_arguments(func_arguments.Length());
1289 invoke_arguments.Add(&closure); 1288 invoke_arguments.Add(&closure);
1290 for (intptr_t i = 0; i < func_arguments.Length(); i++) { 1289 for (intptr_t i = 1; i < func_arguments.Length(); i++) {
1291 const Object& value = Object::Handle(func_arguments.At(i)); 1290 const Object& value = Object::Handle(func_arguments.At(i));
1292 invoke_arguments.Add(&value); 1291 invoke_arguments.Add(&value);
1293 } 1292 }
1294 1293
1295 // Now Call the invoke stub which will invoke the closure. 1294 // Now Call the invoke stub which will invoke the closure.
1296 DartEntry::invokestub entrypoint = reinterpret_cast<DartEntry::invokestub>( 1295 DartEntry::invokestub entrypoint = reinterpret_cast<DartEntry::invokestub>(
1297 StubCode::InvokeDartCodeEntryPoint()); 1296 StubCode::InvokeDartCodeEntryPoint());
1298 ASSERT(context.isolate() == Isolate::Current()); 1297 ASSERT(context.isolate() == Isolate::Current());
1299 const Object& result = Object::Handle( 1298 const Object& result = Object::Handle(
1300 entrypoint(instrs.EntryPoint(), 1299 entrypoint(instrs.EntryPoint(),
1301 arg_descriptor, 1300 arg_descriptor,
1302 invoke_arguments.data(), 1301 invoke_arguments.data(),
1303 context)); 1302 context));
1304 CheckResultError(result); 1303 CheckResultError(result);
1305 arguments.SetReturn(result); 1304 arguments.SetReturn(result);
1306 } 1305 }
1307 1306
1308 1307
1309 // Invoke appropriate noSuchMethod function. 1308 // Invoke appropriate noSuchMethod function.
1310 // Arg0: receiver. 1309 // Arg0: receiver.
1311 // Arg1: ic-data. 1310 // Arg1: ic-data.
1312 // Arg2: original arguments descriptor array. 1311 // Arg2: original arguments descriptor array.
1313 // Arg3: original arguments array. 1312 // Arg3: original arguments array.
1314 DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodFunction, 4) { 1313 DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodFunction, 4) {
1315 ASSERT(arguments.ArgCount() == 1314 ASSERT(arguments.ArgCount() ==
1316 kInvokeNoSuchMethodFunctionRuntimeEntry.argument_count()); 1315 kInvokeNoSuchMethodFunctionRuntimeEntry.argument_count());
1317 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); 1316 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0));
1318 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); 1317 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1));
1319 const String& original_function_name = String::Handle(ic_data.target_name()); 1318 const String& original_function_name = String::Handle(ic_data.target_name());
1320 ASSERT(!Array::CheckedHandle(arguments.ArgAt(2)).IsNull()); 1319 const Array& orig_arguments_desc = Array::CheckedHandle(arguments.ArgAt(2));
1321 const Array& orig_arguments = Array::CheckedHandle(arguments.ArgAt(3)); 1320 const Array& orig_arguments = Array::CheckedHandle(arguments.ArgAt(3));
1322 // Allocate an InvocationMirror object. 1321 // Allocate an InvocationMirror object.
1323 // TODO(regis): Fill in the InvocationMirror object correctly at
1324 // this point we do not deal with named arguments and treat them
1325 // all as positional.
1326 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 1322 const Library& core_lib = Library::Handle(Library::CoreLibrary());
1327 const String& invocation_mirror_name = String::Handle( 1323 const String& invocation_mirror_name = String::Handle(
1328 Symbols::InvocationMirror()); 1324 Symbols::InvocationMirror());
1329 Class& invocation_mirror_class = Class::Handle( 1325 Class& invocation_mirror_class = Class::Handle(
1330 core_lib.LookupClassAllowPrivate(invocation_mirror_name)); 1326 core_lib.LookupClassAllowPrivate(invocation_mirror_name));
1331 ASSERT(!invocation_mirror_class.IsNull()); 1327 ASSERT(!invocation_mirror_class.IsNull());
1332 const String& allocation_function_name = String::Handle( 1328 const String& allocation_function_name = String::Handle(
1333 Symbols::AllocateInvocationMirror()); 1329 Symbols::AllocateInvocationMirror());
1334 const Function& allocation_function = Function::ZoneHandle( 1330 const Function& allocation_function = Function::ZoneHandle(
1335 Resolver::ResolveStaticByName(invocation_mirror_class, 1331 Resolver::ResolveStaticByName(invocation_mirror_class,
1336 allocation_function_name, 1332 allocation_function_name,
1337 Resolver::kIsQualified)); 1333 Resolver::kIsQualified));
1338 ASSERT(!allocation_function.IsNull()); 1334 ASSERT(!allocation_function.IsNull());
1339 GrowableArray<const Object*> allocation_arguments(2); 1335 GrowableArray<const Object*> allocation_arguments(3);
1340 allocation_arguments.Add(&original_function_name); 1336 allocation_arguments.Add(&original_function_name);
1337 allocation_arguments.Add(&orig_arguments_desc);
1341 allocation_arguments.Add(&orig_arguments); 1338 allocation_arguments.Add(&orig_arguments);
1342 const Array& kNoArgumentNames = Array::Handle(); 1339 const Array& kNoArgumentNames = Array::Handle();
1343 const Object& invocation_mirror = Object::Handle( 1340 const Object& invocation_mirror = Object::Handle(
1344 DartEntry::InvokeStatic(allocation_function, 1341 DartEntry::InvokeStatic(allocation_function,
1345 allocation_arguments, 1342 allocation_arguments,
1346 kNoArgumentNames)); 1343 kNoArgumentNames));
1347 1344
1348 const int kNumArguments = 2; 1345 const int kNumArguments = 2;
1349 const int kNumNamedArguments = 0; 1346 const int kNumNamedArguments = 0;
1350 const String& function_name = String::Handle(Symbols::NoSuchMethod()); 1347 const String& function_name = String::Handle(Symbols::NoSuchMethod());
(...skipping 11 matching lines...) Expand all
1362 invoke_arguments, 1359 invoke_arguments,
1363 kNoArgumentNames)); 1360 kNoArgumentNames));
1364 CheckResultError(result); 1361 CheckResultError(result);
1365 arguments.SetReturn(result); 1362 arguments.SetReturn(result);
1366 } 1363 }
1367 1364
1368 1365
1369 // 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
1370 // on it. 1367 // on it.
1371 // Arg0: non-closure object. 1368 // Arg0: non-closure object.
1372 // Arg1: arguments array. 1369 // Arg1: arguments array, including non-closure object.
1373 // TODO(regis): Rename this entry? 1370 // TODO(regis): Rename this entry?
1374 DEFINE_RUNTIME_ENTRY(ReportObjectNotClosure, 2) { 1371 DEFINE_RUNTIME_ENTRY(ReportObjectNotClosure, 2) {
1375 ASSERT(arguments.ArgCount() == 1372 ASSERT(arguments.ArgCount() ==
1376 kReportObjectNotClosureRuntimeEntry.argument_count()); 1373 kReportObjectNotClosureRuntimeEntry.argument_count());
1377 const Instance& instance = Instance::CheckedHandle(arguments.ArgAt(0)); 1374 const Instance& instance = Instance::CheckedHandle(arguments.ArgAt(0));
1378 const Array& function_args = Array::CheckedHandle(arguments.ArgAt(1)); 1375 const Array& function_args = Array::CheckedHandle(arguments.ArgAt(1));
1379 const String& function_name = String::Handle(Symbols::Call()); 1376 const String& function_name = String::Handle(Symbols::Call());
1380 GrowableArray<const Object*> dart_arguments(5); 1377 GrowableArray<const Object*> dart_arguments(5);
1381 1378
1382 // TODO(regis): Resolve and invoke "call" method, if existing. 1379 // TODO(regis): Resolve and invoke "call" method, if existing.
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
1926 Isolate* isolate = Isolate::Current(); 1923 Isolate* isolate = Isolate::Current();
1927 StackZone zone(isolate); 1924 StackZone zone(isolate);
1928 HANDLESCOPE(isolate); 1925 HANDLESCOPE(isolate);
1929 const Bigint& big_left = Bigint::Handle(left); 1926 const Bigint& big_left = Bigint::Handle(left);
1930 const Bigint& big_right = Bigint::Handle(right); 1927 const Bigint& big_right = Bigint::Handle(right);
1931 return BigintOperations::Compare(big_left, big_right); 1928 return BigintOperations::Compare(big_left, big_right);
1932 } 1929 }
1933 END_LEAF_RUNTIME_ENTRY 1930 END_LEAF_RUNTIME_ENTRY
1934 1931
1935 } // namespace dart 1932 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/bootstrap_natives.h ('k') | runtime/vm/flow_graph_builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698