Mercurial > hg > graal-jvmci-8
comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java @ 11443:b33783cbd8ce
Truffle-DSL: refactored redundant guard generation code.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Wed, 28 Aug 2013 11:41:10 +0200 |
parents | 2868b55001d4 |
children | 5fbd1ba4a5f3 |
comparison
equal
deleted
inserted
replaced
11442:2868b55001d4 | 11443:b33783cbd8ce |
---|---|
322 body.startGroup(); | 322 body.startGroup(); |
323 body.staticReference(singleton.getEnclosingElement().asType(), singleton.getSimpleName().toString()); | 323 body.staticReference(singleton.getEnclosingElement().asType(), singleton.getSimpleName().toString()); |
324 body.string(".").startCall(methodName); | 324 body.string(".").startCall(methodName); |
325 } | 325 } |
326 | 326 |
327 private CodeTree createGuardAndCast(CodeTreeBuilder parent, String conditionPrefix, SpecializationData sourceSpecialization, SpecializationData targetSpecialization, boolean castValues, | |
328 CodeTree guardedStatements, CodeTree elseStatements, boolean emitAssumptions, boolean forceElse) { | |
329 | |
330 NodeData node = targetSpecialization.getNode(); | |
331 CodeTreeBuilder builder = new CodeTreeBuilder(parent); | |
332 CodeTree implicitGuards = createImplicitGuards(parent, conditionPrefix, sourceSpecialization, targetSpecialization, emitAssumptions); | |
333 CodeTree explicitGuards = createExplicitGuards(parent, implicitGuards == null ? conditionPrefix : null, sourceSpecialization, targetSpecialization); | |
334 | |
335 Set<String> valuesNeedsCast; | |
336 if (castValues) { | |
337 // cast all | |
338 valuesNeedsCast = null; | |
339 } else { | |
340 // find out which values needs a cast | |
341 valuesNeedsCast = new HashSet<>(); | |
342 for (GuardData guard : targetSpecialization.getGuards()) { | |
343 for (ActualParameter targetParameter : guard.getParameters()) { | |
344 NodeChildData field = node.findChild(targetParameter.getSpecification().getName()); | |
345 if (field == null) { | |
346 continue; | |
347 } | |
348 TypeData targetType = targetParameter.getTypeSystemType(); | |
349 ActualParameter sourceParameter = sourceSpecialization.findParameter(targetParameter.getLocalName()); | |
350 if (sourceParameter == null) { | |
351 sourceParameter = targetParameter; | |
352 } | |
353 TypeData sourceType = sourceParameter.getTypeSystemType(); | |
354 | |
355 if (sourceType.needsCastTo(getContext(), targetType)) { | |
356 valuesNeedsCast.add(targetParameter.getLocalName()); | |
357 } | |
358 } | |
359 } | |
360 } | |
361 | |
362 int ifCount = 0; | |
363 | |
364 if (implicitGuards != null) { | |
365 builder.startIf(); | |
366 builder.tree(implicitGuards); | |
367 builder.end(); | |
368 builder.startBlock(); | |
369 ifCount++; | |
370 } | |
371 | |
372 builder.tree(createCasts(parent, valuesNeedsCast, sourceSpecialization, targetSpecialization)); | |
373 | |
374 if (explicitGuards != null) { | |
375 builder.startIf(); | |
376 builder.tree(explicitGuards); | |
377 builder.end(); | |
378 builder.startBlock(); | |
379 ifCount++; | |
380 } | |
381 | |
382 if (implicitGuards == null && explicitGuards == null && conditionPrefix != null && !conditionPrefix.isEmpty()) { | |
383 builder.startIf(); | |
384 builder.string(conditionPrefix); | |
385 builder.end().startBlock(); | |
386 ifCount++; | |
387 } | |
388 | |
389 builder.tree(guardedStatements); | |
390 | |
391 builder.end(ifCount); | |
392 if (elseStatements != null && (forceElse || ifCount > 0)) { | |
393 builder.tree(elseStatements); | |
394 } | |
395 return builder.getRoot(); | |
396 } | |
397 | |
398 private CodeTree createExplicitGuards(CodeTreeBuilder parent, String conditionPrefix, TemplateMethod valueSpecialization, SpecializationData guardedSpecialization) { | |
399 CodeTreeBuilder builder = new CodeTreeBuilder(parent); | |
400 String andOperator = conditionPrefix != null ? conditionPrefix + " && " : ""; | |
401 if (guardedSpecialization.getGuards().size() > 0) { | |
402 // Explicitly specified guards | |
403 for (GuardData guard : guardedSpecialization.getGuards()) { | |
404 builder.string(andOperator); | |
405 if (guard.isNegated()) { | |
406 builder.string("!"); | |
407 } | |
408 builder.tree(createTemplateMethodCall(parent, null, valueSpecialization, guard, null)); | |
409 andOperator = " && "; | |
410 } | |
411 } | |
412 | |
413 return builder.isEmpty() ? null : builder.getRoot(); | |
414 } | |
415 | |
416 private CodeTree createCasts(CodeTreeBuilder parent, Set<String> castWhiteList, TemplateMethod valueSpecialization, SpecializationData guardedSpecialization) { | |
417 CodeTreeBuilder builder = new CodeTreeBuilder(parent); | |
418 // Implict guards based on method signature | |
419 for (ActualParameter guardedParam : guardedSpecialization.getParameters()) { | |
420 NodeChildData field = guardedSpecialization.getNode().findChild(guardedParam.getSpecification().getName()); | |
421 if (field == null) { | |
422 continue; | |
423 } | |
424 ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getLocalName()); | |
425 | |
426 if (valueParam == null) { | |
427 /* | |
428 * If used inside a function execute method. The value param may not exist. In that | |
429 * case it assumes that the value is already converted. | |
430 */ | |
431 valueParam = guardedParam; | |
432 } | |
433 | |
434 if (castWhiteList != null && !castWhiteList.contains(guardedParam.getLocalName())) { | |
435 continue; | |
436 } | |
437 | |
438 CodeTree cast = createCast(parent, field, valueParam, guardedParam.getTypeSystemType()); | |
439 if (cast == null) { | |
440 continue; | |
441 } | |
442 builder.tree(cast); | |
443 } | |
444 | |
445 return builder.getRoot(); | |
446 } | |
447 | |
448 private CodeTree createImplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization, boolean emitAssumptions) { | |
449 CodeTreeBuilder builder = new CodeTreeBuilder(parent); | |
450 // Implict guards based on method signature | |
451 String andOperator = conditionPrefix != null ? conditionPrefix + " && " : ""; | |
452 | |
453 if (emitAssumptions) { | |
454 for (String assumption : guardedSpecialization.getAssumptions()) { | |
455 builder.string(andOperator); | |
456 builder.string("this"); | |
457 builder.string(".").string(assumption).string(".isValid()"); | |
458 andOperator = " && "; | |
459 } | |
460 } | |
461 | |
462 for (ActualParameter guardedParam : guardedSpecialization.getParameters()) { | |
463 NodeChildData field = guardedSpecialization.getNode().findChild(guardedParam.getSpecification().getName()); | |
464 if (field == null) { | |
465 continue; | |
466 } | |
467 ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getLocalName()); | |
468 | |
469 if (valueParam == null) { | |
470 /* | |
471 * If used inside a function execute method. The value param may not exist. In that | |
472 * case it assumes that the value is already converted. | |
473 */ | |
474 valueParam = guardedParam; | |
475 } | |
476 | |
477 CodeTree implicitGuard = createTypeGuard(builder, field, valueParam, guardedParam.getTypeSystemType()); | |
478 if (implicitGuard == null) { | |
479 continue; | |
480 } | |
481 | |
482 builder.string(andOperator); | |
483 builder.tree(implicitGuard); | |
484 andOperator = " && "; | |
485 } | |
486 | |
487 return builder.isEmpty() ? null : builder.getRoot(); | |
488 } | |
489 | |
490 private CodeTree createTypeGuard(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, TypeData targetType) { | |
491 NodeData node = field.getNodeData(); | |
492 | |
493 CodeTreeBuilder builder = new CodeTreeBuilder(parent); | |
494 | |
495 TypeData sourceType = source.getTypeSystemType(); | |
496 | |
497 if (!sourceType.needsCastTo(getContext(), targetType)) { | |
498 return null; | |
499 } | |
500 | |
501 builder.startGroup(); | |
502 | |
503 if (field.isShortCircuit()) { | |
504 ActualParameter shortCircuit = source.getPreviousParameter(); | |
505 assert shortCircuit != null; | |
506 builder.string("("); | |
507 builder.string("!").string(valueName(shortCircuit)); | |
508 builder.string(" || "); | |
509 } | |
510 | |
511 startCallTypeSystemMethod(getContext(), builder, node, TypeSystemCodeGenerator.isTypeMethodName(targetType)); | |
512 builder.string(valueName(source)); | |
513 builder.end().end(); // call | |
514 | |
515 if (field.isShortCircuit()) { | |
516 builder.string(")"); | |
517 } | |
518 | |
519 builder.end(); // group | |
520 | |
521 return builder.getRoot(); | |
522 } | |
523 | |
524 private CodeTree createCast(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, TypeData targetType) { | |
525 NodeData node = field.getNodeData(); | |
526 TypeData sourceType = source.getTypeSystemType(); | |
527 | |
528 if (!sourceType.needsCastTo(getContext(), targetType)) { | |
529 return null; | |
530 } | |
531 | |
532 CodeTree condition = null; | |
533 if (field.isShortCircuit()) { | |
534 ActualParameter shortCircuit = source.getPreviousParameter(); | |
535 assert shortCircuit != null; | |
536 condition = CodeTreeBuilder.singleString(valueName(shortCircuit)); | |
537 } | |
538 | |
539 CodeTree value = createCallTypeSystemMethod(context, parent, node, TypeSystemCodeGenerator.asTypeMethodName(targetType), CodeTreeBuilder.singleString(valueName(source))); | |
540 | |
541 return createLazyAssignment(parent, castValueName(source), targetType.getPrimitiveType(), condition, value); | |
542 } | |
543 | |
544 /** | 327 /** |
545 * <pre> | 328 * <pre> |
546 * variant1 $condition != null | 329 * variant1 $condition != null |
547 * | 330 * |
548 * $type $name = defaultValue($type); | 331 * $type $name = defaultValue($type); |
1442 builder.tree(createExecuteTree(builder, node.getGenericSpecialization(), rootGroup, true, new CodeBlock<SpecializationData>() { | 1225 builder.tree(createExecuteTree(builder, node.getGenericSpecialization(), rootGroup, true, new CodeBlock<SpecializationData>() { |
1443 | 1226 |
1444 public CodeTree create(CodeTreeBuilder b, SpecializationData current) { | 1227 public CodeTree create(CodeTreeBuilder b, SpecializationData current) { |
1445 return createGenericInvokeAndSpecialize(b, node.getGenericSpecialization(), current, currentNodeVar); | 1228 return createGenericInvokeAndSpecialize(b, node.getGenericSpecialization(), current, currentNodeVar); |
1446 } | 1229 } |
1447 })); | 1230 }, null, false, true)); |
1448 | 1231 |
1449 boolean firstUnreachable = true; | 1232 boolean firstUnreachable = true; |
1450 for (SpecializationData current : node.getSpecializations()) { | 1233 for (SpecializationData current : node.getSpecializations()) { |
1451 if (current.isUninitialized() || current.isReachable()) { | 1234 if (current.isUninitialized() || current.isReachable()) { |
1452 continue; | 1235 continue; |
1486 builder.tree(createExecuteTree(builder, node.getGenericSpecialization(), group, false, new CodeBlock<SpecializationData>() { | 1269 builder.tree(createExecuteTree(builder, node.getGenericSpecialization(), group, false, new CodeBlock<SpecializationData>() { |
1487 | 1270 |
1488 public CodeTree create(CodeTreeBuilder b, SpecializationData current) { | 1271 public CodeTree create(CodeTreeBuilder b, SpecializationData current) { |
1489 return createGenericInvoke(builder, current.getNode().getGenericSpecialization(), current); | 1272 return createGenericInvoke(builder, current.getNode().getGenericSpecialization(), current); |
1490 } | 1273 } |
1491 })); | 1274 }, null, false, true)); |
1492 | 1275 |
1493 emitUnreachableSpecializations(builder, node); | 1276 emitUnreachableSpecializations(builder, node); |
1494 | 1277 |
1495 return method; | 1278 return method; |
1496 } | 1279 } |
1502 } | 1285 } |
1503 builder.string("// unreachable ").string(current.getId()).newLine(); | 1286 builder.string("// unreachable ").string(current.getId()).newLine(); |
1504 } | 1287 } |
1505 } | 1288 } |
1506 | 1289 |
1507 private CodeTree createExecuteTree(CodeTreeBuilder outerParent, final SpecializationData source, final SpecializationGroup group, final boolean checkMinimumState, | 1290 protected CodeTree createExecuteTree(CodeTreeBuilder outerParent, final SpecializationData source, final SpecializationGroup group, final boolean checkMinimumState, |
1508 final CodeBlock<SpecializationData> guardedblock) { | 1291 final CodeBlock<SpecializationData> guardedblock, final CodeTree elseBlock, boolean forceElse, final boolean emitAssumptions) { |
1509 return guard(outerParent, source, group, checkMinimumState, new CodeBlock<Void>() { | 1292 return guard(outerParent, source, group, checkMinimumState, new CodeBlock<Integer>() { |
1510 | 1293 |
1511 public CodeTree create(CodeTreeBuilder parent, Void value) { | 1294 public CodeTree create(CodeTreeBuilder parent, Integer ifCount) { |
1512 CodeTreeBuilder builder = parent.create(); | 1295 CodeTreeBuilder builder = parent.create(); |
1513 | 1296 |
1514 if (group.getSpecialization() != null) { | 1297 if (group.getSpecialization() != null) { |
1515 builder.tree(guardedblock.create(builder, group.getSpecialization())); | 1298 builder.tree(guardedblock.create(builder, group.getSpecialization())); |
1516 | 1299 |
1517 assert group.getChildren().isEmpty() : "missed a specialization"; | 1300 assert group.getChildren().isEmpty() : "missed a specialization"; |
1301 | |
1518 } else { | 1302 } else { |
1519 for (SpecializationGroup childGroup : group.getChildren()) { | 1303 for (SpecializationGroup childGroup : group.getChildren()) { |
1520 builder.tree(createExecuteTree(builder, source, childGroup, checkMinimumState, guardedblock)); | 1304 builder.tree(createExecuteTree(builder, source, childGroup, checkMinimumState, guardedblock, null, false, emitAssumptions)); |
1521 } | 1305 } |
1522 } | 1306 } |
1523 | 1307 |
1524 return builder.getRoot(); | 1308 return builder.getRoot(); |
1525 } | 1309 } |
1526 }); | 1310 }, elseBlock, forceElse, emitAssumptions); |
1527 } | 1311 } |
1528 | 1312 |
1529 private CodeTree guard(CodeTreeBuilder parent, SpecializationData source, SpecializationGroup group, boolean checkMinimumState, CodeBlock<Void> bodyBlock) { | 1313 private CodeTree guard(CodeTreeBuilder parent, SpecializationData source, SpecializationGroup group, boolean checkMinimumState, CodeBlock<Integer> bodyBlock, CodeTree elseBlock, |
1314 boolean forceElse, boolean emitAssumptions) { | |
1530 CodeTreeBuilder builder = parent.create(); | 1315 CodeTreeBuilder builder = parent.create(); |
1531 | 1316 |
1532 int ifCount = emitGuards(builder, source, group, checkMinimumState); | 1317 int ifCount = emitGuards(builder, source, group, checkMinimumState, emitAssumptions); |
1533 | 1318 |
1534 if (isReachableGroup(group, ifCount, checkMinimumState)) { | 1319 if (isReachableGroup(group, ifCount, checkMinimumState)) { |
1535 builder.tree(bodyBlock.create(builder, null)); | 1320 builder.tree(bodyBlock.create(builder, ifCount)); |
1536 } | 1321 } |
1537 | 1322 |
1538 builder.end(ifCount); | 1323 builder.end(ifCount); |
1324 | |
1325 if (elseBlock != null) { | |
1326 if (ifCount > 0 || forceElse) { | |
1327 builder.tree(elseBlock); | |
1328 } | |
1329 } | |
1539 | 1330 |
1540 return builder.getRoot(); | 1331 return builder.getRoot(); |
1541 } | 1332 } |
1542 | 1333 |
1543 private boolean isReachableGroup(SpecializationGroup group, int ifCount, boolean checkMinimumState) { | 1334 private boolean isReachableGroup(SpecializationGroup group, int ifCount, boolean checkMinimumState) { |
1559 } | 1350 } |
1560 | 1351 |
1561 return true; | 1352 return true; |
1562 } | 1353 } |
1563 | 1354 |
1564 private int emitGuards(CodeTreeBuilder builder, SpecializationData source, SpecializationGroup group, boolean checkMinimumState) { | 1355 private int emitGuards(CodeTreeBuilder builder, SpecializationData source, SpecializationGroup group, boolean checkMinimumState, boolean emitAssumptions) { |
1565 NodeData node = source.getNode(); | 1356 NodeData node = source.getNode(); |
1566 | 1357 |
1567 CodeTreeBuilder guardsBuilder = builder.create(); | 1358 CodeTreeBuilder guardsBuilder = builder.create(); |
1568 CodeTreeBuilder castBuilder = builder.create(); | 1359 CodeTreeBuilder castBuilder = builder.create(); |
1569 CodeTreeBuilder guardsCastBuilder = builder.create(); | 1360 CodeTreeBuilder guardsCastBuilder = builder.create(); |
1599 guardsBuilder.string("minimumState < " + groupMaxIndex); | 1390 guardsBuilder.string("minimumState < " + groupMaxIndex); |
1600 guardsAnd = " && "; | 1391 guardsAnd = " && "; |
1601 } | 1392 } |
1602 } | 1393 } |
1603 | 1394 |
1604 for (String assumption : group.getAssumptions()) { | 1395 if (emitAssumptions) { |
1605 guardsBuilder.string(guardsAnd); | 1396 for (String assumption : group.getAssumptions()) { |
1606 guardsBuilder.string("this"); | 1397 guardsBuilder.string(guardsAnd); |
1607 guardsBuilder.string(".").string(assumption).string(".isValid()"); | 1398 guardsBuilder.string("this"); |
1608 guardsAnd = " && "; | 1399 guardsBuilder.string(".").string(assumption).string(".isValid()"); |
1400 guardsAnd = " && "; | |
1401 } | |
1609 } | 1402 } |
1610 | 1403 |
1611 for (TypeGuard typeGuard : group.getTypeGuards()) { | 1404 for (TypeGuard typeGuard : group.getTypeGuards()) { |
1612 ActualParameter valueParam = source.getSignatureParameter(typeGuard.getSignatureIndex()); | 1405 ActualParameter valueParam = source.getSignatureParameter(typeGuard.getSignatureIndex()); |
1613 | 1406 |
1695 ActualParameter sourceParameter = source.findParameter(parameter.getLocalName()); | 1488 ActualParameter sourceParameter = source.findParameter(parameter.getLocalName()); |
1696 if (sourceParameter == null) { | 1489 if (sourceParameter == null) { |
1697 sourceParameter = source.getNode().getGenericSpecialization().findParameter(parameter.getLocalName()); | 1490 sourceParameter = source.getNode().getGenericSpecialization().findParameter(parameter.getLocalName()); |
1698 } | 1491 } |
1699 | 1492 |
1700 if (sourceParameter.getTypeSystemType().needsCastTo(getContext(), requiredType)) { | 1493 if (Utils.needsCastTo(getContext(), sourceParameter.getType(), requiredType.getPrimitiveType())) { |
1701 return true; | 1494 return true; |
1702 } | 1495 } |
1703 } | 1496 } |
1704 | 1497 |
1705 signatureIndex++; | 1498 signatureIndex++; |
1706 } | 1499 } |
1707 return false; | 1500 return false; |
1501 } | |
1502 | |
1503 private CodeTree createTypeGuard(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, TypeData targetType) { | |
1504 NodeData node = field.getNodeData(); | |
1505 | |
1506 CodeTreeBuilder builder = new CodeTreeBuilder(parent); | |
1507 | |
1508 TypeData sourceType = source.getTypeSystemType(); | |
1509 | |
1510 if (!sourceType.needsCastTo(getContext(), targetType)) { | |
1511 return null; | |
1512 } | |
1513 | |
1514 builder.startGroup(); | |
1515 | |
1516 if (field.isShortCircuit()) { | |
1517 ActualParameter shortCircuit = source.getPreviousParameter(); | |
1518 assert shortCircuit != null; | |
1519 builder.string("("); | |
1520 builder.string("!").string(valueName(shortCircuit)); | |
1521 builder.string(" || "); | |
1522 } | |
1523 | |
1524 startCallTypeSystemMethod(getContext(), builder, node, TypeSystemCodeGenerator.isTypeMethodName(targetType)); | |
1525 builder.string(valueName(source)); | |
1526 builder.end().end(); // call | |
1527 | |
1528 if (field.isShortCircuit()) { | |
1529 builder.string(")"); | |
1530 } | |
1531 | |
1532 builder.end(); // group | |
1533 | |
1534 return builder.getRoot(); | |
1535 } | |
1536 | |
1537 private CodeTree createCast(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, TypeData targetType) { | |
1538 NodeData node = field.getNodeData(); | |
1539 TypeData sourceType = source.getTypeSystemType(); | |
1540 | |
1541 if (!sourceType.needsCastTo(getContext(), targetType)) { | |
1542 return null; | |
1543 } | |
1544 | |
1545 CodeTree condition = null; | |
1546 if (field.isShortCircuit()) { | |
1547 ActualParameter shortCircuit = source.getPreviousParameter(); | |
1548 assert shortCircuit != null; | |
1549 condition = CodeTreeBuilder.singleString(valueName(shortCircuit)); | |
1550 } | |
1551 | |
1552 CodeTree value = createCallTypeSystemMethod(context, parent, node, TypeSystemCodeGenerator.asTypeMethodName(targetType), CodeTreeBuilder.singleString(valueName(source))); | |
1553 | |
1554 return createLazyAssignment(parent, castValueName(source), targetType.getPrimitiveType(), condition, value); | |
1708 } | 1555 } |
1709 | 1556 |
1710 private CodeTree createMethodGuard(CodeTreeBuilder parent, String prefix, SpecializationData source, GuardData guard) { | 1557 private CodeTree createMethodGuard(CodeTreeBuilder parent, String prefix, SpecializationData source, GuardData guard) { |
1711 CodeTreeBuilder builder = parent.create(); | 1558 CodeTreeBuilder builder = parent.create(); |
1712 builder.string(prefix); | 1559 builder.string(prefix); |
2457 } | 2304 } |
2458 | 2305 |
2459 protected void createCachedExecuteMethods(SpecializationData specialization) { | 2306 protected void createCachedExecuteMethods(SpecializationData specialization) { |
2460 NodeData node = specialization.getNode(); | 2307 NodeData node = specialization.getNode(); |
2461 CodeTypeElement clazz = getElement(); | 2308 CodeTypeElement clazz = getElement(); |
2462 for (SpecializationData polymorphic : node.getPolymorphicSpecializations()) { | 2309 for (final SpecializationData polymorphic : node.getPolymorphicSpecializations()) { |
2463 if (!specialization.getSignature().isCompatibleTo(polymorphic.getSignature())) { | 2310 if (!specialization.getSignature().isCompatibleTo(polymorphic.getSignature())) { |
2464 continue; | 2311 continue; |
2465 } | 2312 } |
2466 ExecutableElement executeCached = nodeGen.getMethod(executeCachedName(polymorphic)); | 2313 ExecutableElement executeCached = nodeGen.getMethod(executeCachedName(polymorphic)); |
2467 ExecutableTypeData execType = new ExecutableTypeData(polymorphic, executeCached, node.getTypeSystem(), polymorphic.getReturnType().getTypeSystemType()); | 2314 ExecutableTypeData execType = new ExecutableTypeData(polymorphic, executeCached, node.getTypeSystem(), polymorphic.getReturnType().getTypeSystemType()); |
2478 } else { | 2325 } else { |
2479 CodeTreeBuilder elseBuilder = new CodeTreeBuilder(builder); | 2326 CodeTreeBuilder elseBuilder = new CodeTreeBuilder(builder); |
2480 elseBuilder.startReturn().startCall("this.next0", executeCachedName(polymorphic)); | 2327 elseBuilder.startReturn().startCall("this.next0", executeCachedName(polymorphic)); |
2481 addInternalValueParameterNames(elseBuilder, polymorphic, polymorphic, null, true, true); | 2328 addInternalValueParameterNames(elseBuilder, polymorphic, polymorphic, null, true, true); |
2482 elseBuilder.end().end(); | 2329 elseBuilder.end().end(); |
2483 CodeTreeBuilder execute = new CodeTreeBuilder(builder); | 2330 |
2484 execute.tree(createGenericInvoke(builder, polymorphic, specialization)); | 2331 boolean forceElse = specialization.getExceptions().size() > 0; |
2485 boolean forceElse = !specialization.getExceptions().isEmpty(); | 2332 builder.tree(createExecuteTree(builder, polymorphic, SpecializationGroup.create(specialization), false, new CodeBlock<SpecializationData>() { |
2486 builder.tree(createGuardAndCast(builder, null, polymorphic, specialization, true, execute.getRoot(), elseBuilder.getRoot(), true, forceElse)); | 2333 |
2334 public CodeTree create(CodeTreeBuilder b, SpecializationData current) { | |
2335 return createGenericInvoke(b, polymorphic, current); | |
2336 } | |
2337 }, elseBuilder.getRoot(), forceElse, true)); | |
2487 } | 2338 } |
2488 clazz.add(executeMethod); | 2339 clazz.add(executeMethod); |
2489 } | 2340 } |
2490 } | 2341 } |
2491 | 2342 |
2620 } | 2471 } |
2621 | 2472 |
2622 return filteredTypes; | 2473 return filteredTypes; |
2623 } | 2474 } |
2624 | 2475 |
2625 private CodeTree createFunctionalExecute(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData executable) { | 2476 private CodeTree createFunctionalExecute(CodeTreeBuilder parent, final SpecializationData specialization, final ExecutableTypeData executable) { |
2626 CodeTreeBuilder builder = new CodeTreeBuilder(parent); | 2477 CodeTreeBuilder builder = new CodeTreeBuilder(parent); |
2627 if (specialization.isUninitialized()) { | 2478 if (specialization.isUninitialized()) { |
2628 builder.tree(createDeoptimize(builder)); | 2479 builder.tree(createDeoptimize(builder)); |
2629 } | 2480 } |
2630 | 2481 |
2631 builder.tree(createExecuteChildren(builder, executable, specialization, specialization.getParameters(), null, false)); | 2482 builder.tree(createExecuteChildren(builder, executable, specialization, specialization.getParameters(), null, false)); |
2632 | |
2633 CodeTree executeNode = createExecute(builder, executable, specialization); | |
2634 | 2483 |
2635 CodeTree returnSpecialized = null; | 2484 CodeTree returnSpecialized = null; |
2636 | 2485 |
2637 if (specialization.findNextSpecialization() != null) { | 2486 if (specialization.findNextSpecialization() != null) { |
2638 CodeTreeBuilder returnBuilder = new CodeTreeBuilder(builder); | 2487 CodeTreeBuilder returnBuilder = new CodeTreeBuilder(builder); |
2639 returnBuilder.tree(createDeoptimize(builder)); | 2488 returnBuilder.tree(createDeoptimize(builder)); |
2640 returnBuilder.tree(createReturnExecuteAndSpecialize(builder, executable, specialization, null, "One of guards " + specialization.getGuardDefinitions() + " failed")); | 2489 returnBuilder.tree(createReturnExecuteAndSpecialize(builder, executable, specialization, null, "One of guards " + specialization.getGuardDefinitions() + " failed")); |
2641 returnSpecialized = returnBuilder.getRoot(); | 2490 returnSpecialized = returnBuilder.getRoot(); |
2642 } | 2491 } |
2643 | 2492 |
2644 builder.tree(createGuardAndCast(builder, null, specialization, specialization, true, executeNode, returnSpecialized, false, false)); | 2493 builder.tree(createExecuteTree(builder, specialization, SpecializationGroup.create(specialization), false, new CodeBlock<SpecializationData>() { |
2494 | |
2495 public CodeTree create(CodeTreeBuilder b, SpecializationData current) { | |
2496 return createExecute(b, executable, specialization); | |
2497 } | |
2498 }, returnSpecialized, false, false)); | |
2645 | 2499 |
2646 return builder.getRoot(); | 2500 return builder.getRoot(); |
2647 } | 2501 } |
2648 | 2502 |
2649 private CodeTree createExecute(CodeTreeBuilder parent, ExecutableTypeData executable, SpecializationData specialization) { | 2503 private CodeTree createExecute(CodeTreeBuilder parent, ExecutableTypeData executable, SpecializationData specialization) { |