diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/internal/writer/BlockWriter.java b/com.amd.aparapi/src/java/com/amd/aparapi/internal/writer/BlockWriter.java index c8074224b186acff30be215b0ccabcd536183822..090c14542a9faad28a257043c40edee46834ef37 100644 --- a/com.amd.aparapi/src/java/com/amd/aparapi/internal/writer/BlockWriter.java +++ b/com.amd.aparapi/src/java/com/amd/aparapi/internal/writer/BlockWriter.java @@ -41,11 +41,13 @@ import com.amd.aparapi.*; import com.amd.aparapi.internal.exception.*; import com.amd.aparapi.internal.instruction.*; import com.amd.aparapi.internal.instruction.BranchSet.LogicalExpressionNode; +import com.amd.aparapi.internal.instruction.InstructionSet.AccessInstanceField; import com.amd.aparapi.internal.instruction.BranchSet.*; import com.amd.aparapi.internal.instruction.InstructionSet.*; import com.amd.aparapi.internal.model.ClassModel.ConstantPool.*; import com.amd.aparapi.internal.model.ClassModel.*; import com.amd.aparapi.internal.model.*; +import com.amd.aparapi.internal.model.ClassModel.ConstantPool.NameAndTypeEntry; import java.util.*; @@ -57,7 +59,7 @@ import java.util.*; * */ -public abstract class BlockWriter { +public abstract class BlockWriter{ public final static String arrayLengthMangleSuffix = "__javaArrayLength"; @@ -415,7 +417,8 @@ public abstract class BlockWriter { final AccessArrayElement arrayLoadInstruction = (AccessArrayElement) _instruction; //object array, get address - if (arrayLoadInstruction instanceof I_AALOAD) { + boolean isMultiDimensional = arrayLoadInstruction instanceof I_AALOAD && isMultiDimensionalArray(arrayLoadInstruction); + if (isMultiDimensional) { write("(&"); } writeInstruction(arrayLoadInstruction.getArrayRef()); @@ -424,7 +427,7 @@ public abstract class BlockWriter { //object array, find the size of each object in the array //for 2D arrays, this size is the size of a row. - if (arrayLoadInstruction instanceof I_AALOAD) { + if (isMultiDimensional) { int dim = 0; Instruction load = arrayLoadInstruction.getArrayRef(); while (load instanceof I_AALOAD) { @@ -432,15 +435,17 @@ public abstract class BlockWriter { dim++; } - String arrayName = ((AccessInstanceField) load).getConstantPoolFieldEntry().getNameAndTypeEntry().getNameUTF8Entry() - .getUTF8(); - write(" * this->" + arrayName + arrayDimMangleSuffix + dim); + NameAndTypeEntry nameAndTypeEntry = ((AccessInstanceField) load).getConstantPoolFieldEntry().getNameAndTypeEntry(); + if (isMultiDimensionalArray(nameAndTypeEntry)) { + String arrayName = nameAndTypeEntry.getNameUTF8Entry().getUTF8(); + write(" * this->" + arrayName + arrayDimMangleSuffix + dim); + } } write("]"); //object array, close parentheses - if (arrayLoadInstruction instanceof I_AALOAD) { + if (isMultiDimensional) { write(")"); } } else if (_instruction instanceof AccessField) { @@ -471,9 +476,10 @@ public abstract class BlockWriter { load = load.getFirstChild(); dim++; } - final AccessInstanceField child = (AccessInstanceField) load; - final String arrayName = child.getConstantPoolFieldEntry().getNameAndTypeEntry().getNameUTF8Entry().getUTF8(); - write("this->" + arrayName + arrayLengthMangleSuffix + dim); + NameAndTypeEntry nameAndTypeEntry = ((AccessInstanceField) load).getConstantPoolFieldEntry().getNameAndTypeEntry(); + final String arrayName = nameAndTypeEntry.getNameUTF8Entry().getUTF8(); + String dimSuffix = isMultiDimensionalArray(nameAndTypeEntry) ? Integer.toString(dim) : ""; + write("this->" + arrayName + arrayLengthMangleSuffix + dimSuffix); } else if (_instruction instanceof AssignToField) { final AssignToField assignedField = (AssignToField) _instruction; @@ -723,6 +729,33 @@ public abstract class BlockWriter { } + private boolean isMultiDimensionalArray(NameAndTypeEntry nameAndTypeEntry) { + return nameAndTypeEntry.getDescriptorUTF8Entry().getUTF8().startsWith("[["); + } + + private boolean isObjectArray(NameAndTypeEntry nameAndTypeEntry) { + return nameAndTypeEntry.getDescriptorUTF8Entry().getUTF8().startsWith("[L"); + } + + private boolean isMultiDimensionalArray(final AccessArrayElement arrayLoadInstruction) { + AccessInstanceField accessInstanceField = getUltimateInstanceFieldAccess(arrayLoadInstruction); + return isMultiDimensionalArray(accessInstanceField.getConstantPoolFieldEntry().getNameAndTypeEntry()); + } + + private boolean isObjectArray(final AccessArrayElement arrayLoadInstruction) { + AccessInstanceField accessInstanceField = getUltimateInstanceFieldAccess(arrayLoadInstruction); + return isObjectArray(accessInstanceField.getConstantPoolFieldEntry().getNameAndTypeEntry()); + } + + private AccessInstanceField getUltimateInstanceFieldAccess(final AccessArrayElement arrayLoadInstruction) { + Instruction load = arrayLoadInstruction.getArrayRef(); + while (load instanceof I_AALOAD) { + load = load.getFirstChild(); + } + + return (AccessInstanceField) load; + } + public void writeMethod(MethodCall _methodCall, MethodEntry _methodEntry) throws CodeGenException { boolean noCL = _methodEntry.getOwnerClassModel().getNoCLMethods() .contains(_methodEntry.getNameAndTypeEntry().getNameUTF8Entry().getUTF8());