org.jetbrains.java.decompiler.util.InterpreterUtil Java Examples

The following examples show how to use org.jetbrains.java.decompiler.util.InterpreterUtil. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ConsoleDecompiler.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
@Override
public byte[] getBytecode(String externalPath, String internalPath) throws IOException {
    File file = new File(externalPath);
    if (internalPath == null) {
        return InterpreterUtil.getBytes(file);
    } else {
        ZipFile archive = new ZipFile(file);
        try {
            ZipEntry entry = archive.getEntry(internalPath);
            if (entry == null) throw new IOException("Entry not found: " + internalPath);
            return InterpreterUtil.getBytes(archive, entry);
        } finally {
            archive.close();
        }
    }
}
 
Example #2
Source File: FastExtendedPostdominanceHelper.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
private void calcReachabilitySuppPoints(final int edgetype) {
    iterateReachability(new IReachabilityAction() {
        @Override
        public boolean action(Statement node, HashMap<Integer, FastFixedSet<Integer>> mapSets) {
            // consider to be a support point
            for (StatEdge sucedge : node.getAllSuccessorEdges()) {
                if ((sucedge.getType() & edgetype) != 0) {
                    if (mapSets.containsKey(sucedge.getDestination().id)) {
                        FastFixedSet<Integer> setReachability = mapSets.get(node.id);

                        if (!InterpreterUtil.equalObjects(setReachability, mapSupportPoints.get(node.id))) {
                            mapSupportPoints.put(node.id, setReachability);
                            return true;
                        }
                    }
                }
            }

            return false;
        }
    }, edgetype);
}
 
Example #3
Source File: SSAConstructorSparseEx.java    From JByteMod-Beta with GNU General Public License v2.0 6 votes vote down vote up
private static boolean mapsEqual(SFormsFastMapDirect map1, SFormsFastMapDirect map2) {

    if (map1 == null) {
      return map2 == null;
    } else if (map2 == null) {
      return false;
    }

    if (map1.size() != map2.size()) {
      return false;
    }

    for (Entry<Integer, FastSparseSet<Integer>> ent2 : map2.entryList()) {
      if (!InterpreterUtil.equalObjects(map1.get(ent2.getKey()), ent2.getValue())) {
        return false;
      }
    }

    return true;
  }
 
Example #4
Source File: SSAUConstructorSparseEx.java    From JByteMod-Beta with GNU General Public License v2.0 6 votes vote down vote up
private static boolean mapsEqual(SFormsFastMapDirect map1, SFormsFastMapDirect map2) {

    if (map1 == null) {
      return map2 == null;
    } else if (map2 == null) {
      return false;
    }

    if (map1.size() != map2.size()) {
      return false;
    }

    for (Entry<Integer, FastSparseSet<Integer>> ent2 : map2.entryList()) {
      if (!InterpreterUtil.equalObjects(map1.get(ent2.getKey()), ent2.getValue())) {
        return false;
      }
    }

    return true;
  }
 
Example #5
Source File: FastExtendedPostdominanceHelper.java    From JByteMod-Beta with GNU General Public License v2.0 6 votes vote down vote up
private void calcReachabilitySuppPoints(final int edgetype) {

    iterateReachability(new IReachabilityAction() {
      public boolean action(Statement node, HashMap<Integer, FastFixedSet<Integer>> mapSets) {

        // consider to be a support point
        for (StatEdge sucedge : node.getAllSuccessorEdges()) {
          if ((sucedge.getType() & edgetype) != 0) {
            if (mapSets.containsKey(sucedge.getDestination().id)) {
              FastFixedSet<Integer> setReachability = mapSets.get(node.id);

              if (!InterpreterUtil.equalObjects(setReachability, mapSupportPoints.get(node.id))) {
                mapSupportPoints.put(node.id, setReachability);
                return true;
              }
            }
          }
        }

        return false;
      }
    }, edgetype);
  }
 
Example #6
Source File: AssertProcessor.java    From JByteMod-Beta with GNU General Public License v2.0 6 votes vote down vote up
public static void buildAssertions(ClassNode node) {

    ClassWrapper wrapper = node.getWrapper();

    StructField field = findAssertionField(node);

    if (field != null) {

      String key = InterpreterUtil.makeUniqueKey(field.getName(), field.getDescriptor());

      boolean res = false;

      for (MethodWrapper meth : wrapper.getMethods()) {
        RootStatement root = meth.root;
        if (root != null) {
          res |= replaceAssertions(root, wrapper.getClassStruct().qualifiedName, key);
        }
      }

      if (res) {
        // hide the helper field
        wrapper.getHiddenMembers().add(key);
      }
    }
  }
 
Example #7
Source File: ClassReference14Processor.java    From JByteMod-Beta with GNU General Public License v2.0 6 votes vote down vote up
public static void processClassReferences(ClassNode node) {
  // find the synthetic method Class class$(String) if present
  HashMap<ClassWrapper, MethodWrapper> mapClassMeths = new HashMap<>();
  mapClassMethods(node, mapClassMeths);
  if (mapClassMeths.isEmpty()) {
    return;
  }
  HashSet<ClassWrapper> setFound = new HashSet<>();
  processClassRec(node, mapClassMeths, setFound);

  if (!setFound.isEmpty()) {
    for (ClassWrapper wrp : setFound) {
      StructMethod mt = mapClassMeths.get(wrp).methodStruct;
      wrp.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(mt.getName(), mt.getDescriptor()));
    }
  }
}
 
Example #8
Source File: ConsoleDecompiler.java    From JByteMod-Beta with GNU General Public License v2.0 6 votes vote down vote up
@Override
public void copyEntry(String source, String path, String archiveName, String entryName) {
  String file = new File(getAbsolutePath(path), archiveName).getPath();

  if (!checkEntry(entryName, file)) {
    return;
  }

  try (ZipFile srcArchive = new ZipFile(new File(source))) {
    ZipEntry entry = srcArchive.getEntry(entryName);
    if (entry != null) {
      try (InputStream in = srcArchive.getInputStream(entry)) {
        ZipOutputStream out = mapArchiveStreams.get(file);
        out.putNextEntry(new ZipEntry(entryName));
        InterpreterUtil.copyStream(in, out);
      }
    }
  } catch (IOException ex) {
    String message = "Cannot copy entry " + entryName + " from " + source + " to " + file;
    DecompilerContext.getLogger().writeMessage(message, ex);
  }
}
 
Example #9
Source File: AssertProcessor.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
public static void buildAssertions(ClassNode node) {

        ClassWrapper wrapper = node.getWrapper();

        StructField field = findAssertionField(node);

        if (field != null) {

            String key = InterpreterUtil.makeUniqueKey(field.getName(), field.getDescriptor());

            boolean res = false;

            for (MethodWrapper meth : wrapper.getMethods()) {
                RootStatement root = meth.root;
                if (root != null) {
                    res |= replaceAssertions(root, wrapper.getClassStruct().qualifiedName, key);
                }
            }

            if (res) {
                // hide the helper field
                wrapper.getHiddenMembers().add(key);
            }
        }
    }
 
Example #10
Source File: SimplifyExprentsHelper.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
private static boolean collapseInlinedClass14(Statement stat) {
    boolean ret = class14Builder.match(stat);
    if (ret) {
        String class_name = (String) class14Builder.getVariableValue("$classname$");
        AssignmentExprent assignment = (AssignmentExprent) class14Builder.getVariableValue("$assignfield$");
        FieldExprent fieldExpr = (FieldExprent) class14Builder.getVariableValue("$field$");

        assignment.replaceExprent(assignment.getRight(), new ConstExprent(VarType.VARTYPE_CLASS, class_name, null));

        List<Exprent> data = new ArrayList<>(stat.getFirst().getExprents());

        stat.setExprents(data);

        SequenceHelper.destroyAndFlattenStatement(stat);

        ClassWrapper wrapper = (ClassWrapper) DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_WRAPPER);
        if (wrapper != null) {
            wrapper.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(fieldExpr.getName(), fieldExpr.getDescriptor().descriptorString));
        }
    }

    return ret;
}
 
Example #11
Source File: RuntimeDecompiler.java    From Mixin with MIT License 6 votes vote down vote up
@Override
public void decompile(final File file) {
    try {
        Fernflower fernflower = new Fernflower(new IBytecodeProvider() {
            
            private byte[] byteCode;
            
            @Override
            public byte[] getBytecode(String externalPath, String internalPath) throws IOException {
                if (this.byteCode == null) {
                    this.byteCode = InterpreterUtil.getBytes(new File(externalPath));
                }
                return this.byteCode;
            }
            
        }, this, this.options, this);
        
        fernflower.getStructContext().addSpace(file, true);
        fernflower.decompileContext();
    } catch (Throwable ex) {
        this.logger.warn("Decompilation error while processing {}", file.getName());
    }
}
 
Example #12
Source File: ClassReference14Processor.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
public static void processClassReferences(ClassNode node) {
    // find the synthetic method Class class$(String) if present
    Map<ClassWrapper, MethodWrapper> mapClassMeths = new HashMap<>();
    mapClassMethods(node, mapClassMeths);
    if (mapClassMeths.isEmpty()) {
        return;
    }

    Set<ClassWrapper> setFound = new HashSet<>();
    processClassRec(node, mapClassMeths, setFound);

    if (!setFound.isEmpty()) {
        for (ClassWrapper wrp : setFound) {
            StructMethod mt = mapClassMeths.get(wrp).methodStruct;
            wrp.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(mt.getName(), mt.getDescriptor()));
        }
    }
}
 
Example #13
Source File: InitializerProcessor.java    From JByteMod-Beta with GNU General Public License v2.0 5 votes vote down vote up
private static void extractStaticInitializers(ClassWrapper wrapper, MethodWrapper method) {
  RootStatement root = method.root;
  StructClass cl = wrapper.getClassStruct();
  Statement firstData = Statements.findFirstData(root);
  if (firstData != null) {
    boolean inlineInitializers = cl.hasModifier(CodeConstants.ACC_INTERFACE) || cl.hasModifier(CodeConstants.ACC_ENUM);

    while (!firstData.getExprents().isEmpty()) {
      Exprent exprent = firstData.getExprents().get(0);

      boolean found = false;

      if (exprent.type == Exprent.EXPRENT_ASSIGNMENT) {
        AssignmentExprent assignExpr = (AssignmentExprent) exprent;
        if (assignExpr.getLeft().type == Exprent.EXPRENT_FIELD) {
          FieldExprent fExpr = (FieldExprent) assignExpr.getLeft();
          if (fExpr.isStatic() && fExpr.getClassname().equals(cl.qualifiedName)
              && cl.hasField(fExpr.getName(), fExpr.getDescriptor().descriptorString)) {

            // interfaces fields should always be initialized inline
            if (inlineInitializers || isExprentIndependent(assignExpr.getRight(), method)) {
              String keyField = InterpreterUtil.makeUniqueKey(fExpr.getName(), fExpr.getDescriptor().descriptorString);
              if (!wrapper.getStaticFieldInitializers().containsKey(keyField)) {
                wrapper.getStaticFieldInitializers().addWithKey(assignExpr.getRight(), keyField);
                firstData.getExprents().remove(0);
                found = true;
              }
            }
          }
        }
      }

      if (!found) {
        break;
      }
    }
  }
}
 
Example #14
Source File: FernflowerDecompiler.java    From windup with Eclipse Public License 1.0 5 votes vote down vote up
private IBytecodeProvider getByteCodeProvider()
{
    return new IBytecodeProvider()
    {
        @Override
        public byte[] getBytecode(String externalPath, String internalPath) throws IOException
        {
            return InterpreterUtil.getBytes(new File(externalPath));
        }
    };
}
 
Example #15
Source File: ExitExprent.java    From JByteMod-Beta with GNU General Public License v2.0 5 votes vote down vote up
@Override
public boolean equals(Object o) {
  if (o == this)
    return true;
  if (o == null || !(o instanceof ExitExprent))
    return false;

  ExitExprent et = (ExitExprent) o;
  return exitType == et.getExitType() && InterpreterUtil.equalObjects(value, et.getValue());
}
 
Example #16
Source File: MonitorExprent.java    From JByteMod-Beta with GNU General Public License v2.0 5 votes vote down vote up
@Override
public boolean equals(Object o) {
  if (o == this)
    return true;
  if (o == null || !(o instanceof MonitorExprent))
    return false;

  MonitorExprent me = (MonitorExprent) o;
  return monType == me.getMonType() && InterpreterUtil.equalObjects(value, me.getValue());
}
 
Example #17
Source File: InvocationExprent.java    From JByteMod-Beta with GNU General Public License v2.0 5 votes vote down vote up
@Override
public boolean equals(Object o) {
  if (o == this)
    return true;
  if (o == null || !(o instanceof InvocationExprent))
    return false;

  InvocationExprent it = (InvocationExprent) o;
  return InterpreterUtil.equalObjects(name, it.getName()) && InterpreterUtil.equalObjects(classname, it.getClassname()) && isStatic == it.isStatic()
      && InterpreterUtil.equalObjects(instance, it.getInstance()) && InterpreterUtil.equalObjects(descriptor, it.getDescriptor())
      && functype == it.getFunctype() && InterpreterUtil.equalLists(lstParameters, it.getLstParameters());
}
 
Example #18
Source File: FieldExprent.java    From JByteMod-Beta with GNU General Public License v2.0 5 votes vote down vote up
@Override
public boolean equals(Object o) {
  if (o == this)
    return true;
  if (o == null || !(o instanceof FieldExprent))
    return false;

  FieldExprent ft = (FieldExprent) o;
  return InterpreterUtil.equalObjects(name, ft.getName()) && InterpreterUtil.equalObjects(classname, ft.getClassname()) && isStatic == ft.isStatic()
      && InterpreterUtil.equalObjects(instance, ft.getInstance()) && InterpreterUtil.equalObjects(descriptor, ft.getDescriptor());
}
 
Example #19
Source File: ConstExprent.java    From JByteMod-Beta with GNU General Public License v2.0 5 votes vote down vote up
@Override
public boolean equals(Object o) {
  if (o == this)
    return true;
  if (o == null || !(o instanceof ConstExprent))
    return false;

  ConstExprent cn = (ConstExprent) o;
  return InterpreterUtil.equalObjects(constType, cn.getConstType()) && InterpreterUtil.equalObjects(value, cn.getValue());
}
 
Example #20
Source File: ArrayExprent.java    From JByteMod-Beta with GNU General Public License v2.0 5 votes vote down vote up
@Override
public boolean equals(Object o) {
  if (o == this)
    return true;
  if (o == null || !(o instanceof ArrayExprent))
    return false;

  ArrayExprent arr = (ArrayExprent) o;
  return InterpreterUtil.equalObjects(array, arr.getArray()) && InterpreterUtil.equalObjects(index, arr.getIndex());
}
 
Example #21
Source File: ClassWriter.java    From JByteMod-Beta with GNU General Public License v2.0 5 votes vote down vote up
private static void addTracer(StructClass cls, StructMethod method, BytecodeMappingTracer tracer) {
  StructLineNumberTableAttribute table = (StructLineNumberTableAttribute) method.getAttributes()
      .getWithKey(StructGeneralAttribute.ATTRIBUTE_LINE_NUMBER_TABLE);
  tracer.setLineNumberTable(table);
  String key = InterpreterUtil.makeUniqueKey(method.getName(), method.getDescriptor());
  DecompilerContext.getBytecodeSourceMapper().addTracer(cls.qualifiedName, key, tracer);
}
 
Example #22
Source File: StructLineNumberTableAttribute.java    From JByteMod-Beta with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void initContent(ConstantPool pool) throws IOException {
  DataInputFullStream data = stream();

  int len = data.readUnsignedShort() * 2;
  if (len > 0) {
    myLineInfo = new int[len];
    for (int i = 0; i < len; i += 2) {
      myLineInfo[i] = data.readUnsignedShort();
      myLineInfo[i + 1] = data.readUnsignedShort();
    }
  } else if (myLineInfo.length > 0) {
    myLineInfo = InterpreterUtil.EMPTY_INT_ARRAY;
  }
}
 
Example #23
Source File: IFernflowerPreferences.java    From JByteMod-Beta with GNU General Public License v2.0 5 votes vote down vote up
static Map<String, Object> getDefaults() {
  Map<String, Object> defaults = new HashMap<>();

  defaults.put(REMOVE_BRIDGE, "1");
  defaults.put(REMOVE_SYNTHETIC, "0");
  defaults.put(DECOMPILE_INNER, "1");
  defaults.put(DECOMPILE_CLASS_1_4, "1");
  defaults.put(DECOMPILE_ASSERTIONS, "1");
  defaults.put(HIDE_EMPTY_SUPER, "1");
  defaults.put(HIDE_DEFAULT_CONSTRUCTOR, "1");
  defaults.put(DECOMPILE_GENERIC_SIGNATURES, "0");
  defaults.put(NO_EXCEPTIONS_RETURN, "1");
  defaults.put(DECOMPILE_ENUM, "1");
  defaults.put(REMOVE_GET_CLASS_NEW, "1");
  defaults.put(LITERALS_AS_IS, "0");
  defaults.put(BOOLEAN_TRUE_ONE, "1");
  defaults.put(ASCII_STRING_CHARACTERS, "0");
  defaults.put(SYNTHETIC_NOT_SET, "1");
  defaults.put(UNDEFINED_PARAM_TYPE_OBJECT, "1");
  defaults.put(USE_DEBUG_VAR_NAMES, "1");
  defaults.put(REMOVE_EMPTY_RANGES, "1");
  defaults.put(FINALLY_DEINLINE, "1");
  defaults.put(IDEA_NOT_NULL_ANNOTATION, "1");
  defaults.put(LAMBDA_TO_ANONYMOUS_CLASS, "0");
  defaults.put(BYTECODE_SOURCE_MAPPING, "0");

  defaults.put(LOG_LEVEL, IFernflowerLogger.Severity.INFO.name());
  defaults.put(MAX_PROCESSING_METHOD, "0");
  defaults.put(RENAME_ENTITIES, "0");
  defaults.put(NEW_LINE_SEPARATOR, (InterpreterUtil.IS_WINDOWS ? "0" : "1"));
  defaults.put(INDENT_STRING, "   ");
  defaults.put(BANNER, "");
  defaults.put(UNIT_TEST_MODE, "0");
  defaults.put(DUMP_ORIGINAL_LINES, "0");

  return Collections.unmodifiableMap(defaults);
}
 
Example #24
Source File: VarType.java    From JByteMod-Beta with GNU General Public License v2.0 5 votes vote down vote up
@Override
public boolean equals(Object o) {
  if (o == this) {
    return true;
  }

  if (o == null || !(o instanceof VarType)) {
    return false;
  }

  VarType vt = (VarType) o;
  return type == vt.type && arrayDim == vt.arrayDim && InterpreterUtil.equalObjects(value, vt.value);
}
 
Example #25
Source File: AnnotationExprent.java    From JByteMod-Beta with GNU General Public License v2.0 5 votes vote down vote up
@Override
public boolean equals(Object o) {
  if (o == this)
    return true;
  if (o == null || !(o instanceof AnnotationExprent))
    return false;

  AnnotationExprent ann = (AnnotationExprent) o;
  return className.equals(ann.className) && InterpreterUtil.equalLists(parNames, ann.parNames)
      && InterpreterUtil.equalLists(parValues, ann.parValues);
}
 
Example #26
Source File: NestedClassProcessor.java    From JByteMod-Beta with GNU General Public License v2.0 5 votes vote down vote up
private static String getEnclosingVarField(StructClass cl, MethodWrapper method, DirectGraph graph, int index) {
  String field = "";

  // parameter variable final
  if (method.varproc.getVarFinal(new VarVersionPair(index, 0)) == VarTypeProcessor.VAR_NON_FINAL) {
    return null;
  }

  boolean noSynthFlag = DecompilerContext.getOption(IFernflowerPreferences.SYNTHETIC_NOT_SET);

  // no loop at the begin
  DirectNode firstNode = graph.first;
  if (firstNode.preds.isEmpty()) {
    // assignment to a synthetic field?
    for (Exprent exprent : firstNode.exprents) {
      if (exprent.type == Exprent.EXPRENT_ASSIGNMENT) {
        AssignmentExprent assignExpr = (AssignmentExprent) exprent;
        if (assignExpr.getRight().type == Exprent.EXPRENT_VAR && ((VarExprent) assignExpr.getRight()).getIndex() == index
            && assignExpr.getLeft().type == Exprent.EXPRENT_FIELD) {
          FieldExprent left = (FieldExprent) assignExpr.getLeft();
          StructField fd = cl.getField(left.getName(), left.getDescriptor().descriptorString);

          if (fd != null && cl.qualifiedName.equals(left.getClassname()) && fd.hasModifier(CodeConstants.ACC_FINAL)
              && (fd.isSynthetic() || (noSynthFlag && fd.hasModifier(CodeConstants.ACC_PRIVATE)))) {
            // local (== not inherited) field
            field = InterpreterUtil.makeUniqueKey(left.getName(), left.getDescriptor().descriptorString);
            break;
          }
        }
      }
    }
  }

  return field;
}
 
Example #27
Source File: ClassesProcessor.java    From JByteMod-Beta with GNU General Public License v2.0 5 votes vote down vote up
public ClassNode(String content_class_name, String content_method_name, String content_method_descriptor, int content_method_invocation_type,
    String lambda_class_name, String lambda_method_name, String lambda_method_descriptor, StructClass classStruct) { // lambda class constructor
  this.type = CLASS_LAMBDA;
  this.classStruct = classStruct; // 'parent' class containing the static function

  lambdaInformation = new LambdaInformation();

  lambdaInformation.class_name = lambda_class_name;
  lambdaInformation.method_name = lambda_method_name;
  lambdaInformation.method_descriptor = lambda_method_descriptor;

  lambdaInformation.content_class_name = content_class_name;
  lambdaInformation.content_method_name = content_method_name;
  lambdaInformation.content_method_descriptor = content_method_descriptor;
  lambdaInformation.content_method_invocation_type = content_method_invocation_type;

  lambdaInformation.content_method_key = InterpreterUtil.makeUniqueKey(lambdaInformation.content_method_name,
      lambdaInformation.content_method_descriptor);

  anonymousClassType = new VarType(lambda_class_name, true);

  boolean is_method_reference = (content_class_name != classStruct.qualifiedName);
  if (!is_method_reference) { // content method in the same class, check synthetic flag
    StructMethod mt = classStruct.getMethod(content_method_name, content_method_descriptor);
    is_method_reference = !mt.isSynthetic(); // if not synthetic -> method reference
  }

  lambdaInformation.is_method_reference = is_method_reference;
  lambdaInformation.is_content_method_static = (lambdaInformation.content_method_invocation_type == CodeConstants.CONSTANT_MethodHandle_REF_invokeStatic); // FIXME: redundant?
}
 
Example #28
Source File: ConsoleDecompiler.java    From JByteMod-Beta with GNU General Public License v2.0 5 votes vote down vote up
@Override
public byte[] getBytecode(String externalPath, String internalPath) throws IOException {
  File file = new File(externalPath);
  if (internalPath == null) {
    return InterpreterUtil.getBytes(file);
  } else {
    try (ZipFile archive = new ZipFile(file)) {
      ZipEntry entry = archive.getEntry(internalPath);
      if (entry == null)
        throw new IOException("Entry not found: " + internalPath);
      return InterpreterUtil.getBytes(archive, entry);
    }
  }
}
 
Example #29
Source File: ConsoleDecompiler.java    From JByteMod-Beta with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void copyFile(String source, String path, String entryName) {
  try {
    InterpreterUtil.copyFile(new File(source), new File(getAbsolutePath(path), entryName));
  } catch (IOException ex) {
    DecompilerContext.getLogger().writeMessage("Cannot copy " + source + " to " + entryName, ex);
  }
}
 
Example #30
Source File: StructContext.java    From JByteMod-Beta with GNU General Public License v2.0 5 votes vote down vote up
private void addArchive(String path, File file, int type, boolean isOwn) throws IOException {
  //noinspection IOResourceOpenedButNotSafelyClosed
  try (ZipFile archive = type == ContextUnit.TYPE_JAR ? new JarFile(file) : new ZipFile(file)) {
    Enumeration<? extends ZipEntry> entries = archive.entries();
    while (entries.hasMoreElements()) {
      ZipEntry entry = entries.nextElement();

      ContextUnit unit = units.get(path + "/" + file.getName());
      if (unit == null) {
        unit = new ContextUnit(type, path, file.getName(), isOwn, saver, decompiledData);
        if (type == ContextUnit.TYPE_JAR) {
          unit.setManifest(((JarFile) archive).getManifest());
        }
        units.put(path + "/" + file.getName(), unit);
      }

      String name = entry.getName();
      if (!entry.isDirectory()) {
        if (name.endsWith(".class")) {
          byte[] bytes = InterpreterUtil.getBytes(archive, entry);
          StructClass cl = new StructClass(bytes, isOwn, loader);
          classes.put(cl.qualifiedName, cl);
          unit.addClass(cl, name);
          loader.addClassLink(cl.qualifiedName, new LazyLoader.Link(LazyLoader.Link.ENTRY, file.getAbsolutePath(), name));
        } else {
          unit.addOtherEntry(file.getAbsolutePath(), name);
        }
      } else {
        unit.addDirEntry(name);
      }
    }
  }
}