1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-11-26 12:49:21 +00:00

Moved ASM code gen and ASM encoding handling into separate util classes.

This commit is contained in:
jespergravgaard 2021-12-27 00:33:30 +01:00
parent 87cc51d685
commit 44ec5be5e8
4 changed files with 135 additions and 110 deletions

View File

@ -0,0 +1,70 @@
package dk.camelot64.kickc.fragment;
import dk.camelot64.kickc.asm.AsmProgram;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.iterator.ProgramValue;
import dk.camelot64.kickc.model.iterator.ProgramValueHandler;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.values.ConstantChar;
import dk.camelot64.kickc.model.values.ConstantString;
import dk.camelot64.kickc.model.values.StringEncoding;
import dk.camelot64.kickc.model.values.Value;
import java.util.LinkedHashSet;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
public class AsmEncodingHelper {
/**
* Ensure that the current encoding in the ASM matches any encoding in the data to be emitted
*
* @param asm The ASM program (where any .encoding directive will be emitted)
* @param asmFragmentInstance The ASM fragment to be emitted
*/
static void ensureEncoding(AsmProgram asm, AsmFragmentInstanceSpec asmFragmentInstance) {
asm.ensureEncoding(getEncoding(asmFragmentInstance));
}
public static void ensureEncoding(AsmProgram asm, Value value) {
asm.ensureEncoding(getEncoding(value));
}
/**
* Examine a constantvalue to see if any string encoding information is present
*
* @param value The constant to examine
* @return Any encoding found inside the constant
*/
public static Set<StringEncoding> getEncoding(Value value) {
LinkedHashSet<StringEncoding> encodings = new LinkedHashSet<>();
ProgramValue programValue = new ProgramValue.GenericValue(value);
ProgramValueHandler handler = (ProgramValue pVal, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) -> {
Value val = pVal.get();
if(val instanceof ConstantChar) {
encodings.add(((ConstantChar) val).getEncoding());
} else if(val instanceof ConstantString) {
encodings.add(((ConstantString) val).getEncoding());
}
};
ProgramValueIterator.execute(programValue, handler, null, null, null);
return encodings;
}
/**
* Examine an ASM fragment to see if any string encoding information is present
*
* @param asmFragmentInstance The asm fragment instance to examine
* @return Any encoding found inside the constant
*/
private static Set<StringEncoding> getEncoding(AsmFragmentInstanceSpec asmFragmentInstance) {
LinkedHashSet<StringEncoding> encodings = new LinkedHashSet<>();
Map<String, Value> bindings = asmFragmentInstance.getBindings();
for(Value boundValue : bindings.values()) {
encodings.addAll(getEncoding(boundValue));
}
return encodings;
}
}

View File

@ -0,0 +1,43 @@
package dk.camelot64.kickc.fragment;
import dk.camelot64.kickc.asm.AsmProgram;
import dk.camelot64.kickc.model.Program;
public class AsmFragmentCodeGenerator {
/**
* Generate ASM code for an ASM fragment instance
*
* @param asm The ASM program to generate into
* @param fragmentInstanceSpec The ASM fragment instance specification
* @param program The program. Used for getting global statics.
*/
public static void generateAsm(AsmProgram asm, AsmFragmentInstanceSpec fragmentInstanceSpec, Program program) {
AsmEncodingHelper.ensureEncoding(asm, fragmentInstanceSpec);
String initialSignature = fragmentInstanceSpec.getSignature();
AsmFragmentInstance fragmentInstance = null;
StringBuilder fragmentVariationsTried = new StringBuilder();
while(fragmentInstance == null) {
try {
final AsmFragmentTemplateSynthesizer cpuSynthesizer = program.getAsmFragmentMasterSynthesizer().getSynthesizer(program.getTargetCpu());
fragmentInstance = cpuSynthesizer.getFragmentInstance(fragmentInstanceSpec, program.getLog());
} catch(AsmFragmentTemplateSynthesizer.UnknownFragmentException e) {
// Unknown fragment - keep looking through alternative ASM fragment instance specs until we have tried them all
String signature = fragmentInstanceSpec.getSignature();
fragmentVariationsTried.append(signature).append(" ");
if(fragmentInstanceSpec.hasNextVariation()) {
fragmentInstanceSpec.nextVariation();
if(program.getLog().isVerboseFragmentLog()) {
program.getLog().append("Fragment not found " + signature + ". Attempting another variation " + fragmentInstanceSpec.getSignature());
}
} else {
// No more variations available - fail with an error
throw new AsmFragmentTemplateSynthesizer.UnknownFragmentException("Fragment not found " + initialSignature + ". Attempted variations " + fragmentVariationsTried);
}
}
}
asm.getCurrentChunk().setFragment(fragmentInstance.getFragmentName());
fragmentInstance.generate(asm);
}
}

View File

@ -83,7 +83,7 @@ public class AsmFragmentInstanceSpec {
/** /**
* Does any more variations of the ASM fragment instance specification exist? * Does any more variations of the ASM fragment instance specification exist?
* Variations are used for finding the right fragment to use for constant numbers. * Variations are used for finding the right fragment to use for constant numbers.
* For instance the number 1000 can be represented as several different types (unsigned/signed word/dword). * For instance the number 1000 can be represented as several types (unsigned/signed word/dword).
* *
* @return true if more variations exits * @return true if more variations exits
*/ */

View File

@ -6,9 +6,6 @@ import dk.camelot64.kickc.asm.*;
import dk.camelot64.kickc.fragment.*; import dk.camelot64.kickc.fragment.*;
import dk.camelot64.kickc.model.InternalError; import dk.camelot64.kickc.model.InternalError;
import dk.camelot64.kickc.model.*; import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.iterator.ProgramValue;
import dk.camelot64.kickc.model.iterator.ProgramValueHandler;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.operators.Operators; import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.*; import dk.camelot64.kickc.model.statements.*;
import dk.camelot64.kickc.model.symbols.*; import dk.camelot64.kickc.model.symbols.*;
@ -461,7 +458,7 @@ public class Pass4CodeGeneration {
// Add any comments // Add any comments
generateComments(asm, constantVar.getComments()); generateComments(asm, constantVar.getComments());
// Ensure encoding is good // Ensure encoding is good
ensureEncoding(asm, constantVar.getInitValue()); AsmEncodingHelper.ensureEncoding(asm, constantVar.getInitValue());
asm.addConstant(AsmFormat.asmFix(asmName), asmConstant); asm.addConstant(AsmFormat.asmFix(asmName), asmConstant);
} }
@ -469,7 +466,7 @@ public class Pass4CodeGeneration {
// Add any comments // Add any comments
generateComments(asm, variable.getComments()); generateComments(asm, variable.getComments());
// Ensure encoding is good // Ensure encoding is good
ensureEncoding(asm, variable.getInitValue()); AsmEncodingHelper.ensureEncoding(asm, variable.getInitValue());
// Find the constant value calculation // Find the constant value calculation
asm.addLabelDecl(AsmFormat.asmFix(asmName), asmConstant); asm.addLabelDecl(AsmFormat.asmFix(asmName), asmConstant);
} }
@ -666,7 +663,7 @@ public class Pass4CodeGeneration {
ConstantValue paddingSizeVal = new ConstantInteger(paddingSize); ConstantValue paddingSizeVal = new ConstantInteger(paddingSize);
String paddingBytesAsm = AsmFormat.getAsmConstant(program, paddingSizeVal, 99, scopeRef); String paddingBytesAsm = AsmFormat.getAsmConstant(program, paddingSizeVal, 99, scopeRef);
ConstantValue zeroValue = new ConstantInteger(0l, SymbolType.BYTE); ConstantValue zeroValue = new ConstantInteger(0l, SymbolType.BYTE);
dataChunk.addDataZeroFilled(AsmDataNumeric.Type.BYTE, paddingBytesAsm, (int) paddingSize, getEncoding(zeroValue)); dataChunk.addDataZeroFilled(AsmDataNumeric.Type.BYTE, paddingBytesAsm, (int) paddingSize, AsmEncodingHelper.getEncoding(zeroValue));
} }
} else if(value instanceof StructZero) { } else if(value instanceof StructZero) {
final SymbolTypeStruct typeStruct = ((StructZero) value).getTypeStruct(); final SymbolTypeStruct typeStruct = ((StructZero) value).getTypeStruct();
@ -713,12 +710,12 @@ public class Pass4CodeGeneration {
if(declaredSize != null) { if(declaredSize != null) {
bytes = declaredSize * elementType.getSizeBytes(); bytes = declaredSize * elementType.getSizeBytes();
} }
dataChunk.addDataKickAsm(bytes, kickAsm.getKickAsmCode(), getEncoding(value)); dataChunk.addDataKickAsm(bytes, kickAsm.getKickAsmCode(), AsmEncodingHelper.getEncoding(value));
dataNumElements = bytes; dataNumElements = bytes;
} else if(value instanceof ConstantString) { } else if(value instanceof ConstantString) {
ConstantString stringValue = (ConstantString) value; ConstantString stringValue = (ConstantString) value;
String asmConstant = AsmFormat.getAsmConstant(program, stringValue, 99, scopeRef); String asmConstant = AsmFormat.getAsmConstant(program, stringValue, 99, scopeRef);
dataChunk.addDataString(asmConstant, getEncoding(stringValue)); dataChunk.addDataString(asmConstant, AsmEncodingHelper.getEncoding(stringValue));
if(stringValue.isZeroTerminated()) { if(stringValue.isZeroTerminated()) {
dataChunk.addDataNumeric(AsmDataNumeric.Type.BYTE, "0", null); dataChunk.addDataNumeric(AsmDataNumeric.Type.BYTE, "0", null);
} }
@ -748,7 +745,7 @@ public class Pass4CodeGeneration {
} }
ConstantValue zeroValue = Initializers.createZeroValue(new Initializers.ValueTypeSpec(elementType), null); ConstantValue zeroValue = Initializers.createZeroValue(new Initializers.ValueTypeSpec(elementType), null);
if(zeroValue instanceof ConstantInteger | zeroValue instanceof ConstantPointer) { if(zeroValue instanceof ConstantInteger | zeroValue instanceof ConstantPointer) {
dataChunk.addDataZeroFilled(getNumericType(elementType), paddingBytesAsm, (int) paddingSize, getEncoding(zeroValue)); dataChunk.addDataZeroFilled(getNumericType(elementType), paddingBytesAsm, (int) paddingSize, AsmEncodingHelper.getEncoding(zeroValue));
} else { } else {
for(int i = 0; i < paddingSize; i++) { for(int i = 0; i < paddingSize; i++) {
addChunkData(dataChunk, zeroValue, elementType, null, scopeRef); addChunkData(dataChunk, zeroValue, elementType, null, scopeRef);
@ -760,20 +757,20 @@ public class Pass4CodeGeneration {
ConstantString stringValue = (ConstantString) value; ConstantString stringValue = (ConstantString) value;
// Ensure encoding is good // Ensure encoding is good
String asmConstant = AsmFormat.getAsmConstant(program, stringValue, 99, scopeRef); String asmConstant = AsmFormat.getAsmConstant(program, stringValue, 99, scopeRef);
dataChunk.addDataString(asmConstant, getEncoding(stringValue)); dataChunk.addDataString(asmConstant, AsmEncodingHelper.getEncoding(stringValue));
if(stringValue.isZeroTerminated()) { if(stringValue.isZeroTerminated()) {
dataChunk.addDataNumeric(AsmDataNumeric.Type.BYTE, "0", null); dataChunk.addDataNumeric(AsmDataNumeric.Type.BYTE, "0", null);
} }
} else if(SymbolType.BYTE.equals(valueType) || SymbolType.SBYTE.equals(valueType)) { } else if(SymbolType.BYTE.equals(valueType) || SymbolType.SBYTE.equals(valueType)) {
dataChunk.addDataNumeric(AsmDataNumeric.Type.BYTE, AsmFormat.getAsmConstant(program, value, 99, scopeRef), getEncoding(value)); dataChunk.addDataNumeric(AsmDataNumeric.Type.BYTE, AsmFormat.getAsmConstant(program, value, 99, scopeRef), AsmEncodingHelper.getEncoding(value));
} else if(SymbolType.WORD.equals(valueType) || SymbolType.SWORD.equals(valueType)) { } else if(SymbolType.WORD.equals(valueType) || SymbolType.SWORD.equals(valueType)) {
dataChunk.addDataNumeric(AsmDataNumeric.Type.WORD, AsmFormat.getAsmConstant(program, value, 99, scopeRef), getEncoding(value)); dataChunk.addDataNumeric(AsmDataNumeric.Type.WORD, AsmFormat.getAsmConstant(program, value, 99, scopeRef), AsmEncodingHelper.getEncoding(value));
} else if(SymbolType.DWORD.equals(valueType) || SymbolType.SDWORD.equals(valueType)) { } else if(SymbolType.DWORD.equals(valueType) || SymbolType.SDWORD.equals(valueType)) {
dataChunk.addDataNumeric(AsmDataNumeric.Type.DWORD, AsmFormat.getAsmConstant(program, value, 99, scopeRef), getEncoding(value)); dataChunk.addDataNumeric(AsmDataNumeric.Type.DWORD, AsmFormat.getAsmConstant(program, value, 99, scopeRef), AsmEncodingHelper.getEncoding(value));
} else if(valueType instanceof SymbolTypePointer) { } else if(valueType instanceof SymbolTypePointer) {
dataChunk.addDataNumeric(AsmDataNumeric.Type.WORD, AsmFormat.getAsmConstant(program, value, 99, scopeRef), getEncoding(value)); dataChunk.addDataNumeric(AsmDataNumeric.Type.WORD, AsmFormat.getAsmConstant(program, value, 99, scopeRef), AsmEncodingHelper.getEncoding(value));
} else if(SymbolType.BOOLEAN.equals(valueType)) { } else if(SymbolType.BOOLEAN.equals(valueType)) {
dataChunk.addDataNumeric(AsmDataNumeric.Type.BYTE, AsmFormat.getAsmConstant(program, value, 99, scopeRef), getEncoding(value)); dataChunk.addDataNumeric(AsmDataNumeric.Type.BYTE, AsmFormat.getAsmConstant(program, value, 99, scopeRef), AsmEncodingHelper.getEncoding(value));
} else { } else {
throw new InternalError("Unhandled array element type " + valueType.toString() + " value " + value.toString(program)); throw new InternalError("Unhandled array element type " + valueType.toString() + " value " + value.toString(program));
} }
@ -848,7 +845,7 @@ public class Pass4CodeGeneration {
throw new AsmFragmentInstance.AluNotApplicableException(); throw new AsmFragmentInstance.AluNotApplicableException();
} }
StatementAssignment assignment = (StatementAssignment) statement; StatementAssignment assignment = (StatementAssignment) statement;
generateAsm(asm, AsmFragmentInstanceSpecBuilder.assignmentAlu(assignment, assignmentAlu, program)); AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.assignmentAlu(assignment, assignmentAlu, program), program);
aluState.clear(); aluState.clear();
return; return;
} }
@ -871,17 +868,17 @@ public class Pass4CodeGeneration {
if(assignment.getOperator() == null && assignment.getrValue1() == null && isRegisterCopy(lValue, assignment.getrValue2())) { if(assignment.getOperator() == null && assignment.getrValue1() == null && isRegisterCopy(lValue, assignment.getrValue2())) {
//asm.addComment(lValue.toString(program) + " = " + assignment.getrValue2().toString(program) + " // register copy " + getRegister(lValue)); //asm.addComment(lValue.toString(program) + " = " + assignment.getrValue2().toString(program) + " // register copy " + getRegister(lValue));
} else { } else {
generateAsm(asm, AsmFragmentInstanceSpecBuilder.assignment(assignment, program)); AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.assignment(assignment, program), program);
} }
} }
} else if(statement instanceof StatementConditionalJump) { } else if(statement instanceof StatementConditionalJump) {
generateAsm(asm, AsmFragmentInstanceSpecBuilder.conditionalJump((StatementConditionalJump) statement, block, program)); AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.conditionalJump((StatementConditionalJump) statement, block, program), program);
} else if(statement instanceof StatementCall) { } else if(statement instanceof StatementCall) {
StatementCall call = (StatementCall) statement; StatementCall call = (StatementCall) statement;
Procedure procedure = getScope().getProcedure(call.getProcedure()); Procedure procedure = getScope().getProcedure(call.getProcedure());
if(procedure.isDeclaredIntrinsic()) { if(procedure.isDeclaredIntrinsic()) {
if(Pass1ByteXIntrinsicRewrite.INTRINSIC_MAKELONG4.equals(procedure.getFullName())) { if(Pass1ByteXIntrinsicRewrite.INTRINSIC_MAKELONG4.equals(procedure.getFullName())) {
generateAsm(asm, AsmFragmentInstanceSpecBuilder.makelong4(call, program)); AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.makelong4(call, program), program);
} else { } else {
throw new CompileError("Intrinsic procedure not supported " + procedure.toString(program)); throw new CompileError("Intrinsic procedure not supported " + procedure.toString(program));
} }
@ -905,12 +902,12 @@ public class Pass4CodeGeneration {
StatementCallExecute call = (StatementCallExecute) statement; StatementCallExecute call = (StatementCallExecute) statement;
RValue procedureRVal = call.getProcedureRVal(); RValue procedureRVal = call.getProcedureRVal();
// Generate ASM for a call // Generate ASM for a call
generateAsm(asm, AsmFragmentInstanceSpecBuilder.call(call, indirectCallCount++, program)); AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.call(call, indirectCallCount++, program), program);
if(!(procedureRVal instanceof ProcedureRef)) { if(!(procedureRVal instanceof ProcedureRef)) {
asm.getCurrentChunk().setClobberOverwrite(CpuClobber.CLOBBER_ALL); asm.getCurrentChunk().setClobberOverwrite(CpuClobber.CLOBBER_ALL);
} }
} else if(statement instanceof StatementExprSideEffect) { } else if(statement instanceof StatementExprSideEffect) {
generateAsm(asm, AsmFragmentInstanceSpecBuilder.exprSideEffect((StatementExprSideEffect) statement, program)); AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.exprSideEffect((StatementExprSideEffect) statement, program), program);
} else if(statement instanceof StatementReturn) { } else if(statement instanceof StatementReturn) {
Procedure procedure = null; Procedure procedure = null;
ScopeRef scope = block.getScope(); ScopeRef scope = block.getScope();
@ -953,40 +950,6 @@ public class Pass4CodeGeneration {
} }
} }
/**
* Generate ASM code for an ASM fragment instance
*
* @param asm The ASM program to generate into
* @param fragmentInstanceSpec The ASM fragment instance specification
*/
private void generateAsm(AsmProgram asm, AsmFragmentInstanceSpec fragmentInstanceSpec) {
ensureEncoding(asm, fragmentInstanceSpec);
String initialSignature = fragmentInstanceSpec.getSignature();
AsmFragmentInstance fragmentInstance = null;
StringBuilder fragmentVariationsTried = new StringBuilder();
while(fragmentInstance == null) {
try {
final AsmFragmentTemplateSynthesizer cpuSynthesizer = program.getAsmFragmentMasterSynthesizer().getSynthesizer(program.getTargetCpu());
fragmentInstance = cpuSynthesizer.getFragmentInstance(fragmentInstanceSpec, program.getLog());
} catch(AsmFragmentTemplateSynthesizer.UnknownFragmentException e) {
// Unknown fragment - keep looking through alternative ASM fragment instance specs until we have tried them all
String signature = fragmentInstanceSpec.getSignature();
fragmentVariationsTried.append(signature).append(" ");
if(fragmentInstanceSpec.hasNextVariation()) {
fragmentInstanceSpec.nextVariation();
if(program.getLog().isVerboseFragmentLog()) {
program.getLog().append("Fragment not found " + signature + ". Attempting another variation " + fragmentInstanceSpec.getSignature());
}
} else {
// No more variations available - fail with an error
throw new AsmFragmentTemplateSynthesizer.UnknownFragmentException("Fragment not found " + initialSignature + ". Attempted variations " + fragmentVariationsTried);
}
}
}
asm.getCurrentChunk().setFragment(fragmentInstance.getFragmentName());
fragmentInstance.generate(asm);
}
/** /**
* Generate exit-code for entering an interrupt procedure based on the interrupt type * Generate exit-code for entering an interrupt procedure based on the interrupt type
* *
@ -1006,7 +969,7 @@ public class Pass4CodeGeneration {
} }
try { try {
asm.startChunk(procedure.getRef(), null, "interrupt(" + entryName + ")"); asm.startChunk(procedure.getRef(), null, "interrupt(" + entryName + ")");
generateAsm(asm, entryFragment); AsmFragmentCodeGenerator.generateAsm(asm, entryFragment, program);
} catch(AsmFragmentTemplateSynthesizer.UnknownFragmentException e) { } catch(AsmFragmentTemplateSynthesizer.UnknownFragmentException e) {
throw new CompileError("Interrupt type not supported " + procedure.getInterruptType() + " int " + procedure + "\n" + e.getMessage()); throw new CompileError("Interrupt type not supported " + procedure.getInterruptType() + " int " + procedure + "\n" + e.getMessage());
} }
@ -1031,7 +994,7 @@ public class Pass4CodeGeneration {
} }
asm.startChunk(procedure.getRef(), null, "interrupt(" + entryName + ")"); asm.startChunk(procedure.getRef(), null, "interrupt(" + entryName + ")");
try { try {
generateAsm(asm, entryFragment); AsmFragmentCodeGenerator.generateAsm(asm, entryFragment, program);
} catch(AsmFragmentTemplateSynthesizer.UnknownFragmentException e) { } catch(AsmFragmentTemplateSynthesizer.UnknownFragmentException e) {
throw new CompileError("Interrupt type not supported " + procedure.getInterruptType() + " int " + procedure + "\n" + e.getMessage()); throw new CompileError("Interrupt type not supported " + procedure.getInterruptType() + " int " + procedure + "\n" + e.getMessage());
} }
@ -1110,7 +1073,7 @@ public class Pass4CodeGeneration {
if(isRegisterCopy(lValue, rValue)) { if(isRegisterCopy(lValue, rValue)) {
asm.getCurrentChunk().setFragment("register_copy"); asm.getCurrentChunk().setFragment("register_copy");
} else { } else {
generateAsm(asm, AsmFragmentInstanceSpecBuilder.assignment(lValue, rValue, program, scope)); AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.assignment(lValue, rValue, program, scope), program);
} }
} }
transitionSetGenerated(transition); transitionSetGenerated(transition);
@ -1119,57 +1082,6 @@ public class Pass4CodeGeneration {
} }
} }
/**
* Ensure that the current encoding in the ASM matches any encoding in the data to be emitted
*
* @param asm The ASM program (where any .encoding directive will be emitted)
* @param asmFragmentInstance The ASM fragment to be emitted
*/
private static void ensureEncoding(AsmProgram asm, AsmFragmentInstanceSpec asmFragmentInstance) {
asm.ensureEncoding(getEncoding(asmFragmentInstance));
}
private static void ensureEncoding(AsmProgram asm, Value value) {
asm.ensureEncoding(getEncoding(value));
}
/**
* Examine a constantvalue to see if any string encoding information is present
*
* @param value The constant to examine
* @return Any encoding found inside the constant
*/
private static Set<StringEncoding> getEncoding(Value value) {
LinkedHashSet<StringEncoding> encodings = new LinkedHashSet<>();
ProgramValue programValue = new ProgramValue.GenericValue(value);
ProgramValueHandler handler = (ProgramValue pVal, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) -> {
Value val = pVal.get();
if(val instanceof ConstantChar) {
encodings.add(((ConstantChar) val).getEncoding());
} else if(val instanceof ConstantString) {
encodings.add(((ConstantString) val).getEncoding());
}
};
ProgramValueIterator.execute(programValue, handler, null, null, null);
return encodings;
}
/**
* Examine an ASM fragment to see if any string encoding information is present
*
* @param asmFragmentInstance The asm fragment instance to examine
* @return Any encoding found inside the constant
*/
private static Set<StringEncoding> getEncoding(AsmFragmentInstanceSpec asmFragmentInstance) {
LinkedHashSet<StringEncoding> encodings = new LinkedHashSet<>();
Map<String, Value> bindings = asmFragmentInstance.getBindings();
for(Value boundValue : bindings.values()) {
encodings.addAll(getEncoding(boundValue));
}
return encodings;
}
/** /**
* Get phi transitions for a specific to-block. * Get phi transitions for a specific to-block.
* *