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 }