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

Side by Side Diff: pkg/fletchc/lib/src/codegen_visitor.dart

Issue 1450393002: Roll sdk dependency to 34357cdad108dcba734949bd13bd28c76ea285e0 (Closed) Base URL: git@github.com:dart-lang/fletch.git@master
Patch Set: Update status files Created 5 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
OLDNEW
1 // Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Fletch 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.md file. 3 // BSD-style license that can be found in the LICENSE.md file.
4 4
5 library fletchc.codegen_visitor; 5 library fletchc.codegen_visitor;
6 6
7 import 'package:compiler/src/resolution/semantic_visitor.dart'; 7 import 'package:compiler/src/resolution/semantic_visitor.dart';
8 8
9 import 'package:compiler/src/resolution/operators.dart' show 9 import 'package:compiler/src/resolution/operators.dart' show
10 AssignmentOperator, 10 AssignmentOperator,
11 BinaryOperator, 11 BinaryOperator,
12 IncDecOperator, 12 IncDecOperator,
13 UnaryOperator; 13 UnaryOperator;
14 14
15 import 'package:compiler/src/constants/expressions.dart' show 15 import 'package:compiler/src/constants/expressions.dart' show
16 BoolFromEnvironmentConstantExpression, 16 BoolFromEnvironmentConstantExpression,
17 IntFromEnvironmentConstantExpression, 17 IntFromEnvironmentConstantExpression,
18 StringFromEnvironmentConstantExpression, 18 StringFromEnvironmentConstantExpression,
19 ConstantExpression, 19 ConstantExpression,
20 ConstructedConstantExpression, 20 ConstructedConstantExpression,
21 TypeConstantExpression; 21 TypeConstantExpression;
22 22
23 import 'package:compiler/src/dart2jslib.dart' show 23 import 'package:compiler/src/resolution/tree_elements.dart' show
24 MessageKind, 24 TreeElements;
25 Registry;
26 25
27 import 'package:compiler/src/util/util.dart' show 26 import 'package:compiler/src/util/util.dart' show
28 Link; 27 Link;
29 28
29 import 'package:compiler/src/common/names.dart' show
30 Names,
31 Selectors;
32
33 import 'package:compiler/src/universe/use.dart' show DynamicUse, StaticUse;
34
30 import 'package:compiler/src/elements/elements.dart'; 35 import 'package:compiler/src/elements/elements.dart';
31 import 'package:compiler/src/resolution/resolution.dart';
32 import 'package:compiler/src/tree/tree.dart'; 36 import 'package:compiler/src/tree/tree.dart';
33 import 'package:compiler/src/universe/universe.dart'; 37 import 'package:compiler/src/universe/call_structure.dart' show
34 import 'package:compiler/src/util/util.dart' show Spannable; 38 CallStructure;
39 import 'package:compiler/src/universe/selector.dart' show
40 Selector;
41 import 'package:compiler/src/diagnostics/spannable.dart' show
42 Spannable;
35 import 'package:compiler/src/dart_types.dart'; 43 import 'package:compiler/src/dart_types.dart';
36 44
37 import 'fletch_context.dart'; 45 import 'fletch_context.dart';
38 46
39 import 'fletch_backend.dart'; 47 import 'fletch_backend.dart';
40 48
41 import 'fletch_constants.dart' show 49 import 'fletch_constants.dart' show
42 FletchFunctionBuilderConstant,
43 FletchClassConstant, 50 FletchClassConstant,
44 FletchClassInstanceConstant; 51 FletchClassInstanceConstant;
45 52
46 import 'fletch_function_builder.dart' show 53 import 'fletch_function_builder.dart' show
47 FletchFunctionBuilder; 54 FletchFunctionBuilder;
48 55
49 import 'fletch_class_builder.dart' show 56 import 'fletch_class_builder.dart' show
50 FletchClassBuilder; 57 FletchClassBuilder;
51 58
52 import 'fletch_selector.dart'; 59 import 'fletch_selector.dart';
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 BinaryBulkMixin, 210 BinaryBulkMixin,
204 PrefixBulkMixin, 211 PrefixBulkMixin,
205 PostfixBulkMixin, 212 PostfixBulkMixin,
206 NewBulkMixin, 213 NewBulkMixin,
207 VariableBulkMixin, 214 VariableBulkMixin,
208 ParameterBulkMixin, 215 ParameterBulkMixin,
209 FunctionBulkMixin, 216 FunctionBulkMixin,
210 ConstructorBulkMixin, 217 ConstructorBulkMixin,
211 InitializerBulkMixin, 218 InitializerBulkMixin,
212 BaseImplementationOfStaticsMixin, 219 BaseImplementationOfStaticsMixin,
213 BaseImplementationOfLocalsMixin 220 BaseImplementationOfLocalsMixin,
221 SetIfNullBulkMixin
214 implements SemanticSendVisitor, SemanticDeclarationVisitor { 222 implements SemanticSendVisitor, SemanticDeclarationVisitor {
215 // A literal int can have up to 31 bits of information (32 minus sign). 223 // A literal int can have up to 31 bits of information (32 minus sign).
216 static const int LITERAL_INT_MAX = 0x3FFFFFFF; 224 static const int LITERAL_INT_MAX = 0x3FFFFFFF;
217 static const int MAX_INT64 = (1 << 63) - 1; 225 static const int MAX_INT64 = (1 << 63) - 1;
218 static const int MIN_INT64 = -(1 << 63); 226 static const int MIN_INT64 = -(1 << 63);
219 227
220 final FletchContext context; 228 final FletchContext context;
221 229
222 final ClosureEnvironment closureEnvironment; 230 final ClosureEnvironment closureEnvironment;
223 231
224 final ExecutableElement element; 232 final ExecutableElement element;
225 233
226 final MemberElement member;
227
228 final FletchFunctionBuilder functionBuilder; 234 final FletchFunctionBuilder functionBuilder;
229 235
230 final Map<Element, LocalValue> scope = <Element, LocalValue>{}; 236 final Map<Element, LocalValue> scope = <Element, LocalValue>{};
231 237
232 final Map<Node, JumpInfo> jumpInfo = <Node, JumpInfo>{}; 238 final Map<Node, JumpInfo> jumpInfo = <Node, JumpInfo>{};
233 239
234 // Stack of try blocks (inner-most first), in the lexical scope. 240 // Stack of try blocks (inner-most first), in the lexical scope.
235 Link<TryBlock> tryBlockStack = const Link<TryBlock>(); 241 Link<TryBlock> tryBlockStack = const Link<TryBlock>();
236 242
237 VisitState visitState; 243 VisitState visitState;
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 } 366 }
361 367
362 void pushVariableDeclaration(LocalValue value) { 368 void pushVariableDeclaration(LocalValue value) {
363 scope[value.element] = value; 369 scope[value.element] = value;
364 } 370 }
365 371
366 void popVariableDeclaration(Element local) { 372 void popVariableDeclaration(Element local) {
367 scope.remove(local); 373 scope.remove(local);
368 } 374 }
369 375
370 void registerDynamicInvocation(Selector selector); 376 void registerDynamicUse(Selector selector);
371 377
372 void registerDynamicGetter(Selector selector); 378 void registerStaticUse(StaticUse use);
ahe 2015/12/01 10:12:12 StaticUse (like DynamicUse) is problematic to use
sigurdm 2015/12/03 14:48:09 Done.
373
374 void registerDynamicSetter(Selector selector);
375
376 void registerStaticInvocation(FunctionElement function);
377 379
378 void registerInstantiatedClass(ClassElement klass); 380 void registerInstantiatedClass(ClassElement klass);
379 381
380 void registerIsCheck(DartType type); 382 void registerIsCheck(DartType type);
381 383
382 void registerLocalInvoke(LocalElement element, Selector selector); 384 void registerLocalInvoke(LocalElement element, Selector selector);
383 385
384 /// Register that [element] is a closure. This can happen for a tear-off, or 386 /// Register that [element] is a closure. This can happen for a tear-off, or
385 /// for local functions. See [ClosureKind] for more information about the 387 /// for local functions. See [ClosureKind] for more information about the
386 /// various kinds of implicit or explicit closurizations that can occur. 388 /// various kinds of implicit or explicit closurizations that can occur.
387 void registerClosurization(FunctionElement element, ClosureKind kind); 389 void registerClosurization(FunctionElement element, ClosureKind kind);
388 390
389 int compileLazyFieldInitializer(FieldElement field); 391 int compileLazyFieldInitializer(FieldElement field);
390 392
391 void invokeMethod(Node node, Selector selector) { 393 void invokeMethod(Node node, Selector selector) {
392 registerDynamicInvocation(selector); 394 registerDynamicUse(selector);
393 String symbol = context.getSymbolFromSelector(selector); 395 String symbol = context.getSymbolFromSelector(selector);
394 int id = context.getSymbolId(symbol); 396 int id = context.getSymbolId(symbol);
395 int arity = selector.argumentCount; 397 int arity = selector.argumentCount;
396 int fletchSelector = FletchSelector.encodeMethod(id, arity); 398 int fletchSelector = FletchSelector.encodeMethod(id, arity);
397 assembler.invokeMethod(fletchSelector, arity, selector.name); 399 assembler.invokeMethod(fletchSelector, arity, selector.name);
398 } 400 }
399 401
400 void invokeGetter(Node node, Selector selector) { 402 void invokeGetter(Node node, Name name) {
401 registerDynamicGetter(selector); 403 registerDynamicUse(new Selector.getter(name));
ahe 2015/12/01 10:12:12 This shouldn't create new objects.
sigurdm 2015/12/03 14:48:09 Done.
402 String symbol = context.getSymbolFromSelector(selector); 404 String symbol = context.mangleName(name);
403 int id = context.getSymbolId(symbol); 405 int id = context.getSymbolId(symbol);
404 int fletchSelector = FletchSelector.encodeGetter(id); 406 int fletchSelector = FletchSelector.encodeGetter(id);
405 assembler.invokeMethod(fletchSelector, 0); 407 assembler.invokeMethod(fletchSelector, 0);
406 } 408 }
407 409
408 void invokeSetter(Node node, Selector selector) { 410 void invokeSetter(Node node, Name name) {
409 registerDynamicSetter(selector); 411 registerDynamicUse(new Selector.setter(name));
ahe 2015/12/01 10:12:12 Ditto.
sigurdm 2015/12/03 14:48:09 Done.
410 String symbol = context.getSymbolFromSelector(selector); 412 String symbol = context.mangleName(name);
411 int id = context.getSymbolId(symbol); 413 int id = context.getSymbolId(symbol);
412 int fletchSelector = FletchSelector.encodeSetter(id); 414 int fletchSelector = FletchSelector.encodeSetter(id);
413 assembler.invokeMethod(fletchSelector, 1); 415 assembler.invokeMethod(fletchSelector, 1);
414 } 416 }
415 417
416 void invokeFactory(Node node, int constId, int arity) { 418 void invokeFactory(Node node, int constId, int arity) {
417 assembler.invokeFactory(constId, arity); 419 assembler.invokeFactory(constId, arity);
418 } 420 }
419 421
420 void invokeStatic(Node node, int constId, int arity) { 422 void invokeStatic(Node node, int constId, int arity) {
(...skipping 21 matching lines...) Expand all
442 int constId = allocateConstantFromNode(caseMatch.expression); 444 int constId = allocateConstantFromNode(caseMatch.expression);
443 assembler.loadConst(constId); 445 assembler.loadConst(constId);
444 // For debugging, ignore the equality checks in connection 446 // For debugging, ignore the equality checks in connection
445 // with case matches by not associating the calls with 447 // with case matches by not associating the calls with
446 // any node. 448 // any node.
447 invokeMethod(null, new Selector.binaryOperator('==')); 449 invokeMethod(null, new Selector.binaryOperator('=='));
448 assembler.branchIfTrue(ifTrue); 450 assembler.branchIfTrue(ifTrue);
449 } 451 }
450 452
451 FletchFunctionBase requireFunction(FunctionElement element) { 453 FletchFunctionBase requireFunction(FunctionElement element) {
452 registerStaticInvocation(element); 454 // TODO(johnniwinther): More precise use.
455 registerStaticUse(new StaticUse.foreignUse(element));
ahe 2015/12/01 10:12:12 Ditto.
sigurdm 2015/12/03 14:48:09 Done.
453 return context.backend.getFunctionForElement(element); 456 return context.backend.getFunctionForElement(element);
454 } 457 }
455 458
456 FletchFunctionBase requireConstructorInitializer( 459 FletchFunctionBase requireConstructorInitializer(
457 ConstructorElement constructor) { 460 ConstructorElement constructor) {
458 assert(constructor.isGenerativeConstructor); 461 assert(constructor.isGenerativeConstructor);
459 registerInstantiatedClass(constructor.enclosingClass); 462 registerInstantiatedClass(constructor.enclosingClass);
460 registerStaticInvocation(constructor); 463 registerStaticUse(new StaticUse.foreignUse(constructor));
ahe 2015/12/01 10:12:12 Ditto.
sigurdm 2015/12/03 14:48:09 Done.
461 return context.backend.getConstructorInitializerFunction(constructor); 464 return context.backend.getConstructorInitializerFunction(constructor);
462 } 465 }
463 466
464 void doStaticFunctionInvoke( 467 void doStaticFunctionInvoke(
465 Node node, 468 Node node,
466 FletchFunctionBase function, 469 FletchFunctionBase function,
467 NodeList arguments, 470 NodeList arguments,
468 CallStructure callStructure, 471 CallStructure callStructure,
469 {bool factoryInvoke: false}) { 472 {bool factoryInvoke: false}) {
470 if (function.isInstanceMember) loadThis(); 473 if (function.isInstanceMember) loadThis();
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 assembler.loadLiteralTrue(); 905 assembler.loadLiteralTrue();
903 return; 906 return;
904 } 907 }
905 908
906 if (type.isTypedef) { 909 if (type.isTypedef) {
907 // TODO(ajohnsen): This only matches with the number of arguments, not 910 // TODO(ajohnsen): This only matches with the number of arguments, not
908 // the actual argument types. 911 // the actual argument types.
909 TypedefType typedefType = type; 912 TypedefType typedefType = type;
910 int arity = typedefType.element.functionSignature.parameterCount; 913 int arity = typedefType.element.functionSignature.parameterCount;
911 int fletchSelector = context.toFletchIsSelector( 914 int fletchSelector = context.toFletchIsSelector(
912 context.backend.compiler.functionClass, arity); 915 context.backend.compiler.coreClasses.functionClass, arity);
913 assembler.invokeTest(fletchSelector, 0); 916 assembler.invokeTest(fletchSelector, 0);
914 return; 917 return;
915 } 918 }
916 919
917 if (!type.isInterfaceType) { 920 if (!type.isInterfaceType) {
918 assembler.pop(); 921 assembler.pop();
919 generateUnimplementedError( 922 generateUnimplementedError(
920 diagnosticLocation, "Unhandled type test for $type."); 923 diagnosticLocation, "Unhandled type test for $type.");
921 return; 924 return;
922 } 925 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
994 FletchClassBuilder classBuilder = 997 FletchClassBuilder classBuilder =
995 context.backend.createTearoffClass(target); 998 context.backend.createTearoffClass(target);
996 assert(classBuilder.fields == 0); 999 assert(classBuilder.fields == 0);
997 int constId = allocateConstantClassInstance(classBuilder.classId); 1000 int constId = allocateConstantClassInstance(classBuilder.classId);
998 assembler.loadConst(constId); 1001 assembler.loadConst(constId);
999 applyVisitState(); 1002 applyVisitState();
1000 } 1003 }
1001 1004
1002 void doMainCall(Send node, NodeList arguments) { 1005 void doMainCall(Send node, NodeList arguments) {
1003 FunctionElement function = context.compiler.mainFunction; 1006 FunctionElement function = context.compiler.mainFunction;
1004 if (function.isErroneous) { 1007 if (function.isMalformed) {
1005 doCompileError(); 1008 doCompileError();
1006 return; 1009 return;
1007 } 1010 }
1008 if (context.compiler.libraryLoader.libraries.any(checkCompileError)) return; 1011 if (context.compiler.libraryLoader.libraries.any(checkCompileError)) return;
1009 1012
1010 // Load up to 'parameterCount' arguments, padding with nulls. 1013 // Load up to 'parameterCount' arguments, padding with nulls.
1011 int parameterCount = function.functionSignature.parameterCount; 1014 int parameterCount = function.functionSignature.parameterCount;
1012 int argumentCount = 0; 1015 int argumentCount = 0;
1013 for (Node argument in arguments) { 1016 for (Node argument in arguments) {
1014 if (argumentCount == parameterCount) break; 1017 if (argumentCount == parameterCount) break;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 Send node, 1071 Send node,
1069 MethodElement element, 1072 MethodElement element,
1070 NodeList arguments, 1073 NodeList arguments,
1071 CallStructure callStructure, 1074 CallStructure callStructure,
1072 _) { 1075 _) {
1073 doStaticallyBoundInvoke(node, element, arguments, callStructure); 1076 doStaticallyBoundInvoke(node, element, arguments, callStructure);
1074 applyVisitState(); 1077 applyVisitState();
1075 } 1078 }
1076 1079
1077 void doSuperCall(Node node, FunctionElement function) { 1080 void doSuperCall(Node node, FunctionElement function) {
1078 registerStaticInvocation(function); 1081 registerStaticUse(new StaticUse.foreignUse(function));
ahe 2015/12/01 10:12:12 Ditto.
sigurdm 2015/12/03 14:48:09 Done.
1079 int arity = function.functionSignature.parameterCount + 1; 1082 int arity = function.functionSignature.parameterCount + 1;
1080 FletchFunctionBase base = requireFunction(function); 1083 FletchFunctionBase base = requireFunction(function);
1081 int constId = functionBuilder.allocateConstantFromFunction(base.functionId); 1084 int constId = functionBuilder.allocateConstantFromFunction(base.functionId);
1082 invokeStatic(node, constId, arity); 1085 invokeStatic(node, constId, arity);
1083 } 1086 }
1084 1087
1085 void visitSuperGetterGet( 1088 void visitSuperGetterGet(
1086 Send node, 1089 Send node,
1087 FunctionElement getter, 1090 FunctionElement getter,
1088 _) { 1091 _) {
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1285 invokeMethod(node, callStructure.callSelector); 1288 invokeMethod(node, callStructure.callSelector);
1286 applyVisitState(); 1289 applyVisitState();
1287 } 1290 }
1288 1291
1289 void visitDynamicPropertyInvoke( 1292 void visitDynamicPropertyInvoke(
1290 Send node, 1293 Send node,
1291 Node receiver, 1294 Node receiver,
1292 NodeList arguments, 1295 NodeList arguments,
1293 Selector selector, 1296 Selector selector,
1294 _) { 1297 _) {
1295 if (selector == null) {
1296 // TODO(ajohnsen): Remove hack - dart2js has a problem with generating
1297 // selectors in initializer bodies.
1298 selector = new Selector.call(
1299 node.selector.asIdentifier().source,
1300 element.library,
1301 arguments.slowLength());
1302 }
1303 visitForValue(receiver); 1298 visitForValue(receiver);
1304 for (Node argument in arguments) { 1299 for (Node argument in arguments) {
1305 visitForValue(argument); 1300 visitForValue(argument);
1306 } 1301 }
1307 invokeMethod(node, selector); 1302 invokeMethod(node, selector);
1308 applyVisitState(); 1303 applyVisitState();
1309 } 1304 }
1310 1305
1306 void visitIfNull(
1307 Send node,
1308 Node left,
1309 Node right,
1310 _) {
1311 BytecodeLabel end = new BytecodeLabel();
1312 visitForValue(left);
1313 assembler.dup();
1314 assembler.loadLiteralNull();
1315 assembler.identicalNonNumeric();
1316 assembler.branchIfFalse(end);
1317 assembler.pop();
1318 visitForValue(right);
1319 assembler.bind(end);
1320 applyVisitState();
1321 }
1322
1311 void doIfNotNull(Node receiver, void ifNotNull()) { 1323 void doIfNotNull(Node receiver, void ifNotNull()) {
1312 BytecodeLabel end = new BytecodeLabel(); 1324 BytecodeLabel end = new BytecodeLabel();
1313 visitForValue(receiver); 1325 visitForValue(receiver);
1314 assembler.dup(); 1326 assembler.dup();
1315 assembler.loadLiteralNull(); 1327 assembler.loadLiteralNull();
1316 assembler.identicalNonNumeric(); 1328 assembler.identicalNonNumeric();
1317 assembler.branchIfTrue(end); 1329 assembler.branchIfTrue(end);
1318 ifNotNull(); 1330 ifNotNull();
1319 assembler.bind(end); 1331 assembler.bind(end);
1320 } 1332 }
(...skipping 10 matching lines...) Expand all
1331 } 1343 }
1332 invokeMethod(node, selector); 1344 invokeMethod(node, selector);
1333 }); 1345 });
1334 applyVisitState(); 1346 applyVisitState();
1335 } 1347 }
1336 1348
1337 void visitExpressionInvoke( 1349 void visitExpressionInvoke(
1338 Send node, 1350 Send node,
1339 Expression receiver, 1351 Expression receiver,
1340 NodeList arguments, 1352 NodeList arguments,
1341 Selector selector, 1353 CallStructure callStructure,
1342 _) { 1354 _) {
1343 visitForValue(receiver); 1355 visitForValue(receiver);
1344 for (Node argument in arguments) { 1356 for (Node argument in arguments) {
1345 visitForValue(argument); 1357 visitForValue(argument);
1346 } 1358 }
1347 invokeMethod(node, selector); 1359 invokeMethod(node, new Selector.call(Names.call, callStructure));
1348 applyVisitState(); 1360 applyVisitState();
1349 } 1361 }
1350 1362
1351 void visitThisPropertyInvoke( 1363 void visitThisPropertyInvoke(
1352 Send node, 1364 Send node,
1353 NodeList arguments, 1365 NodeList arguments,
1354 Selector selector, 1366 Selector selector,
1355 _) { 1367 _) {
1356 loadThis(); 1368 loadThis();
1357 1369
1358 // If the property is statically known to be a field, instead invoke the 1370 // If the property is statically known to be a field, instead invoke the
1359 // getter and then invoke 'call(...)' on the value. 1371 // getter and then invoke 'call(...)' on the value.
1360 // TODO(ajohnsen): This is a fix that only works when the field is 1372 // TODO(ajohnsen): This is a fix that only works when the field is
1361 // statically known - that is not always the case. Implement VM support? 1373 // statically known - that is not always the case. Implement VM support?
1362 Element target = elements[node]; 1374 Element target = elements[node];
1363 if (target != null && target.isField) { 1375 if (target != null && target.isField) {
1364 invokeGetter(node, new Selector.getter(target.name, element.library)); 1376 invokeGetter(node, new Name(target.name, element.library));
1365 selector = new Selector.callClosureFrom(selector); 1377 selector = new Selector.callClosureFrom(selector);
1366 } 1378 }
1367 for (Node argument in arguments) { 1379 for (Node argument in arguments) {
1368 visitForValue(argument); 1380 visitForValue(argument);
1369 } 1381 }
1370 invokeMethod(node, selector); 1382 invokeMethod(node, selector);
1371 applyVisitState(); 1383 applyVisitState();
1372 } 1384 }
1373 1385
1374 void visitThisInvoke( 1386 void visitThisInvoke(
(...skipping 14 matching lines...) Expand all
1389 ConstantExpression constant, 1401 ConstantExpression constant,
1390 _) { 1402 _) {
1391 generateUnimplementedError( 1403 generateUnimplementedError(
1392 node, "[visitClassTypeLiteralGet] isn't implemented."); 1404 node, "[visitClassTypeLiteralGet] isn't implemented.");
1393 applyVisitState(); 1405 applyVisitState();
1394 } 1406 }
1395 1407
1396 void visitDynamicPropertyGet( 1408 void visitDynamicPropertyGet(
1397 Send node, 1409 Send node,
1398 Node receiver, 1410 Node receiver,
1399 Selector selector, 1411 Name name,
1400 _) { 1412 _) {
1401 if (selector == null) { 1413 if (name.text == "runtimeType") {
1402 // TODO(ajohnsen): Remove hack - dart2js has a problem with generating
1403 // selectors in initializer bodies.
1404 selector = new Selector.getter(
1405 node.selector.asIdentifier().source,
1406 element.library);
1407 }
1408 if (selector.name == "runtimeType") {
1409 // TODO(ahe): Implement runtimeType. 1414 // TODO(ahe): Implement runtimeType.
1410 generateUnimplementedError( 1415 generateUnimplementedError(
1411 node, 1416 node,
1412 "'runtimeType' isn't supported in Fletch. See https://goo.gl/ELH6Zc"); 1417 "'runtimeType' isn't supported in Fletch. See https://goo.gl/ELH6Zc");
1413 applyVisitState(); 1418 applyVisitState();
1414 return; 1419 return;
1415 } 1420 }
1416 visitForValue(receiver); 1421 visitForValue(receiver);
1417 invokeGetter(node, selector); 1422 invokeGetter(node, name);
1418 applyVisitState(); 1423 applyVisitState();
1419 } 1424 }
1420 1425
1421 void visitIfNotNullDynamicPropertyGet( 1426 void visitIfNotNullDynamicPropertyGet(
1422 Send node, 1427 Send node,
1423 Node receiver, 1428 Node receiver,
1424 Selector selector, 1429 Name name,
1425 _) { 1430 _) {
1426 doIfNotNull(receiver, () { 1431 doIfNotNull(receiver, () {
1427 invokeGetter(node, selector); 1432 invokeGetter(node, name);
1428 }); 1433 });
1429 applyVisitState(); 1434 applyVisitState();
1430 } 1435 }
1431 1436
1432 void visitThisPropertyGet( 1437 void visitThisPropertyGet(
1433 Send node, 1438 Send node,
1434 Selector selector, 1439 Name name,
1435 _) { 1440 _) {
1436 loadThis(); 1441 loadThis();
1437 invokeGetter(node, selector); 1442 invokeGetter(node, name);
1438 applyVisitState(); 1443 applyVisitState();
1439 } 1444 }
1440 1445
1441 void visitThisPropertySet( 1446 void visitThisPropertySet(
1442 Send node, 1447 Send node,
1443 Selector selector, 1448 Name name,
1444 Node rhs, 1449 Node rhs,
1445 _) { 1450 _) {
1446 loadThis(); 1451 loadThis();
1447 visitForValue(rhs); 1452 visitForValue(rhs);
1448 invokeSetter(node, selector); 1453 invokeSetter(node, name);
1449 applyVisitState(); 1454 applyVisitState();
1450 } 1455 }
1451 1456
1452 void doStaticFieldGet(FieldElement field) { 1457 void doStaticFieldGet(FieldElement field) {
1453 if (checkCompileError(field)) return; 1458 if (checkCompileError(field)) return;
1454 if (field.isConst) { 1459 if (field.isConst) {
1455 int constId = allocateConstantFromNode( 1460 int constId = allocateConstantFromNode(
1456 field.initializer, 1461 field.initializer,
1457 elements: field.resolvedAst.elements); 1462 elements: field.resolvedAst.elements);
1458 assembler.loadConst(constId); 1463 assembler.loadConst(constId);
1459 } else { 1464 } else {
1460 int index = compileLazyFieldInitializer(field); 1465 int index = compileLazyFieldInitializer(field);
1461 if (field.initializer != null) { 1466 if (field.initializer != null) {
1462 assembler.loadStaticInit(index); 1467 assembler.loadStaticInit(index);
1463 } else { 1468 } else {
1464 assembler.loadStatic(index); 1469 assembler.loadStatic(index);
1465 } 1470 }
1466 } 1471 }
1467 } 1472 }
1468 1473
1469 void handleStaticFieldGet( 1474 void handleStaticFieldGet(
1470 Send node, 1475 Send node,
1471 FieldElement field, 1476 FieldElement field,
1472 _) { 1477 _) {
1473 doStaticFieldGet(field); 1478 doStaticFieldGet(field);
1474 applyVisitState(); 1479 applyVisitState();
1475 } 1480 }
1476 1481
1477 void visitAssert(Send node, Node expression, _) { 1482 void visitAssert(Assert node) {
1478 // TODO(ajohnsen): Emit assert in checked mode. 1483 // TODO(ajohnsen): Emit assert in checked mode.
1479 } 1484 }
1480 1485
1481 void visitDynamicPropertySet( 1486 void visitDynamicPropertySet(
1482 Send node, 1487 Send node,
1483 Node receiver, 1488 Node receiver,
1484 Selector selector, 1489 Name name,
1485 Node rhs, 1490 Node rhs,
1486 _) { 1491 _) {
1487 visitForValue(receiver); 1492 visitForValue(receiver);
1488 visitForValue(rhs); 1493 visitForValue(rhs);
1489 invokeSetter(node, selector); 1494 invokeSetter(node, name);
1490 applyVisitState(); 1495 applyVisitState();
1491 } 1496 }
1492 1497
1493 void visitIfNotNullDynamicPropertySet( 1498 void visitIfNotNullDynamicPropertySet(
1494 SendSet node, 1499 SendSet node,
1495 Node receiver, 1500 Node receiver,
1496 Selector selector, 1501 Name name,
1497 Node rhs, 1502 Node rhs,
1498 _) { 1503 _) {
1499 doIfNotNull(receiver, () { 1504 doIfNotNull(receiver, () {
1500 visitForValue(rhs); 1505 visitForValue(rhs);
1501 invokeSetter(node, selector); 1506 invokeSetter(node, name);
1502 }); 1507 });
1503 applyVisitState(); 1508 applyVisitState();
1504 } 1509 }
1505 1510
1506 void doStaticFieldSet(FieldElement field) { 1511 void doStaticFieldSet(
ahe 2015/12/01 10:12:12 Why this change?
sigurdm 2015/12/03 14:48:09 Not sure - reverted.
1512 FieldElement field) {
1507 int index = context.getStaticFieldIndex(field, element); 1513 int index = context.getStaticFieldIndex(field, element);
1508 assembler.storeStatic(index); 1514 assembler.storeStatic(index);
1509 } 1515 }
1510 1516
1511 void handleStaticFieldSet( 1517 void handleStaticFieldSet(
1512 SendSet node, 1518 SendSet node,
1513 FieldElement field, 1519 FieldElement field,
1514 Node rhs, 1520 Node rhs,
1515 _) { 1521 _) {
1516 visitForValue(rhs); 1522 visitForValue(rhs);
1517 doStaticFieldSet(field); 1523 doStaticFieldSet(field);
1518 applyVisitState(); 1524 applyVisitState();
1519 } 1525 }
1520 1526
1521 void visitStringJuxtaposition(StringJuxtaposition node) { 1527 void visitStringJuxtaposition(StringJuxtaposition node) {
1522 // TODO(ajohnsen): This could probably be optimized to string constants in 1528 // TODO(ajohnsen): This could probably be optimized to string constants in
1523 // some cases. 1529 // some cases.
1524 visitForValue(node.first); 1530 visitForValue(node.first);
1525 visitForValue(node.second); 1531 visitForValue(node.second);
1526 // TODO(ajohnsen): Cache these in context/backend. 1532 // TODO(ajohnsen): Cache these in context/backend.
1527 Selector concat = new Selector.binaryOperator('+'); 1533 Selector concat = new Selector.binaryOperator('+');
1528 invokeMethod(node, concat); 1534 invokeMethod(node, concat);
1529 applyVisitState(); 1535 applyVisitState();
1530 } 1536 }
1531 1537
1532 void visitStringInterpolation(StringInterpolation node) { 1538 void visitStringInterpolation(StringInterpolation node) {
1533 // TODO(ajohnsen): Cache these in context/backend. 1539 // TODO(ajohnsen): Cache this in context/backend.
1534 Selector toString = new Selector.call('toString', null, 0);
1535 Selector concat = new Selector.binaryOperator('+'); 1540 Selector concat = new Selector.binaryOperator('+');
1536 visitForValueNoDebugInfo(node.string); 1541 visitForValueNoDebugInfo(node.string);
1537 for (StringInterpolationPart part in node.parts) { 1542 for (StringInterpolationPart part in node.parts) {
1538 visitForValue(part.expression); 1543 visitForValue(part.expression);
1539 invokeMethod(part.expression, toString); 1544 invokeMethod(part.expression, Selectors.toString_);
1540 LiteralString string = part.string; 1545 LiteralString string = part.string;
1541 if (string.dartString.isNotEmpty) { 1546 if (string.dartString.isNotEmpty) {
1542 visitForValueNoDebugInfo(string); 1547 visitForValueNoDebugInfo(string);
1543 invokeMethod(null, concat); 1548 invokeMethod(null, concat);
1544 } 1549 }
1545 invokeMethod(null, concat); 1550 invokeMethod(null, concat);
1546 } 1551 }
1547 applyVisitState(); 1552 applyVisitState();
1548 } 1553 }
1549 1554
1550 void visitLiteralNull(LiteralNull node) { 1555 void visitLiteralNull(LiteralNull node) {
1551 if (visitState == VisitState.Value) { 1556 if (visitState == VisitState.Value) {
1552 assembler.loadLiteralNull(); 1557 assembler.loadLiteralNull();
1553 } else if (visitState == VisitState.Test) { 1558 } else if (visitState == VisitState.Test) {
1554 assembler.branch(falseLabel); 1559 if (falseLabel != null) assembler.branch(falseLabel);
1555 } 1560 }
1556 } 1561 }
1557 1562
1558 void visitLiteralSymbol(LiteralSymbol node) { 1563 void visitLiteralSymbol(LiteralSymbol node) {
1559 int constId = allocateConstantFromNode(node); 1564 int constId = allocateConstantFromNode(node);
1560 assembler.loadConst(constId); 1565 assembler.loadConst(constId);
1561 applyVisitState(); 1566 applyVisitState();
1562 } 1567 }
1563 1568
1564 void visitLiteralBool(LiteralBool node) { 1569 void visitLiteralBool(LiteralBool node) {
(...skipping 26 matching lines...) Expand all
1591 node, 1596 node,
1592 'Program compiled without support for big integers'); 1597 'Program compiled without support for big integers');
1593 } else { 1598 } else {
1594 int constId = allocateConstantFromNode(node); 1599 int constId = allocateConstantFromNode(node);
1595 assembler.loadConst(constId); 1600 assembler.loadConst(constId);
1596 } 1601 }
1597 } else { 1602 } else {
1598 assembler.loadLiteral(value); 1603 assembler.loadLiteral(value);
1599 } 1604 }
1600 } else if (visitState == VisitState.Test) { 1605 } else if (visitState == VisitState.Test) {
1601 assembler.branch(falseLabel); 1606 if (falseLabel != null) assembler.branch(falseLabel);
1602 } 1607 }
1603 } 1608 }
1604 1609
1605 void visitLiteral(Literal node) { 1610 void visitLiteral(Literal node) {
1606 if (visitState == VisitState.Value) { 1611 if (visitState == VisitState.Value) {
1607 assembler.loadConst(allocateConstantFromNode(node)); 1612 assembler.loadConst(allocateConstantFromNode(node));
1608 } else if (visitState == VisitState.Test) { 1613 } else if (visitState == VisitState.Test) {
1609 assembler.branch(falseLabel); 1614 if (falseLabel != null) assembler.branch(falseLabel);
1610 } 1615 }
1611 } 1616 }
1612 1617
1613 void visitLiteralList(LiteralList node) { 1618 void visitLiteralList(LiteralList node) {
1614 if (node.isConst) { 1619 if (node.isConst) {
1615 int constId = allocateConstantFromNode(node); 1620 int constId = allocateConstantFromNode(node);
1616 assembler.loadConst(constId); 1621 assembler.loadConst(constId);
1617 applyVisitState(); 1622 applyVisitState();
1618 return; 1623 return;
1619 } 1624 }
1620 ClassElement literalClass = context.backend.growableListClass; 1625 ClassElement literalClass = context.backend.growableListClass;
1621 ConstructorElement constructor = literalClass.lookupDefaultConstructor(); 1626 ConstructorElement constructor = literalClass.lookupDefaultConstructor();
1622 if (constructor == null) { 1627 if (constructor == null) {
1623 internalError(node, "Failed to lookup default list constructor"); 1628 internalError(node, "Failed to lookup default list constructor");
1624 } 1629 }
1625 // Call with empty arguments, as we call the default constructor. 1630 // Call with empty arguments, as we call the default constructor.
1626 callConstructor( 1631 callConstructor(
1627 node, constructor, new NodeList.empty(), CallStructure.NO_ARGS); 1632 node, constructor, new NodeList.empty(), CallStructure.NO_ARGS);
1628 Selector add = new Selector.call('add', null, 1); 1633 Selector add = new Selector.call(new Name('add', null),
1634 CallStructure.ONE_ARG);
1629 for (Node element in node.elements) { 1635 for (Node element in node.elements) {
1630 assembler.dup(); 1636 assembler.dup();
1631 visitForValue(element); 1637 visitForValue(element);
1632 invokeMethod(node, add); 1638 invokeMethod(node, add);
1633 assembler.pop(); 1639 assembler.pop();
1634 } 1640 }
1635 applyVisitState(); 1641 applyVisitState();
1636 } 1642 }
1637 1643
1638 void visitLiteralMap(LiteralMap node) { 1644 void visitLiteralMap(LiteralMap node) {
1639 if (node.isConst) { 1645 if (node.isConst) {
1640 int constId = allocateConstantFromNode(node); 1646 int constId = allocateConstantFromNode(node);
1641 assembler.loadConst(constId); 1647 assembler.loadConst(constId);
1642 applyVisitState(); 1648 applyVisitState();
1643 return; 1649 return;
1644 } 1650 }
1645 ClassElement literalClass = context.backend.mapImplementation; 1651 ClassElement literalClass =
1646 ConstructorElement constructor = literalClass.lookupDefaultConstructor(); 1652 context.backend.mapImplementation.implementation;
1653 ConstructorElement constructor = literalClass.lookupConstructor("");
1647 if (constructor == null) { 1654 if (constructor == null) {
1648 internalError(literalClass, "Failed to lookup default map constructor"); 1655 internalError(literalClass, "Failed to lookup default map constructor");
1649 return; 1656 return;
1650 } 1657 }
1651 // The default constructor is a redirecting factory constructor. Follow it. 1658 // The default constructor is a redirecting factory constructor. Follow it.
1652 constructor = constructor.effectiveTarget; 1659 constructor = constructor.effectiveTarget;
1653 FletchFunctionBase function = requireFunction(constructor.declaration); 1660 FletchFunctionBase function = requireFunction(constructor.declaration);
1654 doStaticFunctionInvoke( 1661 doStaticFunctionInvoke(
1655 node, 1662 node,
1656 function, 1663 function,
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
1881 Send node, 1888 Send node,
1882 FieldElement field, 1889 FieldElement field,
1883 IncDecOperator operator, 1890 IncDecOperator operator,
1884 _) { 1891 _) {
1885 doStaticFieldPrefix(node, field, operator); 1892 doStaticFieldPrefix(node, field, operator);
1886 applyVisitState(); 1893 applyVisitState();
1887 } 1894 }
1888 1895
1889 void doDynamicPropertyCompound( 1896 void doDynamicPropertyCompound(
1890 Node node, 1897 Node node,
1898 Name name,
1891 AssignmentOperator operator, 1899 AssignmentOperator operator,
1892 Node rhs, 1900 Node rhs) {
1893 Selector getterSelector,
1894 Selector setterSelector) {
1895 // Dup receiver for setter. 1901 // Dup receiver for setter.
1896 assembler.dup(); 1902 assembler.dup();
1897 invokeGetter(node, getterSelector); 1903 invokeGetter(node, name);
1898 visitForValue(rhs); 1904 visitForValue(rhs);
1899 invokeMethod(node, getAssignmentSelector(operator)); 1905 invokeMethod(node, getAssignmentSelector(operator));
1900 invokeSetter(node, setterSelector); 1906 invokeSetter(node, name);
1901 } 1907 }
1902 1908
1903 void visitDynamicPropertyCompound( 1909 void visitDynamicPropertyCompound(
1904 Send node, 1910 Send node,
1905 Node receiver, 1911 Node receiver,
1912 Name name,
1906 AssignmentOperator operator, 1913 AssignmentOperator operator,
1907 Node rhs, 1914 Node rhs,
1908 Selector getterSelector,
1909 Selector setterSelector,
1910 _) { 1915 _) {
1911 visitForValue(receiver); 1916 visitForValue(receiver);
1912 doDynamicPropertyCompound( 1917 doDynamicPropertyCompound(
1913 node, 1918 node,
1919 name,
1914 operator, 1920 operator,
1915 rhs, 1921 rhs);
1916 getterSelector,
1917 setterSelector);
1918 applyVisitState(); 1922 applyVisitState();
1919 } 1923 }
1920 1924
1921 void visitIfNotNullDynamicPropertyCompound( 1925 void visitIfNotNullDynamicPropertyCompound(
1922 Send node, 1926 Send node,
1923 Node receiver, 1927 Node receiver,
1928 Name name,
1924 AssignmentOperator operator, 1929 AssignmentOperator operator,
1925 Node rhs, 1930 Node rhs,
1926 Selector getterSelector,
1927 Selector setterSelector,
1928 _) { 1931 _) {
1929 doIfNotNull(receiver, () { 1932 doIfNotNull(receiver, () {
1930 doDynamicPropertyCompound( 1933 doDynamicPropertyCompound(
1931 node, 1934 node,
1935 name,
1932 operator, 1936 operator,
1933 rhs, 1937 rhs);
1934 getterSelector,
1935 setterSelector);
1936 }); 1938 });
1937 applyVisitState(); 1939 applyVisitState();
1938 } 1940 }
1939 1941
1940 void visitThisPropertyCompound( 1942 void visitThisPropertyCompound(
1941 Send node, 1943 Send node,
1944 Name name,
1942 AssignmentOperator operator, 1945 AssignmentOperator operator,
1943 Node rhs, 1946 Node rhs,
1944 Selector getterSelector,
1945 Selector setterSelector,
1946 _) { 1947 _) {
1947 loadThis(); 1948 loadThis();
1948 doDynamicPropertyCompound( 1949 doDynamicPropertyCompound(
1949 node, 1950 node,
1951 name,
1950 operator, 1952 operator,
1951 rhs, 1953 rhs);
1952 getterSelector,
1953 setterSelector);
1954 applyVisitState(); 1954 applyVisitState();
1955 } 1955 }
1956 1956
1957 void doDynamicPrefix( 1957 void doDynamicPrefix(
1958 Node node, 1958 Node node,
1959 IncDecOperator operator, 1959 Name name,
1960 Selector getterSelector, 1960 IncDecOperator operator) {
1961 Selector setterSelector) {
1962 assembler.dup(); 1961 assembler.dup();
1963 invokeGetter(node, getterSelector); 1962 invokeGetter(node, name);
1964 assembler.loadLiteral(1); 1963 assembler.loadLiteral(1);
1965 invokeMethod(node, getIncDecSelector(operator)); 1964 invokeMethod(node, getIncDecSelector(operator));
1966 invokeSetter(node, setterSelector); 1965 invokeSetter(node, name);
1967 } 1966 }
1968 1967
1969 void doIndexPrefix( 1968 void doIndexPrefix(
1970 SendSet node, 1969 SendSet node,
1971 Node receiver, 1970 Node receiver,
1972 Node index, 1971 Node index,
1973 IncDecOperator operator) { 1972 IncDecOperator operator) {
1974 visitForValue(receiver); 1973 visitForValue(receiver);
1975 visitForValue(index); 1974 visitForValue(index);
1976 // Load already evaluated receiver and index for '[]' call. 1975 // Load already evaluated receiver and index for '[]' call.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2037 invokeMethod(node, new Selector.index()); 2036 invokeMethod(node, new Selector.index());
2038 visitForValue(rhs); 2037 visitForValue(rhs);
2039 invokeMethod(node, getAssignmentSelector(operator)); 2038 invokeMethod(node, getAssignmentSelector(operator));
2040 // Use existing evaluated receiver and index for '[]=' call. 2039 // Use existing evaluated receiver and index for '[]=' call.
2041 invokeMethod(node, new Selector.indexSet()); 2040 invokeMethod(node, new Selector.indexSet());
2042 applyVisitState(); 2041 applyVisitState();
2043 } 2042 }
2044 2043
2045 void visitThisPropertyPrefix( 2044 void visitThisPropertyPrefix(
2046 Send node, 2045 Send node,
2046 Name name,
2047 IncDecOperator operator, 2047 IncDecOperator operator,
2048 Selector getterSelector,
2049 Selector setterSelector,
2050 _) { 2048 _) {
2051 loadThis(); 2049 loadThis();
2052 doDynamicPrefix(node, operator, getterSelector, setterSelector); 2050 doDynamicPrefix(node, name, operator);
2053 applyVisitState(); 2051 applyVisitState();
2054 } 2052 }
2055 2053
2056 void visitThisPropertyPostfix( 2054 void visitThisPropertyPostfix(
2057 Send node, 2055 Send node,
2056 Name name,
2058 IncDecOperator operator, 2057 IncDecOperator operator,
2059 Selector getterSelector,
2060 Selector setterSelector,
2061 _) { 2058 _) {
2062 // If visitState is for effect, we can ignore the return value, thus always 2059 // If visitState is for effect, we can ignore the return value, thus always
2063 // generate code for the simpler 'prefix' case. 2060 // generate code for the simpler 'prefix' case.
2064 if (visitState == VisitState.Effect) { 2061 if (visitState == VisitState.Effect) {
2065 loadThis(); 2062 loadThis();
2066 doDynamicPrefix(node, operator, getterSelector, setterSelector); 2063 doDynamicPrefix(node, name, operator);
2067 applyVisitState(); 2064 applyVisitState();
2068 return; 2065 return;
2069 } 2066 }
2070 2067
2071 loadThis(); 2068 loadThis();
2072 invokeGetter(node, getterSelector); 2069 invokeGetter(node, name);
2073 // For postfix, keep local, unmodified version, to 'return' after store. 2070 // For postfix, keep local, unmodified version, to 'return' after store.
2074 assembler.dup(); 2071 assembler.dup();
2075 assembler.loadLiteral(1); 2072 assembler.loadLiteral(1);
2076 invokeMethod(node, getIncDecSelector(operator)); 2073 invokeMethod(node, getIncDecSelector(operator));
2077 loadThis(); 2074 loadThis();
2078 assembler.loadLocal(1); 2075 assembler.loadLocal(1);
2079 invokeSetter(node, setterSelector); 2076 invokeSetter(node, name);
2080 assembler.popMany(2); 2077 assembler.popMany(2);
2081 applyVisitState(); 2078 applyVisitState();
2082 } 2079 }
2083 2080
2084 void visitDynamicPropertyPrefix( 2081 void visitDynamicPropertyPrefix(
2085 Send node, 2082 Send node,
2086 Node receiver, 2083 Node receiver,
2084 Name name,
2087 IncDecOperator operator, 2085 IncDecOperator operator,
2088 Selector getterSelector,
2089 Selector setterSelector,
2090 _) { 2086 _) {
2091 visitForValue(receiver); 2087 visitForValue(receiver);
2092 doDynamicPrefix(node, operator, getterSelector, setterSelector); 2088 doDynamicPrefix(node, name, operator);
2093 applyVisitState(); 2089 applyVisitState();
2094 } 2090 }
2095 2091
2096 void visitIfNotNullDynamicPropertyPrefix( 2092 void visitIfNotNullDynamicPropertyPrefix(
2097 Send node, 2093 Send node,
2098 Node receiver, 2094 Node receiver,
2095 Name name,
2099 IncDecOperator operator, 2096 IncDecOperator operator,
2100 Selector getterSelector,
2101 Selector setterSelector,
2102 _) { 2097 _) {
2103 doIfNotNull(receiver, () { 2098 doIfNotNull(receiver, () {
2104 doDynamicPrefix(node, operator, getterSelector, setterSelector); 2099 doDynamicPrefix(node, name, operator);
2105 }); 2100 });
2106 applyVisitState(); 2101 applyVisitState();
2107 } 2102 }
2108 2103
2109 void doDynamicPostfix( 2104 void doDynamicPostfix(
2110 Send node, 2105 Send node,
2111 Node receiver, 2106 Node receiver,
2112 IncDecOperator operator, 2107 Name name,
2113 Selector getterSelector, 2108 IncDecOperator operator) {
2114 Selector setterSelector) {
2115 int receiverSlot = assembler.stackSize - 1; 2109 int receiverSlot = assembler.stackSize - 1;
2116 assembler.loadSlot(receiverSlot); 2110 assembler.loadSlot(receiverSlot);
2117 invokeGetter(node, getterSelector); 2111 invokeGetter(node, name);
2118 // For postfix, keep local, unmodified version, to 'return' after store. 2112 // For postfix, keep local, unmodified version, to 'return' after store.
2119 assembler.dup(); 2113 assembler.dup();
2120 assembler.loadLiteral(1); 2114 assembler.loadLiteral(1);
2121 invokeMethod(node, getIncDecSelector(operator)); 2115 invokeMethod(node, getIncDecSelector(operator));
2122 assembler.loadSlot(receiverSlot); 2116 assembler.loadSlot(receiverSlot);
2123 assembler.loadLocal(1); 2117 assembler.loadLocal(1);
2124 invokeSetter(node, setterSelector); 2118 invokeSetter(node, name);
2125 assembler.popMany(2); 2119 assembler.popMany(2);
2126 assembler.storeLocal(1); 2120 assembler.storeLocal(1);
2127 // Pop receiver. 2121 // Pop receiver.
2128 assembler.pop(); 2122 assembler.pop();
2129 } 2123 }
2130 2124
2131 void visitDynamicPropertyPostfix( 2125 void visitDynamicPropertyPostfix(
2132 Send node, 2126 Send node,
2133 Node receiver, 2127 Node receiver,
2128 Name name,
2134 IncDecOperator operator, 2129 IncDecOperator operator,
2135 Selector getterSelector,
2136 Selector setterSelector,
2137 _) { 2130 _) {
2138 // If visitState is for effect, we can ignore the return value, thus always 2131 // If visitState is for effect, we can ignore the return value, thus always
2139 // generate code for the simpler 'prefix' case. 2132 // generate code for the simpler 'prefix' case.
2140 if (visitState == VisitState.Effect) { 2133 if (visitState == VisitState.Effect) {
2141 visitForValue(receiver); 2134 visitForValue(receiver);
2142 doDynamicPrefix(node, operator, getterSelector, setterSelector); 2135 doDynamicPrefix(node, name, operator);
2143 applyVisitState(); 2136 applyVisitState();
2144 return; 2137 return;
2145 } 2138 }
2146 2139
2147 visitForValue(receiver); 2140 visitForValue(receiver);
2148 doDynamicPostfix(node, receiver, operator, getterSelector, setterSelector); 2141 doDynamicPostfix(node, receiver, name, operator);
2149 applyVisitState(); 2142 applyVisitState();
2150 } 2143 }
2151 2144
2152 void visitIfNotNullDynamicPropertyPostfix( 2145 void visitIfNotNullDynamicPropertyPostfix(
2153 Send node, 2146 Send node,
2154 Node receiver, 2147 Node receiver,
2148 Name name,
2155 IncDecOperator operator, 2149 IncDecOperator operator,
2156 Selector getterSelector,
2157 Selector setterSelector,
2158 _) { 2150 _) {
2159 doIfNotNull(receiver, () { 2151 doIfNotNull(receiver, () {
2160 doDynamicPostfix( 2152 doDynamicPostfix(
2161 node,receiver, operator, getterSelector, setterSelector); 2153 node, receiver, name, operator);
2162 }); 2154 });
2163 applyVisitState(); 2155 applyVisitState();
2164 } 2156 }
2165 2157
2166 void visitThrow(Throw node) { 2158 void visitThrow(Throw node) {
2167 visitForValue(node.expression); 2159 visitForValue(node.expression);
2168 assembler.emitThrow(); 2160 assembler.emitThrow();
2169 // TODO(ahe): It seems suboptimal that each throw is followed by a pop. 2161 // TODO(ahe): It seems suboptimal that each throw is followed by a pop.
2170 applyVisitState(); 2162 applyVisitState();
2171 } 2163 }
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after
2747 void visitSyncForIn(SyncForIn node) { 2739 void visitSyncForIn(SyncForIn node) {
2748 visitForIn(node); 2740 visitForIn(node);
2749 } 2741 }
2750 2742
2751 void visitForIn(ForIn node) { 2743 void visitForIn(ForIn node) {
2752 BytecodeLabel start = new BytecodeLabel(); 2744 BytecodeLabel start = new BytecodeLabel();
2753 BytecodeLabel end = new BytecodeLabel(); 2745 BytecodeLabel end = new BytecodeLabel();
2754 2746
2755 // Evalutate expression and iterator. 2747 // Evalutate expression and iterator.
2756 visitForValue(node.expression); 2748 visitForValue(node.expression);
2757 invokeGetter(node.expression, new Selector.getter('iterator', null)); 2749 invokeGetter(node.expression, Names.iterator);
2758 2750
2759 jumpInfo[node] = new JumpInfo(assembler.stackSize, start, end); 2751 jumpInfo[node] = new JumpInfo(assembler.stackSize, start, end);
2760 2752
2761 assembler.bind(start); 2753 assembler.bind(start);
2762 2754
2763 assembler.dup(); 2755 assembler.dup();
2764 invokeMethod(node, new Selector.call('moveNext', null, 0)); 2756 invokeMethod(node, Selectors.moveNext);
2765 assembler.branchIfFalse(end); 2757 assembler.branchIfFalse(end);
2766 2758
2767 bool isVariableDeclaration = node.declaredIdentifier.asSend() == null; 2759 bool isVariableDeclaration = node.declaredIdentifier.asSend() == null;
2768 Element element = elements[node]; 2760 Element element = elements[node];
2769 if (isVariableDeclaration) { 2761 if (isVariableDeclaration) {
2770 // Create local value and load the current element to it. 2762 // Create local value and load the current element to it.
2771 LocalValue value = createLocalValueFor(element); 2763 LocalValue value = createLocalValueFor(element);
2772 assembler.dup(); 2764 assembler.dup();
2773 invokeGetter(node, new Selector.getter('current', null)); 2765 invokeGetter(node, Names.current);
2774 value.initialize(assembler); 2766 value.initialize(assembler);
2775 pushVariableDeclaration(value); 2767 pushVariableDeclaration(value);
2776 } else { 2768 } else {
2777 if (element == null || element.isInstanceMember) { 2769 if (element == null || element.isInstanceMember) {
2778 loadThis(); 2770 loadThis();
2779 assembler.loadLocal(1); 2771 assembler.loadLocal(1);
2780 invokeGetter(node, new Selector.getter('current', null)); 2772 invokeGetter(node, Names.current);
2781 Selector selector = elements.getSelector(node.declaredIdentifier); 2773 Selector selector = elements.getSelector(node.declaredIdentifier);
2782 invokeSetter(node, selector); 2774 invokeSetter(node, selector.memberName);
2783 } else { 2775 } else {
2784 assembler.dup(); 2776 assembler.dup();
2785 invokeGetter(node, new Selector.getter('current', null)); 2777 invokeGetter(node, Names.current);
2786 if (element.isLocal) { 2778 if (element.isLocal) {
2787 scope[element].store(assembler); 2779 scope[element].store(assembler);
2788 } else if (element.isField) { 2780 } else if (element.isField) {
2789 doStaticFieldSet(element); 2781 doStaticFieldSet(element);
2790 } else if (element.isErroneous) { 2782 } else if (element.isMalformed) {
2791 doUnresolved(element.name); 2783 doUnresolved(element.name);
2792 assembler.pop(); 2784 assembler.pop();
2793 } else { 2785 } else {
2794 internalError(node, "Unhandled store in for-in"); 2786 internalError(node, "Unhandled store in for-in");
2795 } 2787 }
2796 } 2788 }
2797 assembler.pop(); 2789 assembler.pop();
2798 } 2790 }
2799 2791
2800 doScopedStatement(node.body); 2792 doScopedStatement(node.body);
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
3092 NodeList arguments, 3084 NodeList arguments,
3093 CallStructure callStructure, 3085 CallStructure callStructure,
3094 _) { 3086 _) {
3095 if (!checkCompileError(function)) { 3087 if (!checkCompileError(function)) {
3096 doUnresolved(function.name); 3088 doUnresolved(function.name);
3097 } 3089 }
3098 applyVisitState(); 3090 applyVisitState();
3099 } 3091 }
3100 3092
3101 void internalError(Spannable spannable, String reason) { 3093 void internalError(Spannable spannable, String reason) {
3102 context.compiler.internalError(spannable, reason); 3094 context.compiler.reporter.internalError(spannable, reason);
3103 } 3095 }
3104 3096
3105 void generateUnimplementedError(Spannable spannable, String reason) { 3097 void generateUnimplementedError(Spannable spannable, String reason) {
3106 context.backend.generateUnimplementedError( 3098 context.backend.generateUnimplementedError(
3107 spannable, 3099 spannable,
3108 reason, 3100 reason,
3109 functionBuilder); 3101 functionBuilder);
3110 } 3102 }
3111 3103
3112 String toString() => "FunctionCompiler(${element.name})"; 3104 String toString() => "FunctionCompiler(${element.name})";
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
3164 void handleStaticFunctionSet( 3156 void handleStaticFunctionSet(
3165 SendSet node, 3157 SendSet node,
3166 MethodElement function, 3158 MethodElement function,
3167 Node rhs, 3159 Node rhs,
3168 _) { 3160 _) {
3169 generateUnimplementedError( 3161 generateUnimplementedError(
3170 node, "[handleStaticFunctionSet] isn't implemented."); 3162 node, "[handleStaticFunctionSet] isn't implemented.");
3171 applyVisitState(); 3163 applyVisitState();
3172 } 3164 }
3173 3165
3166 @override
3167 void bulkHandleSetIfNull(Node node, _) {
3168 generateUnimplementedError(
3169 node, "[bulkHandleSetIfNull] isn't implemented.");
3170 applyVisitState();
3171 }
3172
3174 void previsitDeferredAccess(Send node, PrefixElement prefix, _) { 3173 void previsitDeferredAccess(Send node, PrefixElement prefix, _) {
3175 // We don't support deferred access, so nothing to do for now. 3174 // We don't support deferred access, so nothing to do for now.
3176 } 3175 }
3177 3176
3178 void bulkHandleNode(Node node, String msg, _) { 3177 void bulkHandleNode(Node node, String msg, _) {
3179 generateUnimplementedError(node, msg.replaceAll('#', node.toString())); 3178 generateUnimplementedError(node, msg.replaceAll('#', node.toString()));
3180 applyVisitState(); 3179 applyVisitState();
3181 } 3180 }
3182 3181
3183 void visitNode(Node node) { 3182 void visitNode(Node node) {
(...skipping 10 matching lines...) Expand all
3194 3193
3195 void applyParameters(NodeList parameters, _) { 3194 void applyParameters(NodeList parameters, _) {
3196 internalError(parameters, "[applyParameters] isn't implemented."); 3195 internalError(parameters, "[applyParameters] isn't implemented.");
3197 } 3196 }
3198 } 3197 }
3199 3198
3200 abstract class FletchRegistryMixin { 3199 abstract class FletchRegistryMixin {
3201 FletchRegistry get registry; 3200 FletchRegistry get registry;
3202 FletchContext get context; 3201 FletchContext get context;
3203 3202
3204 void registerDynamicInvocation(Selector selector) { 3203 void registerDynamicUse(Selector selector) {
3205 registry.registerDynamicInvocation(new UniverseSelector(selector, null)); 3204 registry.registerDynamicUse(selector);
3206 } 3205 }
3207 3206
3208 void registerDynamicGetter(Selector selector) { 3207 void registerStaticUse(StaticUse staticUse) {
3209 registry.registerDynamicGetter(new UniverseSelector(selector, null)); 3208 registry.registerStaticUse(staticUse);
3210 }
3211
3212 void registerDynamicSetter(Selector selector) {
3213 registry.registerDynamicSetter(new UniverseSelector(selector, null));
3214 }
3215
3216 void registerStaticInvocation(FunctionElement function) {
3217 registry.registerStaticInvocation(function);
3218 } 3209 }
3219 3210
3220 void registerInstantiatedClass(ClassElement klass) { 3211 void registerInstantiatedClass(ClassElement klass) {
3221 registry.registerInstantiatedClass(klass); 3212 registry.registerInstantiatedClass(klass);
3222 } 3213 }
3223 3214
3224 void registerIsCheck(DartType type) { 3215 void registerIsCheck(DartType type) {
3225 registry.registerIsCheck(type); 3216 registry.registerIsCheck(type);
3226 } 3217 }
3227 3218
3228 void registerLocalInvoke(LocalElement element, Selector selector) { 3219 void registerLocalInvoke(LocalElement element, Selector selector) {
3229 registry.registerLocalInvoke(element, selector); 3220 registry.registerLocalInvoke(element, selector);
3230 } 3221 }
3231 3222
3232 void registerClosurization(FunctionElement element, ClosureKind kind) { 3223 void registerClosurization(FunctionElement element, ClosureKind kind) {
3233 if (kind == ClosureKind.localFunction) { 3224 if (kind == ClosureKind.localFunction) {
3234 // TODO(ahe): Get rid of the call to [registerStaticInvocation]. It is 3225 // TODO(ahe): Get rid of the call to [registerStaticUse]. It is
3235 // currently needed to ensure that local function expression closures are 3226 // currently needed to ensure that local function expression closures are
3236 // compiled correctly. For example, `[() {}].last()`, notice that `last` 3227 // compiled correctly. For example, `[() {}].last()`, notice that `last`
3237 // is a getter. This happens for both named and unnamed. 3228 // is a getter. This happens for both named and unnamed.
3238 registerStaticInvocation(element); 3229 registerStaticUse(new StaticUse.foreignUse(element));
3239 } 3230 }
3240 registry.registerClosurization(element, kind); 3231 registry.registerClosurization(element, kind);
3241 } 3232 }
3242 3233
3243 int compileLazyFieldInitializer(FieldElement field) { 3234 int compileLazyFieldInitializer(FieldElement field) {
3244 return context.backend.compileLazyFieldInitializer(field, registry); 3235 return context.backend.compileLazyFieldInitializer(field, registry);
3245 } 3236 }
3246 } 3237 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698