From cd42c1721dd79b0c53849f7508687208ab44344d Mon Sep 17 00:00:00 2001 From: xxxue <1659809758@qq.com> Date: Fri, 23 Jun 2023 20:08:08 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=BC=96=E8=AF=91=20js=20=E5=88=B0=20dex=20=E4=B8=8E=20?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2=E5=8A=A0=E5=AF=86=E8=A7=A3=E5=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 5 + gradle/wrapper/gradle-wrapper.properties | 2 +- src/defpackage/StrUtils.java | 97 ++ .../mozilla/classfile/ClassFileWriter.java | 6 + .../javascript/optimizer/BodyCodegen.java | 1134 +++++++++-------- .../mozilla/javascript/optimizer/Codegen.java | 13 +- src/org/mozilla/mycode/main.java | 225 ++++ 7 files changed, 920 insertions(+), 562 deletions(-) create mode 100644 src/defpackage/StrUtils.java create mode 100644 src/org/mozilla/mycode/main.java diff --git a/build.gradle b/build.gradle index 5532cd8..6f452c5 100644 --- a/build.gradle +++ b/build.gradle @@ -58,6 +58,11 @@ sourceSets { } dependencies { + // 添加依赖 + implementation 'cn.hutool:hutool-all:5.3.6' + implementation group: 'com.itranswarp', name: 'compiler', version: '1.0' + + // 原始依赖 testImplementation "junit:junit:4.13.2" testImplementation "org.yaml:snakeyaml:1.28" testImplementation "javax.xml.soap:javax.xml.soap-api:1.4.0" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ffed3a2..ad5667f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-7.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/defpackage/StrUtils.java b/src/defpackage/StrUtils.java new file mode 100644 index 0000000..f989add --- /dev/null +++ b/src/defpackage/StrUtils.java @@ -0,0 +1,97 @@ +package defpackage; + +import org.mozilla.classfile.ByteCode; +import org.mozilla.classfile.ClassFileWriter; + +public class StrUtils +{ + + /** + * 字符串加密 + */ + public static String e(String data) + { + byte[] b = data.getBytes(); + for (int i = 0; i < b.length; i++) + { + b[i] = (byte) (b[i] + 1); + } + StringBuilder hex = new StringBuilder(); + for (int i2 = 0; i2 < b.length; i2++) + { + hex.append(String.format("%02X", Byte.valueOf(b[i2]))); + } + return hex.toString(); + } + + /** + * 字符串解密 + */ + public static String d(String data) + { + int l = data.length() / 2; + byte[] b = new byte[l]; + for (int i = 0; i < l; i++) + { + b[i] = Integer.valueOf(data.substring(i * 2, (i * 2) + 2), 16).byteValue(); + } + for (int i2 = 0; i2 < b.length; i2++) + { + b[i2] = (byte) (b[i2] - 1); + } + return new String(b); + } + + /** + * 加密,把一个字符串在原有的基础上 加一个数值 + */ + public static String e2(String data) + { + + //把字符串转为字节数组 + byte[] b = data.getBytes(); + //遍历 + for (int i = 0; i < b.length; i++) + { + b[i] += 3;//在原有的基础上 加一个数值 + } + return new String(b); + } + + /** + * 解密:把一个加密后的字符串在原有基础上 减一个数 + * + * @param data 加密后的字符串 + * @return 返回解密后的新字符串 + */ + public static String d2(String data) + { + //把字符串转为字节数组 + byte[] b = data.getBytes(); + //遍历 + for (int i = 0; i < b.length; i++) + { + b[i] -= 3;//在原有的基础上 减一个数 + } + return new String(b); + } + + /** + * 字符串加密 + */ + public static void strE(ClassFileWriter cfw, String content) + { + //System.out.println(content); + if (content.isEmpty()) + { + //为空 则 不调用 解密.. + cfw.addPush(content); + } + else + { + cfw.addPush(StrUtils.e(content)); + cfw.addInvoke(ByteCode.INVOKESTATIC, "defpackage.StrUtils", "d", "(Ljava/lang/String;)" + + "Ljava/lang/String;"); + } + } +} \ No newline at end of file diff --git a/src/org/mozilla/classfile/ClassFileWriter.java b/src/org/mozilla/classfile/ClassFileWriter.java index 092fed9..bb55947 100644 --- a/src/org/mozilla/classfile/ClassFileWriter.java +++ b/src/org/mozilla/classfile/ClassFileWriter.java @@ -945,6 +945,12 @@ public void addPush(double k) { * @param k the constant */ public void addPush(String k) { + + if (k == null) + { + k = ""; + } + int length = k.length(); int limit = itsConstantPool.getUtfEncodingLimit(k, 0, length); if (limit == length) { diff --git a/src/org/mozilla/javascript/optimizer/BodyCodegen.java b/src/org/mozilla/javascript/optimizer/BodyCodegen.java index d63f597..07c6a83 100644 --- a/src/org/mozilla/javascript/optimizer/BodyCodegen.java +++ b/src/org/mozilla/javascript/optimizer/BodyCodegen.java @@ -3,6 +3,7 @@ import static org.mozilla.classfile.ClassFileWriter.ACC_PRIVATE; import static org.mozilla.classfile.ClassFileWriter.ACC_STATIC; +import defpackage.StrUtils; import java.util.ArrayList; import java.util.HashMap; import java.util.IdentityHashMap; @@ -646,76 +647,76 @@ private void generateStatement(Node node) { break; case Token.LOCAL_BLOCK: - { - boolean prevLocal = inLocalBlock; - inLocalBlock = true; - int local = getNewWordLocal(); - if (isGenerator) { - cfw.add(ByteCode.ACONST_NULL); - cfw.addAStore(local); - } - node.putIntProp(Node.LOCAL_PROP, local); - while (child != null) { - generateStatement(child); - child = child.getNext(); - } - releaseWordLocal((short) local); - node.removeProp(Node.LOCAL_PROP); - inLocalBlock = prevLocal; - break; + { + boolean prevLocal = inLocalBlock; + inLocalBlock = true; + int local = getNewWordLocal(); + if (isGenerator) { + cfw.add(ByteCode.ACONST_NULL); + cfw.addAStore(local); } + node.putIntProp(Node.LOCAL_PROP, local); + while (child != null) { + generateStatement(child); + child = child.getNext(); + } + releaseWordLocal((short) local); + node.removeProp(Node.LOCAL_PROP); + inLocalBlock = prevLocal; + break; + } case Token.FUNCTION: - { - int fnIndex = node.getExistingIntProp(Node.FUNCTION_PROP); - OptFunctionNode ofn = OptFunctionNode.get(scriptOrFn, fnIndex); - int t = ofn.fnode.getFunctionType(); - if (t == FunctionNode.FUNCTION_EXPRESSION_STATEMENT) { - visitFunction(ofn, t); - } else { - if (t != FunctionNode.FUNCTION_STATEMENT) { - throw Codegen.badTree(); - } + { + int fnIndex = node.getExistingIntProp(Node.FUNCTION_PROP); + OptFunctionNode ofn = OptFunctionNode.get(scriptOrFn, fnIndex); + int t = ofn.fnode.getFunctionType(); + if (t == FunctionNode.FUNCTION_EXPRESSION_STATEMENT) { + visitFunction(ofn, t); + } else { + if (t != FunctionNode.FUNCTION_STATEMENT) { + throw Codegen.badTree(); } - break; } + break; + } case Token.TRY: visitTryCatchFinally((Jump) node, child); break; case Token.CATCH_SCOPE: - { - // nothing stays on the stack on entry into a catch scope - cfw.setStackTop((short) 0); + { + // nothing stays on the stack on entry into a catch scope + cfw.setStackTop((short) 0); - int local = getLocalBlockRegister(node); - int scopeIndex = node.getExistingIntProp(Node.CATCH_SCOPE_PROP); + int local = getLocalBlockRegister(node); + int scopeIndex = node.getExistingIntProp(Node.CATCH_SCOPE_PROP); - String name = child.getString(); // name of exception - child = child.getNext(); - generateExpression(child, node); // load expression object - if (scopeIndex == 0) { - cfw.add(ByteCode.ACONST_NULL); - } else { - // Load previous catch scope object - cfw.addALoad(local); - } - cfw.addPush(name); - cfw.addALoad(contextLocal); - cfw.addALoad(variableObjectLocal); - - addScriptRuntimeInvoke( - "newCatchScope", - "(Ljava/lang/Throwable;" - + "Lorg/mozilla/javascript/Scriptable;" - + "Ljava/lang/String;" - + "Lorg/mozilla/javascript/Context;" - + "Lorg/mozilla/javascript/Scriptable;" - + ")Lorg/mozilla/javascript/Scriptable;"); - cfw.addAStore(local); + String name = child.getString(); // name of exception + child = child.getNext(); + generateExpression(child, node); // load expression object + if (scopeIndex == 0) { + cfw.add(ByteCode.ACONST_NULL); + } else { + // Load previous catch scope object + cfw.addALoad(local); } - break; + cfw.addPush(name); + cfw.addALoad(contextLocal); + cfw.addALoad(variableObjectLocal); + + addScriptRuntimeInvoke( + "newCatchScope", + "(Ljava/lang/Throwable;" + + "Lorg/mozilla/javascript/Scriptable;" + + "Ljava/lang/String;" + + "Lorg/mozilla/javascript/Context;" + + "Lorg/mozilla/javascript/Scriptable;" + + ")Lorg/mozilla/javascript/Scriptable;"); + cfw.addAStore(local); + } + break; case Token.THROW: generateExpression(child, node); @@ -792,10 +793,10 @@ private void generateStatement(Node node) { type == Token.ENUM_INIT_KEYS ? ScriptRuntime.ENUMERATE_KEYS : type == Token.ENUM_INIT_VALUES - ? ScriptRuntime.ENUMERATE_VALUES - : type == Token.ENUM_INIT_VALUES_IN_ORDER - ? ScriptRuntime.ENUMERATE_VALUES_IN_ORDER - : ScriptRuntime.ENUMERATE_ARRAY; + ? ScriptRuntime.ENUMERATE_VALUES + : type == Token.ENUM_INIT_VALUES_IN_ORDER + ? ScriptRuntime.ENUMERATE_VALUES_IN_ORDER + : ScriptRuntime.ENUMERATE_ARRAY; cfw.addPush(enumType); addScriptRuntimeInvoke( "enumInit", @@ -835,13 +836,13 @@ private void generateStatement(Node node) { break; case Token.TARGET: - { - if (compilerEnv.isGenerateObserverCount()) addInstructionCount(); - int label = getTargetLabel(node); - cfw.markLabel(label); - if (compilerEnv.isGenerateObserverCount()) saveCurrentCodeOffset(); - } - break; + { + if (compilerEnv.isGenerateObserverCount()) addInstructionCount(); + int label = getTargetLabel(node); + cfw.markLabel(label); + if (compilerEnv.isGenerateObserverCount()) saveCurrentCodeOffset(); + } + break; case Token.JSR: case Token.GOTO: @@ -852,50 +853,50 @@ private void generateStatement(Node node) { break; case Token.FINALLY: - { - // This is the non-exception case for a finally block. In - // other words, since we inline finally blocks wherever - // jsr was previously used, and jsr is only used when the - // function is not a generator, we don't need to generate - // this case if the function isn't a generator. - if (!isGenerator) { - break; - } + { + // This is the non-exception case for a finally block. In + // other words, since we inline finally blocks wherever + // jsr was previously used, and jsr is only used when the + // function is not a generator, we don't need to generate + // this case if the function isn't a generator. + if (!isGenerator) { + break; + } - if (compilerEnv.isGenerateObserverCount()) saveCurrentCodeOffset(); - // there is exactly one value on the stack when enterring - // finally blocks: the return address (or its int encoding) - cfw.setStackTop((short) 1); + if (compilerEnv.isGenerateObserverCount()) saveCurrentCodeOffset(); + // there is exactly one value on the stack when enterring + // finally blocks: the return address (or its int encoding) + cfw.setStackTop((short) 1); - // Save return address in a new local - int finallyRegister = getNewWordLocal(); + // Save return address in a new local + int finallyRegister = getNewWordLocal(); - int finallyStart = cfw.acquireLabel(); - int finallyEnd = cfw.acquireLabel(); - cfw.markLabel(finallyStart); + int finallyStart = cfw.acquireLabel(); + int finallyEnd = cfw.acquireLabel(); + cfw.markLabel(finallyStart); - generateIntegerWrap(); - cfw.addAStore(finallyRegister); + generateIntegerWrap(); + cfw.addAStore(finallyRegister); - while (child != null) { - generateStatement(child); - child = child.getNext(); - } + while (child != null) { + generateStatement(child); + child = child.getNext(); + } - cfw.addALoad(finallyRegister); - cfw.add(ByteCode.CHECKCAST, "java/lang/Integer"); - generateIntegerUnwrap(); - FinallyReturnPoint ret = finallys.get(node); - ret.tableLabel = cfw.acquireLabel(); - cfw.add(ByteCode.GOTO, ret.tableLabel); + cfw.addALoad(finallyRegister); + cfw.add(ByteCode.CHECKCAST, "java/lang/Integer"); + generateIntegerUnwrap(); + FinallyReturnPoint ret = finallys.get(node); + ret.tableLabel = cfw.acquireLabel(); + cfw.add(ByteCode.GOTO, ret.tableLabel); - // After this GOTO we expect stack to be empty again! - cfw.setStackTop((short) 0); + // After this GOTO we expect stack to be empty again! + cfw.setStackTop((short) 0); - releaseWordLocal((short) finallyRegister); - cfw.markLabel(finallyEnd); - } - break; + releaseWordLocal((short) finallyRegister); + cfw.markLabel(finallyEnd); + } + break; case Token.DEBUGGER: break; @@ -953,39 +954,40 @@ private void generateExpression(Node node, Node parent) { break; case Token.NAME: - { - cfw.addALoad(contextLocal); - cfw.addALoad(variableObjectLocal); - cfw.addPush(node.getString()); - addScriptRuntimeInvoke( - "name", - "(Lorg/mozilla/javascript/Context;" - + "Lorg/mozilla/javascript/Scriptable;" - + "Ljava/lang/String;" - + ")Ljava/lang/Object;"); - } - break; + { + cfw.addALoad(contextLocal); + cfw.addALoad(variableObjectLocal); + //cfw.addPush(node.getString()); + StrUtils.strE(cfw, node.getString()); + addScriptRuntimeInvoke( + "name", + "(Lorg/mozilla/javascript/Context;" + + "Lorg/mozilla/javascript/Scriptable;" + + "Ljava/lang/String;" + + ")Ljava/lang/Object;"); + } + break; case Token.CALL: case Token.NEW: - { - int specialType = node.getIntProp(Node.SPECIALCALL_PROP, Node.NON_SPECIALCALL); - if (specialType == Node.NON_SPECIALCALL) { - OptFunctionNode target; - target = (OptFunctionNode) node.getProp(Node.DIRECTCALL_PROP); - - if (target != null) { - visitOptimizedCall(node, target, type, child); - } else if (type == Token.CALL) { - visitStandardCall(node, child); - } else { - visitStandardNew(node, child); - } + { + int specialType = node.getIntProp(Node.SPECIALCALL_PROP, Node.NON_SPECIALCALL); + if (specialType == Node.NON_SPECIALCALL) { + OptFunctionNode target; + target = (OptFunctionNode) node.getProp(Node.DIRECTCALL_PROP); + + if (target != null) { + visitOptimizedCall(node, target, type, child); + } else if (type == Token.CALL) { + visitStandardCall(node, child); } else { - visitSpecialCall(node, type, specialType, child); + visitStandardNew(node, child); } + } else { + visitSpecialCall(node, type, specialType, child); } - break; + } + break; case Token.REF_CALL: generateFunctionAndThisObj(child, node); @@ -1003,36 +1005,37 @@ private void generateExpression(Node node, Node parent) { break; case Token.NUMBER: - { - double num = node.getDouble(); - if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1) { - cfw.addPush(num); - } else { - codegen.pushNumberAsObject(cfw, num); - } + { + double num = node.getDouble(); + if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1) { + cfw.addPush(num); + } else { + codegen.pushNumberAsObject(cfw, num); } - break; + } + break; case Token.BIGINT: - { - byte[] bytes = node.getBigInt().toByteArray(); - cfw.add(ByteCode.NEW, "java/math/BigInteger"); + { + byte[] bytes = node.getBigInt().toByteArray(); + cfw.add(ByteCode.NEW, "java/math/BigInteger"); + cfw.add(ByteCode.DUP); + cfw.addPush(bytes.length); + cfw.add(ByteCode.NEWARRAY, ByteCode.T_BYTE); + for (int i = 0; i < bytes.length; i++) { cfw.add(ByteCode.DUP); - cfw.addPush(bytes.length); - cfw.add(ByteCode.NEWARRAY, ByteCode.T_BYTE); - for (int i = 0; i < bytes.length; i++) { - cfw.add(ByteCode.DUP); - cfw.addPush(i); - cfw.add(ByteCode.BIPUSH, bytes[i]); - cfw.add(ByteCode.BASTORE); - } - cfw.addInvoke( - ByteCode.INVOKESPECIAL, "java/math/BigInteger", "", "([B)V"); + cfw.addPush(i); + cfw.add(ByteCode.BIPUSH, bytes[i]); + cfw.add(ByteCode.BASTORE); } - break; + cfw.addInvoke( + ByteCode.INVOKESPECIAL, "java/math/BigInteger", "", "([B)V"); + } + break; case Token.STRING: - cfw.addPush(node.getString()); + //cfw.addPush(node.getString()); + StrUtils.strE(cfw, node.getString()); break; case Token.THIS: @@ -1056,58 +1059,58 @@ private void generateExpression(Node node, Node parent) { break; case Token.REGEXP: - { - // Create a new wrapper around precompiled regexp - cfw.addALoad(contextLocal); - cfw.addALoad(variableObjectLocal); - int i = node.getExistingIntProp(Node.REGEXP_PROP); - cfw.add( - ByteCode.GETSTATIC, - codegen.mainClassName, - codegen.getCompiledRegexpName(scriptOrFn, i), - "Ljava/lang/Object;"); - cfw.addInvoke( - ByteCode.INVOKESTATIC, - "org/mozilla/javascript/ScriptRuntime", - "wrapRegExp", - "(Lorg/mozilla/javascript/Context;" - + "Lorg/mozilla/javascript/Scriptable;" - + "Ljava/lang/Object;" - + ")Lorg/mozilla/javascript/Scriptable;"); - } - break; + { + // Create a new wrapper around precompiled regexp + cfw.addALoad(contextLocal); + cfw.addALoad(variableObjectLocal); + int i = node.getExistingIntProp(Node.REGEXP_PROP); + cfw.add( + ByteCode.GETSTATIC, + codegen.mainClassName, + codegen.getCompiledRegexpName(scriptOrFn, i), + "Ljava/lang/Object;"); + cfw.addInvoke( + ByteCode.INVOKESTATIC, + "org/mozilla/javascript/ScriptRuntime", + "wrapRegExp", + "(Lorg/mozilla/javascript/Context;" + + "Lorg/mozilla/javascript/Scriptable;" + + "Ljava/lang/Object;" + + ")Lorg/mozilla/javascript/Scriptable;"); + } + break; case Token.COMMA: - { - Node next = child.getNext(); - while (next != null) { - generateExpression(child, node); - cfw.add(ByteCode.POP); - child = next; - next = next.getNext(); - } + { + Node next = child.getNext(); + while (next != null) { generateExpression(child, node); - break; + cfw.add(ByteCode.POP); + child = next; + next = next.getNext(); } + generateExpression(child, node); + break; + } case Token.ENUM_NEXT: case Token.ENUM_ID: - { - int local = getLocalBlockRegister(node); - cfw.addALoad(local); - if (type == Token.ENUM_NEXT) { - addScriptRuntimeInvoke( - "enumNext", "(Ljava/lang/Object;)Ljava/lang/Boolean;"); - } else { - cfw.addALoad(contextLocal); - addScriptRuntimeInvoke( - "enumId", - "(Ljava/lang/Object;" - + "Lorg/mozilla/javascript/Context;" - + ")Ljava/lang/Object;"); - } - break; + { + int local = getLocalBlockRegister(node); + cfw.addALoad(local); + if (type == Token.ENUM_NEXT) { + addScriptRuntimeInvoke( + "enumNext", "(Ljava/lang/Object;)Ljava/lang/Boolean;"); + } else { + cfw.addALoad(contextLocal); + addScriptRuntimeInvoke( + "enumId", + "(Ljava/lang/Object;" + + "Lorg/mozilla/javascript/Context;" + + ")Ljava/lang/Object;"); } + break; + } case Token.ARRAYLIT: visitArrayLiteral(node, child, false); @@ -1118,25 +1121,25 @@ private void generateExpression(Node node, Node parent) { break; case Token.NOT: - { - int trueTarget = cfw.acquireLabel(); - int falseTarget = cfw.acquireLabel(); - int beyond = cfw.acquireLabel(); - generateIfJump(child, node, trueTarget, falseTarget); - - cfw.markLabel(trueTarget); - cfw.add( - ByteCode.GETSTATIC, - "java/lang/Boolean", - "FALSE", - "Ljava/lang/Boolean;"); - cfw.add(ByteCode.GOTO, beyond); - cfw.markLabel(falseTarget); - cfw.add(ByteCode.GETSTATIC, "java/lang/Boolean", "TRUE", "Ljava/lang/Boolean;"); - cfw.markLabel(beyond); - cfw.adjustStackTop(-1); - break; - } + { + int trueTarget = cfw.acquireLabel(); + int falseTarget = cfw.acquireLabel(); + int beyond = cfw.acquireLabel(); + generateIfJump(child, node, trueTarget, falseTarget); + + cfw.markLabel(trueTarget); + cfw.add( + ByteCode.GETSTATIC, + "java/lang/Boolean", + "FALSE", + "Ljava/lang/Boolean;"); + cfw.add(ByteCode.GOTO, beyond); + cfw.markLabel(falseTarget); + cfw.add(ByteCode.GETSTATIC, "java/lang/Boolean", "TRUE", "Ljava/lang/Boolean;"); + cfw.markLabel(beyond); + cfw.adjustStackTop(-1); + break; + } case Token.BITNOT: visitBitNot(node, child); @@ -1164,68 +1167,68 @@ private void generateExpression(Node node, Node parent) { case Token.OR: case Token.AND: - { - generateExpression(child, node); - cfw.add(ByteCode.DUP); - addScriptRuntimeInvoke("toBoolean", "(Ljava/lang/Object;)Z"); - int falseTarget = cfw.acquireLabel(); - if (type == Token.AND) cfw.add(ByteCode.IFEQ, falseTarget); - else cfw.add(ByteCode.IFNE, falseTarget); - cfw.add(ByteCode.POP); - generateExpression(child.getNext(), node); - cfw.markLabel(falseTarget); - } - break; + { + generateExpression(child, node); + cfw.add(ByteCode.DUP); + addScriptRuntimeInvoke("toBoolean", "(Ljava/lang/Object;)Z"); + int falseTarget = cfw.acquireLabel(); + if (type == Token.AND) cfw.add(ByteCode.IFEQ, falseTarget); + else cfw.add(ByteCode.IFNE, falseTarget); + cfw.add(ByteCode.POP); + generateExpression(child.getNext(), node); + cfw.markLabel(falseTarget); + } + break; case Token.HOOK: - { - Node ifThen = child.getNext(); - Node ifElse = ifThen.getNext(); - generateExpression(child, node); - addScriptRuntimeInvoke("toBoolean", "(Ljava/lang/Object;)Z"); - int elseTarget = cfw.acquireLabel(); - cfw.add(ByteCode.IFEQ, elseTarget); - short stack = cfw.getStackTop(); - generateExpression(ifThen, node); - int afterHook = cfw.acquireLabel(); - cfw.add(ByteCode.GOTO, afterHook); - cfw.markLabel(elseTarget, stack); - generateExpression(ifElse, node); - cfw.markLabel(afterHook); - } - break; + { + Node ifThen = child.getNext(); + Node ifElse = ifThen.getNext(); + generateExpression(child, node); + addScriptRuntimeInvoke("toBoolean", "(Ljava/lang/Object;)Z"); + int elseTarget = cfw.acquireLabel(); + cfw.add(ByteCode.IFEQ, elseTarget); + short stack = cfw.getStackTop(); + generateExpression(ifThen, node); + int afterHook = cfw.acquireLabel(); + cfw.add(ByteCode.GOTO, afterHook); + cfw.markLabel(elseTarget, stack); + generateExpression(ifElse, node); + cfw.markLabel(afterHook); + } + break; case Token.ADD: - { - generateExpression(child, node); - generateExpression(child.getNext(), node); - switch (node.getIntProp(Node.ISNUMBER_PROP, -1)) { - case Node.BOTH: - cfw.add(ByteCode.DADD); - break; - case Node.LEFT: - cfw.addALoad(contextLocal); - addOptRuntimeInvoke( - "add", - "(DLjava/lang/Object;Lorg/mozilla/javascript/Context;)Ljava/lang/Object;"); - break; - case Node.RIGHT: - cfw.addALoad(contextLocal); - addOptRuntimeInvoke( - "add", - "(Ljava/lang/Object;DLorg/mozilla/javascript/Context;)Ljava/lang/Object;"); - break; - default: - cfw.addALoad(contextLocal); - addScriptRuntimeInvoke( - "add", - "(Ljava/lang/Object;" - + "Ljava/lang/Object;" - + "Lorg/mozilla/javascript/Context;" - + ")Ljava/lang/Object;"); - } + { + generateExpression(child, node); + generateExpression(child.getNext(), node); + switch (node.getIntProp(Node.ISNUMBER_PROP, -1)) { + case Node.BOTH: + cfw.add(ByteCode.DADD); + break; + case Node.LEFT: + cfw.addALoad(contextLocal); + addOptRuntimeInvoke( + "add", + "(DLjava/lang/Object;Lorg/mozilla/javascript/Context;)Ljava/lang/Object;"); + break; + case Node.RIGHT: + cfw.addALoad(contextLocal); + addOptRuntimeInvoke( + "add", + "(Ljava/lang/Object;DLorg/mozilla/javascript/Context;)Ljava/lang/Object;"); + break; + default: + cfw.addALoad(contextLocal); + addScriptRuntimeInvoke( + "add", + "(Ljava/lang/Object;" + + "Ljava/lang/Object;" + + "Lorg/mozilla/javascript/Context;" + + ")Ljava/lang/Object;"); } - break; + } + break; case Token.SUB: case Token.MUL: @@ -1248,29 +1251,29 @@ private void generateExpression(Node node, Node parent) { break; case Token.POS: - { - int childNumberFlag = node.getIntProp(Node.ISNUMBER_PROP, -1); - generateExpression(child, node); - if (childNumberFlag == -1) { - addObjectToDouble(); - addDoubleWrap(); - } - break; + { + int childNumberFlag = node.getIntProp(Node.ISNUMBER_PROP, -1); + generateExpression(child, node); + if (childNumberFlag == -1) { + addObjectToDouble(); + addDoubleWrap(); } + break; + } case Token.NEG: - { - int childNumberFlag = node.getIntProp(Node.ISNUMBER_PROP, -1); - generateExpression(child, node); - if (childNumberFlag == -1) { - addObjectToNumeric(); - addScriptRuntimeInvoke( - "negate", "(Ljava/lang/Number;" + ")Ljava/lang/Number;"); - } else { - cfw.add(ByteCode.DNEG); - } - break; + { + int childNumberFlag = node.getIntProp(Node.ISNUMBER_PROP, -1); + generateExpression(child, node); + if (childNumberFlag == -1) { + addObjectToNumeric(); + addScriptRuntimeInvoke( + "negate", "(Ljava/lang/Number;" + ")Ljava/lang/Number;"); + } else { + cfw.add(ByteCode.DNEG); } + break; + } case Token.TO_DOUBLE: // cnvt to double (not Double) @@ -1279,22 +1282,22 @@ private void generateExpression(Node node, Node parent) { break; case Token.TO_OBJECT: - { - // convert from double - int prop = -1; - if (child.getType() == Token.NUMBER) { - prop = child.getIntProp(Node.ISNUMBER_PROP, -1); - } - if (prop != -1) { - child.removeProp(Node.ISNUMBER_PROP); - generateExpression(child, node); - child.putIntProp(Node.ISNUMBER_PROP, prop); - } else { - generateExpression(child, node); - addDoubleWrap(); - } - break; + { + // convert from double + int prop = -1; + if (child.getType() == Token.NUMBER) { + prop = child.getIntProp(Node.ISNUMBER_PROP, -1); + } + if (prop != -1) { + child.removeProp(Node.ISNUMBER_PROP); + generateExpression(child, node); + child.putIntProp(Node.ISNUMBER_PROP, prop); + } else { + generateExpression(child, node); + addDoubleWrap(); } + break; + } case Token.IN: case Token.INSTANCEOF: @@ -1302,25 +1305,25 @@ private void generateExpression(Node node, Node parent) { case Token.LT: case Token.GE: case Token.GT: - { - int trueGOTO = cfw.acquireLabel(); - int falseGOTO = cfw.acquireLabel(); - visitIfJumpRelOp(node, child, trueGOTO, falseGOTO); - addJumpedBooleanWrap(trueGOTO, falseGOTO); - break; - } + { + int trueGOTO = cfw.acquireLabel(); + int falseGOTO = cfw.acquireLabel(); + visitIfJumpRelOp(node, child, trueGOTO, falseGOTO); + addJumpedBooleanWrap(trueGOTO, falseGOTO); + break; + } case Token.EQ: case Token.NE: case Token.SHEQ: case Token.SHNE: - { - int trueGOTO = cfw.acquireLabel(); - int falseGOTO = cfw.acquireLabel(); - visitIfJumpEqOp(node, child, trueGOTO, falseGOTO); - addJumpedBooleanWrap(trueGOTO, falseGOTO); - break; - } + { + int trueGOTO = cfw.acquireLabel(); + int falseGOTO = cfw.acquireLabel(); + visitIfJumpEqOp(node, child, trueGOTO, falseGOTO); + addJumpedBooleanWrap(trueGOTO, falseGOTO); + break; + } case Token.GETPROP: case Token.GETPROPNOWARN: @@ -1395,30 +1398,30 @@ private void generateExpression(Node node, Node parent) { case Token.SET_REF: case Token.SET_REF_OP: - { - generateExpression(child, node); - child = child.getNext(); - if (type == Token.SET_REF_OP) { - cfw.add(ByteCode.DUP); - cfw.addALoad(contextLocal); - addScriptRuntimeInvoke( - "refGet", - "(Lorg/mozilla/javascript/Ref;" - + "Lorg/mozilla/javascript/Context;" - + ")Ljava/lang/Object;"); - } - generateExpression(child, node); + { + generateExpression(child, node); + child = child.getNext(); + if (type == Token.SET_REF_OP) { + cfw.add(ByteCode.DUP); cfw.addALoad(contextLocal); - cfw.addALoad(variableObjectLocal); addScriptRuntimeInvoke( - "refSet", + "refGet", "(Lorg/mozilla/javascript/Ref;" - + "Ljava/lang/Object;" + "Lorg/mozilla/javascript/Context;" - + "Lorg/mozilla/javascript/Scriptable;" + ")Ljava/lang/Object;"); } - break; + generateExpression(child, node); + cfw.addALoad(contextLocal); + cfw.addALoad(variableObjectLocal); + addScriptRuntimeInvoke( + "refSet", + "(Lorg/mozilla/javascript/Ref;" + + "Ljava/lang/Object;" + + "Lorg/mozilla/javascript/Context;" + + "Lorg/mozilla/javascript/Scriptable;" + + ")Ljava/lang/Object;"); + } + break; case Token.DEL_REF: generateExpression(child, node); @@ -1446,106 +1449,108 @@ private void generateExpression(Node node, Node parent) { break; case Token.BINDNAME: - { - while (child != null) { - generateExpression(child, node); - child = child.getNext(); - } - // Generate code for "ScriptRuntime.bind(varObj, "s")" - cfw.addALoad(contextLocal); - cfw.addALoad(variableObjectLocal); - cfw.addPush(node.getString()); - addScriptRuntimeInvoke( - "bind", - "(Lorg/mozilla/javascript/Context;" - + "Lorg/mozilla/javascript/Scriptable;" - + "Ljava/lang/String;" - + ")Lorg/mozilla/javascript/Scriptable;"); + { + while (child != null) { + generateExpression(child, node); + child = child.getNext(); } - break; + // Generate code for "ScriptRuntime.bind(varObj, "s")" + cfw.addALoad(contextLocal); + cfw.addALoad(variableObjectLocal); + //cfw.addPush(node.getString()); + StrUtils.strE(cfw, node.getString()); + addScriptRuntimeInvoke( + "bind", + "(Lorg/mozilla/javascript/Context;" + + "Lorg/mozilla/javascript/Scriptable;" + + "Ljava/lang/String;" + + ")Lorg/mozilla/javascript/Scriptable;"); + } + break; case Token.LOCAL_LOAD: cfw.addALoad(getLocalBlockRegister(node)); break; case Token.REF_SPECIAL: - { - String special = (String) node.getProp(Node.NAME_PROP); - generateExpression(child, node); - cfw.addPush(special); - cfw.addALoad(contextLocal); - cfw.addALoad(variableObjectLocal); - addScriptRuntimeInvoke( - "specialRef", - "(Ljava/lang/Object;" - + "Ljava/lang/String;" - + "Lorg/mozilla/javascript/Context;" - + "Lorg/mozilla/javascript/Scriptable;" - + ")Lorg/mozilla/javascript/Ref;"); - } - break; + { + String special = (String) node.getProp(Node.NAME_PROP); + generateExpression(child, node); + //cfw.addPush(special); + StrUtils.strE(cfw, special); + cfw.addALoad(contextLocal); + cfw.addALoad(variableObjectLocal); + addScriptRuntimeInvoke( + "specialRef", + "(Ljava/lang/Object;" + + "Ljava/lang/String;" + + "Lorg/mozilla/javascript/Context;" + + "Lorg/mozilla/javascript/Scriptable;" + + ")Lorg/mozilla/javascript/Ref;"); + } + break; case Token.REF_MEMBER: case Token.REF_NS_MEMBER: case Token.REF_NAME: case Token.REF_NS_NAME: - { - int memberTypeFlags = node.getIntProp(Node.MEMBER_TYPE_PROP, 0); - // generate possible target, possible namespace and member - do { - generateExpression(child, node); - child = child.getNext(); - } while (child != null); - cfw.addALoad(contextLocal); - String methodName, signature; - switch (type) { - case Token.REF_MEMBER: - methodName = "memberRef"; - signature = - "(Ljava/lang/Object;" - + "Ljava/lang/Object;" - + "Lorg/mozilla/javascript/Context;" - + "I" - + ")Lorg/mozilla/javascript/Ref;"; - break; - case Token.REF_NS_MEMBER: - methodName = "memberRef"; - signature = - "(Ljava/lang/Object;" - + "Ljava/lang/Object;" - + "Ljava/lang/Object;" - + "Lorg/mozilla/javascript/Context;" - + "I" - + ")Lorg/mozilla/javascript/Ref;"; - break; - case Token.REF_NAME: - methodName = "nameRef"; - signature = - "(Ljava/lang/Object;" - + "Lorg/mozilla/javascript/Context;" - + "Lorg/mozilla/javascript/Scriptable;" - + "I" - + ")Lorg/mozilla/javascript/Ref;"; - cfw.addALoad(variableObjectLocal); - break; - case Token.REF_NS_NAME: - methodName = "nameRef"; - signature = - "(Ljava/lang/Object;" - + "Ljava/lang/Object;" - + "Lorg/mozilla/javascript/Context;" - + "Lorg/mozilla/javascript/Scriptable;" - + "I" - + ")Lorg/mozilla/javascript/Ref;"; - cfw.addALoad(variableObjectLocal); - break; - default: - throw Kit.codeBug(); - } - cfw.addPush(memberTypeFlags); - addScriptRuntimeInvoke(methodName, signature); + { + int memberTypeFlags = node.getIntProp(Node.MEMBER_TYPE_PROP, 0); + // generate possible target, possible namespace and member + do { + generateExpression(child, node); + child = child.getNext(); + } while (child != null); + cfw.addALoad(contextLocal); + String methodName, signature; + switch (type) { + case Token.REF_MEMBER: + methodName = "memberRef"; + signature = + "(Ljava/lang/Object;" + + "Ljava/lang/Object;" + + "Lorg/mozilla/javascript/Context;" + + "I" + + ")Lorg/mozilla/javascript/Ref;"; + break; + case Token.REF_NS_MEMBER: + methodName = "memberRef"; + signature = + "(Ljava/lang/Object;" + + "Ljava/lang/Object;" + + "Ljava/lang/Object;" + + "Lorg/mozilla/javascript/Context;" + + "I" + + ")Lorg/mozilla/javascript/Ref;"; + break; + case Token.REF_NAME: + methodName = "nameRef"; + signature = + "(Ljava/lang/Object;" + + "Lorg/mozilla/javascript/Context;" + + "Lorg/mozilla/javascript/Scriptable;" + + "I" + + ")Lorg/mozilla/javascript/Ref;"; + cfw.addALoad(variableObjectLocal); + break; + case Token.REF_NS_NAME: + methodName = "nameRef"; + signature = + "(Ljava/lang/Object;" + + "Ljava/lang/Object;" + + "Lorg/mozilla/javascript/Context;" + + "Lorg/mozilla/javascript/Scriptable;" + + "I" + + ")Lorg/mozilla/javascript/Ref;"; + cfw.addALoad(variableObjectLocal); + break; + default: + throw Kit.codeBug(); } - break; + cfw.addPush(memberTypeFlags); + addScriptRuntimeInvoke(methodName, signature); + } + break; case Token.DOTQUERY: visitDotQuery(node, child); @@ -1587,24 +1592,24 @@ private void generateExpression(Node node, Node parent) { break; case Token.WITHEXPR: - { - Node enterWith = child; - Node with = enterWith.getNext(); - Node leaveWith = with.getNext(); - generateStatement(enterWith); - generateExpression(with.getFirstChild(), with); - generateStatement(leaveWith); - break; - } + { + Node enterWith = child; + Node with = enterWith.getNext(); + Node leaveWith = with.getNext(); + generateStatement(enterWith); + generateExpression(with.getFirstChild(), with); + generateStatement(leaveWith); + break; + } case Token.ARRAYCOMP: - { - Node initStmt = child; - Node expr = child.getNext(); - generateStatement(initStmt); - generateExpression(expr, node); - break; - } + { + Node initStmt = child; + Node expr = child.getNext(); + generateStatement(initStmt); + generateExpression(expr, node); + break; + } case Token.TEMPLATE_LITERAL: visitTemplateLiteral(node); @@ -1809,18 +1814,18 @@ private void generateIfJump(Node node, Node parent, int trueLabel, int falseLabe case Token.OR: case Token.AND: - { - int interLabel = cfw.acquireLabel(); - if (type == Token.AND) { - generateIfJump(child, node, interLabel, falseLabel); - } else { - generateIfJump(child, node, trueLabel, interLabel); - } - cfw.markLabel(interLabel); - child = child.getNext(); - generateIfJump(child, node, trueLabel, falseLabel); - break; + { + int interLabel = cfw.acquireLabel(); + if (type == Token.AND) { + generateIfJump(child, node, interLabel, falseLabel); + } else { + generateIfJump(child, node, trueLabel, interLabel); } + cfw.markLabel(interLabel); + child = child.getNext(); + generateIfJump(child, node, trueLabel, falseLabel); + break; + } case Token.IN: case Token.INSTANCEOF: @@ -2037,7 +2042,8 @@ private void visitArrayLiteral(Node node, Node child, boolean topLevel) { cfw.add(ByteCode.ACONST_NULL); cfw.add(ByteCode.ICONST_0); } else { - cfw.addPush(OptRuntime.encodeIntArray(skipIndexes)); + //cfw.addPush(OptRuntime.encodeIntArray(skipIndexes)); + StrUtils.strE(cfw, OptRuntime.encodeIntArray(skipIndexes)); cfw.addPush(skipIndexes.length); } cfw.addALoad(contextLocal); @@ -2060,7 +2066,8 @@ private void addLoadPropertyIds(Object[] properties, int count) { cfw.addPush(i); Object id = properties[i]; if (id instanceof String) { - cfw.addPush((String) id); + //cfw.addPush((String) id); + StrUtils.strE(cfw, (String) id); } else { cfw.addPush(((Integer) id).intValue()); addScriptRuntimeInvoke("wrapInt", "(I)Ljava/lang/Integer;"); @@ -2245,7 +2252,8 @@ private void visitSpecialCall(Node node, int type, int specialType, Node child) cfw.addALoad(thisObjLocal); cfw.addPush(specialType); String sourceName = scriptOrFn.getSourceName(); - cfw.addPush(sourceName == null ? "" : sourceName); + //cfw.addPush(sourceName == null ? "" : sourceName); + StrUtils.strE(cfw,sourceName == null ? "" : sourceName); cfw.addPush(itsLineNumber); } @@ -2265,7 +2273,8 @@ private void visitStandardCall(Node node, Node child) { if (childType == Token.NAME) { // name() call String name = child.getString(); - cfw.addPush(name); + //cfw.addPush(name); + StrUtils.strE(cfw, name); methodName = "callName0"; signature = "(Ljava/lang/String;" @@ -2278,7 +2287,8 @@ private void visitStandardCall(Node node, Node child) { generateExpression(propTarget, node); Node id = propTarget.getNext(); String property = id.getString(); - cfw.addPush(property); + //cfw.addPush(property); + StrUtils.strE(cfw, property); methodName = "callProp0"; signature = "(Ljava/lang/Object;" @@ -2306,7 +2316,8 @@ private void visitStandardCall(Node node, Node child) { // there are no checks for it String name = child.getString(); generateCallArgArray(node, firstArgChild, false); - cfw.addPush(name); + //cfw.addPush(name); + StrUtils.strE(cfw, name); methodName = "callName"; signature = "([Ljava/lang/Object;" @@ -2562,52 +2573,54 @@ private void generateFunctionAndThisObj(Node node, Node parent) { case Token.GETPROP: case Token.GETELEM: - { - Node target = node.getFirstChild(); - generateExpression(target, node); - Node id = target.getNext(); - if (type == Token.GETPROP) { - String property = id.getString(); - cfw.addPush(property); - cfw.addALoad(contextLocal); - cfw.addALoad(variableObjectLocal); - addScriptRuntimeInvoke( - "getPropFunctionAndThis", - "(Ljava/lang/Object;" - + "Ljava/lang/String;" - + "Lorg/mozilla/javascript/Context;" - + "Lorg/mozilla/javascript/Scriptable;" - + ")Lorg/mozilla/javascript/Callable;"); - } else { - generateExpression(id, node); // id - if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1) addDoubleWrap(); - cfw.addALoad(contextLocal); - cfw.addALoad(variableObjectLocal); - addScriptRuntimeInvoke( - "getElemFunctionAndThis", - "(Ljava/lang/Object;" - + "Ljava/lang/Object;" - + "Lorg/mozilla/javascript/Context;" - + "Lorg/mozilla/javascript/Scriptable;" - + ")Lorg/mozilla/javascript/Callable;"); - } - break; - } - - case Token.NAME: - { - String name = node.getString(); - cfw.addPush(name); + { + Node target = node.getFirstChild(); + generateExpression(target, node); + Node id = target.getNext(); + if (type == Token.GETPROP) { + String property = id.getString(); + //cfw.addPush(property); + StrUtils.strE(cfw, property); cfw.addALoad(contextLocal); cfw.addALoad(variableObjectLocal); addScriptRuntimeInvoke( - "getNameFunctionAndThis", - "(Ljava/lang/String;" + "getPropFunctionAndThis", + "(Ljava/lang/Object;" + + "Ljava/lang/String;" + + "Lorg/mozilla/javascript/Context;" + + "Lorg/mozilla/javascript/Scriptable;" + + ")Lorg/mozilla/javascript/Callable;"); + } else { + generateExpression(id, node); // id + if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1) addDoubleWrap(); + cfw.addALoad(contextLocal); + cfw.addALoad(variableObjectLocal); + addScriptRuntimeInvoke( + "getElemFunctionAndThis", + "(Ljava/lang/Object;" + + "Ljava/lang/Object;" + "Lorg/mozilla/javascript/Context;" + "Lorg/mozilla/javascript/Scriptable;" + ")Lorg/mozilla/javascript/Callable;"); - break; } + break; + } + + case Token.NAME: + { + String name = node.getString(); + //cfw.addPush(name); + StrUtils.strE(cfw, name); + cfw.addALoad(contextLocal); + cfw.addALoad(variableObjectLocal); + addScriptRuntimeInvoke( + "getNameFunctionAndThis", + "(Ljava/lang/String;" + + "Lorg/mozilla/javascript/Context;" + + "Lorg/mozilla/javascript/Scriptable;" + + ")Lorg/mozilla/javascript/Callable;"); + break; + } default: // including GETVAR generateExpression(node, parent); @@ -3159,8 +3172,8 @@ private void visitSwitch(Jump switchNode, Node child) { cfw.addAStore(selector); for (Jump caseNode = (Jump) child.getNext(); - caseNode != null; - caseNode = (Jump) caseNode.getNext()) { + caseNode != null; + caseNode = (Jump) caseNode.getNext()) { if (caseNode.getType() != Token.CASE) throw Codegen.badTree(); Node test = caseNode.getFirstChild(); generateExpression(test, caseNode); @@ -3200,7 +3213,8 @@ private void visitTypeofname(Node node) { } } cfw.addALoad(variableObjectLocal); - cfw.addPush(node.getString()); + //cfw.addPush(node.getString()); + StrUtils.strE(cfw, node.getString()); addScriptRuntimeInvoke( "typeofName", "(Lorg/mozilla/javascript/Scriptable;" @@ -3330,7 +3344,8 @@ private void visitIncDec(Node node) { break; case Token.NAME: cfw.addALoad(variableObjectLocal); - cfw.addPush(child.getString()); // push name + //cfw.addPush(child.getString()); // push name + StrUtils.strE(cfw, child.getString()); cfw.addALoad(contextLocal); cfw.addPush(incrDecrMask); addScriptRuntimeInvoke( @@ -3343,66 +3358,66 @@ private void visitIncDec(Node node) { case Token.GETPROPNOWARN: throw Kit.codeBug(); case Token.GETPROP: - { - Node getPropChild = child.getFirstChild(); - generateExpression(getPropChild, node); - generateExpression(getPropChild.getNext(), node); - cfw.addALoad(contextLocal); - cfw.addALoad(variableObjectLocal); - cfw.addPush(incrDecrMask); - addScriptRuntimeInvoke( - "propIncrDecr", + { + Node getPropChild = child.getFirstChild(); + generateExpression(getPropChild, node); + generateExpression(getPropChild.getNext(), node); + cfw.addALoad(contextLocal); + cfw.addALoad(variableObjectLocal); + cfw.addPush(incrDecrMask); + addScriptRuntimeInvoke( + "propIncrDecr", + "(Ljava/lang/Object;" + + "Ljava/lang/String;" + + "Lorg/mozilla/javascript/Context;" + + "Lorg/mozilla/javascript/Scriptable;" + + "I)Ljava/lang/Object;"); + break; + } + case Token.GETELEM: + { + Node elemChild = child.getFirstChild(); + generateExpression(elemChild, node); + generateExpression(elemChild.getNext(), node); + cfw.addALoad(contextLocal); + cfw.addALoad(variableObjectLocal); + cfw.addPush(incrDecrMask); + if (elemChild.getNext().getIntProp(Node.ISNUMBER_PROP, -1) != -1) { + addOptRuntimeInvoke( + "elemIncrDecr", "(Ljava/lang/Object;" - + "Ljava/lang/String;" + + "D" + "Lorg/mozilla/javascript/Context;" + "Lorg/mozilla/javascript/Scriptable;" - + "I)Ljava/lang/Object;"); - break; - } - case Token.GETELEM: - { - Node elemChild = child.getFirstChild(); - generateExpression(elemChild, node); - generateExpression(elemChild.getNext(), node); - cfw.addALoad(contextLocal); - cfw.addALoad(variableObjectLocal); - cfw.addPush(incrDecrMask); - if (elemChild.getNext().getIntProp(Node.ISNUMBER_PROP, -1) != -1) { - addOptRuntimeInvoke( - "elemIncrDecr", - "(Ljava/lang/Object;" - + "D" - + "Lorg/mozilla/javascript/Context;" - + "Lorg/mozilla/javascript/Scriptable;" - + "I" - + ")Ljava/lang/Object;"); - } else { - addScriptRuntimeInvoke( - "elemIncrDecr", - "(Ljava/lang/Object;" - + "Ljava/lang/Object;" - + "Lorg/mozilla/javascript/Context;" - + "Lorg/mozilla/javascript/Scriptable;" - + "I" - + ")Ljava/lang/Object;"); - } - break; - } - case Token.GET_REF: - { - Node refChild = child.getFirstChild(); - generateExpression(refChild, node); - cfw.addALoad(contextLocal); - cfw.addALoad(variableObjectLocal); - cfw.addPush(incrDecrMask); + + "I" + + ")Ljava/lang/Object;"); + } else { addScriptRuntimeInvoke( - "refIncrDecr", - "(Lorg/mozilla/javascript/Ref;" + "elemIncrDecr", + "(Ljava/lang/Object;" + + "Ljava/lang/Object;" + "Lorg/mozilla/javascript/Context;" + "Lorg/mozilla/javascript/Scriptable;" - + "I)Ljava/lang/Object;"); - break; + + "I" + + ")Ljava/lang/Object;"); } + break; + } + case Token.GET_REF: + { + Node refChild = child.getFirstChild(); + generateExpression(refChild, node); + cfw.addALoad(contextLocal); + cfw.addALoad(variableObjectLocal); + cfw.addPush(incrDecrMask); + addScriptRuntimeInvoke( + "refIncrDecr", + "(Lorg/mozilla/javascript/Ref;" + + "Lorg/mozilla/javascript/Context;" + + "Lorg/mozilla/javascript/Scriptable;" + + "I)Ljava/lang/Object;"); + break; + } default: Codegen.badTree(); } @@ -3811,7 +3826,8 @@ private void visitSetName(Node node, Node child) { } cfw.addALoad(contextLocal); cfw.addALoad(variableObjectLocal); - cfw.addPush(name); + //cfw.addPush(name); + StrUtils.strE(cfw, name); addScriptRuntimeInvoke( "setName", "(Lorg/mozilla/javascript/Scriptable;" @@ -3830,7 +3846,8 @@ private void visitStrictSetName(Node node, Node child) { } cfw.addALoad(contextLocal); cfw.addALoad(variableObjectLocal); - cfw.addPush(name); + //cfw.addPush(name); + StrUtils.strE(cfw, name); addScriptRuntimeInvoke( "strictSetName", "(Lorg/mozilla/javascript/Scriptable;" @@ -3848,7 +3865,8 @@ private void visitSetConst(Node node, Node child) { child = child.getNext(); } cfw.addALoad(contextLocal); - cfw.addPush(name); + //cfw.addPush(name); + StrUtils.strE(cfw, name); addScriptRuntimeInvoke( "setConst", "(Lorg/mozilla/javascript/Scriptable;" diff --git a/src/org/mozilla/javascript/optimizer/Codegen.java b/src/org/mozilla/javascript/optimizer/Codegen.java index 0c5d93b..9542677 100644 --- a/src/org/mozilla/javascript/optimizer/Codegen.java +++ b/src/org/mozilla/javascript/optimizer/Codegen.java @@ -6,6 +6,7 @@ package org.mozilla.javascript.optimizer; +import defpackage.StrUtils; import static org.mozilla.classfile.ClassFileWriter.ACC_FINAL; import static org.mozilla.classfile.ClassFileWriter.ACC_PRIVATE; import static org.mozilla.classfile.ClassFileWriter.ACC_PROTECTED; @@ -823,7 +824,8 @@ private void generateNativeFunctionOverrides(ClassFileWriter cfw, String encoded cfw.addPush(""); } else { String name = ((FunctionNode) n).getName(); - cfw.addPush(name); + //cfw.addPush(name); + StrUtils.strE(cfw, name); } cfw.add(ByteCode.ARETURN); break; @@ -853,7 +855,11 @@ private void generateNativeFunctionOverrides(ClassFileWriter cfw, String encoded } else if (paramAndVarCount == 1) { // As above do not check for valid index but always // return the name of the first param - cfw.addPush(n.getParamOrVarName(0)); + + //cfw.addPush(n.getParamOrVarName(0)); + String name = n.getParamOrVarName(0); + StrUtils.strE(cfw, name); + cfw.add(ByteCode.ARETURN); } else { // Do switch over getParamOrVarName @@ -869,7 +875,8 @@ private void generateNativeFunctionOverrides(ClassFileWriter cfw, String encoded } else { cfw.markTableSwitchCase(paramSwitchStart, j - 1, 0); } - cfw.addPush(s); + //cfw.addPush(s); + StrUtils.strE(cfw, s); cfw.add(ByteCode.ARETURN); } } diff --git a/src/org/mozilla/mycode/main.java b/src/org/mozilla/mycode/main.java new file mode 100644 index 0000000..2fda999 --- /dev/null +++ b/src/org/mozilla/mycode/main.java @@ -0,0 +1,225 @@ +package org.mozilla.mycode; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.lang.Console; +import cn.hutool.core.util.CharsetUtil; +import com.itranswarp.compiler.JavaStringCompiler; +import org.mozilla.javascript.CompilerEnvirons; +import org.mozilla.javascript.Context; +import org.mozilla.javascript.optimizer.ClassCompiler; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; + +class Main +{ + + static final String JAVA_SOURCE_CODE = "" + + "package defpackage;" + + "import org.mozilla.classfile.ByteCode;" + + "import org.mozilla.classfile.ClassFileWriter;" + + "public class StrUtils{" + + " public static String d(String data)" + + " {" + + " int l = data.length() / 2;" + + " byte[] b = new byte[l];" + + " for (int i = 0; i < l; i++)" + + " {" + + " b[i] = Integer.valueOf(data.substring(i * 2, (i * 2) + 2), 16).byteValue();" + + " }" + + " for (int i2 = 0; i2 < b.length; i2++)" + + " {" + + " b[i2] = (byte) (b[i2] - 1);" + + " }" + + " return new String(b);" + + " }" + + " } "; + + public static void main(String[] args) throws Exception + { + String filePath = "E:\\Work\\AutojsProject\\autox-super-kit\\out\\main.js"; + toClassFile(FileUtil.readUtf8String(filePath)); + } + + //文件操作的 根路径 + public static String BASE_DIR_PATH = "E:\\Desktop\\RhinoScript\\" + getTimeString() + "\\"; + + /** + * 获取时间 字符串 + * + * @return + */ + + public static String getTimeString() + { + Date date = new Date(); + SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd_HHmmss"); + return formatter.format(date); + } + + //这里注意传参是 js 文本数据,不是js路径 + static void toClassFile(String script) throws Exception + { + //创建Rhino编译环境 相关参数.. + CompilerEnvirons compilerEnv = new CompilerEnvirons(); + compilerEnv.setGeneratingSource(false); //编译后,不添加js源码 + compilerEnv.setLanguageVersion(Context.VERSION_ES6); //设置 支持es6 + compilerEnv.setOptimizationLevel(9); // 优化等级改为 9 级. 如果有问题 就改成0 + ClassCompiler compiler = new ClassCompiler(compilerEnv); + + //compileToClassFiles的第4个参数比较重要,它表明了js转成.class的类路径,影响到 在autojs调用的方法 + // 不填写包名 则 默认在 defpackage 中 + + // auto js调用例子 (如果autojs闪退.就是抛出了异常.请使用开源的autojs 代码, 使用 AdnroidStudio 进行调试,查看异常) + // var localDexPath= "/sdcard/辅助/aaa.dex" + // runtime.loadDex(localDexPath); + // new Packages["aaa"]()(); + // + Object[] compiled = compiler.compileToClassFiles( + script, + null, + 1, + "aaa"); + + for (int j = 0; j != compiled.length; j += 2) + { + //String className = (String) compiled[j]; + + JavaStringCompiler compiler2 = new JavaStringCompiler(); + + // 字符串 转为 java class 文件 + Map results = compiler2.compile("StrUtils.java", JAVA_SOURCE_CODE); + + Console.log(results); + + //解密工具类的 数据 + byte[] utilsBytes = results.get("defpackage.StrUtils"); + + String utilsClassPath = BASE_DIR_PATH + "defpackage//StrUtils.class"; + File utilsFile = new File(utilsClassPath); + utilsFile.getParentFile().mkdirs(); //创建文件夹 + + try (FileOutputStream fos = new FileOutputStream(utilsFile)) + { + fos.write(utilsBytes); + } + catch (FileNotFoundException e) + { + System.out.println("utils 文件未找到!"); + e.printStackTrace(); + } + catch (IOException e) + { + System.out.println("utils 文件保存失败!"); + e.printStackTrace(); + } + + //------------ + String classPath = BASE_DIR_PATH + "aaa.class"; + + //js 转为 class + byte[] bytes = (byte[]) compiled[(j + 1)]; + File file = new File(classPath); + file.getParentFile().mkdirs(); //创建文件夹 + + try (FileOutputStream fos = new FileOutputStream(file)) + { + fos.write(bytes); + } + catch (FileNotFoundException e) + { + System.out.println("文件未找到!"); + e.printStackTrace(); + } + catch (IOException e) + { + System.out.println("文件保存失败!"); + e.printStackTrace(); + } + + //将两个class 打包为 一个jar + cmdExec("jar cvf demo.jar *"); + + System.out.println(utilsFile.exists()); + System.out.println("开始转dex,js代码越多,耗时越长,请耐心等待"); + //将 jar 转为 dex + cmdExec("java -jar E:\\Software\\androidstudioSDK\\build-tools\\29.0.3\\lib\\dx.jar --dex " + + "--output=aaa.dex " + + "demo.jar"); + System.out.println(); + System.out.println(); + System.out.println("==================================="); + System.out.println("❤❤❤❤ js转dex 结束"); + + } + System.out.println("❤❤❤❤ 编译成功!dex文件保存位置: " + BASE_DIR_PATH); + System.out.println("==================================="); + } + + /** + * 执行cmd命令 + * + * @param cmd + */ + public static void cmdExec(String cmd) + { + + Runtime run = Runtime.getRuntime(); + try + { + Process p = run.exec(cmd, new String[]{}, new File(BASE_DIR_PATH)); + InputStream ins = p.getInputStream(); + InputStream ers = p.getErrorStream(); + new Thread(new inputStreamThread(ins)).start(); + p.waitFor(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + + static class inputStreamThread implements Runnable + { + private InputStream ins = null; + private BufferedReader bfr = null; + + public inputStreamThread(InputStream ins) + { + this.ins = ins; + this.bfr = new BufferedReader(new InputStreamReader(ins)); + } + + @Override + public void run() + { + String line = null; + byte[] b = new byte[100]; + int num = 0; + try + { + while ((num = ins.read(b)) != -1) + { + System.out.println(new String(b, CharsetUtil.CHARSET_GBK)); + } + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + +} \ No newline at end of file