@Override public VariableIdentifierExpr clone() { return new VariableIdentifierExpr(name); }
@Override public Expr generateExpr(IRandom generator, Expr... args) { assert args.length == getNumArguments(); return new VariableIdentifierExpr(name); }
private Expr makeHasReturned() { return new VariableIdentifierExpr( makeHasReturnedName()); }
private Expr makeReturnValue() { return new VariableIdentifierExpr( makeReturnValueName()); }
private Expr injectionSwitch(String dimension) { assert generationParams.getInjectionSwitchIsAvailable(); return new MemberLookupExpr(new VariableIdentifierExpr(Constants.INJECTION_SWITCH), dimension); }
private BinaryExpr compareWithGlFragCoord(boolean value, boolean constContext, Fuzzer fuzzer, int newDepth, String coord) { return new BinaryExpr( new MemberLookupExpr(new VariableIdentifierExpr(OpenGlConstants.GL_FRAG_COORD), coord), makeOpaqueZero(BasicType.FLOAT, constContext, newDepth, fuzzer), value ? BinOp.GE : BinOp.LT); }
@Override public void visitFloatConstantExpr(FloatConstantExpr floatConstantExpr) { if (!literalToUniformIndex.containsKey(floatConstantExpr.getValue())) { literalToUniformIndex.put(floatConstantExpr.getValue(), uniformIndex); uniformIndex++; } parentMap.getParent(floatConstantExpr).replaceChild(floatConstantExpr, new ArrayIndexExpr(new VariableIdentifierExpr(Constants.FLOAT_CONST), new IntConstantExpr(Integer.toString( literalToUniformIndex.get(floatConstantExpr.getValue()))))); }
@Override public void visitDeclarationStmt(DeclarationStmt declarationStmt) { List<String> existingKeys = new ArrayList<>(); existingKeys.addAll(currentScope.keys()); super.visitDeclarationStmt(declarationStmt); List<String> newKeys = currentScope.keys().stream().filter(key -> !existingKeys.contains(key)) .collect(Collectors.toList()); newKeys.sort(String::compareTo); for (String newKey : newKeys) { if (isCurrentComponentVariable(newKey)) { final ExprStmt insertedStmt = new ExprStmt( new BinaryExpr( new MemberLookupExpr( new VariableIdentifierExpr(mergeSet.getMergedName()), getSwizzle(newKey)), new VariableIdentifierExpr(newKey), BinOp.ASSIGN )); assert parentMap.getParent(declarationStmt) instanceof BlockStmt; ((BlockStmt) parentMap.getParent(declarationStmt)).insertAfter(declarationStmt, insertedStmt); } } } }
private void adjustBound(ForStmt loop, int numIterationsToSplitAfter, LoopSplitInfo loopSplitInfo, String newLoopCounter) { final Integer newBound = new Integer(loopSplitInfo.getStartValue() + (loopSplitInfo.getIncreasing() ? 1 : -1) * numIterationsToSplitAfter); final BinOp newOp = loopSplitInfo.getIncreasing() ? BinOp.LT : BinOp.GT; loop.setCondition( new BinaryExpr( new VariableIdentifierExpr(newLoopCounter), new IntConstantExpr(newBound.toString()), newOp)); }
private void addGlobalInitializers(FunctionDefinition mainFunction) { assert mainFunction.getPrototype().getName().equals("main"); for (int i = globalsToBeReInitialized.size() - 1; i >= 0; i--) { for (int j = globalsToBeReInitialized.get(i).getNumDecls() - 1; j >= 0; j--) { final VariableDeclInfo vdi = globalsToBeReInitialized.get(i).getDeclInfo(j); if (!(vdi.getInitializer() instanceof ScalarInitializer)) { throw new RuntimeException("Only know how to deal with scalar initializers at present."); } mainFunction.getBody().insertStmt(0, new ExprStmt(new BinaryExpr(new VariableIdentifierExpr(vdi.getName()), ((ScalarInitializer) vdi.getInitializer()).getExpr(), BinOp.ASSIGN))); vdi.setInitializer(null); } } }
@Override public void visitVariableIdentifierExpr(VariableIdentifierExpr variableIdentifierExpr) { super.visitVariableIdentifierExpr(variableIdentifierExpr); if (isCurrentComponentVariable(variableIdentifierExpr.getName()) && !inDeclarationOfTargetVariable) { parentMap.getParent(variableIdentifierExpr).replaceChild( variableIdentifierExpr, new MemberLookupExpr(new VariableIdentifierExpr(mergeSet.getMergedName()), getSwizzle(variableIdentifierExpr.getName()))); } }
private IfStmt prepareFragColorWrite(IInjectionPoint injectionPoint, IRandom generator, ShadingLanguageVersion shadingLanguageVersion, GenerationParams generationParams) { final Pair<String, Type> outputVariableInfo = chooseOutputVariable(injectionPoint, generator, shadingLanguageVersion, generationParams); final String outputVariableName = outputVariableInfo.getLeft(); final Type outputVariableType = outputVariableInfo.getRight(); return AddJumpStmts.makeDeadConditional(injectionPoint, new BlockStmt(Arrays.asList( new ExprStmt(new BinaryExpr( new VariableIdentifierExpr(outputVariableName), new Fuzzer(new FuzzingContext(), shadingLanguageVersion, generator, generationParams) .fuzzExpr(outputVariableType, false, false, 0), BinOp.ASSIGN) )), true), generator, shadingLanguageVersion, generationParams); }
@Override public void visitMemberLookupExpr(MemberLookupExpr memberLookupExpr) { super.visitMemberLookupExpr(memberLookupExpr); if (isComponentAccess(memberLookupExpr, currentScope)) { try { parentMap.getParent(memberLookupExpr).replaceChild(memberLookupExpr, new VariableIdentifierExpr(getComponentName())); } catch (ChildDoesNotExistException exception) { // The child must have already been eliminated from its parent by some other reduction // step } } } }.visit(block);
private Expr insertFieldIntoStruct(String enclosingStructName, StructDefinitionType enclosingStruct, IRandom generator) { Expr result = new VariableIdentifierExpr(enclosingStructName); StructDefinitionType currentStruct = enclosingStruct; while (true) { Map<String, StructDefinitionType> structFields = getStructFields(currentStruct); if (!structFields.keySet().isEmpty() && generator.nextBoolean()) { String fieldName = structFields.keySet().stream().collect(Collectors.toList()) .get(generator.nextInt(structFields.size())); result = new MemberLookupExpr(result, fieldName); currentStruct = structFields.get(fieldName); } else { // Choose random position at which to insert the field. currentStruct.insertField(generator.nextInt(currentStruct.getNumFields() + 1), declToTransform.getVariablesDeclaration().getDeclInfo(0).getName(), declToTransform.getVariablesDeclaration().getBaseType()); result = new MemberLookupExpr(result, declToTransform.getVariablesDeclaration() .getDeclInfo(0).getName()); return result; } } }
@Override public void visitFunctionCallExpr(FunctionCallExpr functionCallExpr) { super.visitFunctionCallExpr(functionCallExpr); for (int i = 0; i < functionCallExpr.getNumArgs(); i++) { Expr arg = functionCallExpr.getArg(i); if (arg instanceof VariableIdentifierExpr && ((VariableIdentifierExpr) arg) .getName().equals(declaration.getVariablesDeclaration().getDeclInfo(0).getName())) { functionCallExpr.setArg(i, new VariableIdentifierExpr(originalVariableInfo.getName())); } } }
private Stmt makeSingleIterationForStmt(Stmt stmt, OpaqueExpressionGenerator opaqueExpressionGenerator, Fuzzer fuzzer, IRandom generator, ShadingLanguageVersion shadingLanguageVersion) { boolean up = generator.nextBoolean(); String loopVariableName = "_injected_loop_counter_" + loopVariableCounter; loopVariableCounter++; boolean loopBoundsMustBeConst = shadingLanguageVersion.restrictedForLoops(); Expr start = up ? opaqueExpressionGenerator .makeOpaqueZero(BasicType.INT, loopBoundsMustBeConst, 0, fuzzer) : opaqueExpressionGenerator .makeOpaqueOne(BasicType.INT, loopBoundsMustBeConst, 0, fuzzer); DeclarationStmt init = new DeclarationStmt(new VariablesDeclaration(BasicType.INT, new VariableDeclInfo(loopVariableName, null, new ScalarInitializer(start)))); Expr end = up ? opaqueExpressionGenerator .makeOpaqueOne(BasicType.INT, loopBoundsMustBeConst, 0, fuzzer) : opaqueExpressionGenerator .makeOpaqueZero(BasicType.INT, loopBoundsMustBeConst, 0, fuzzer); BinOp testOp = generator.nextBoolean() ? (up ? BinOp.LT : BinOp.GT) : BinOp.NE; Expr test = new BinaryExpr(new VariableIdentifierExpr(loopVariableName), end, testOp); UnOp incOp = up ? UnOp.POST_INC : UnOp.POST_DEC; Expr inc = new UnaryExpr(new VariableIdentifierExpr(loopVariableName), incOp); return new ForStmt(init, makeWrappedLoopCondition(test), inc, stmt); }
private List<Stmt> getInlinedStmts(FunctionDefinition functionDefinition, Optional<String> returnVariableName) { final List<Stmt> inlinedStmts = new ArrayList<>(); for (int i = 0; i < functionDefinition.getPrototype().getNumParameters(); i++) { ParameterDecl pd = functionDefinition.getPrototype().getParameter(i); inlinedStmts.add(new DeclarationStmt( new VariablesDeclaration( pd.getType().getWithoutQualifiers(), new VariableDeclInfo(pd.getName(), null, new ScalarInitializer(call.getArg(i).clone()))))); } for (Stmt stmt : functionDefinition.getBody().getStmts()) { if (stmt instanceof ReturnStmt) { if (((ReturnStmt) stmt).hasExpr()) { inlinedStmts.add(new ExprStmt( new BinaryExpr( new VariableIdentifierExpr(returnVariableName.get()), (((ReturnStmt) stmt).getExpr()), BinOp.ASSIGN))); } } else { inlinedStmts.add(stmt); } } return inlinedStmts; }
@Override public void visitMemberLookupExpr(MemberLookupExpr memberLookupExpr) { super.visitMemberLookupExpr(memberLookupExpr); if (!(memberLookupExpr.getStructure() instanceof VariableIdentifierExpr)) { return; } VariableIdentifierExpr structVariable = ((VariableIdentifierExpr) memberLookupExpr .getStructure()); ScopeEntry se = currentScope.lookupScopeEntry(structVariable.getName()); if (se == null) { return; } if (se.getType().getWithoutQualifiers().equals(declaration.getVariablesDeclaration() .getBaseType().getWithoutQualifiers())) { // We've found the variable reference, but now we might have a chain, like: // s._f0._f2._f1._f0.v // We need to find the member expression that has .v and replace that with v MemberLookupExpr current = memberLookupExpr; while (current.getMember().startsWith(Constants.STRUCTIFICATION_FIELD_PREFIX)) { current = (MemberLookupExpr) parentMap.getParent(current); } parentMap.getParent(current).replaceChild( current, new VariableIdentifierExpr(originalVariableInfo.getName())); } } }.visit(tu);
@Override public void visitFunctionCallExpr(FunctionCallExpr functionCallExpr) { super.visitFunctionCallExpr(functionCallExpr); if (functionCallExpr != call) { return; } if (currentBlockStmt == null) { // Cannot inline e.g. at global scope return; } currentBlockStmt.insertStmt(currentIndex, new BlockStmt(inlinedStmts, true)); if (returnVariableName.isPresent()) { currentBlockStmt.insertStmt(currentIndex, new DeclarationStmt( new VariablesDeclaration( clonedFunctionDefinition.getPrototype().getReturnType() .getWithoutQualifiers(), new VariableDeclInfo(returnVariableName.get(), null, null)))); parentMap.getParent(functionCallExpr).replaceChild(functionCallExpr, new VariableIdentifierExpr(returnVariableName.get())); } else { assert clonedFunctionDefinition.getPrototype().getReturnType().getWithoutQualifiers() == VoidType.VOID; assert parentMap.getParent(functionCallExpr) instanceof ExprStmt; currentBlockStmt.removeStmt((Stmt) parentMap.getParent(functionCallExpr)); } } }.visit(tu);
@Override public Expr visitPrimary_expression(Primary_expressionContext ctx) { if (ctx.variable_identifier() != null) { return new VariableIdentifierExpr(ctx.variable_identifier().getText()); } if (ctx.INTCONSTANT() != null) { return new IntConstantExpr(ctx.INTCONSTANT().getText()); } if (ctx.UINTCONSTANT() != null) { return new UIntConstantExpr(ctx.UINTCONSTANT().getText()); } if (ctx.FLOATCONSTANT() != null) { return new FloatConstantExpr(ctx.FLOATCONSTANT().getText()); } if (ctx.BOOLCONSTANT() != null) { if (ctx.BOOLCONSTANT().getText().equals("true")) { return BoolConstantExpr.TRUE; } assert (ctx.BOOLCONSTANT().getText().equals("false")); return BoolConstantExpr.FALSE; } assert ctx.LPAREN() != null; return new ParenExpr(visitExpression(ctx.expression())); }