scanengine.java

来自「linux下建立JAVA虚拟机的源码KAFFE」· Java 代码 · 共 861 行 · 第 1/2 页

JAVA
861
字号
              primitiveInstantiation("float", args[0].toString());            else if (valueClass == Double.class)              primitiveInstantiation("double", args[0].toString());            else              objectInstantiation(targetClass.getName(), id);            return;          }        else if (value instanceof Class)          {            String className = ((Class) value).getName();            // At this point we know that some *static* method will be called.            if (methodName.equals("forName"))              {                // However "Class.forName" represents class resolution and has a                // special syntax.                classResolution(className);                return;              }            else if (methodName.equals("getField"))              {                // The same goes for "Class.getField".                // Note: The name of the wanted field is given in                // the argument array.                staticFieldAccess(className, args[0].toString());                return;              }            else              {                // If nothing fits it is just a static method                // invocation which we decode as such.                staticMethodInvocation(className, methodName);                return;              }          }      }    else if (target instanceof List)      {        // Special behavior for indexed get and set method for list-style        // classes.        // The arguments are in the args array but we need them as subelements.        if (methodName.equals("get"))          {            listGet();            return;          }        else if (methodName.equals("set"))          {            listSet();            return;          }      }    // If nothing else could be used then this is a normal    // method invocation.    methodInvocation(methodName);  }  /**   * Ends the current state and returns to the last one.   */  public void end()  {    current.end();    if (DEBUG) System.err.print("back from " + current.getName());    ScannerState oldCurrent = current;    current = (ScannerState) parents.pop();    if (DEBUG) System.err.println(" to " + current.getName());  }  /**   * Returns to the last state and deletes the last element in the object tree.   */  public void revoke()  {    ScannerState oldCurrent = current;    current = (ScannerState) parents.pop();    root.deleteLast();  }  /** Scans the argument and calls one of event methods. See   * the introduction of this class for details.   *    * @param stmt The statement to serialize.   */  public void writeStatement(Statement stmt)  {    // This is a simplified version of writeExpression. Everything    // that would not create something that is embedded in a <void> tag    // is left out (instantiation, getters, ...).    // TODO: Is this the right thing to do?    String methodName = stmt.getMethodName();    Object target = stmt.getTarget();    Object[] args = stmt.getArguments();    if (target == Array.class && methodName.equals("set"))      {        arraySet(args[1].toString());        return;      }    if (target instanceof List)      {        if (methodName.equals("set"))          {            listSet();            return;          }      }    // If nothing else could be used then this is a normal    // method invocation.    methodInvocation(methodName);  }  /** Scans the argument and calls one of event methods. See   * the introduction of this class for details.   *    * @param o The object to serialize.   */  public boolean writeObject(Object o)  {    ObjectId id = null;    if (o == null)      {        // Handle null objects which have a special syntax.        nullObject();        end();      }    else if (o.getClass() == String.class)      {        // Handle strings which are treated extremely special        // in the encoder (they are never converted into a        // Expression).        stringReference((String) o);        end();      }    else if ((id = (ObjectId) objects.get(o)) != null)      {        // Multiple references to a Class object do not generate        // an object reference but we use the id to detect that        // situation.        if (o.getClass() == Class.class)          {            classResolution(((Class) o).getName());            end();            return false;          }                // If our object has a corresponding ObjectId instance        // then generate an objectReference. This will         // initialize the id (= brings it in the "used" state)        // when this is the first referal.        objectReference(id);        end();        return false;      }    return true;  }  /**   * Writes the currently constructed object tree out as   * XML and clears the object to {@link ObjectId} relations.   */  public void flush()  {    // Make all references unreachable. That means we have to generate    // new object ids.    objects.clear();    root.traverse(writer);  }  /** Writes the final bits if the object tree and closes the stream   * afterwards.   */  public void close()  {    flush();    root.close(writer);  }  /**   * Does a transition from one state to another using the given event.   *    * <p>This involves saving the current state, retrieving it's   * successor and setting it as the current state.</p>   *    * @param transition One of {@link ScannerStates]'s transition constants.   */  private void transition(int transition)  {    parents.push(current);    String stateName = current.getSuccessor(transition);        if (DEBUG)      {        System.err.println("from state: " + current.getName() + "\n\troute: "                           + ScannerState.transitionNames[transition]                           + "\n\t\tto state: "                           + stateName);      }        ScannerState newState = (ScannerState) states.get(stateName);        newState.enter(new Context(current.getName(), current.getCalls()));    assert (newState != null) : "State '" + stateName + "' was not defined.";    current = newState;  }  /** Event method that denotes a (non-static) method invocation.   *   * <p>More details about this method can be found in this   * class' introduction.</p>   *    * @param methodName The name of the method which is called.   */  void methodInvocation(String methodName)  {    transition(ScannerState.TRANSITION_METHOD_INVOCATION);    current.methodInvocation(methodName);  }  /** Event method that denotes a static method invocation.  *  * <p>More details about this method can be found in this  * class' introduction.</p>  *   * @param methodName The name of the method which is called.  * @param className The name of the class in which the method is called.  */  void staticMethodInvocation(String className, String methodName)  {    transition(ScannerState.TRANSITION_STATIC_METHOD_INVOCATION);    current.staticMethodInvocation(className, methodName);  }  /** Event method that denotes the retrieval of a static field's value.  *  * <p>More details about this method can be found in this  * class' introduction.</p>  *   * @param fieldName The name of the field whose value is retrieved.  * @param className The name of the class in which the method is called.  */  void staticFieldAccess(String className, String fieldName)  {    transition(ScannerState.TRANSITION_STATIC_FIELD_ACCESS);    current.staticFieldAccess(className, fieldName);  }  /** Event method that denotes the resolution of a class.  *  * <p>More details about this method can be found in this  * class' introduction.</p>  *   * @param className The name of the class in which the method is called.  */  void classResolution(String className)  {    transition(ScannerState.TRANSITION_CLASS_RESOLUTION);    current.classResolution(className);  }  /** Event method that denotes the instantiation of an object.  *  * <p>More details about this method can be found in this  * class' introduction.</p>  *   * @param className The name of the class in which the method is called.  * @param objectId An ObjectId instance which can be activated later.  */  void objectInstantiation(String className, ObjectId objectId)  {    transition(ScannerState.TRANSITION_OBJECT_INSTANTIATION);    current.objectInstantiation(className, objectId);  }  /** Event method that denotes the instantiation of a primitive.  *  * <p>More details about this method can be found in this  * class' introduction.</p>  *   * @param primitiveName One of "boolean, "byte", "short", "int", "long"  * , "float" or "double"  * @param valueAsString The value of the primitive as a String.  */  void primitiveInstantiation(String primitiveName, String valueAsString)  {    transition(ScannerState.TRANSITION_PRIMITIVE_INSTANTIATION);    current.primitiveInstantiation(primitiveName, valueAsString);  }  /** Event method that denotes the instantiation of an object array.  *  * <p>More details about this method can be found in this  * class' introduction.</p>  *   * @param arrayClassName The array's class name.  * @param objectId An ObjectId instance which can be activated later.  * @param lengthAsString The array's length as String.  */  void objectArrayInstantiation(String arrayClassName, String lengthAsString,                          ObjectId objectId)  {    transition(ScannerState.TRANSITION_OBJECT_ARRAY_INSTANTIATION);    current.objectArrayInstantiation(arrayClassName, lengthAsString, objectId);  }  /** Event method that denotes the instantiation of a primitive array.  *  * <p>More details about this method can be found in this  * class' introduction.</p>  *   * @param arrayClassName The array's class name.  * @param objectId An ObjectId instance which can be activated later.  * @param lengthAsString The array's length as String.  */  void primitiveArrayInstantiation(String arrayClassName, String lengthAsString,                                ObjectId objectId)  {    transition(ScannerState.TRANSITION_PRIMITIVE_ARRAY_INSTANTIATION);    current.objectArrayInstantiation(arrayClassName, lengthAsString, objectId);  }    /** Event method that denotes the setting of a value in an array.  *  * <p>More details about this method can be found in this  * class' introduction.</p>  *   * @param indexAsString The index to as a String.  */  void arraySet(String indexAsString)  {    transition(ScannerState.TRANSITION_ARRAY_SET);    current.arraySet(indexAsString);  }  /** Event method that denotes the retrieval of a value in an array.  *  * <p>More details about this method can be found in this  * class' introduction.</p>  *   * @param indexAsString The index to as a String.  */  void arrayGet(String indexAsString)  {    transition(ScannerState.TRANSITION_ARRAY_GET);    current.arrayGet(indexAsString);  }  /** Event method that denotes the setting of a value in a list.  *  * <p>More details about this method can be found in this  * class' introduction.</p>  */  void listSet()  {    transition(ScannerState.TRANSITION_LIST_SET);    current.listSet();  }  /** Event method that denotes the retrieval of a value in a list.  *  * <p>More details about this method can be found in this  * class' introduction.</p>  */  void listGet()  {    transition(ScannerState.TRANSITION_LIST_GET);    current.listGet();  }  /** Event method that denotes the null value.  */  void nullObject()  {    transition(ScannerState.TRANSITION_NULL_OBJECT);    current.nullObject();  }  /** Event method that denotes a string.   *    * @param string The string that should be written.   */  void stringReference(String string)  {    transition(ScannerState.TRANSITION_STRING_REFERENCE);    current.stringReference(string);  }  /** Event method that denotes a reference to an existing object.   *    * @param id The ObjectId to be used.   */  void objectReference(ObjectId id)  {    transition(ScannerState.TRANSITION_OBJECT_REFERENCE);    current.objectReference(id);  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?