package php.runtime.loader.dump; import php.runtime.common.LangMode; import php.runtime.env.Context; import php.runtime.env.Environment; import php.runtime.loader.dump.io.DumpException; import php.runtime.loader.dump.io.DumpInputStream; import php.runtime.loader.dump.io.DumpOutputStream; import php.runtime.reflection.ClassEntity; import php.runtime.reflection.ConstantEntity; import php.runtime.reflection.FunctionEntity; import php.runtime.reflection.ModuleEntity; import php.runtime.reflection.helper.ClosureEntity; import php.runtime.reflection.helper.GeneratorEntity; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class ModuleDumper extends Dumper<ModuleEntity> { public final static int DUMP_STAMP = 479873682; public final static int DUMP_VERSION = 20141011; protected ConstantDumper constantDumper = new ConstantDumper(context, env, debugInformation); protected ClosureDumper closureDumper = new ClosureDumper(context, env, debugInformation); protected FunctionDumper functionDumper = new FunctionDumper(context, env, debugInformation); protected ClassDumper classDumper = new ClassDumper(context, null, env, debugInformation); protected GeneratorDumper generatorDumper = new GeneratorDumper(context, env, debugInformation); public ModuleDumper(Context context, Environment env, boolean debugInformation) { super(context, env, debugInformation); } @Override public void setIncludeData(boolean includeData) { super.setIncludeData(includeData); constantDumper.setIncludeData(includeData); closureDumper.setIncludeData(includeData); functionDumper.setIncludeData(includeData); classDumper.setIncludeData(includeData); generatorDumper.setIncludeData(includeData); } @Override public int getType() { return -1; } @Override public void save(ModuleEntity entity, OutputStream output) throws IOException { if (entity.getData() == null) throw new DumpException("Module '" + entity.getName() + "' not compiled"); DumpOutputStream data = new DumpOutputStream(output); // version data.writeInt(DUMP_STAMP); data.writeInt(DUMP_VERSION); // legacy code. data.writeEnum(LangMode.DEFAULT); // module name data.writeName(entity.getContext().getModuleName()); data.writeName(entity.getInternalName()); // trace data.writeTrace(entity.getTrace()); // constants data.writeInt(entity.getConstants().size()); for(ConstantEntity e : entity.getConstants()){ constantDumper.save(e, output); } // closures data.writeInt(entity.getClosures().size()); for(ClosureEntity e : entity.getClosures()){ closureDumper.save(e, output); } // generators data.writeInt(entity.getGenerators().size()); for(GeneratorEntity e : entity.getGenerators()){ generatorDumper.save(e, output); } // functions data.writeInt(entity.getFunctions().size()); for(FunctionEntity e : entity.getFunctions()){ functionDumper.save(e, output); } // classes data.writeInt(entity.getClasses().size()); for(ClassEntity e : entity.getClasses()){ classDumper.save(e, output); } if (includeData) { // byte code data.writeInt(entity.getData().length); data.write(entity.getData()); } else { data.writeInt(0); } data.writeRawData(null, 1024 * 1024 * 5); // 5 mb } @Override public ModuleEntity load(InputStream input) throws IOException { DumpInputStream data = new DumpInputStream(input); int STAMP = data.readInt(); if (STAMP != DUMP_STAMP) throw new DumpException("Invalid file format"); int VERSION = data.readInt(); if (VERSION != DUMP_VERSION) throw new DumpException("Invalid dump version - " + VERSION + ", only " + DUMP_VERSION); data.readLangMode(); // legacy ModuleEntity entity = new ModuleEntity(context); entity.setName(data.readName()); entity.setInternalName(data.readName()); entity.setTrace(data.readTrace(context)); // constants int count = data.readInt(); for(int i = 0; i < count; i++){ ConstantEntity el = constantDumper.load(input); el.setModule(entity); entity.addConstant(el); } // closures count = data.readInt(); for(int i = 0; i < count; i++){ ClosureEntity el = closureDumper.load(input); el.setModule(entity); entity.addClosure(el); } count = data.readInt(); for(int i = 0; i < count; i++){ GeneratorEntity el = generatorDumper.load(input); el.setModule(entity); entity.addGenerator(el); } // functions count = data.readInt(); for(int i = 0; i < count; i++){ FunctionEntity el = functionDumper.load(input); el.setModule(entity); entity.addFunction(el); } // classes count = data.readInt(); ClassDumper classDumper = new ClassDumper(context, entity, env, debugInformation); for(int i = 0; i < count; i++){ ClassEntity el = classDumper.load(input); el.setModule(entity); entity.addClass(el); } // byte code entity.setData(data.readRawData(Integer.MAX_VALUE)); data.readRawData(1024 * 1024 * 5); return entity; } }