AST Variables(AST parent, bool in_for_init) { VariableStatement pn = new VariableStatement (parent, new Location (ts.SourceName, ts.LineNumber)); bool first = true; decompiler.AddToken (Token.VAR); for (;;) { VariableDeclaration name; AST init = null; MustMatchToken (Token.NAME, "msg.bad.var"); string s = ts.GetString; if (!first) decompiler.AddToken (Token.COMMA); first = false; decompiler.AddName (s); name = new VariableDeclaration (parent, s, null, null, new Location (ts.SourceName, ts.LineNumber)); // ommited check for argument hiding if (ts.MatchToken (Token.ASSIGN)) { decompiler.AddToken (Token.ASSIGN); init = AssignExpr (parent, in_for_init); name.val = init; } pn.Add (name); if (!ts.MatchToken (Token.COMMA)) break; } return pn; }
private void ParseAst(JS.AST ast, string sp) { if (ast == null) { return; } if (CheckWorker()) { return; } //_logView.LogStr("JSM->" + sp + ast.ToString() + "\t\t" + ast.GetType().Name); if (ast is JS.FunctionDeclaration) { JS.Function func = ast as JS.Function; ParseAstList(func.func_obj.body.elems, sp + " "); } else if (ast is JS.Assign) { JS.Assign ass = ast as JS.Assign; ParseAst(ass.left, sp + "l "); ParseAst(ass.right, sp + "r "); } else if (ast is JS.Binary) { JS.Binary bin = ast as JS.Binary; string[] parts = bin.ToString().Split('.'); if (parts.Length > 1) { if (parts[parts.Length - 2] == "This") { string calledId = parts[parts.Length - 1] + "()"; //dup // If we have a method of this name in this file/class if (_addedNodes.ContainsKey(calledId)) { // Create an edge. // A definite functional assignment link. AddEdge(_methodNodeId, calledId, EdgeStyle.NormalArrow, Color.Aqua); } else { // It's a call to a method outside this class/file. // //_logView.LogStr("skipped assign ref -->" + _methodNodeId + " --------> " + calledId); // } } else if (parts[parts.Length - 2] == "self") { string calledId = parts[parts.Length - 1] + "()"; //dup // If we have a method of this name in this file/class if (_addedNodes.ContainsKey(calledId)) { // Get the graph node that we're linking to. //Node calledNode = _addedNodes[calledId]; // Create an edge. // A definite functional assignment link. AddEdge(_methodNodeId, calledId, EdgeStyle.NormalArrow, Color.Aqua); } else { // It's a call to a method outside this class/file. _logView.LogStr("skipped assign ref -->" + _methodNodeId + " --------> " + calledId); } } } } else if (ast is JS.Expression) { JS.Expression expr = ast as JS.Expression; ParseAstList(expr.exprs, sp + " "); } else if (ast is JS.FunctionExpression) { JS.FunctionExpression expr = ast as JS.FunctionExpression; ParseAstList(expr.func_obj.body.elems, sp + " "); } else if (ast is JS.For) { JS.For fr = ast as JS.For; ParseAst(fr.stms, sp + " "); } else if (ast is JS.If) { JS.If iff = ast as JS.If; ParseAst(iff.false_stm, sp + "f "); ParseAst(iff.true_stm, sp + "t "); } else if (ast is JS.Block) { JS.Block block = ast as JS.Block; ParseAstList(block.elems, sp + " "); } else if (ast is JS.VariableStatement) { JS.VariableStatement var = ast as JS.VariableStatement; //var. ParseAstList(var.var_decls, sp + " "); } else if (ast is JS.Return) { JS.Return ret = ast as JS.Return; ParseAst(ret.expression, sp + " "); } else if (ast is JS.VariableDeclaration) { JS.VariableDeclaration var = ast as JS.VariableDeclaration; Microsoft.JScript.New newval = var.val as Microsoft.JScript.New; if (newval != null && newval.exp != null) { //_logView.LogStr("new:" + newval.exp.ToString()); string[] parts = newval.exp.ToString().Split('.'); if (parts.Length > 0) { string calledId = parts[parts.Length - 1] + "()"; // If we have a method of this name in this file/class, then // we have a possible constructor link. if (_addedNodes.ContainsKey(calledId)) { // Create an edge. AddEdge(_methodNodeId, calledId, EdgeStyle.NormalArrow, Color.Green); } } } else { if (var.val != null) { string valStr = var.val.ToString(); string[] parts = valStr.Split('.'); if (parts.Length > 1 && parts[0] == "self") { // dup.. string calledId = parts[parts.Length - 1] + "()"; // If we have a method of this name in this file/class, then // we have a possible constructor link. if (_addedNodes.ContainsKey(calledId)) { // Create an edge. AddEdge(_methodNodeId, calledId, EdgeStyle.NormalArrow, Color.Green); } } } } //ParseAstList(var.var_decls, sp + " "); } else if (ast is JS.Call) { JS.Call call = ast as JS.Call; string[] parts = call.ToString().Split(' '); string[] bits = parts[0].Split('.'); string calledId = bits[bits.Length - 1] + "()"; bool methodInThisClass = true; if (bits.Length > 1) { if ((bits[bits.Length - 2] != "This") && (bits[bits.Length - 2] != "self")) { methodInThisClass = false; } } // If we have a method of this name in this file/class if (_addedNodes.ContainsKey(calledId)) { // Create an edge. if (methodInThisClass) { // A definite link. AddEdge(_methodNodeId, calledId, EdgeStyle.NormalArrow, Color.Black); } else { // A tentative link. AddEdge(_methodNodeId, calledId, EdgeStyle.NormalArrow, Color.Gray); } } else { // It's a call to a method outside this class/file. // //_logView.LogStr("skipped -------->" + _methodNodeId + " --------> " + parts[0]); // } } }
internal override void Emit(EmitContext ec) { ILGenerator ig = ec.ig; bool varStm = lhs is VariableStatement; object var = null; if (varStm) { VariableStatement stm = (VariableStatement)lhs; ig.Emit(OpCodes.Ldnull); var = TypeManager.Get(((VariableDeclaration)stm.var_decls [0]).id); set_builder(ig, var); } if (obj != null) { obj.Emit(ec); } CodeGenerator.load_engine(InFunction, ig); Type convert = typeof(Convert); ig.Emit(OpCodes.Call, convert.GetMethod("ToForInObject")); ig.Emit(OpCodes.Call, typeof(ForIn).GetMethod("JScriptGetEnumerator")); Type ienumerator = typeof(IEnumerator); LocalBuilder iter = ig.DeclareLocal(ienumerator); LocalBuilder current = ig.DeclareLocal(typeof(object)); ig.Emit(OpCodes.Stloc, iter); Label init_loop = ig.DefineLabel(); Label move_next = ig.DefineLabel(); Label exit = ig.DefineLabel(); ig.Emit(OpCodes.Br, move_next); ig.MarkLabel(init_loop); if (body != null) { body.Emit(ec); } ig.MarkLabel(move_next); ig.Emit(OpCodes.Ldloc, iter); ig.Emit(OpCodes.Callvirt, ienumerator.GetMethod("MoveNext")); ig.Emit(OpCodes.Brfalse, exit); ig.Emit(OpCodes.Ldloc, iter); ig.Emit(OpCodes.Callvirt, ienumerator.GetProperty("Current").GetGetMethod()); ig.Emit(OpCodes.Stloc, current); ig.Emit(OpCodes.Ldloc, current); if (varStm) { set_builder(ig, var); } else { if (lhs is Expression) { AST ast = ((Expression)lhs).Last; if (ast is Identifier) { ((Identifier)ast).EmitStore(ec); } else { throw new NotImplementedException(); } } else { throw new NotImplementedException(); } } ig.Emit(OpCodes.Br, init_loop); ig.MarkLabel(exit); }