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 1106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1117 Instance::Handle(Closure::New(closure_function, context)); | 1117 Instance::Handle(Closure::New(closure_function, context)); |
1118 if (receiver_class.HasTypeArguments()) { | 1118 if (receiver_class.HasTypeArguments()) { |
1119 const AbstractTypeArguments& type_arguments = | 1119 const AbstractTypeArguments& type_arguments = |
1120 AbstractTypeArguments::Handle(receiver.GetTypeArguments()); | 1120 AbstractTypeArguments::Handle(receiver.GetTypeArguments()); |
1121 closure.SetTypeArguments(type_arguments); | 1121 closure.SetTypeArguments(type_arguments); |
1122 } | 1122 } |
1123 return closure.raw(); | 1123 return closure.raw(); |
1124 } | 1124 } |
1125 | 1125 |
1126 | 1126 |
1127 static RawInstructions* EnsureCompiled(const Function& function) { | |
1128 if (!function.HasCode()) { | |
1129 const Error& error = Error::Handle(Compiler::CompileFunction(function)); | |
1130 if (!error.IsNull()) { | |
1131 Exceptions::PropagateError(error); | |
1132 } | |
1133 } | |
1134 const Code& code = Code::Handle(function.CurrentCode()); | |
1135 ASSERT(!code.IsNull()); | |
1136 const Instructions& instrs = Instructions::Handle(code.instructions()); | |
1137 ASSERT(!instrs.IsNull()); | |
1138 return instrs.raw(); | |
1139 } | |
1140 | |
1141 | |
1142 static RawObject* InvokeNoSuchMethod(const Instance& receiver, | 1127 static RawObject* InvokeNoSuchMethod(const Instance& receiver, |
1143 const String& target_name, | 1128 const String& target_name, |
1144 const Array& arguments_descriptor, | 1129 const Array& arguments_descriptor, |
1145 const Array& arguments) { | 1130 const Array& arguments) { |
1146 // Allocate an InvocationMirror object. | 1131 // Allocate an InvocationMirror object. |
1147 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 1132 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
1148 const String& invocation_mirror_name = | 1133 const String& invocation_mirror_name = |
1149 String::Handle(Symbols::InvocationMirror()); | 1134 String::Handle(Symbols::InvocationMirror()); |
1150 Class& invocation_mirror_class = | 1135 Class& invocation_mirror_class = |
1151 Class::Handle(core_lib.LookupClassAllowPrivate(invocation_mirror_name)); | 1136 Class::Handle(core_lib.LookupClassAllowPrivate(invocation_mirror_name)); |
1152 ASSERT(!invocation_mirror_class.IsNull()); | 1137 ASSERT(!invocation_mirror_class.IsNull()); |
1153 const String& allocation_function_name = | 1138 const String& allocation_function_name = |
1154 String::Handle(Symbols::AllocateInvocationMirror()); | 1139 String::Handle(Symbols::AllocateInvocationMirror()); |
1155 const Function& allocation_function = Function::Handle( | 1140 const Function& allocation_function = Function::Handle( |
1156 Resolver::ResolveStaticByName(invocation_mirror_class, | 1141 Resolver::ResolveStaticByName(invocation_mirror_class, |
1157 allocation_function_name, | 1142 allocation_function_name, |
1158 Resolver::kIsQualified)); | 1143 Resolver::kIsQualified)); |
1159 ASSERT(!allocation_function.IsNull()); | 1144 ASSERT(!allocation_function.IsNull()); |
1160 GrowableArray<const Object*> allocation_arguments(3); | 1145 const int kNumAllocationArgs = 3; |
1161 allocation_arguments.Add(&target_name); | 1146 const Array& allocation_args = Array::Handle(Array::New(kNumAllocationArgs)); |
1162 allocation_arguments.Add(&arguments_descriptor); | 1147 allocation_args.SetAt(0, target_name); |
1163 allocation_arguments.Add(&arguments); | 1148 allocation_args.SetAt(1, arguments_descriptor); |
1164 const Array& kNoArgumentNames = Array::Handle(); | 1149 allocation_args.SetAt(2, arguments); |
1165 const Object& invocation_mirror = | 1150 const Object& invocation_mirror = |
1166 Object::Handle(DartEntry::InvokeStatic(allocation_function, | 1151 Object::Handle(DartEntry::InvokeStatic(allocation_function, |
1167 allocation_arguments, | 1152 allocation_args)); |
1168 kNoArgumentNames)); | |
1169 | 1153 |
| 1154 // Now use the invocation mirror object and invoke NoSuchMethod. |
1170 const String& function_name = String::Handle(Symbols::NoSuchMethod()); | 1155 const String& function_name = String::Handle(Symbols::NoSuchMethod()); |
1171 const int kNumArguments = 2; | 1156 const int kNumArguments = 2; |
1172 const int kNumNamedArguments = 0; | 1157 const int kNumNamedArguments = 0; |
1173 const Function& function = Function::Handle( | 1158 const Function& function = Function::Handle( |
1174 Resolver::ResolveDynamic(receiver, | 1159 Resolver::ResolveDynamic(receiver, |
1175 function_name, | 1160 function_name, |
1176 kNumArguments, | 1161 kNumArguments, |
1177 kNumNamedArguments)); | 1162 kNumNamedArguments)); |
1178 ASSERT(!function.IsNull()); | 1163 ASSERT(!function.IsNull()); |
1179 GrowableArray<const Object*> invoke_arguments(1); | 1164 const Array& args = Array::Handle(Array::New(kNumArguments)); |
1180 invoke_arguments.Add(&invocation_mirror); | 1165 args.SetAt(0, receiver); |
1181 const Object& result = | 1166 args.SetAt(1, invocation_mirror); |
1182 Object::Handle(DartEntry::InvokeDynamic(receiver, | 1167 const Object& result = Object::Handle(DartEntry::InvokeDynamic(function, |
1183 function, | 1168 args)); |
1184 invoke_arguments, | |
1185 kNoArgumentNames)); | |
1186 CheckResultError(result); | |
1187 return result.raw(); | |
1188 } | |
1189 | |
1190 | |
1191 static RawObject* InvokeClosure(const Instance& closure, | |
1192 const Array& arguments_descriptor, | |
1193 const Array& arguments) { | |
1194 const Function& function = Function::Handle(Closure::function(closure)); | |
1195 ASSERT(!function.IsNull()); | |
1196 const Instructions& instrs = Instructions::Handle(EnsureCompiled(function)); | |
1197 const Context& context = Context::Handle(Closure::context(closure)); | |
1198 | |
1199 // The closure object is passed as implicit first argument to closure | |
1200 // functions, since it may be needed to throw a NoSuchMethodError, in case | |
1201 // the wrong number of arguments is passed. | |
1202 // Replace the original receiver in the arguments array by the closure. | |
1203 GrowableArray<const Object*> invoke_arguments(arguments.Length()); | |
1204 invoke_arguments.Add(&closure); | |
1205 for (intptr_t i = 1; i < arguments.Length(); i++) { | |
1206 const Object& value = Object::Handle(arguments.At(i)); | |
1207 invoke_arguments.Add(&value); | |
1208 } | |
1209 // Now call the invoke stub which will invoke the closure. | |
1210 DartEntry::invokestub entrypoint = reinterpret_cast<DartEntry::invokestub>( | |
1211 StubCode::InvokeDartCodeEntryPoint()); | |
1212 ASSERT(context.isolate() == Isolate::Current()); | |
1213 const Object& result = Object::Handle(entrypoint(instrs.EntryPoint(), | |
1214 arguments_descriptor, | |
1215 invoke_arguments.data(), | |
1216 context)); | |
1217 CheckResultError(result); | 1169 CheckResultError(result); |
1218 return result.raw(); | 1170 return result.raw(); |
1219 } | 1171 } |
1220 | 1172 |
1221 | 1173 |
1222 static RawObject* InvokeNonClosure(const Instance& receiver, | 1174 static RawObject* InvokeNonClosure(const Instance& receiver, |
1223 const Class& receiver_class, | 1175 const Class& receiver_class, |
1224 const Array& arguments_descriptor, | 1176 const Array& arguments_descriptor, |
1225 const Array& arguments) { | 1177 const Array& arguments) { |
1226 // Resolve and invoke the "call" method if it exists. | 1178 // Resolve and invoke the "call" method if it exists. |
1227 const String& call_symbol = String::Handle(Symbols::Call()); | 1179 const String& call_symbol = String::Handle(Symbols::Call()); |
1228 | 1180 |
1229 Class& current_class = Class::Handle(receiver_class.raw()); | 1181 Class& current_class = Class::Handle(receiver_class.raw()); |
1230 Function& call_function = Function::Handle(); | 1182 Function& call_function = Function::Handle(); |
1231 do { | 1183 do { |
1232 call_function = current_class.LookupDynamicFunction(call_symbol); | 1184 call_function = current_class.LookupDynamicFunction(call_symbol); |
1233 | 1185 |
1234 if (!call_function.IsNull()) { | 1186 if (!call_function.IsNull()) { |
1235 const Instructions& instrs = | |
1236 Instructions::Handle(EnsureCompiled(call_function)); | |
1237 // The non-closure object is passed as implicit first argument | 1187 // The non-closure object is passed as implicit first argument |
1238 // (receiver). It is already included in the arguments array. | 1188 // (receiver). It is already included in the arguments array. |
1239 GrowableArray<const Object*> invoke_arguments(arguments.Length()); | |
1240 for (intptr_t i = 0; i < arguments.Length(); i++) { | |
1241 const Object& value = Object::Handle(arguments.At(i)); | |
1242 invoke_arguments.Add(&value); | |
1243 } | |
1244 | 1189 |
1245 // Now call the invoke stub which will invoke the call method. | 1190 // Now call the invoke stub which will invoke the call method. |
1246 DartEntry::invokestub entrypoint = | |
1247 reinterpret_cast<DartEntry::invokestub>( | |
1248 StubCode::InvokeDartCodeEntryPoint()); | |
1249 const Context& context = Context::ZoneHandle( | |
1250 Isolate::Current()->object_store()->empty_context()); | |
1251 const Object& result = | 1191 const Object& result = |
1252 Object::Handle(entrypoint(instrs.EntryPoint(), | 1192 Object::Handle(DartEntry::InvokeDynamic(call_function, |
1253 arguments_descriptor, | 1193 arguments, |
1254 invoke_arguments.data(), | 1194 arguments_descriptor)); |
1255 context)); | |
1256 CheckResultError(result); | 1195 CheckResultError(result); |
1257 return result.raw(); | 1196 return result.raw(); |
1258 } | 1197 } |
1259 | 1198 |
1260 current_class = current_class.SuperClass(); | 1199 current_class = current_class.SuperClass(); |
1261 } while (!current_class.IsNull()); | 1200 } while (!current_class.IsNull()); |
1262 | 1201 |
1263 // There is no 'call' method, so invoke noSuchMethod. | 1202 // There is no 'call' method, so invoke noSuchMethod. |
1264 return InvokeNoSuchMethod(receiver, | 1203 return InvokeNoSuchMethod(receiver, |
1265 call_symbol, | 1204 call_symbol, |
(...skipping 17 matching lines...) Expand all Loading... |
1283 const int kNumArguments = 1; | 1222 const int kNumArguments = 1; |
1284 const int kNumNamedArguments = 0; | 1223 const int kNumNamedArguments = 0; |
1285 const Function& getter = Function::Handle( | 1224 const Function& getter = Function::Handle( |
1286 Resolver::ResolveDynamicForReceiverClass(receiver_class, | 1225 Resolver::ResolveDynamicForReceiverClass(receiver_class, |
1287 getter_name, | 1226 getter_name, |
1288 kNumArguments, | 1227 kNumArguments, |
1289 kNumNamedArguments)); | 1228 kNumNamedArguments)); |
1290 if (getter.IsNull()) return false; | 1229 if (getter.IsNull()) return false; |
1291 | 1230 |
1292 // 2. Invoke the getter. | 1231 // 2. Invoke the getter. |
1293 GrowableArray<const Object*> invoke_arguments(0); | 1232 const Array& args = Array::Handle(Array::New(kNumArguments)); |
1294 const Array& kNoArgumentNames = Array::Handle(); | 1233 args.SetAt(0, receiver); |
1295 const Object& value = | 1234 const Object& value = Object::Handle(DartEntry::InvokeDynamic(getter, args)); |
1296 Object::Handle(DartEntry::InvokeDynamic(receiver, | |
1297 getter, | |
1298 invoke_arguments, | |
1299 kNoArgumentNames)); | |
1300 | 1235 |
1301 // 3. If the getter threw an exception, treat it as no such method. | 1236 // 3. If the getter threw an exception, treat it as no such method. |
1302 if (value.IsUnhandledException()) return false; | 1237 if (value.IsUnhandledException()) return false; |
1303 | 1238 |
1304 // 4. If there was some other error, propagate it. | 1239 // 4. If there was some other error, propagate it. |
1305 if (value.IsError()) { | 1240 if (value.IsError()) { |
1306 Exceptions::PropagateError(Error::Cast(value)); | 1241 Exceptions::PropagateError(Error::Cast(value)); |
1307 } | 1242 } |
1308 | 1243 |
1309 // 5. If the value is a closure, invoke it and return the result. If it | 1244 // 5. If the value is a closure, invoke it and return the result. If it |
1310 // is a non-closure, invoke "call" on it and return the result. | 1245 // is a non-closure, invoke "call" on it and return the result. |
1311 Instance& instance = Instance::Handle(); | 1246 Instance& instance = Instance::Handle(); |
1312 instance ^= value.raw(); | 1247 instance ^= value.raw(); |
1313 const Class& instance_class = Class::Handle(instance.clazz()); | 1248 const Class& instance_class = Class::Handle(instance.clazz()); |
1314 ASSERT(!instance_class.IsNull()); | 1249 ASSERT(!instance_class.IsNull()); |
1315 // An object is a closure iff. its class has a non-null signature function. | 1250 // An object is a closure iff. its class has a non-null signature function. |
1316 if (instance_class.signature_function() != Function::null()) { | 1251 if (instance_class.signature_function() != Function::null()) { |
1317 *result = InvokeClosure(instance, arguments_descriptor, arguments); | 1252 // The closure object is passed as implicit first argument to closure |
| 1253 // functions, since it may be needed to throw a NoSuchMethodError, in case |
| 1254 // the wrong number of arguments is passed. |
| 1255 // Replace the original receiver in the arguments array by the closure. |
| 1256 arguments.SetAt(0, instance); |
| 1257 *result = DartEntry::InvokeClosure(instance, |
| 1258 arguments, |
| 1259 arguments_descriptor); |
| 1260 CheckResultError(*result); |
1318 } else { | 1261 } else { |
1319 *result = InvokeNonClosure(instance, | 1262 *result = InvokeNonClosure(instance, |
1320 instance_class, | 1263 instance_class, |
1321 arguments_descriptor, | 1264 arguments_descriptor, |
1322 arguments); | 1265 arguments); |
1323 } | 1266 } |
1324 return true; | 1267 return true; |
1325 } | 1268 } |
1326 | 1269 |
1327 | 1270 |
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1949 return; | 1892 return; |
1950 } | 1893 } |
1951 HeapTrace* heap_trace = Isolate::Current()->heap()->trace(); | 1894 HeapTrace* heap_trace = Isolate::Current()->heap()->trace(); |
1952 heap_trace->TraceStoreIntoObject(RawObject::ToAddr(object), | 1895 heap_trace->TraceStoreIntoObject(RawObject::ToAddr(object), |
1953 field_addr, | 1896 field_addr, |
1954 RawObject::ToAddr(value)); | 1897 RawObject::ToAddr(value)); |
1955 } | 1898 } |
1956 END_LEAF_RUNTIME_ENTRY | 1899 END_LEAF_RUNTIME_ENTRY |
1957 | 1900 |
1958 } // namespace dart | 1901 } // namespace dart |
OLD | NEW |