Author: glen Date: Wed Jan 7 12:35:57 2009 GMT Module: SOURCES Tag: HEAD ---- Log message: - from dojo-release-1.2.2-shrinksafe
---- Files affected: SOURCES: custom_rhino.diff (NONE -> 1.1) (NEW) ---- Diffs: ================================================================ Index: SOURCES/custom_rhino.diff diff -u /dev/null SOURCES/custom_rhino.diff:1.1 --- /dev/null Wed Jan 7 13:35:57 2009 +++ SOURCES/custom_rhino.diff Wed Jan 7 13:35:51 2009 @@ -0,0 +1,1343 @@ +Index: src/org/mozilla/javascript/BaseFunction.java +=================================================================== +RCS file: /cvsroot/mozilla/js/rhino/src/org/mozilla/javascript/BaseFunction.java,v +retrieving revision 1.63 +diff -u -8 -p -r1.63 BaseFunction.java +--- src/org/mozilla/javascript/BaseFunction.java 16 May 2007 12:41:00 -0000 1.63 ++++ src/org/mozilla/javascript/BaseFunction.java 19 Oct 2007 11:28:27 -0000 +@@ -371,16 +371,38 @@ public class BaseFunction extends IdScri + sb.append(getArity()); + sb.append("]\n"); + if (!justbody) { + sb.append("}\n"); + } + return sb.toString(); + } + ++ String compress(int indent, int flags) ++ { ++ StringBuffer sb = new StringBuffer(); ++ String FuncName = null; ++ boolean justbody = (0 != (flags & Decompiler.ONLY_BODY_FLAG)); ++ if (!justbody) { ++ sb.append("function"); ++ FuncName = getFunctionName(); ++ if(FuncName.length()>0){ ++ sb.append(" "+FuncName); ++ } ++ sb.append("(){"); ++ } ++ sb.append("[native code, arity="); ++ sb.append(getArity()); ++ sb.append("]"); ++ if (!justbody) { ++ sb.append("}"); ++ } ++ return sb.toString(); ++ } ++ + public int getArity() { return 0; } + + public int getLength() { return 0; } + + public String getFunctionName() + { + return ""; + } +Index: src/org/mozilla/javascript/Context.java +=================================================================== +RCS file: /cvsroot/mozilla/js/rhino/src/org/mozilla/javascript/Context.java,v +retrieving revision 1.255.2.1 +diff -u -8 -p -r1.255.2.1 Context.java +--- src/org/mozilla/javascript/Context.java 6 Jun 2007 14:58:49 -0000 1.255.2.1 ++++ src/org/mozilla/javascript/Context.java 19 Oct 2007 11:28:27 -0000 +@@ -1211,16 +1211,43 @@ public class Context + * @param securityDomain an arbitrary object that specifies security + * information about the origin or owner of the script. For + * implementations that don't care about security, this value + * may be null. + * @return the result of evaluating the source + * + * @exception IOException if an IOException was generated by the Reader + */ ++ public final String decompileReader(Scriptable scope, Reader in, ++ String sourceName, int lineno, ++ Object securityDomain) ++ throws IOException ++ { ++ Script script = compileReader(scope, in, sourceName, lineno, ++ securityDomain); ++ if (script != null) { ++ // System.err.println(script); ++ return decompileScript(script, 0); ++ } else { ++ return null; ++ } ++ } ++ ++ public final String compressReader(Scriptable scope, Script script, String source, ++ String sourceName, int lineno, Object securityDomain){ ++ ++ if (script != null) { ++ // System.err.println(script); ++ return compressScript(script, 0, source,lineno); ++ } else { ++ return null; ++ } ++ } ++ ++ + public final Object evaluateReader(Scriptable scope, Reader in, + String sourceName, int lineno, + Object securityDomain) + throws IOException + { + Script script = compileReader(scope, in, sourceName, lineno, + securityDomain); + if (script != null) { +@@ -1393,16 +1420,44 @@ public class Context + catch (IOException ioe) { + // Should never happen because we just made the reader + // from a String + throw new RuntimeException(); + } + } + + /** ++ * Compress the script. ++ * <p> ++ * Compressed script is returned. ++ * ++ * @param script the script object ++ * @param indent the number of spaces to indent the result ++ * @return a string representing the script source ++ */ ++ public final String compressScript(Script script, int indent, String source,int lineno) ++ { ++ //Make sure to clear out the TokenMapper state before running. ++ //This allows for more than one script to be compressed. ++ //However, this is not a very clean way to do the reset. ++ TokenMapper.reset(); ++ Decompiler.tm = new TokenMapper(); ++ ++ NativeFunction scriptImpl = (NativeFunction) script; ++ ++ CompilerEnvirons compilerEnv = new CompilerEnvirons(); ++ ++ Parser parser = new Parser(compilerEnv, compilerEnv.getErrorReporter()); ++ ++ ScriptOrFnNode tree = parser.parse(source, null, lineno); ++ ++ return scriptImpl.compress( tree,indent, 0); ++ } ++ ++ /** + * Decompile the script. + * <p> + * The canonical source of the script is returned. + * + * @param script the script to decompile + * @param indent the number of spaces to indent the result + * @return a string representing the script source + */ +@@ -2287,27 +2342,27 @@ public class Context + Interpreter compiler, + ErrorReporter compilationErrorReporter) + throws IOException + { + if (securityDomain != null && securityController == null) { + throw new IllegalArgumentException( + "securityDomain should be null if setSecurityController() was never called"); + } +- + // One of sourceReader or sourceString has to be null + if (!(sourceReader == null ^ sourceString == null)) Kit.codeBug(); + // scope should be given if and only if compiling function + if (!(scope == null ^ returnFunction)) Kit.codeBug(); + + CompilerEnvirons compilerEnv = new CompilerEnvirons(); + compilerEnv.initFromContext(this); + if (compilationErrorReporter == null) { + compilationErrorReporter = compilerEnv.getErrorReporter(); + } ++ + + if (debugger != null) { + if (sourceReader != null) { + sourceString = Kit.readReader(sourceReader); + sourceReader = null; + } + } + +Index: src/org/mozilla/javascript/Decompiler.java +=================================================================== +RCS file: /cvsroot/mozilla/js/rhino/src/org/mozilla/javascript/Decompiler.java,v +retrieving revision 1.23 +diff -u -8 -p -r1.23 Decompiler.java +--- src/org/mozilla/javascript/Decompiler.java 4 Apr 2007 20:52:09 -0000 1.23 ++++ src/org/mozilla/javascript/Decompiler.java 19 Oct 2007 11:28:28 -0000 +@@ -36,16 +36,21 @@ + * them with the notice and other provisions required by the GPL. If you do + * not delete the provisions above, a recipient may use your version of this + * file under either the MPL or the GPL. + * + * ***** END LICENSE BLOCK ***** */ + + package org.mozilla.javascript; + ++import java.util.ArrayList; ++import java.util.Arrays; ++import java.util.HashMap; ++import java.util.List; ++ + /** + * The following class save decompilation information about the source. + * Source information is returned from the parser as a String + * associated with function nodes and with the toplevel script. When + * saved in the constant pool of a class, this string will be UTF-8 + * encoded, and token values will occupy a single byte. + + * Source is saved (mostly) as token numbers. The tokens saved pretty +@@ -69,16 +74,282 @@ package org.mozilla.javascript; + * followed by a character giving the length of the string (assumed to + * be less than 2^16), followed by the characters of the string + * inlined into the source string. Changing this to some reference to + * to the string in the compiled class' constant pool would probably + * save a lot of space... but would require some method of deriving + * the final constant pool entry from information available at parse + * time. + */ ++ ++class TokenMapper { ++ private ArrayList functionBracePositions = new ArrayList(); ++ ++ /** ++ * Map of all replaced tokens ++ */ ++ private ArrayList replacedTokens = new ArrayList(); ++ ++ /** ++ * Collection of Function nodes ++ */ ++ private static ObjArray funcObjects = new ObjArray(); ++ ++ /** ++ * Map of each Function node and all the variables in its current function ++ * scope, other variables found while traversing the prototype chain and ++ * variables found in the top-level scope. ++ */ ++ private static ArrayList functionVarMappings = new ArrayList(); ++ ++ public int functionNum = 0; ++ ++ private int parentScope = 0; ++ ++ private int lastTokenCount = 0; ++ ++ /** ++ * Reset the static members for the TokenMapper. ++ */ ++ public static void reset() { ++ funcObjects = new ObjArray(); ++ functionVarMappings = new ArrayList(); ++ } ++ ++ /** ++ * Generate new compressed tokens ++ * <p> ++ * ++ * @param token ++ * value of the string token ++ * @param hasNewMapping ++ * boolean value indicating a new variable binding ++ * @return compressed token ++ */ ++ private String getMappedToken(String token, boolean hasNewMapping) { ++ String newToken = null; ++ HashMap tokens = null; ++ String blank = new String(""); ++ int localScope = functionBracePositions.size() - 1; ++ ++ String oldToken = getPreviousTokenMapping(token, hasNewMapping); ++ ++ if (!oldToken.equalsIgnoreCase(blank)) { ++ return oldToken; ++ } else if ((hasNewMapping || isInScopeChain(token))) { ++ lastTokenCount++; ++ newToken = new String("_" + Integer.toHexString(lastTokenCount)); ++ if (newToken.length() >= token.length()) { ++ newToken = token; ++ } ++ if (hasNewMapping) { ++ tokens = (HashMap) replacedTokens.get(localScope); ++ } else { ++ tokens = (HashMap) replacedTokens.get(parentScope); ++ } ++ ++ tokens.put(token, newToken); ++ return newToken; ++ } ++ return token; ++ } ++ ++ /** ++ * Checks for variable names in prototype chain ++ * <p> ++ * ++ * @param token ++ * value of the string token ++ * @return boolean value indicating if the token is present in the chained ++ * scope ++ */ ++ private boolean isInScopeChain(String token) { ++ int scope = functionBracePositions.size(); ++ HashMap chainedScopeVars = (HashMap) functionVarMappings ++ .get(functionNum); ++ if (!chainedScopeVars.isEmpty()) { ++ for (int i = scope; i > 0; i--) { ++ if (chainedScopeVars.containsKey(new Integer(i))) { ++ parentScope = i - 1; ++ List temp = Arrays.asList((String[]) chainedScopeVars ++ .get(new Integer(i))); ++ if (temp.indexOf(token) != -1) { ++ return true; ++ } ++ } ++ } ++ } ++ return false; ++ } ++ ++ /** ++ * Checks previous token mapping ++ * <p> ++ * ++ * @param token ++ * value of the string token ++ * @param hasNewMapping ++ * boolean value indicating a new variable binding ++ * @return string value of the previous token or blank string ++ */ ++ private String getPreviousTokenMapping(String token, boolean hasNewMapping) { ++ String result = new String(""); ++ int scope = replacedTokens.size() - 1; ++ ++ if (scope < 0) { ++ return result; ++ } ++ ++ if (hasNewMapping) { ++ HashMap tokens = (HashMap) (replacedTokens.get(scope)); ++ if (tokens.containsKey(token)) { ++ result = (String) tokens.get(token); ++ return result; ++ } ++ } else { ++ for (int i = scope; i > -1; i--) { ++ HashMap tokens = (HashMap) (replacedTokens.get(i)); ++ if (tokens.containsKey(token)) { ++ result = (String) tokens.get(token); ++ return result; ++ } ++ } ++ } ++ return result; ++ } ++ ++ /** ++ * Generate mappings for each Function node and parameters and variables ++ * names associated with it. ++ * <p> ++ * ++ * @param parseTree ++ * Mapping for each function node and corresponding parameters & ++ * variables names ++ */ ++ private void collectFunctionMappings(ScriptOrFnNode parseTree) { ++ int level = -1; ++ collectFuncNodes(parseTree, level); ++ } ++ ++ /** ++ * Recursive method to traverse all Function nodes ++ * <p> ++ * ++ * @param parseTree ++ * Mapping for each function node and corresponding parameters & ++ * variables names ++ * @param level ++ * scoping level ++ */ ++ private static void collectFuncNodes(ScriptOrFnNode parseTree, int level) { ++ level++; ++ functionVarMappings.add(new HashMap()); ++ ++ HashMap bindingNames = (HashMap) functionVarMappings ++ .get(functionVarMappings.size() - 1); ++ bindingNames.put(new Integer(level), parseTree.getParamAndVarNames()); ++ funcObjects.add(parseTree); ++ ++ int nestedCount = parseTree.getFunctionCount(); ++ for (int i = 0; i != nestedCount; ++i) { ++ collectFuncNodes(parseTree.getFunctionNode(i), level); ++ bindingNames = (HashMap) functionVarMappings ++ .get(functionVarMappings.size() - 1); ++ bindingNames.put(new Integer(level), parseTree ++ .getParamAndVarNames()); ++ } ++ } ++ ++ /** ++ * Compress the script ++ * <p> ++ * ++ * @param encodedSource ++ * encoded source string ++ * @param offset ++ * position within the encoded source ++ * @param asQuotedString ++ * boolean value indicating a quoted string ++ * @param sb ++ * String buffer reference ++ * @param prevToken ++ * Previous token in encoded source ++ * @param inArgsList ++ * boolean value indicating position inside arguments list ++ * @param currentLevel ++ * embeded function level ++ * @param parseTree ++ * Mapping of each function node and corresponding parameters & ++ * variables names ++ * @return compressed script ++ */ ++ public int sourceCompress(String encodedSource, int offset, ++ boolean asQuotedString, StringBuffer sb, int prevToken, ++ boolean inArgsList, int currentLevel, ScriptOrFnNode parseTree) { ++ ++ boolean hasNewMapping = false; ++ ++ if (functionVarMappings.isEmpty()) ++ collectFunctionMappings(parseTree); ++ ++ int length = encodedSource.charAt(offset); ++ ++offset; ++ if ((0x8000 & length) != 0) { ++ length = ((0x7FFF & length) << 16) | encodedSource.charAt(offset); ++ ++offset; ++ } ++ if (sb != null) { ++ String str = encodedSource.substring(offset, offset + length); ++ String sourceStr = new String(str); ++ if ((prevToken == Token.VAR) || (inArgsList)) { ++ hasNewMapping = true; ++ } ++ if (((functionBracePositions.size() > 0) && (currentLevel >= (((Integer) functionBracePositions ++ .get(functionBracePositions.size() - 1)).intValue()))) ++ || (inArgsList)) { ++ if (prevToken != Token.DOT) { ++ str = this.getMappedToken(str, hasNewMapping); ++ } ++ } ++ if ((!inArgsList) && (asQuotedString)) { ++ if ((prevToken == Token.LC) || (prevToken == Token.COMMA)) { ++ str = sourceStr; ++ } ++ } ++ if (!asQuotedString) { ++ sb.append(str); ++ } else { ++ sb.append('"'); ++ sb.append(ScriptRuntime.escapeString(str)); ++ sb.append('"'); ++ } ++ } ++ return offset + length; ++ } ++ ++ public void enterNestingLevel(int braceNesting) { ++ functionBracePositions.add(new Integer(braceNesting + 1)); ++ replacedTokens.add(new HashMap()); ++ } ++ ++ public void leaveNestingLevel(int braceNesting) { ++ Integer bn = new Integer(braceNesting); ++ ++ if ((functionBracePositions.contains(bn)) ++ && (replacedTokens.size() > 0)) { ++ // remove our mappings now! ++ int scopedSize = replacedTokens.size(); ++ replacedTokens.remove(scopedSize - 1); ++ functionBracePositions.remove(bn); ++ } ++ } ++} ++ ++ + public class Decompiler + { + /** + * Flag to indicate that the decompilation should omit the + * function header and trailing brace. + */ + public static final int ONLY_BODY_FLAG = 1 << 0; + +@@ -265,16 +536,536 @@ public class Decompiler + } + + private String sourceToString(int offset) + { + if (offset < 0 || sourceTop < offset) Kit.codeBug(); + return new String(sourceBuffer, offset, sourceTop - offset); + } + ++ //Used to be private, but making it public so we ++ //can reset the token state between compression runs. ++ //Not very pretty. ++ public static TokenMapper tm = new TokenMapper(); ++ ++ /** ++ * Compress the script ++ * <p> ++ * ++ * @param encodedSource encoded source string ++ * @param flags Flags specifying format of decompilation output ++ * @param properties Decompilation properties ++ * @param parseTree Mapping for each function node and corresponding parameters & variables names ++ * @return compressed script ++ */ ++ public static String compress(String encodedSource, int flags, ++ UintMap properties, ScriptOrFnNode parseTree){ ++ ++ int length = encodedSource.length(); ++ if (length == 0) { return ""; } ++ int indent = properties.getInt(INITIAL_INDENT_PROP, 0); ++ if (indent < 0) throw new IllegalArgumentException(); ++ int indentGap = properties.getInt(INDENT_GAP_PROP, 4); ++ if (indentGap < 0) throw new IllegalArgumentException(); ++ int caseGap = properties.getInt(CASE_GAP_PROP, 2); ++ if (caseGap < 0) throw new IllegalArgumentException(); ++ StringBuffer result = new StringBuffer(); ++ boolean justFunctionBody = (0 != (flags & Decompiler.ONLY_BODY_FLAG)); ++ boolean toSource = (0 != (flags & Decompiler.TO_SOURCE_FLAG)); ++ // Spew tokens in source, for debugging. ++ // as TYPE number char ++ if (printSource) { ++ System.err.println("length:" + length); ++ for (int i = 0; i < length; ++i) { ++ // Note that tokenToName will fail unless Context.printTrees ++ // is true. ++ String tokenname = null; ++ if (Token.printNames) { ++ tokenname = Token.name(encodedSource.charAt(i)); ++ } ++ if (tokenname == null) { ++ tokenname = "---"; ++ } ++ String pad = tokenname.length() > 7 ++ ? "\t" ++ : "\t\t"; ++ System.err.println ++ (tokenname ++ + pad + (int)encodedSource.charAt(i) ++ + "\t'" + ScriptRuntime.escapeString ++ (encodedSource.substring(i, i+1)) ++ + "'"); ++ } ++ System.err.println(); ++ } ++ int braceNesting = 0; ++ boolean afterFirstEOL = false; ++ int i = 0; ++ int prevToken = 0; ++ boolean primeFunctionNesting = false; ++ boolean inArgsList = false; ++ boolean primeInArgsList = false; ++ int topFunctionType; ++ if (encodedSource.charAt(i) == Token.SCRIPT) { ++ ++i; ++ topFunctionType = -1; ++ } else { ++ topFunctionType = encodedSource.charAt(i + 1); ++ } ++ if (!toSource) { ++ // add an initial newline to exactly match js. ++ // result.append('\n'); ++ for (int j = 0; j < indent; j++){ ++ // result.append(' '); ++ result.append(""); ++ } ++ } else { ++ if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) { ++ result.append('('); ++ } ++ } ++ while (i < length) { ++ if(i>0){ ++ prevToken = encodedSource.charAt(i-1); ++ } ++ // System.out.println(Token.name(getNext(source, length, i))); ++ switch(encodedSource.charAt(i)) { ++ case Token.NAME: ++ case Token.REGEXP: // re-wrapped in '/'s in parser... ++ int jumpPos = getSourceStringEnd(encodedSource, i+1); ++ if(Token.OBJECTLIT == encodedSource.charAt(jumpPos)){ ++ i = printSourceString(encodedSource, i + 1, false, result); ++ }else{ ++ i = tm.sourceCompress( encodedSource, i + 1, false, result, prevToken, ++ inArgsList, braceNesting, parseTree); ++ } ++ continue; ++ case Token.STRING: ++ i = printSourceString(encodedSource, i + 1, true, result); <<Diff was trimmed, longer than 597 lines>> _______________________________________________ pld-cvs-commit mailing list pld-cvs-commit@lists.pld-linux.org http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit