// C: This is for console applications. don't refactor this method and the other merge()
// before we ship.
private void merge(List<byte[]> abcList, boolean debug, boolean runPeephole)
{
Encoder encoder;
Decoder decoder;
boolean skipFrame = false;
int majorVersion = 0, minorVersion = 0, abcSize = abcList.size();
if (abcSize == 0)
{
return;
}
Decoder[] decoders = new Decoder[abcSize];
ConstantPool[] pools = new ConstantPool[abcSize];
// create decoders...
for (int j = 0; j < abcSize; j++)
{
byte[] abc = abcList.get(j);
BytecodeBuffer in = new BytecodeBuffer(abc);
try
{
decoders[j] = new Decoder(in);
majorVersion = decoders[j].majorVersion;
minorVersion = decoders[j].minorVersion;
pools[j] = decoders[j].constantPool;
}
catch (Throwable ex)
{
StringWriter stringWriter = new StringWriter();
ex.printStackTrace(new PrintWriter(stringWriter));
assert false : stringWriter.toString();
skipFrame = true;
break;
}
}
if (skipFrame)
{
return;
}
encoder = new Encoder(majorVersion, minorVersion);
// all the constant pools are merged here...
try
{
encoder.addConstantPools(pools);
if (!debug)
{
encoder.disableDebugging();
}
// always remove metadata...
encoder.removeMetadata();
// keep the following metadata
/*
encoder.addMetadataToKeep(StandardDefs.MD_BINDABLE);
encoder.addMetadataToKeep(StandardDefs.MD_MANAGED);
encoder.addMetadataToKeep(StandardDefs.MD_CHANGEEVENT);
encoder.addMetadataToKeep(StandardDefs.MD_NONCOMMITTINGCHANGEEVENT);
encoder.addMetadataToKeep(StandardDefs.MD_TRANSIENT);
*/
// always enable peephole optimization...
if (runPeephole)
{
encoder.enablePeepHole();
}
encoder.configure(decoders);
}
catch (Throwable ex)
{
StringWriter stringWriter = new StringWriter();
ex.printStackTrace(new PrintWriter(stringWriter));
assert false : stringWriter.toString();
return;
}
// decode methodInfo...
for (int j = 0; j < abcSize; j++)
{
decoder = decoders[j];
encoder.useConstantPool(j);
Decoder.MethodInfo methodInfo = decoder.methodInfo;
try
{
for (int k = 0, infoSize = methodInfo.size(); k < infoSize; k++)
{
methodInfo.decode(k, encoder);
}
}
catch (Throwable ex)
{
StringWriter stringWriter = new StringWriter();
ex.printStackTrace(new PrintWriter(stringWriter));
assert false : stringWriter.toString();
skipFrame = true;
break;
}
}
if (skipFrame)
{
return;
}
// decode metadataInfo...
for (int j = 0; j < abcSize; j++)
{
decoder = decoders[j];
encoder.useConstantPool(j);
Decoder.MetaDataInfo metadataInfo = decoder.metadataInfo;
try
{
for (int k = 0, infoSize = metadataInfo.size(); k < infoSize; k++)
{
metadataInfo.decode(k, encoder);
}
}
catch (Throwable ex)
{
StringWriter stringWriter = new StringWriter();
ex.printStackTrace(new PrintWriter(stringWriter));
assert false : stringWriter.toString();
skipFrame = true;
break;
}
}
if (skipFrame)
{
return;
}
// decode classInfo...
for (int j = 0; j < abcSize; j++)
{
decoder = decoders[j];
encoder.useConstantPool(j);
Decoder.ClassInfo classInfo = decoder.classInfo;
try
{
for (int k = 0, infoSize = classInfo.size(); k < infoSize; k++)
{
classInfo.decodeInstance(k, encoder);
}
}
catch (Throwable ex)
{
StringWriter stringWriter = new StringWriter();
ex.printStackTrace(new PrintWriter(stringWriter));
assert false : stringWriter.toString();
skipFrame = true;
break;
}
}
if (skipFrame)
{
return;
}
for (int j = 0; j < abcSize; j++)
{
decoder = decoders[j];
encoder.useConstantPool(j);
Decoder.ClassInfo classInfo = decoder.classInfo;
try
{
for (int k = 0, infoSize = classInfo.size(); k < infoSize; k++)
{
classInfo.decodeClass(k, 0, encoder);
}
}
catch (Throwable ex)
{
StringWriter stringWriter = new StringWriter();
ex.printStackTrace(new PrintWriter(stringWriter));
assert false : stringWriter.toString();
skipFrame = true;
break;
}
}
if (skipFrame)
{
return;
}
// decode scripts...
for (int j = 0; j < abcSize; j++)
{
decoder = decoders[j];
encoder.useConstantPool(j);
Decoder.ScriptInfo scriptInfo = decoder.scriptInfo;
try
{
for (int k = 0, scriptSize = scriptInfo.size(); k < scriptSize; k++)
{
scriptInfo.decode(k, encoder);
}
}
catch (Throwable ex)
{
StringWriter stringWriter = new StringWriter();
ex.printStackTrace(new PrintWriter(stringWriter));
assert false : stringWriter.toString();
skipFrame = true;
break;
}
}
if (skipFrame)
{
return;
}
// decode method bodies...
for (int j = 0; j < abcSize; j++)
{
decoder = decoders[j];
encoder.useConstantPool(j);
Decoder.MethodBodies methodBodies = decoder.methodBodies;
try
{
for (int k = 0, bodySize = methodBodies.size(); k < bodySize; k++)
{
methodBodies.decode(k, 2, encoder);
}
}
catch (Throwable ex)
{
StringWriter stringWriter = new StringWriter();
ex.printStackTrace(new PrintWriter(stringWriter));
assert false : stringWriter.toString();
skipFrame = true;
break;
}
}
if (skipFrame)
{
return;
}
byte[] abc = encoder.toABC();
if (abc != null)
{
abcList.clear();
abcList.add(abc);