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 1121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1132 } | 1132 } |
1133 } | 1133 } |
1134 const Code& code = Code::Handle(function.CurrentCode()); | 1134 const Code& code = Code::Handle(function.CurrentCode()); |
1135 ASSERT(!code.IsNull()); | 1135 ASSERT(!code.IsNull()); |
1136 const Instructions& instrs = Instructions::Handle(code.instructions()); | 1136 const Instructions& instrs = Instructions::Handle(code.instructions()); |
1137 ASSERT(!instrs.IsNull()); | 1137 ASSERT(!instrs.IsNull()); |
1138 return instrs.raw(); | 1138 return instrs.raw(); |
1139 } | 1139 } |
1140 | 1140 |
1141 | 1141 |
| 1142 static RawObject* InvokeNoSuchMethod(const Instance& receiver, |
| 1143 const String& target_name, |
| 1144 const Array& arguments_descriptor, |
| 1145 const Array& arguments) { |
| 1146 // Allocate an InvocationMirror object. |
| 1147 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| 1148 const String& invocation_mirror_name = |
| 1149 String::Handle(Symbols::InvocationMirror()); |
| 1150 Class& invocation_mirror_class = |
| 1151 Class::Handle(core_lib.LookupClassAllowPrivate(invocation_mirror_name)); |
| 1152 ASSERT(!invocation_mirror_class.IsNull()); |
| 1153 const String& allocation_function_name = |
| 1154 String::Handle(Symbols::AllocateInvocationMirror()); |
| 1155 const Function& allocation_function = Function::Handle( |
| 1156 Resolver::ResolveStaticByName(invocation_mirror_class, |
| 1157 allocation_function_name, |
| 1158 Resolver::kIsQualified)); |
| 1159 ASSERT(!allocation_function.IsNull()); |
| 1160 GrowableArray<const Object*> allocation_arguments(3); |
| 1161 allocation_arguments.Add(&target_name); |
| 1162 allocation_arguments.Add(&arguments_descriptor); |
| 1163 allocation_arguments.Add(&arguments); |
| 1164 const Array& kNoArgumentNames = Array::Handle(); |
| 1165 const Object& invocation_mirror = |
| 1166 Object::Handle(DartEntry::InvokeStatic(allocation_function, |
| 1167 allocation_arguments, |
| 1168 kNoArgumentNames)); |
| 1169 |
| 1170 const String& function_name = String::Handle(Symbols::NoSuchMethod()); |
| 1171 const int kNumArguments = 2; |
| 1172 const int kNumNamedArguments = 0; |
| 1173 const Function& function = Function::Handle( |
| 1174 Resolver::ResolveDynamic(receiver, |
| 1175 function_name, |
| 1176 kNumArguments, |
| 1177 kNumNamedArguments)); |
| 1178 ASSERT(!function.IsNull()); |
| 1179 GrowableArray<const Object*> invoke_arguments(1); |
| 1180 invoke_arguments.Add(&invocation_mirror); |
| 1181 const Object& result = |
| 1182 Object::Handle(DartEntry::InvokeDynamic(receiver, |
| 1183 function, |
| 1184 invoke_arguments, |
| 1185 kNoArgumentNames)); |
| 1186 CheckResultError(result); |
| 1187 return result.raw(); |
| 1188 } |
| 1189 |
| 1190 |
1142 static RawObject* InvokeClosure(const Instance& closure, | 1191 static RawObject* InvokeClosure(const Instance& closure, |
1143 const Array& arguments_descriptor, | 1192 const Array& arguments_descriptor, |
1144 const Array& arguments) { | 1193 const Array& arguments) { |
1145 const Function& function = Function::Handle(Closure::function(closure)); | 1194 const Function& function = Function::Handle(Closure::function(closure)); |
1146 ASSERT(!function.IsNull()); | 1195 ASSERT(!function.IsNull()); |
1147 const Instructions& instrs = Instructions::Handle(EnsureCompiled(function)); | 1196 const Instructions& instrs = Instructions::Handle(EnsureCompiled(function)); |
1148 const Context& context = Context::Handle(Closure::context(closure)); | 1197 const Context& context = Context::Handle(Closure::context(closure)); |
1149 | 1198 |
1150 // The closure object is passed as implicit first argument to closure | 1199 // The closure object is passed as implicit first argument to closure |
1151 // functions, since it may be needed to throw a NoSuchMethodError, in case | 1200 // functions, since it may be needed to throw a NoSuchMethodError, in case |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1204 arguments_descriptor, | 1253 arguments_descriptor, |
1205 invoke_arguments.data(), | 1254 invoke_arguments.data(), |
1206 context)); | 1255 context)); |
1207 CheckResultError(result); | 1256 CheckResultError(result); |
1208 return result.raw(); | 1257 return result.raw(); |
1209 } | 1258 } |
1210 | 1259 |
1211 current_class = current_class.SuperClass(); | 1260 current_class = current_class.SuperClass(); |
1212 } while (!current_class.IsNull()); | 1261 } while (!current_class.IsNull()); |
1213 | 1262 |
1214 const Object& null_object = Object::Handle(); | 1263 // There is no 'call' method, so invoke noSuchMethod. |
1215 GrowableArray<const Object*> dart_arguments(5); | 1264 return InvokeNoSuchMethod(receiver, |
1216 dart_arguments.Add(&receiver); | 1265 call_symbol, |
1217 dart_arguments.Add(&call_symbol); | 1266 arguments_descriptor, |
1218 dart_arguments.Add(&arguments); | 1267 arguments); |
1219 dart_arguments.Add(&null_object); // TODO(regis): Provide names. | |
1220 // If a function "call" with different arguments exists, it will have been | |
1221 // invoked above, so no need to handle this case here. | |
1222 Exceptions::ThrowByType(Exceptions::kNoSuchMethod, dart_arguments); | |
1223 UNREACHABLE(); | |
1224 return Object::null(); | |
1225 } | 1268 } |
1226 | 1269 |
1227 | 1270 |
1228 // An instance call of the form o.f(...) could not be resolved. Check if | 1271 // An instance call of the form o.f(...) could not be resolved. Check if |
1229 // there is a getter with the same name. If so, invoke it. If the value is | 1272 // there is a getter with the same name. If so, invoke it. If the value is |
1230 // a closure, invoke it with the given arguments. If the value is a | 1273 // a closure, invoke it with the given arguments. If the value is a |
1231 // non-closure, attempt to invoke "call" on it. | 1274 // non-closure, attempt to invoke "call" on it. |
1232 static bool ResolveCallThroughGetter(const Instance& receiver, | 1275 static bool ResolveCallThroughGetter(const Instance& receiver, |
1233 const Class& receiver_class, | 1276 const Class& receiver_class, |
1234 const String& target_name, | 1277 const String& target_name, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1275 } else { | 1318 } else { |
1276 *result = InvokeNonClosure(instance, | 1319 *result = InvokeNonClosure(instance, |
1277 instance_class, | 1320 instance_class, |
1278 arguments_descriptor, | 1321 arguments_descriptor, |
1279 arguments); | 1322 arguments); |
1280 } | 1323 } |
1281 return true; | 1324 return true; |
1282 } | 1325 } |
1283 | 1326 |
1284 | 1327 |
1285 static RawObject* InvokeNoSuchMethod(const Instance& receiver, | |
1286 const String& target_name, | |
1287 const Array& arguments_descriptor, | |
1288 const Array& arguments) { | |
1289 // Allocate an InvocationMirror object. | |
1290 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | |
1291 const String& invocation_mirror_name = | |
1292 String::Handle(Symbols::InvocationMirror()); | |
1293 Class& invocation_mirror_class = | |
1294 Class::Handle(core_lib.LookupClassAllowPrivate(invocation_mirror_name)); | |
1295 ASSERT(!invocation_mirror_class.IsNull()); | |
1296 const String& allocation_function_name = | |
1297 String::Handle(Symbols::AllocateInvocationMirror()); | |
1298 const Function& allocation_function = Function::Handle( | |
1299 Resolver::ResolveStaticByName(invocation_mirror_class, | |
1300 allocation_function_name, | |
1301 Resolver::kIsQualified)); | |
1302 ASSERT(!allocation_function.IsNull()); | |
1303 GrowableArray<const Object*> allocation_arguments(3); | |
1304 allocation_arguments.Add(&target_name); | |
1305 allocation_arguments.Add(&arguments_descriptor); | |
1306 allocation_arguments.Add(&arguments); | |
1307 const Array& kNoArgumentNames = Array::Handle(); | |
1308 const Object& invocation_mirror = | |
1309 Object::Handle(DartEntry::InvokeStatic(allocation_function, | |
1310 allocation_arguments, | |
1311 kNoArgumentNames)); | |
1312 | |
1313 const String& function_name = String::Handle(Symbols::NoSuchMethod()); | |
1314 const int kNumArguments = 2; | |
1315 const int kNumNamedArguments = 0; | |
1316 const Function& function = Function::Handle( | |
1317 Resolver::ResolveDynamic(receiver, | |
1318 function_name, | |
1319 kNumArguments, | |
1320 kNumNamedArguments)); | |
1321 ASSERT(!function.IsNull()); | |
1322 GrowableArray<const Object*> invoke_arguments(1); | |
1323 invoke_arguments.Add(&invocation_mirror); | |
1324 const Object& result = | |
1325 Object::Handle(DartEntry::InvokeDynamic(receiver, | |
1326 function, | |
1327 invoke_arguments, | |
1328 kNoArgumentNames)); | |
1329 CheckResultError(result); | |
1330 return result.raw(); | |
1331 } | |
1332 | |
1333 | |
1334 // Invoke appropriate noSuchMethod function. | 1328 // Invoke appropriate noSuchMethod function. |
1335 // Arg0: receiver. | 1329 // Arg0: receiver. |
1336 // Arg1: ic-data. | 1330 // Arg1: ic-data. |
1337 // Arg2: arguments descriptor array. | 1331 // Arg2: arguments descriptor array. |
1338 // Arg3: arguments array. | 1332 // Arg3: arguments array. |
1339 DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodFunction, 4) { | 1333 DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodFunction, 4) { |
1340 ASSERT(arguments.ArgCount() == | 1334 ASSERT(arguments.ArgCount() == |
1341 kInvokeNoSuchMethodFunctionRuntimeEntry.argument_count()); | 1335 kInvokeNoSuchMethodFunctionRuntimeEntry.argument_count()); |
1342 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 1336 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
1343 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); | 1337 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1955 return; | 1949 return; |
1956 } | 1950 } |
1957 HeapTrace* heap_trace = Isolate::Current()->heap()->trace(); | 1951 HeapTrace* heap_trace = Isolate::Current()->heap()->trace(); |
1958 heap_trace->TraceStoreIntoObject(RawObject::ToAddr(object), | 1952 heap_trace->TraceStoreIntoObject(RawObject::ToAddr(object), |
1959 field_addr, | 1953 field_addr, |
1960 RawObject::ToAddr(value)); | 1954 RawObject::ToAddr(value)); |
1961 } | 1955 } |
1962 END_LEAF_RUNTIME_ENTRY | 1956 END_LEAF_RUNTIME_ENTRY |
1963 | 1957 |
1964 } // namespace dart | 1958 } // namespace dart |
OLD | NEW |