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 + -
显示快捷键?