comparison graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java @ 9286:39f08ef7b5d8

Fixed bugs for execute evaluated generation.
author Christian Humer <christian.humer@gmail.com>
date Wed, 24 Apr 2013 18:39:41 +0200
parents e16363e50252
children 8e3a1635cc9e
comparison
equal deleted inserted replaced
9285:90eb4bb7f755 9286:39f08ef7b5d8
65 name += Utils.firstLetterUpperCase(specialization.getId()); 65 name += Utils.firstLetterUpperCase(specialization.getId());
66 name += "Node"; 66 name += "Node";
67 return name; 67 return name;
68 } 68 }
69 69
70 private static String valueNameEvaluated(ActualParameter targetParameter) {
71 return valueName(targetParameter) + "Evaluated";
72 }
73
70 private static String valueName(ActualParameter param) { 74 private static String valueName(ActualParameter param) {
71 return param.getLocalName(); 75 return param.getLocalName();
72 } 76 }
73 77
74 private static String castValueName(ActualParameter parameter) { 78 private static String castValueName(ActualParameter parameter) {
302 valuesNeedsCast = null; 306 valuesNeedsCast = null;
303 } else { 307 } else {
304 // find out which values needs a cast 308 // find out which values needs a cast
305 valuesNeedsCast = new HashSet<>(); 309 valuesNeedsCast = new HashSet<>();
306 for (GuardData guard : targetSpecialization.getGuards()) { 310 for (GuardData guard : targetSpecialization.getGuards()) {
307 for (ActualParameter parameter : guard.getParameters()) { 311 for (ActualParameter targetParameter : guard.getParameters()) {
308 NodeChildData field = node.findChild(parameter.getSpecification().getName()); 312 NodeChildData field = node.findChild(targetParameter.getSpecification().getName());
309 if (field == null) { 313 if (field == null) {
310 continue; 314 continue;
311 } 315 }
312 TypeData typeData = parameter.getTypeSystemType(); 316 TypeData targetType = targetParameter.getTypeSystemType();
313 if (typeData != null && !typeData.isGeneric()) { 317 ActualParameter sourceParameter = sourceSpecialization.findParameter(targetParameter.getLocalName());
314 valuesNeedsCast.add(parameter.getLocalName()); 318 if (sourceParameter == null) {
319 sourceParameter = targetParameter;
320 }
321 TypeData sourceType = sourceParameter.getTypeSystemType();
322
323 if (sourceType.needsCastTo(targetType)) {
324 valuesNeedsCast.add(targetParameter.getLocalName());
315 } 325 }
316 } 326 }
317 } 327 }
318 } 328 }
319 329
351 builder.tree(elseStatements); 361 builder.tree(elseStatements);
352 } 362 }
353 return builder.getRoot(); 363 return builder.getRoot();
354 } 364 }
355 365
356 private CodeTree createExplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) { 366 private CodeTree createExplicitGuards(CodeTreeBuilder parent, String conditionPrefix, TemplateMethod valueSpecialization, SpecializationData guardedSpecialization) {
357 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 367 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
358 String andOperator = conditionPrefix != null ? conditionPrefix + " && " : ""; 368 String andOperator = conditionPrefix != null ? conditionPrefix + " && " : "";
359 if (guardedSpecialization.getGuards().size() > 0) { 369 if (guardedSpecialization.getGuards().size() > 0) {
360 // Explicitly specified guards 370 // Explicitly specified guards
361 for (GuardData guard : guardedSpecialization.getGuards()) { 371 for (GuardData guard : guardedSpecialization.getGuards()) {
366 } 376 }
367 377
368 return builder.isEmpty() ? null : builder.getRoot(); 378 return builder.isEmpty() ? null : builder.getRoot();
369 } 379 }
370 380
371 private CodeTree createCasts(CodeTreeBuilder parent, Set<String> castWhiteList, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) { 381 private CodeTree createCasts(CodeTreeBuilder parent, Set<String> castWhiteList, TemplateMethod valueSpecialization, SpecializationData guardedSpecialization) {
372 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 382 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
373 // Implict guards based on method signature 383 // Implict guards based on method signature
374 for (ActualParameter guardedParam : guardedSpecialization.getParameters()) { 384 for (ActualParameter guardedParam : guardedSpecialization.getParameters()) {
375 NodeChildData field = guardedSpecialization.getNode().findChild(guardedParam.getSpecification().getName()); 385 NodeChildData field = guardedSpecialization.getNode().findChild(guardedParam.getSpecification().getName());
376 if (field == null) { 386 if (field == null) {
377 continue; 387 continue;
378 } 388 }
379 ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getLocalName()); 389 ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getLocalName());
380 390
391 if (valueParam == null) {
392 /*
393 * If used inside a function execute method. The value param may not exist. In that
394 * case it assumes that the value is already converted.
395 */
396 valueParam = guardedParam;
397 }
398
381 if (castWhiteList != null && !castWhiteList.contains(guardedParam.getLocalName())) { 399 if (castWhiteList != null && !castWhiteList.contains(guardedParam.getLocalName())) {
382 continue; 400 continue;
383 } 401 }
384 402
385 CodeTree cast = createCast(parent, field, valueParam, guardedParam); 403 CodeTree cast = createCast(parent, field, valueParam, guardedParam);
417 if (field == null) { 435 if (field == null) {
418 continue; 436 continue;
419 } 437 }
420 ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getLocalName()); 438 ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getLocalName());
421 439
440 if (valueParam == null) {
441 /*
442 * If used inside a function execute method. The value param may not exist. In that
443 * case it assumes that the value is already converted.
444 */
445 valueParam = guardedParam;
446 }
447
422 CodeTree implicitGuard = createImplicitGuard(builder, field, valueParam, guardedParam); 448 CodeTree implicitGuard = createImplicitGuard(builder, field, valueParam, guardedParam);
423 if (implicitGuard == null) { 449 if (implicitGuard == null) {
424 continue; 450 continue;
425 } 451 }
426 452
437 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 463 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
438 464
439 TypeData targetType = target.getTypeSystemType(); 465 TypeData targetType = target.getTypeSystemType();
440 TypeData sourceType = source.getTypeSystemType(); 466 TypeData sourceType = source.getTypeSystemType();
441 467
442 if (targetType.equalsType(sourceType) || targetType.isGeneric()) { 468 if (!sourceType.needsCastTo(targetType)) {
443 return null; 469 return null;
444 } 470 }
445 471
446 builder.startGroup(); 472 builder.startGroup();
447 473
1341 CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), execType.getMethod()); 1367 CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), execType.getMethod());
1342 1368
1343 int i = 0; 1369 int i = 0;
1344 for (VariableElement param : method.getParameters()) { 1370 for (VariableElement param : method.getParameters()) {
1345 CodeVariableElement var = CodeVariableElement.clone(param); 1371 CodeVariableElement var = CodeVariableElement.clone(param);
1346 var.setName(valueName(execType.getParameters().get(i))); 1372 ActualParameter actualParameter = execType.getParameters().get(i);
1373 if (actualParameter.getSpecification().isSignature()) {
1374 var.setName(valueNameEvaluated(actualParameter));
1375 } else {
1376 var.setName(valueName(actualParameter));
1377 }
1347 method.getParameters().set(i, var); 1378 method.getParameters().set(i, var);
1348 i++; 1379 i++;
1349 } 1380 }
1350 1381
1351 method.getAnnotationMirrors().clear(); 1382 method.getAnnotationMirrors().clear();
1411 continue; 1442 continue;
1412 } 1443 }
1413 1444
1414 ActualParameter targetParameter = castExecutable.findParameter(sourceParameter.getLocalName()); 1445 ActualParameter targetParameter = castExecutable.findParameter(sourceParameter.getLocalName());
1415 if (targetParameter != null) { 1446 if (targetParameter != null) {
1416 TypeData sourceType = sourceParameter.getTypeSystemType(); 1447 executeParameters.add(targetParameter);
1417 TypeData targetType = targetParameter.getTypeSystemType();
1418 if (sourceType.needsCastTo(targetType)) {
1419 executeParameters.add(targetParameter);
1420 }
1421 } 1448 }
1422 } 1449 }
1423 1450
1424 builder.tree(createExecuteChildren(builder, executable, specialization, executeParameters, null, true)); 1451 builder.tree(createExecuteChildren(builder, executable, specialization, executeParameters, null, true));
1425 1452
1498 1525
1499 builder.tree(createExecuteChildren(builder, executable, specialization, specialization.getParameters(), null, false)); 1526 builder.tree(createExecuteChildren(builder, executable, specialization, specialization.getParameters(), null, false));
1500 1527
1501 CodeTree executeNode; 1528 CodeTree executeNode;
1502 if (specialization.isUninitialized()) { 1529 if (specialization.isUninitialized()) {
1503 builder.tree(createSpecializeCall(builder, executable, specialization)); 1530 builder.tree(createSpecializeCall(builder, specialization));
1504 } 1531 }
1505 executeNode = createExecute(builder, executable, specialization); 1532 executeNode = createExecute(builder, executable, specialization);
1506 1533
1507 SpecializationData next = specialization.findNextSpecialization(); 1534 SpecializationData next = specialization.findNextSpecialization();
1508 CodeTree returnSpecialized = null; 1535 CodeTree returnSpecialized = null;
1520 builder.startStaticCall(getContext().getTruffleTypes().getCompilerDirectives(), "transferToInterpreter").end(); 1547 builder.startStaticCall(getContext().getTruffleTypes().getCompilerDirectives(), "transferToInterpreter").end();
1521 builder.end(); 1548 builder.end();
1522 return builder.getRoot(); 1549 return builder.getRoot();
1523 } 1550 }
1524 1551
1525 private CodeTree createSpecializeCall(CodeTreeBuilder parent, ExecutableTypeData executable, SpecializationData specialization) { 1552 private CodeTree createSpecializeCall(CodeTreeBuilder parent, SpecializationData specialization) {
1526 NodeData node = specialization.getNode(); 1553 NodeData node = specialization.getNode();
1527 1554
1528 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 1555 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
1529 emitSpecializationListeners(builder, node); 1556 emitSpecializationListeners(builder, node);
1530 1557
1532 builder.startCall("replace"); 1559 builder.startCall("replace");
1533 if (node.needsRewrites(getContext())) { 1560 if (node.needsRewrites(getContext())) {
1534 builder.startCall(factoryClassName(node), "specialize"); 1561 builder.startCall(factoryClassName(node), "specialize");
1535 builder.string("this"); 1562 builder.string("this");
1536 builder.typeLiteral(builder.findMethod().getEnclosingElement().asType()); 1563 builder.typeLiteral(builder.findMethod().getEnclosingElement().asType());
1537 addInternalValueParameterNames(builder, executable, specialization, null, true, true); 1564 addInternalValueParameterNames(builder, specialization, specialization, null, true, true);
1538 builder.end(); // call replace, call specialize 1565 builder.end(); // call replace, call specialize
1539 } else { 1566 } else {
1540 builder.startCall(factoryClassName(node), "createSpecialized").string("this").string("null").end(); 1567 builder.startCall(factoryClassName(node), "createSpecialized").string("this").string("null").end();
1541 } 1568 }
1542 builder.end().end(); 1569 builder.end().end();
1560 CodeTreeBuilder returnBuilder = new CodeTreeBuilder(parent); 1587 CodeTreeBuilder returnBuilder = new CodeTreeBuilder(parent);
1561 if (specialization.isUninitialized()) { 1588 if (specialization.isUninitialized()) {
1562 String genericMethodName = generatedGenericMethodName(null); 1589 String genericMethodName = generatedGenericMethodName(null);
1563 returnBuilder.startCall(factoryClassName(node), genericMethodName); 1590 returnBuilder.startCall(factoryClassName(node), genericMethodName);
1564 returnBuilder.string("this"); 1591 returnBuilder.string("this");
1565 addInternalValueParameterNames(returnBuilder, executable, specialization, null, true, true); 1592 addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, true);
1566 returnBuilder.end(); 1593 returnBuilder.end();
1567 } else if (specialization.getMethod() == null && !node.needsRewrites(context)) { 1594 } else if (specialization.getMethod() == null && !node.needsRewrites(context)) {
1568 emitEncounteredSynthetic(builder); 1595 emitEncounteredSynthetic(builder);
1569 } else if (specialization.isGeneric()) { 1596 } else if (specialization.isGeneric()) {
1570 String genericMethodName; 1597 String genericMethodName;
1574 genericMethodName = generatedGenericMethodName(null); 1601 genericMethodName = generatedGenericMethodName(null);
1575 } 1602 }
1576 1603
1577 returnBuilder.startCall(factoryClassName(node), genericMethodName); 1604 returnBuilder.startCall(factoryClassName(node), genericMethodName);
1578 returnBuilder.string("this"); 1605 returnBuilder.string("this");
1579 addInternalValueParameterNames(returnBuilder, executable, specialization, null, true, true); 1606 addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, true);
1580 returnBuilder.end(); 1607 returnBuilder.end();
1581 } else { 1608 } else {
1582 returnBuilder.tree(createTemplateMethodCall(returnBuilder, executable, specialization, null)); 1609 returnBuilder.tree(createTemplateMethodCall(returnBuilder, specialization, specialization, null));
1583 } 1610 }
1584 1611
1585 if (!returnBuilder.isEmpty()) { 1612 if (!returnBuilder.isEmpty()) {
1586 builder.startReturn(); 1613 builder.startReturn();
1587 1614
1629 1656
1630 ExecutableTypeData targetExecutable = field.getNodeData().findExecutableType(targetType); 1657 ExecutableTypeData targetExecutable = field.getNodeData().findExecutableType(targetType);
1631 1658
1632 ActualParameter sourceParameter = sourceExecutable.findParameter(targetParameter.getLocalName()); 1659 ActualParameter sourceParameter = sourceExecutable.findParameter(targetParameter.getLocalName());
1633 1660
1634 String targetVariableName = null; 1661 String targetVariableName = valueName(targetParameter);
1635 CodeTree executionExpression = null; 1662 CodeTree executionExpression = null;
1636 if (cast || sourceParameter != null) { 1663 if (cast || sourceParameter != null) {
1637 TypeData sourceType = sourceParameter.getTypeSystemType(); 1664 TypeData sourceType = sourceParameter.getTypeSystemType();
1638 if (!sourceType.needsCastTo(targetType)) { 1665 if (!sourceType.needsCastTo(targetType)) {
1639 if (field.isShortCircuit() && sourceParameter != null) { 1666 if (field.isShortCircuit() && sourceParameter != null) {
1640 builder.tree(createShortCircuitValue(builder, sourceExecutable, specialization, field, targetParameter.getPreviousParameter(), unexpectedParameter)); 1667 builder.tree(createShortCircuitValue(builder, specialization, field, targetParameter.getPreviousParameter(), unexpectedParameter));
1641 } 1668 }
1642 continue; 1669 builder.startStatement();
1670 builder.type(targetParameter.getType()).string(" ");
1671 builder.string(valueName(targetParameter)).string(" = ");
1672 builder.tree(CodeTreeBuilder.singleString(valueNameEvaluated(targetParameter)));
1673 builder.end();
1674 } else {
1675 executionExpression = createExpectType(sourceNode, targetExecutable, CodeTreeBuilder.singleString(valueNameEvaluated(targetParameter)));
1643 } 1676 }
1644 executionExpression = createExpectType(sourceNode, targetExecutable, CodeTreeBuilder.singleString(valueName(targetParameter)));
1645 targetVariableName = castValueName(targetParameter);
1646 } else if (sourceParameter == null) { 1677 } else if (sourceParameter == null) {
1647 targetVariableName = valueName(targetParameter);
1648 executionExpression = createExecuteChildExpression(builder, field, targetParameter); 1678 executionExpression = createExecuteChildExpression(builder, field, targetParameter);
1649 } 1679 }
1650 1680
1651 CodeTreeVariable executionVar = new CodeTreeVariable(); 1681 if (executionExpression != null) {
1652 CodeTree shortCircuitTree = createShortCircuitTree(builder, executionVar, targetVariableName, sourceExecutable, specialization, targetParameter, unexpectedParameter); 1682 CodeTreeVariable executionVar = new CodeTreeVariable();
1653 CodeTree unexpectedTree = createCatchUnexpectedTree(builder, executionExpression, targetVariableName, specialization, sourceExecutable, targetExecutable, targetParameter, 1683 CodeTree shortCircuitTree = createShortCircuitTree(builder, executionVar, targetVariableName, specialization, targetParameter, unexpectedParameter);
1654 shortCircuitTree != executionVar); 1684 CodeTree unexpectedTree = createCatchUnexpectedTree(builder, executionExpression, targetVariableName, specialization, sourceExecutable, targetExecutable, targetParameter,
1655 1685 shortCircuitTree != executionVar);
1656 executionVar.set(unexpectedTree); 1686
1657 builder.tree(shortCircuitTree); 1687 executionVar.set(unexpectedTree);
1688 builder.tree(shortCircuitTree);
1689 }
1658 } 1690 }
1659 return builder.getRoot(); 1691 return builder.getRoot();
1660 } 1692 }
1661 1693
1662 private void emitSpecializationListeners(CodeTreeBuilder builder, NodeData node) { 1694 private void emitSpecializationListeners(CodeTreeBuilder builder, NodeData node) {
1736 } 1768 }
1737 builder.end(); 1769 builder.end();
1738 return builder.getRoot(); 1770 return builder.getRoot();
1739 } 1771 }
1740 1772
1741 private CodeTree createShortCircuitTree(CodeTreeBuilder parent, CodeTree body, String targetVariableName, ExecutableTypeData currentExecutable, SpecializationData specialization, 1773 private CodeTree createShortCircuitTree(CodeTreeBuilder parent, CodeTree body, String targetVariableName, SpecializationData specialization, ActualParameter parameter,
1742 ActualParameter parameter, ActualParameter exceptionParam) { 1774 ActualParameter exceptionParam) {
1743 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 1775 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
1744 1776
1745 NodeChildData forField = specialization.getNode().findChild(parameter.getSpecification().getName()); 1777 NodeChildData forField = specialization.getNode().findChild(parameter.getSpecification().getName());
1746 if (forField == null) { 1778 if (forField == null) {
1747 return body; 1779 return body;
1751 return body; 1783 return body;
1752 } 1784 }
1753 1785
1754 ActualParameter shortCircuitParam = specialization.getPreviousParam(parameter); 1786 ActualParameter shortCircuitParam = specialization.getPreviousParam(parameter);
1755 1787
1756 builder.tree(createShortCircuitValue(builder, currentExecutable, specialization, forField, shortCircuitParam, exceptionParam)); 1788 builder.tree(createShortCircuitValue(builder, specialization, forField, shortCircuitParam, exceptionParam));
1757 1789
1758 builder.declaration(parameter.getType(), targetVariableName, CodeTreeBuilder.createBuilder().defaultValue(parameter.getType())); 1790 builder.declaration(parameter.getType(), targetVariableName, CodeTreeBuilder.createBuilder().defaultValue(parameter.getType()));
1759 builder.startIf().string(shortCircuitParam.getLocalName()).end(); 1791 builder.startIf().string(shortCircuitParam.getLocalName()).end();
1760 builder.startBlock(); 1792 builder.startBlock();
1761 builder.tree(body); 1793 builder.tree(body);
1762 builder.end(); 1794 builder.end();
1763 1795
1764 return builder.getRoot(); 1796 return builder.getRoot();
1765 } 1797 }
1766 1798
1767 private CodeTree createShortCircuitValue(CodeTreeBuilder parent, ExecutableTypeData currentExecutable, SpecializationData specialization, NodeChildData forField, 1799 private CodeTree createShortCircuitValue(CodeTreeBuilder parent, SpecializationData specialization, NodeChildData forField, ActualParameter shortCircuitParam, ActualParameter exceptionParam) {
1768 ActualParameter shortCircuitParam, ActualParameter exceptionParam) {
1769 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 1800 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
1770 int shortCircuitIndex = 0; 1801 int shortCircuitIndex = 0;
1771 for (NodeChildData field : specialization.getNode().getChildren()) { 1802 for (NodeChildData field : specialization.getNode().getChildren()) {
1772 if (field.getExecutionKind() == ExecutionKind.SHORT_CIRCUIT) { 1803 if (field.getExecutionKind() == ExecutionKind.SHORT_CIRCUIT) {
1773 if (field == forField) { 1804 if (field == forField) {
1777 } 1808 }
1778 } 1809 }
1779 1810
1780 builder.startStatement().type(shortCircuitParam.getType()).string(" ").string(valueName(shortCircuitParam)).string(" = "); 1811 builder.startStatement().type(shortCircuitParam.getType()).string(" ").string(valueName(shortCircuitParam)).string(" = ");
1781 ShortCircuitData shortCircuitData = specialization.getShortCircuits().get(shortCircuitIndex); 1812 ShortCircuitData shortCircuitData = specialization.getShortCircuits().get(shortCircuitIndex);
1782 builder.tree(createTemplateMethodCall(builder, currentExecutable, shortCircuitData, exceptionParam != null ? exceptionParam.getLocalName() : null)); 1813 builder.tree(createTemplateMethodCall(builder, specialization, shortCircuitData, exceptionParam != null ? exceptionParam.getLocalName() : null));
1783 builder.end(); // statement 1814 builder.end(); // statement
1784 1815
1785 return builder.getRoot(); 1816 return builder.getRoot();
1786 } 1817 }
1787 1818
1788 private CodeTree createReturnSpecializeAndExecute(CodeTreeBuilder parent, ExecutableTypeData executable, SpecializationData nextSpecialization, ActualParameter exceptionParam) { 1819 private CodeTree createReturnSpecializeAndExecute(CodeTreeBuilder parent, ExecutableTypeData executable, SpecializationData nextSpecialization, ActualParameter exceptionParam) {
1789 CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent); 1820 CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent);
1790 specializeCall.startCall("specializeAndExecute"); 1821 specializeCall.startCall("specializeAndExecute");
1791 specializeCall.string(nodeSpecializationClassName(nextSpecialization) + ".class"); 1822 specializeCall.string(nodeSpecializationClassName(nextSpecialization) + ".class");
1792 addInternalValueParameterNames(specializeCall, executable, nextSpecialization.getNode().getGenericSpecialization(), exceptionParam != null ? exceptionParam.getLocalName() : null, true, 1823 addInternalValueParameterNames(specializeCall, nextSpecialization.getNode().getGenericSpecialization(), nextSpecialization.getNode().getGenericSpecialization(),
1793 true); 1824 exceptionParam != null ? exceptionParam.getLocalName() : null, true, true);
1794 specializeCall.end().end(); 1825 specializeCall.end().end();
1795 1826
1796 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 1827 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
1797 builder.startReturn(); 1828 builder.startReturn();
1798 builder.tree(createExpectType(nextSpecialization.getNode(), executable, specializeCall.getRoot())); 1829 builder.tree(createExpectType(nextSpecialization.getNode(), executable, specializeCall.getRoot()));