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 1166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |