/** * Transforms the tree into a lower-level IR suitable for codegen. * Optionally generates the encoded source. */ public ScriptNode transformTree(AstRoot root) { currentScriptOrFn = root; this.inUseStrictDirective = root.isInStrictMode(); int sourceStartOffset = decompiler.getCurrentOffset(); if (Token.printTrees) { System.out.println("IRFactory.transformTree"); System.out.println(root.debugPrint()); } ScriptNode script = (ScriptNode)transform(root); int sourceEndOffset = decompiler.getCurrentOffset(); script.setEncodedSourceBounds(sourceStartOffset, sourceEndOffset); if (compilerEnv.isGeneratingSource()) { script.setEncodedSource(decompiler.getEncodedSource()); } decompiler = null; return script; }
private void transformCompilationUnit(ScriptNode tree, boolean inStrictMode) { loops = new ObjArray(); loopEnds = new ObjArray(); // to save against upchecks if no finally blocks are used. hasFinally = false; // Flatten all only if we are not using scope objects for block scope boolean createScopeObjects = tree.getType() != Token.FUNCTION || ((FunctionNode)tree).requiresActivation(); tree.flattenSymbolTable(!createScopeObjects); //uncomment to print tree before transformation if (Token.printTrees) System.out.println(tree.toStringTree(tree)); transformCompilationUnit_r(tree, tree, tree, createScopeObjects, inStrictMode); }
public Object compile(CompilerEnvirons compilerEnv, ScriptNode tree, String encodedSource, boolean returnFunction) { int serial; synchronized (globalLock) { serial = ++globalSerialClassCounter; } String baseName = "c"; if (tree.getSourceName().length() > 0) { baseName = tree.getSourceName().replaceAll("\\W", "_"); if (!Character.isJavaIdentifierStart(baseName.charAt(0))) { baseName = "_" + baseName; } } String mainClassName = "org.mozilla.javascript.gen." + baseName + "_" + serial; byte[] mainClassBytes = compileToClassFile(compilerEnv, mainClassName, tree, encodedSource, returnFunction); return new Object[] { mainClassName, mainClassBytes }; }
/** * Gets a Java-compatible "informative" name for the the ScriptOrFnNode */ String cleanName(final ScriptNode n) { String result = ""; if (n instanceof FunctionNode) { Name name = ((FunctionNode) n).getFunctionName(); if (name == null) { result = "anonymous"; } else { result = name.getIdentifier(); } } else { result = "script"; } return result; }
String getBodyMethodSignature(ScriptNode n) { StringBuilder sb = new StringBuilder(); sb.append('('); sb.append(mainClassSignature); sb.append("Lorg/mozilla/javascript/Context;" +"Lorg/mozilla/javascript/Scriptable;" +"Lorg/mozilla/javascript/Scriptable;"); if (n.getType() == Token.FUNCTION) { OptFunctionNode ofn = OptFunctionNode.get(n); if (ofn.isTargetOfDirectCall()) { int pCount = ofn.fnode.getParamCount(); for (int i = 0; i != pCount; i++) { sb.append("Ljava/lang/Object;D"); } } } sb.append("[Ljava/lang/Object;)Ljava/lang/Object;"); return sb.toString(); }
private void transformCompilationUnit(ScriptNode tree) { loops = new ObjArray(); loopEnds = new ObjArray(); // to save against upchecks if no finally blocks are used. hasFinally = false; // Flatten all only if we are not using scope objects for block scope boolean createScopeObjects = tree.getType() != Token.FUNCTION || ((FunctionNode)tree).requiresActivation(); tree.flattenSymbolTable(!createScopeObjects); //uncomment to print tree before transformation if (Token.printTrees) System.out.println(tree.toStringTree(tree)); boolean inStrictMode = tree instanceof AstRoot && ((AstRoot)tree).isInStrictMode(); transformCompilationUnit_r(tree, tree, tree, createScopeObjects, inStrictMode); }
String getBodyMethodSignature(ScriptNode n) { StringBuffer sb = new StringBuffer(); sb.append('('); sb.append(mainClassSignature); sb.append("Lorg/mozilla/javascript/Context;" +"Lorg/mozilla/javascript/Scriptable;" +"Lorg/mozilla/javascript/Scriptable;"); if (n.getType() == Token.FUNCTION) { OptFunctionNode ofn = OptFunctionNode.get(n); if (ofn.isTargetOfDirectCall()) { int pCount = ofn.fnode.getParamCount(); for (int i = 0; i != pCount; i++) { sb.append("Ljava/lang/Object;D"); } } } sb.append("[Ljava/lang/Object;)Ljava/lang/Object;"); return sb.toString(); }
/** * Compiles {@code source} and returns the transformed and optimized * {@link ScriptNode} */ protected ScriptNode compile(CharSequence source) { final String mainMethodClassName = "Main"; final String scriptClassName = "Main"; CompilerEnvirons compilerEnv = new CompilerEnvirons(); compilerEnv.initFromContext(cx); Parser p = new Parser(compilerEnv); AstRoot ast = p.parse(source.toString(), "<eval>", 1); IRFactory irf = new IRFactory(compilerEnv); ScriptNode tree = irf.transformTree(ast); Codegen codegen = new Codegen(); codegen.setMainMethodClass(mainMethodClassName); codegen.compileToClassFile(compilerEnv, scriptClassName, tree, tree.getEncodedSource(), false); return tree; }
/** * Checks every variable {@code v} in {@code source} is marked as a * number-variable iff {@code numbers} contains {@code v} */ protected void assertNumberVars(CharSequence source, String... numbers) { // wrap source in function ScriptNode tree = compile("function f(){" + source + "}"); FunctionNode fnode = tree.getFunctionNode(0); assertNotNull(fnode); OptFunctionNode opt = OptFunctionNode.get(fnode); assertNotNull(opt); assertSame(fnode, opt.fnode); for (int i = 0, c = fnode.getParamCount(); i < c; ++i) { assertTrue(opt.isParameter(i)); assertFalse(opt.isNumberVar(i)); } Set<String> set = new HashSet<String>(asList(numbers)); for (int i = fnode.getParamCount(), c = fnode.getParamAndVarCount(); i < c; ++i) { assertFalse(opt.isParameter(i)); String name = fnode.getParamOrVarName(i); String msg = format("{%s -> number? = %b}", name, opt.isNumberVar(i)); assertEquals(msg, set.contains(name), opt.isNumberVar(i)); } }
/** * Compiles {@code source} and returns the transformed and optimized * {@link ScriptNode} */ protected ScriptNode compile(CharSequence source) { final String mainMethodClassName = "Main"; final String scriptClassName = "Main"; CompilerEnvirons compilerEnv = new CompilerEnvirons(); compilerEnv.initFromContext(cx); ErrorReporter compilationErrorReporter = compilerEnv .getErrorReporter(); Parser p = new Parser(compilerEnv, compilationErrorReporter); AstRoot ast = p.parse(source.toString(), "<eval>", 1); IRFactory irf = new IRFactory(compilerEnv); ScriptNode tree = irf.transformTree(ast); Codegen codegen = new Codegen(); codegen.setMainMethodClass(mainMethodClassName); codegen.compileToClassFile(compilerEnv, scriptClassName, tree, tree.getEncodedSource(), false); return tree; }
/** * Checks every variable {@code v} in {@code source} is marked as a * number-variable iff {@code numbers} contains {@code v} */ protected void assertNumberVars(CharSequence source, String... numbers) { // wrap source in function ScriptNode tree = compile("function f(o, fn){" + source + "}"); FunctionNode fnode = tree.getFunctionNode(0); assertNotNull(fnode); OptFunctionNode opt = OptFunctionNode.get(fnode); assertNotNull(opt); assertSame(fnode, opt.fnode); for (int i = 0, c = fnode.getParamCount(); i < c; ++i) { assertTrue(opt.isParameter(i)); assertFalse(opt.isNumberVar(i)); } Set<String> set = new HashSet<String>(asList(numbers)); for (int i = fnode.getParamCount(), c = fnode.getParamAndVarCount(); i < c; ++i) { assertFalse(opt.isParameter(i)); String name = fnode.getParamOrVarName(i); String msg = format("{%s -> number? = %b}", name, opt.isNumberVar(i)); assertEquals(msg, set.contains(name), opt.isNumberVar(i)); } }
/** * * @param expr * @param objectName * @return */ private static String getReferencedScriptObject( String expr, String objectName ) { if ( expr == null ) return null; try { Context cx = Context.enter( ); CompilerEnvirons ce = new CompilerEnvirons( ); Parser p = new Parser( ce, cx.getErrorReporter( ) ); AstRoot tree = p.parse( expr, null, 0 ); IRFactory ir = new IRFactory( ce ); ScriptNode script = ir.transformTree( tree ); return getScriptObjectName( script, objectName ); } finally { Context.exit( ); } }
/** * get the function node index * * @param functionName * @param tree * @return */ private int getFunctionIndex( String functionName, ScriptNode tree ) { int index = -1; for ( int i = 0; i < tree.getFunctionCount( ); i++ ) { if ( tree.getFunctionNode( i ) .getFunctionName( ).getString() .equals( functionName ) ) { index = i; break; } } return index; }
/** * compile the string expression * * @param expression * @param context * @return * @throws DataException */ protected CompiledExpression compileExpression( String expression, ScriptContext context ) throws DataException { String exp = ""; try { exp = expression; if ( exp == null ) return null; IDataScriptEngine engine = (IDataScriptEngine) context.getScriptEngine( IDataScriptEngine.ENGINE_NAME ); ScriptNode tree = parse( exp, engine.getJSContext( context ) ); return processScriptTree( exp, tree, engine.getJSContext( context ) ); } catch ( Exception e ) { DataException dataException = new DataException( ResourceConstants.INVALID_JS_EXPR, e, exp ); throw dataException; } }