Mercurial > hg > graal-compiler
comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeGenFactory.java @ 19711:e9e99d8dca54
Truffle-DSL: fixed possible wrong variable accesses when calling node constructors.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Mon, 09 Mar 2015 00:41:42 +0100 |
parents | ef292a5bb79d |
children | 2f5d4df2af90 |
comparison
equal
deleted
inserted
replaced
19710:48eeda5dfdbf | 19711:e9e99d8dca54 |
---|---|
1076 String name = assumptionName(assumption); | 1076 String name = assumptionName(assumption); |
1077 // needs specialization index for assumption to make unique | 1077 // needs specialization index for assumption to make unique |
1078 String varName = name + specialization.getIndex(); | 1078 String varName = name + specialization.getIndex(); |
1079 TypeMirror type = assumption.getExpression().getResolvedType(); | 1079 TypeMirror type = assumption.getExpression().getResolvedType(); |
1080 builder.declaration(type, varName, assumptions); | 1080 builder.declaration(type, varName, assumptions); |
1081 currentValues.set(name, new LocalVariable(null, type, varName, null)); | 1081 currentValues.set(name, new LocalVariable(null, type, varName, null, null)); |
1082 } | 1082 } |
1083 | 1083 |
1084 builder.startIf(); | 1084 builder.startIf(); |
1085 String sep = ""; | 1085 String sep = ""; |
1086 for (AssumptionExpression assumption : specialization.getAssumptionExpressions()) { | 1086 for (AssumptionExpression assumption : specialization.getAssumptionExpressions()) { |
1242 } | 1242 } |
1243 if (currentValues != null) { | 1243 if (currentValues != null) { |
1244 for (Parameter p : specialization.getSignatureParameters()) { | 1244 for (Parameter p : specialization.getSignatureParameters()) { |
1245 CodeVariableElement var = createImplicitProfileParameter(p.getSpecification().getExecution(), p.getTypeSystemType()); | 1245 CodeVariableElement var = createImplicitProfileParameter(p.getSpecification().getExecution(), p.getTypeSystemType()); |
1246 if (var != null) { | 1246 if (var != null) { |
1247 // we need the original name here | 1247 LocalVariable variable = currentValues.get(p.getLocalName()); |
1248 builder.tree(LocalVariable.fromParameter(p).createReference()); | 1248 if (variable == null) { |
1249 throw new AssertionError("Could not bind cached value " + p.getLocalName() + ": " + currentValues); | |
1250 } | |
1251 builder.tree(variable.original().createReference()); | |
1249 } | 1252 } |
1250 } | 1253 } |
1251 for (CacheExpression cache : specialization.getCaches()) { | 1254 for (CacheExpression cache : specialization.getCaches()) { |
1252 LocalVariable variable = currentValues.get(cache.getParameter().getLocalName()); | 1255 LocalVariable variable = currentValues.get(cache.getParameter().getLocalName()); |
1253 if (variable == null) { | 1256 if (variable == null) { |
2280 String name = cache.getParameter().getLocalName(); | 2283 String name = cache.getParameter().getLocalName(); |
2281 // multiple specializations might use the same name | 2284 // multiple specializations might use the same name |
2282 String varName = name + specialization.getIndex(); | 2285 String varName = name + specialization.getIndex(); |
2283 TypeMirror type = cache.getParameter().getType(); | 2286 TypeMirror type = cache.getParameter().getType(); |
2284 builder.declaration(type, varName, initializer); | 2287 builder.declaration(type, varName, initializer); |
2285 currentValues.set(name, new LocalVariable(null, type, varName, null)); | 2288 currentValues.set(name, new LocalVariable(null, type, varName, null, null)); |
2286 } | 2289 } |
2287 | 2290 |
2288 public static final class LocalContext { | 2291 public static final class LocalContext { |
2289 | 2292 |
2290 private final NodeGenFactory factory; | 2293 private final NodeGenFactory factory; |
2296 | 2299 |
2297 public void loadFastPathState(SpecializationData specialization) { | 2300 public void loadFastPathState(SpecializationData specialization) { |
2298 for (CacheExpression cache : specialization.getCaches()) { | 2301 for (CacheExpression cache : specialization.getCaches()) { |
2299 Parameter cacheParameter = cache.getParameter(); | 2302 Parameter cacheParameter = cache.getParameter(); |
2300 String name = cacheParameter.getVariableElement().getSimpleName().toString(); | 2303 String name = cacheParameter.getVariableElement().getSimpleName().toString(); |
2301 set(cacheParameter.getLocalName(), new LocalVariable(cacheParameter.getTypeSystemType(), cacheParameter.getType(), name, CodeTreeBuilder.singleString("this." + name))); | 2304 set(cacheParameter.getLocalName(), new LocalVariable(cacheParameter.getTypeSystemType(), cacheParameter.getType(), name, CodeTreeBuilder.singleString("this." + name), null)); |
2302 } | 2305 } |
2303 | 2306 |
2304 for (AssumptionExpression assumption : specialization.getAssumptionExpressions()) { | 2307 for (AssumptionExpression assumption : specialization.getAssumptionExpressions()) { |
2305 String name = assumptionName(assumption); | 2308 String name = assumptionName(assumption); |
2306 TypeMirror type = assumption.getExpression().getResolvedType(); | 2309 TypeMirror type = assumption.getExpression().getResolvedType(); |
2307 set(name, new LocalVariable(null, type, name, CodeTreeBuilder.singleString("this." + name))); | 2310 set(name, new LocalVariable(null, type, name, CodeTreeBuilder.singleString("this." + name), null)); |
2308 } | 2311 } |
2309 } | 2312 } |
2310 | 2313 |
2311 public CodeExecutableElement createMethod(Set<Modifier> modifiers, TypeMirror returnType, String name, String... optionalArguments) { | 2314 public CodeExecutableElement createMethod(Set<Modifier> modifiers, TypeMirror returnType, String name, String... optionalArguments) { |
2312 CodeExecutableElement method = new CodeExecutableElement(modifiers, returnType, name); | 2315 CodeExecutableElement method = new CodeExecutableElement(modifiers, returnType, name); |
2334 return field.getName() + "Value"; | 2337 return field.getName() + "Value"; |
2335 } | 2338 } |
2336 | 2339 |
2337 @SuppressWarnings("static-method") | 2340 @SuppressWarnings("static-method") |
2338 public LocalVariable createValue(NodeExecutionData execution, TypeData type) { | 2341 public LocalVariable createValue(NodeExecutionData execution, TypeData type) { |
2339 return new LocalVariable(type, type.getPrimitiveType(), valueName(execution), null); | 2342 return new LocalVariable(type, type.getPrimitiveType(), valueName(execution), null, null); |
2340 } | 2343 } |
2341 | 2344 |
2342 public LocalVariable createShortCircuitValue(NodeExecutionData execution) { | 2345 public LocalVariable createShortCircuitValue(NodeExecutionData execution) { |
2343 return new LocalVariable(factory.typeSystem.getBooleanType(), factory.getType(boolean.class), shortCircuitName(execution), null); | 2346 return new LocalVariable(factory.typeSystem.getBooleanType(), factory.getType(boolean.class), shortCircuitName(execution), null, null); |
2344 } | 2347 } |
2345 | 2348 |
2346 private static String valueName(NodeExecutionData execution) { | 2349 private static String valueName(NodeExecutionData execution) { |
2347 return execution.getName() + "Value"; | 2350 return execution.getName() + "Value"; |
2348 } | 2351 } |
2409 } | 2412 } |
2410 return size >= varArgsThreshold; | 2413 return size >= varArgsThreshold; |
2411 } | 2414 } |
2412 | 2415 |
2413 private void loadValues(int evaluatedArguments, int varargsThreshold) { | 2416 private void loadValues(int evaluatedArguments, int varargsThreshold) { |
2414 values.put(FRAME_VALUE, new LocalVariable(null, factory.getType(Frame.class), FRAME_VALUE, null)); | 2417 values.put(FRAME_VALUE, new LocalVariable(null, factory.getType(Frame.class), FRAME_VALUE, null, null)); |
2415 | 2418 |
2416 for (NodeFieldData field : factory.node.getFields()) { | 2419 for (NodeFieldData field : factory.node.getFields()) { |
2417 String fieldName = fieldValueName(field); | 2420 String fieldName = fieldValueName(field); |
2418 values.put(fieldName, new LocalVariable(null, field.getType(), fieldName, factory.accessParent(field.getName()))); | 2421 values.put(fieldName, new LocalVariable(null, field.getType(), fieldName, factory.accessParent(field.getName()), null)); |
2419 } | 2422 } |
2420 | 2423 |
2421 boolean varargs = needsVarargs(false, varargsThreshold); | 2424 boolean varargs = needsVarargs(false, varargsThreshold); |
2422 for (int i = 0; i < evaluatedArguments; i++) { | 2425 for (int i = 0; i < evaluatedArguments; i++) { |
2423 List<NodeExecutionData> childExecutions = factory.node.getChildExecutions(); | 2426 List<NodeExecutionData> childExecutions = factory.node.getChildExecutions(); |
2428 if (execution.isShortCircuit()) { | 2431 if (execution.isShortCircuit()) { |
2429 LocalVariable shortCircuit = createShortCircuitValue(execution).makeGeneric(); | 2432 LocalVariable shortCircuit = createShortCircuitValue(execution).makeGeneric(); |
2430 if (varargs) { | 2433 if (varargs) { |
2431 shortCircuit = shortCircuit.accessWith(createReadVarargs(i)); | 2434 shortCircuit = shortCircuit.accessWith(createReadVarargs(i)); |
2432 } | 2435 } |
2433 values.put(shortCircuit.getName(), shortCircuit); | 2436 values.put(shortCircuit.getName(), shortCircuit.makeOriginal()); |
2434 } | 2437 } |
2435 LocalVariable value = createValue(execution, factory.genericType); | 2438 LocalVariable value = createValue(execution, factory.genericType); |
2436 if (varargs) { | 2439 if (varargs) { |
2437 value = value.accessWith(createReadVarargs(i)); | 2440 value = value.accessWith(createReadVarargs(i)); |
2438 } | 2441 } |
2439 values.put(value.getName(), value); | 2442 values.put(value.getName(), value.makeOriginal()); |
2440 } | 2443 } |
2441 } | 2444 } |
2442 | 2445 |
2443 private static CodeTree createReadVarargs(int i) { | 2446 private static CodeTree createReadVarargs(int i) { |
2444 return CodeTreeBuilder.createBuilder().string("args_[").string(String.valueOf(i)).string("]").build(); | 2447 return CodeTreeBuilder.createBuilder().string("args_[").string(String.valueOf(i)).string("]").build(); |
2517 | 2520 |
2518 private final TypeData type; | 2521 private final TypeData type; |
2519 private final TypeMirror typeMirror; | 2522 private final TypeMirror typeMirror; |
2520 private final CodeTree accessorTree; | 2523 private final CodeTree accessorTree; |
2521 private final String name; | 2524 private final String name; |
2525 private final LocalVariable previous; | |
2522 | 2526 |
2523 public static LocalVariable fromParameter(Parameter parameter) { | 2527 public static LocalVariable fromParameter(Parameter parameter) { |
2524 NodeExecutionData execution = parameter.getSpecification().getExecution(); | 2528 NodeExecutionData execution = parameter.getSpecification().getExecution(); |
2525 String name = null; | 2529 String name = null; |
2526 if (execution == null) { | 2530 if (execution == null) { |
2527 name = parameter.getLocalName(); | 2531 name = parameter.getLocalName(); |
2528 } else { | 2532 } else { |
2529 name = createName(execution); | 2533 name = createName(execution); |
2530 } | 2534 } |
2531 return new LocalVariable(parameter.getTypeSystemType(), parameter.getType(), name, null); | 2535 return new LocalVariable(parameter.getTypeSystemType(), parameter.getType(), name, null, null); |
2532 } | 2536 } |
2533 | 2537 |
2534 private LocalVariable(TypeData type, TypeMirror typeMirror, String name, CodeTree accessorTree) { | 2538 private LocalVariable(TypeData type, TypeMirror typeMirror, String name, CodeTree accessorTree, LocalVariable previous) { |
2535 Objects.requireNonNull(typeMirror); | 2539 Objects.requireNonNull(typeMirror); |
2536 this.typeMirror = typeMirror; | 2540 this.typeMirror = typeMirror; |
2537 this.accessorTree = accessorTree; | 2541 this.accessorTree = accessorTree; |
2538 this.type = type; | 2542 this.type = type; |
2539 this.name = name; | 2543 this.name = name; |
2544 this.previous = previous; | |
2540 } | 2545 } |
2541 | 2546 |
2542 public TypeData getType() { | 2547 public TypeData getType() { |
2543 return type; | 2548 return type; |
2544 } | 2549 } |
2581 return CodeTreeBuilder.singleString(getName()); | 2586 return CodeTreeBuilder.singleString(getName()); |
2582 } | 2587 } |
2583 } | 2588 } |
2584 | 2589 |
2585 public LocalVariable newType(TypeData newType) { | 2590 public LocalVariable newType(TypeData newType) { |
2586 return new LocalVariable(newType, newType.getPrimitiveType(), name, accessorTree); | 2591 return new LocalVariable(newType, newType.getPrimitiveType(), name, accessorTree, this); |
2587 } | 2592 } |
2588 | 2593 |
2589 public LocalVariable newType(TypeMirror newType) { | 2594 public LocalVariable newType(TypeMirror newType) { |
2590 return new LocalVariable(type, newType, name, accessorTree); | 2595 return new LocalVariable(type, newType, name, accessorTree, this); |
2591 } | 2596 } |
2592 | 2597 |
2593 public LocalVariable accessWith(CodeTree tree) { | 2598 public LocalVariable accessWith(CodeTree tree) { |
2594 return new LocalVariable(type, typeMirror, name, tree); | 2599 return new LocalVariable(type, typeMirror, name, tree, this); |
2595 } | 2600 } |
2596 | 2601 |
2597 public LocalVariable nextName() { | 2602 public LocalVariable nextName() { |
2598 return new LocalVariable(type, typeMirror, createNextName(name), accessorTree); | 2603 return new LocalVariable(type, typeMirror, createNextName(name), accessorTree, this); |
2604 } | |
2605 | |
2606 public LocalVariable makeOriginal() { | |
2607 return new LocalVariable(type, typeMirror, name, accessorTree, null); | |
2608 } | |
2609 | |
2610 public LocalVariable original() { | |
2611 LocalVariable variable = this; | |
2612 while (variable.previous != null) { | |
2613 variable = variable.previous; | |
2614 } | |
2615 return variable; | |
2599 } | 2616 } |
2600 | 2617 |
2601 public LocalVariable makeGeneric() { | 2618 public LocalVariable makeGeneric() { |
2602 return newType(type.getTypeSystem().getGenericTypeData()); | 2619 return newType(type.getTypeSystem().getGenericTypeData()); |
2603 } | 2620 } |