public override void CaseASimpleInvokeExp(ASimpleInvokeExp node) { AMethodDecl target = data.SimpleMethodLinks[node]; for (int i = 0; i < node.GetArgs().Count; i++) { PExp arg = (PExp)node.GetArgs()[i]; currentLocal = null; arg.Apply(this); if (currentLocal != null && target.GetFormals().Cast<AALocalDecl>().ToList()[i].GetRef() != null) { ALocalLvalue local = currentLocal; target.Apply(this); if (target.GetFormals().Cast<AALocalDecl>().ToList()[i].GetRef() != null) { AALocalDecl decl = data.LocalLinks[local]; NeededRefs[Util.GetAncestor<AMethodDecl>(node)].Add(decl); } } } }
public override void CaseASimpleInvokeExp(ASimpleInvokeExp node) { AMethodDecl decl = finalTrans.data.SimpleMethodLinks[node]; if (structMethods.Contains(decl)) {//The target is a struct method that has been moved out if (node.GetArgs().Count < decl.GetFormals().Count && Util.HasAncestor<AStructDecl>(node)) {//If this is the case, we Must be inside the same struct as the target. - Not with enheritance ALocalLvalue local = new ALocalLvalue(new TIdentifier("tempName")); ALvalueExp exp = new ALvalueExp(local); finalTrans.data.LvalueTypes[local] = finalTrans.data.ExpTypes[exp] = structFormal.GetType(); finalTrans.data.LocalLinks[local] = structFormal; //If we're calling from class to struct, we must depointer it AStructDecl currentStruct = finalTrans.data.StructMethods.First( pair => pair.Value.Contains(Util.GetAncestor<AMethodDecl>(node))).Key; AStructDecl baseStruct = finalTrans.data.StructMethods.First( pair => pair.Value.Contains(decl)).Key; if (currentStruct.GetClassToken() != baseStruct.GetClassToken()) //It's not possible to call from struct to class { APointerLvalue pointerLvalue = new APointerLvalue(new TStar("*"), exp); exp = new ALvalueExp(pointerLvalue); finalTrans.data.LvalueTypes[pointerLvalue] = finalTrans.data.ExpTypes[exp] = ((APointerType)structFormal.GetType()).GetType(); } node.GetArgs().Add(exp); } } else if (Util.GetAncestor<AStructDecl>(decl) != null && OldParentStruct.ContainsKey(Util.GetAncestor<AMethodDecl>(node))) {//The target is a struct method that hasn't been moved out if (Util.GetAncestor<AStructDecl>(decl) == OldParentStruct[Util.GetAncestor<AMethodDecl>(node)] && decl.GetStatic() == null) {//We have an internal struct call. Expect to have one too many args if (node.GetArgs().Count == decl.GetFormals().Count) { ALocalLvalue local = new ALocalLvalue(new TIdentifier("tempName")); ALvalueExp exp = new ALvalueExp(local); finalTrans.data.LvalueTypes[local] = finalTrans.data.ExpTypes[exp] = structFormal.GetType(); finalTrans.data.LocalLinks[local] = structFormal; //If we're calling from class to struct, we must depointer it AStructDecl currentStruct = finalTrans.data.StructMethods.First( pair => pair.Value.Contains(Util.GetAncestor<AMethodDecl>(node))).Key; AStructDecl baseStruct = finalTrans.data.StructMethods.First( pair => pair.Value.Contains(decl)).Key; if (currentStruct.GetClassToken() != baseStruct.GetClassToken()) //It's not possible to call from struct to class { APointerLvalue pointerLvalue = new APointerLvalue(new TStar("*"), exp); exp = new ALvalueExp(pointerLvalue); finalTrans.data.LvalueTypes[pointerLvalue] = finalTrans.data.ExpTypes[exp] = ((APointerType)structFormal.GetType()).GetType(); } node.GetArgs().Add(exp); } } } base.CaseASimpleInvokeExp(node); }
public override void CaseANonstaticInvokeExp(ANonstaticInvokeExp node) { PExp reciever = node.GetReceiver(); PType type = finalTrans.data.ExpTypes[reciever]; //If the reciever is not a var, put it in a new var. if (!(reciever is ALvalueExp)) { AALocalDecl localDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(type, data), new TIdentifier("nonstaticInvokeVar"), reciever); ALocalLvalue localRef = new ALocalLvalue(new TIdentifier("nonstaticInvokeVar")); ALvalueExp localRefExp = new ALvalueExp(localRef); node.SetReceiver(localRefExp); PStm pStm = Util.GetAncestor<PStm>(node); AABlock pBlock = (AABlock) pStm.Parent(); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ALocalDeclStm(new TSemicolon(";"), localDecl)); reciever = localRefExp; data.LvalueTypes[localRef] = data.ExpTypes[localRefExp] = type; data.LocalLinks[localRef] = localDecl; localDecl.Apply(this); } if (type is ANamedType && finalTrans.data.StructTypeLinks.ContainsKey((ANamedType)type)) { //ANamedType type = (ANamedType) finalTrans.data.ExpTypes[reciever]; if (finalTrans.data.StructTypeLinks[(ANamedType) type].GetClassToken() != null) { //Pass the pointer ALvalueExp lvalueExp = (ALvalueExp) reciever; APointerLvalue pointerLvalue = (APointerLvalue) lvalueExp.GetLvalue(); reciever = pointerLvalue.GetBase(); } AMethodDecl method = finalTrans.data.StructMethodLinks[node]; ASimpleInvokeExp simpleInvoke = new ASimpleInvokeExp(); simpleInvoke.SetName(node.GetName()); PExp[] exps = new PExp[node.GetArgs().Count]; node.GetArgs().CopyTo(exps, 0); foreach (PExp exp in exps) { simpleInvoke.GetArgs().Add(exp); } simpleInvoke.GetArgs().Add(reciever); node.ReplaceBy(simpleInvoke); finalTrans.data.SimpleMethodLinks[simpleInvoke] = method; finalTrans.data.StructMethodLinks.Remove(node); finalTrans.data.ExpTypes[simpleInvoke] = method.GetReturnType(); finalTrans.data.ExpTypes.Remove(node); simpleInvoke.Apply(this); } else {//Enrichment /*AEnrichmentDecl enrichment = finalTrans.data.EnrichmentTypeLinks[type]; foreach (AEnrichmentDecl enrichmentDecl in finalTrans.data.Enrichments) { if (Util.IsVisible(node, enrichmentDecl) && Util.IsDeclVisible(enrichmentDecl, Util.GetAncestor<AASourceFile>(node)) && Util.TypesEqual(type, enrichmentDecl.GetType(), finalTrans.data)) { enrichment = enrichmentDecl; break; } } if (enrichment == null) { finalTrans.errors.Add(new ErrorCollection.Error(node.GetName(), "TransFormMethodDecls.NonStaticInvoke: Expected enrichment - this is a bug. It should have been caught earlier")); throw new ParserException(node.GetName(), ""); }*/ AMethodDecl method = finalTrans.data.StructMethodLinks[node]; ASimpleInvokeExp simpleInvoke = new ASimpleInvokeExp(); simpleInvoke.SetName(node.GetName()); PExp[] exps = new PExp[node.GetArgs().Count]; node.GetArgs().CopyTo(exps, 0); foreach (PExp exp in exps) { simpleInvoke.GetArgs().Add(exp); } simpleInvoke.GetArgs().Add(reciever); node.ReplaceBy(simpleInvoke); finalTrans.data.SimpleMethodLinks[simpleInvoke] = method; finalTrans.data.StructMethodLinks.Remove(node); finalTrans.data.ExpTypes[simpleInvoke] = method.GetReturnType(); finalTrans.data.ExpTypes.Remove(node); simpleInvoke.Apply(this); } }
public override void CaseAConstructorDecl(AConstructorDecl node) { AStructDecl str = Util.GetAncestor<AStructDecl>(node); AEnrichmentDecl enrichment = Util.GetAncestor<AEnrichmentDecl>(node); AMethodDecl replacer = new AMethodDecl(new APublicVisibilityModifier(), null, null, null, null, null, new AVoidType(new TVoid("void")), node.GetName(), new ArrayList(), node.GetBlock()); replacer.GetName().Text += "_Constructor"; while (node.GetFormals().Count > 0) { replacer.GetFormals().Add(node.GetFormals()[0]); } //Move the method outside the struct AASourceFile file = Util.GetAncestor<AASourceFile>(node); if (str != null) str.RemoveChild(node.Parent()); else enrichment.RemoveChild(node); int i = file.GetDecl().IndexOf(str ?? (PDecl)enrichment); file.GetDecl().Insert(i/* + 1*/, replacer); //Add the struct as a parameter PType type; if (str != null) { ANamedType structType = new ANamedType(new TIdentifier(str.GetName().Text), null); finalTrans.data.StructTypeLinks[structType] = str; type = structType; } else { type = Util.MakeClone(enrichment.GetType(), finalTrans.data); } finalTrans.data.ConstructorMap[node] = replacer; structFormal = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new APointerType(new TStar("*"), type), new TIdentifier("currentStruct", replacer.GetName().Line, replacer.GetName().Pos), null); replacer.GetFormals().Add(structFormal); finalTrans.data.Methods.Add(new SharedData.DeclItem<AMethodDecl>(file, replacer)); //Add return stm replacer.SetReturnType(new APointerType(new TStar("*"), Util.MakeClone(type, data))); replacer.Apply(new TransformConstructorReturns(structFormal, data)); //Insert call to base constructor);); if (finalTrans.data.ConstructorBaseLinks.ContainsKey(node)) { AMethodDecl baseConstructor = finalTrans.data.ConstructorMap[finalTrans.data.ConstructorBaseLinks[node]]; ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier(baseConstructor.GetName().Text), new ArrayList()); while (node.GetBaseArgs().Count > 0) { invoke.GetArgs().Add(node.GetBaseArgs()[0]); } AThisLvalue thisLvalue1 = new AThisLvalue(new TThis("this")); ALvalueExp thisExp1 = new ALvalueExp(thisLvalue1); invoke.GetArgs().Add(thisExp1); AThisLvalue thisLvalue2 = new AThisLvalue(new TThis("this")); AAssignmentExp assignExp = new AAssignmentExp(new TAssign("="), thisLvalue2, invoke); ANamedType structType = new ANamedType(new TIdentifier(str.GetName().Text), null); finalTrans.data.StructTypeLinks[structType] = str; finalTrans.data.LvalueTypes[thisLvalue1] = finalTrans.data.LvalueTypes[thisLvalue2] = finalTrans.data.ExpTypes[thisExp1] = finalTrans.data.ExpTypes[assignExp] = finalTrans.data.ExpTypes[invoke] = new APointerType(new TStar("*"), structType); //finalTrans.data.ExpTypes[invoke] = new AVoidType(new TVoid("void")); finalTrans.data.SimpleMethodLinks[invoke] = baseConstructor; ((AABlock)replacer.GetBlock()).GetStatements().Insert(0, new AExpStm(new TSemicolon(";"), assignExp)); //Inline if base and current are two different kinds of pointer types (int/string) AStructDecl baseStruct = null; AConstructorDecl baseC = finalTrans.data.ConstructorBaseLinks[node]; foreach (KeyValuePair<AStructDecl, List<AConstructorDecl>> pair in finalTrans.data.StructConstructors) { bool found = false; foreach (AConstructorDecl decl in pair.Value) { if (baseC == decl) { found = true; break; } } if (found) { baseStruct = pair.Key; break; } } if ((str.GetIntDim() == null) != (baseStruct.GetIntDim() == null)) { //For the inilining, change the type to the type of the caller AALocalDecl lastFormal = baseConstructor.GetFormals().OfType<AALocalDecl>().Last(); lastFormal.SetRef(new TRef("ref")); APointerType oldType = (APointerType) lastFormal.GetType(); structType = new ANamedType(new TIdentifier(str.GetName().Text), null); finalTrans.data.StructTypeLinks[structType] = str; APointerType newType = new APointerType(new TStar("*"), structType); lastFormal.SetType(newType); foreach ( ALocalLvalue lvalue in data.LocalLinks.Where(pair => pair.Value == lastFormal).Select(pair => pair.Key)) { data.LvalueTypes[lvalue] = newType; if (lvalue.Parent() is ALvalueExp) { data.ExpTypes[(PExp) lvalue.Parent()] = newType; if (lvalue.Parent().Parent() is APointerLvalue) data.LvalueTypes[(PLvalue) lvalue.Parent().Parent()] = newType.GetType(); } } FixInlineMethods.Inline(invoke, finalTrans); lastFormal.SetRef(null); foreach ( ALocalLvalue lvalue in data.LocalLinks.Where(pair => pair.Value == lastFormal).Select(pair => pair.Key)) { data.LvalueTypes[lvalue] = oldType; if (lvalue.Parent() is ALvalueExp) { data.ExpTypes[(PExp) lvalue.Parent()] = oldType; if (lvalue.Parent().Parent() is APointerLvalue) data.LvalueTypes[(PLvalue) lvalue.Parent().Parent()] = oldType.GetType(); } } lastFormal.SetType(oldType); } //Inline it instead, Since the pointer implementations might not be the same (int vs string) /*AMethodDecl baseConstructor = finalTrans.data.ConstructorMap[finalTrans.data.ConstructorBaseLinks[node]]; AABlock localsBlock = new AABlock(new ArrayList(), new TRBrace("}")); ABlockStm cloneBlock = new ABlockStm(new TLBrace("{"), (PBlock) baseConstructor.GetBlock().Clone()); Dictionary<AALocalDecl, PLvalue> localMap = new Dictionary<AALocalDecl, PLvalue>(); for (int argNr = 0; argNr < baseConstructor.GetFormals().Count; argNr++) { AALocalDecl formal = (AALocalDecl) baseConstructor.GetFormals()[i]; PExp arg; if (i < baseConstructor.GetFormals().Count - 1) arg = (PExp)node.GetBaseArgs()[i]; else { AThisLvalue thisLvalue = new AThisLvalue(new TThis("this")); ALvalueExp thisExp = new ALvalueExp(thisLvalue); ANamedType structType = new ANamedType(new TIdentifier(str.GetName().Text), null); finalTrans.data.StructTypeLinks[structType] = str; finalTrans.data.LvalueTypes[thisLvalue] = finalTrans.data.ExpTypes[thisExp] = new APointerType(new TStar("*"), structType); arg = thisExp; } if (formal.GetRef() != null || formal.GetOut() != null) { //Use same variable localMap[formal] = ((ALvalueExp) arg).GetLvalue(); } else { //Make a new variable AALocalDecl newLocal = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(formal.GetType(), finalTrans.data), new TIdentifier(formal.GetName().Text), Util.MakeClone(arg, data)); ALocalLvalue newLocalRef = new ALocalLvalue(new TIdentifier(newLocal.GetName().Text)); localMap[formal] = newLocalRef; data.LvalueTypes[newLocalRef] = newLocal.GetType(); data.LocalLinks[newLocalRef] = newLocal; localsBlock.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), newLocal)); } } CloneMethod cloner = new CloneMethod(finalTrans.data, localMap, cloneBlock); baseConstructor.GetBlock().Apply(cloner); ((AABlock)cloneBlock.GetBlock()).GetStatements().Insert(0, new ABlockStm(new TLBrace("{"), localsBlock)); ((AABlock)node.GetBlock()).GetStatements().Insert(0, cloneBlock);*/ } //Fix refferences to other struct stuff); base.CaseAMethodDecl(replacer); //Add functionality to refference the current struct in a constructor //Want to do it as a pointer type, since the constructer can only be called for pointer types }
public override void CaseASimpleInvokeExp(ASimpleInvokeExp node) { Value += node.GetName().Text + "("; bool first = true; foreach (PExp arg in node.GetArgs()) { if (!first) Value += ", "; else first = false; arg.Apply(this); } Value += ")"; }
public override void CaseASimpleInvokeExp(ASimpleInvokeExp node) { InASimpleInvokeExp(node); { Object[] temp = new Object[node.GetArgs().Count]; node.GetArgs().CopyTo(temp, 0); for (int i = temp.Length - 1; i >= 0; i--) { ((PExp)temp[i]).Apply(this); } } if (node.GetName() != null) { node.GetName().Apply(this); } OutASimpleInvokeExp(node); }
public override void OutASimpleInvokeExp(ASimpleInvokeExp node) { if (data.SimpleMethodLinks.ContainsKey(node)) return; List<AMethodDecl> candidates = new List<AMethodDecl>(); List<AMethodDecl> implicitCandidates = new List<AMethodDecl>(); List<AMethodDecl> matchingNames = new List<AMethodDecl>(); List<PType> argTypes = new List<PType>(); foreach (PExp exp in node.GetArgs()) { argTypes.Add(data.ExpTypes[exp]); } PExp baseExp; bool matchResize; GetTargets(node.GetName().Text, node.GetName(), null, null, argTypes, candidates, out matchResize, implicitCandidates, matchingNames, out baseExp, null, data, errors); if (baseExp != null) { ANonstaticInvokeExp replacer = new ANonstaticInvokeExp(baseExp, new ADotDotType(new TDot(".")), node.GetName(), new ArrayList()); while (node.GetArgs().Count > 0) { replacer.GetArgs().Add(node.GetArgs()[0]); } node.ReplaceBy(replacer); baseExp.Apply(this); OutANonstaticInvokeExp(replacer); return; } AMethodDecl decl; if (candidates.Count == 0 && implicitCandidates.Count == 1) { //Do the implicit casts for (int i = 0; i < node.GetArgs().Count; i++) { PType argType = data.ExpTypes[(PExp)node.GetArgs()[i]]; AALocalDecl formal = (AALocalDecl)implicitCandidates[0].GetFormals()[i]; PType formalType = formal.GetType(); if (formal.GetOut() != null && !Assignable(formalType, argType) || formal.GetRef() != null && !(Assignable(argType, formalType) && Assignable(formalType, argType)) || formal.GetOut() == null && formal.GetRef() == null && !Assignable(argType, formalType)) { PExp exp = (PExp)node.GetArgs()[i]; ACastExp cast = new ACastExp(new TLParen("("), Util.MakeClone(formalType, data), null); exp.ReplaceBy(cast); cast.SetExp(exp); OutACastExp(cast); } } decl = implicitCandidates[0]; } else decl = candidates[0]; data.SimpleMethodLinks.Add(node, decl); data.ExpTypes.Add(node, decl.GetReturnType()); CheckInvoke(node, decl); base.OutASimpleInvokeExp(node); }
public override void OutACastExp(ACastExp node) { string toType = ((AAName)((ANamedType) node.GetType()).GetName()).AsString(); string fromType; PType fromPType = data.ExpTypes[node.GetExp()]; AStructDecl toEnum = null; AStructDecl fromEnum = null; if (data.StructTypeLinks.ContainsKey((ANamedType)node.GetType())) { AStructDecl str = data.StructTypeLinks[(ANamedType)node.GetType()]; if (data.Enums.ContainsKey(str)) toEnum = str; } if (fromPType is ANamedType) { fromType = ((AAName)((ANamedType)fromPType).GetName()).AsString(); //Namespace ignored if (data.StructTypeLinks.ContainsKey((ANamedType) fromPType)) { AStructDecl str = data.StructTypeLinks[(ANamedType) fromPType]; if (data.Enums.ContainsKey(str)) fromEnum = str; } } else { errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile, LocRM.GetString("ErrorText121"))); throw new ParserException(node.GetToken(), "Invalid cast"); } if (toEnum != null && (fromType == "int" || fromType == "byte")) { ANamedType type = new ANamedType(new TIdentifier(toEnum.GetName().Text), null); data.StructTypeLinks[type] = toEnum; data.ExpTypes[node.GetExp()] = type; node.ReplaceBy(node.GetExp()); return; } if (fromEnum != null && (toType == "int" || toType == "byte")) { int enumDefinitions = 0; foreach (PLocalDecl local in fromEnum.GetLocals()) { if (local is AALocalDecl) enumDefinitions++; } string typeName = enumDefinitions > 255 ? "int" : "byte"; ANamedType type = new ANamedType(new TIdentifier(typeName), null); data.ExpTypes[node.GetExp()] = new ANamedType(new TIdentifier(typeName), null); node.ReplaceBy(node.GetExp()); return; } if (fromEnum != null && toType == "string") { AMethodDecl targetMethod = data.StructMethods[fromEnum][0]; ASimpleInvokeExp invokeExp = new ASimpleInvokeExp(new TIdentifier("toString"), new ArrayList(){node.GetExp()}); data.SimpleMethodLinks[invokeExp] = targetMethod; data.ExpTypes[invokeExp] = targetMethod.GetReturnType(); node.ReplaceBy(invokeExp); return; } ASimpleInvokeExp replacementMethod = null; switch (toType) { case "string": switch (fromType) { case "wave": replacementMethod = new ASimpleInvokeExp(new TIdentifier("AIWaveToString"), new ArrayList{node.GetExp()}); break; case "fixed"://Implicit AFieldLvalue precisionArg = new AFieldLvalue(new TIdentifier("c_fixedPrecisionAny")); ALvalueExp exp = new ALvalueExp(precisionArg); data.FieldLinks[precisionArg] = data.Libraries.Fields.First(field => field.GetName().Text == precisionArg.GetName().Text); replacementMethod = new ASimpleInvokeExp(new TIdentifier("FixedToString"), new ArrayList { node.GetExp(), exp}); break; case "int"://Implicit case "byte"://Implicit replacementMethod = new ASimpleInvokeExp(new TIdentifier("IntToString"), new ArrayList { node.GetExp()}); break; case "bool"://Implicit replacementMethod = new ASimpleInvokeExp(new TIdentifier("libNtve_gf_ConvertBooleanToString"), new ArrayList { node.GetExp() }); break; case "color"://Implicit replacementMethod = new ASimpleInvokeExp(new TIdentifier("libNtve_gf_ConvertColorToString"), new ArrayList { node.GetExp() }); break; } break; case "text": switch (fromType) { case "wave": replacementMethod = new ASimpleInvokeExp(new TIdentifier("AIWaveToText"), new ArrayList { node.GetExp() }); break; case "fixed"://Implicit AFieldLvalue precisionArg = new AFieldLvalue(new TIdentifier("c_fixedPrecisionAny")); ALvalueExp exp = new ALvalueExp(precisionArg); data.FieldLinks[precisionArg] = data.Libraries.Fields.First(field => field.GetName().Text == precisionArg.GetName().Text); replacementMethod = new ASimpleInvokeExp(new TIdentifier("FixedToText"), new ArrayList { node.GetExp(), exp }); break; case "int"://Implicit case "byte": replacementMethod = new ASimpleInvokeExp(new TIdentifier("IntToText"), new ArrayList { node.GetExp() }); break; case "bool"://Implicit replacementMethod = new ASimpleInvokeExp(new TIdentifier("libNtve_gf_ConvertBooleanToText"), new ArrayList { node.GetExp() }); break; case "string"://Implicit replacementMethod = new ASimpleInvokeExp(new TIdentifier("StringToText"), new ArrayList { node.GetExp() }); break; } break; case "int": switch (fromType) { case "bool": replacementMethod = new ASimpleInvokeExp(new TIdentifier("BoolToInt"), new ArrayList {node.GetExp()}); break; case "fixed": replacementMethod = new ASimpleInvokeExp(new TIdentifier("FixedToInt"), new ArrayList { node.GetExp() }); break; case "string": replacementMethod = new ASimpleInvokeExp(new TIdentifier("StringToInt"), new ArrayList { node.GetExp() }); break; } break; case "fixed": switch (fromType) { case "int"://Already implicit replacementMethod = new ASimpleInvokeExp(new TIdentifier("IntToFixed"), new ArrayList { node.GetExp() }); break; case "string": replacementMethod = new ASimpleInvokeExp(new TIdentifier("StringToFixed"), new ArrayList { node.GetExp() }); break; } break; case "bool": switch (fromType) { case "int": case "byte": case "fixed": //Replace by //exp != 0 AIntConstExp zero = new AIntConstExp(new TIntegerLiteral("0")); ABinopExp binop = new ABinopExp(node.GetExp(), new ANeBinop(new TNeq("!=")), zero); node.ReplaceBy(binop); binop.Apply(this); return; } break; } if (replacementMethod == null) { errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile, LocRM.GetString("ErrorText122") + fromType + LocRM.GetString("ErrorText123") + toType)); throw new ParserException(node.GetToken(), LocRM.GetString("ErrorText121")); } data.SimpleMethodLinks[replacementMethod] = data.Libraries.Methods.First(method => method.GetName().Text == replacementMethod.GetName().Text); data.ExpTypes[replacementMethod] = data.SimpleMethodLinks[replacementMethod].GetReturnType(); node.ReplaceBy(replacementMethod); for (int i = 1; i < replacementMethod.GetArgs().Count; i++) { ((Node)replacementMethod.GetArgs()[i]).Apply(this); } }
public override void CaseAArrayLvalue(AArrayLvalue node) { hadPointer = false; node.GetIndex().Apply(this); if (hadPointer) {//The index is a dynamic int string typeName = ((ANamedType) data.ExpTypes[node.GetIndex()]).AsString(); node.GetIndex().ReplaceBy(CreateDynaicGetStm(typeName)); } node.GetBase().Apply(this); if (hadPointer) { //if (Util.GetAncestor<AAssignmentExp>(node) != null || Util.GetAncestor<APArrayLengthLvalue>(node) != null) { //Todo: Check if the index is within array (runtime) ASimpleInvokeExp intToString = new ASimpleInvokeExp(new TIdentifier("IntToString"), new ArrayList()); intToString.GetArgs().Add(Util.MakeClone(node.GetIndex(), data)); ABinopExp binopExp1 = new ABinopExp(nameExp, new APlusBinop(new TPlus("+")), new AStringConstExp(new TStringLiteral("\"[\""))); ABinopExp binopExp2 = new ABinopExp(binopExp1, new APlusBinop(new TPlus("+")), intToString); ABinopExp binopExp3 = new ABinopExp(binopExp2, new APlusBinop(new TPlus("+")), new AStringConstExp(new TStringLiteral("\"]\""))); data.ExpTypes[binopExp1] = data.ExpTypes[binopExp2] = data.ExpTypes[binopExp3] = data.ExpTypes[binopExp1.GetRight()] = data.ExpTypes[binopExp3.GetRight()] = data.ExpTypes[intToString] =new ANamedType(new TIdentifier("string"), null); data.SimpleMethodLinks[intToString] = data.Libraries.Methods.First(method => method.GetName().Text == intToString.GetName().Text); nameExp = binopExp3; } CheckDynamicLvalue(node); } }
public static AMethodDecl CreateNewObjectMethod(Node node, SharedData data) { if (newObjectMethod != null) return newObjectMethod; /* Insert string CreateNewObject() { //Get next item nr int itemNr = DataTableGetInt(true, "Objects\\Count"); itemNr = itemNr + 1; DataTableSetInt(true, "Objects\\Count", itemNr); DataTableSetBool(true, "Objects\\" + IntToString(itemNr) + "\\Exists", true); return "Objects\\" + IntToString(itemNr); } */ AABlock methodBlock = new AABlock(); AMethodDecl method = new AMethodDecl(new APublicVisibilityModifier(), null, null, null, null, null, new ANamedType(new TIdentifier("string"), null), new TIdentifier("CreateNewObject"), new ArrayList(), methodBlock); ASimpleInvokeExp dataTableGetIntInvoke = new ASimpleInvokeExp(new TIdentifier("DataTableGetInt"), new ArrayList()); ABooleanConstExp trueConst1 = new ABooleanConstExp(new ATrueBool()); dataTableGetIntInvoke.GetArgs().Add(trueConst1); AStringConstExp stringConst1 = new AStringConstExp(new TStringLiteral("\"Objects\\\\Count\"")); dataTableGetIntInvoke.GetArgs().Add(stringConst1); AALocalDecl itemNrDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("int"), null), new TIdentifier("itemNr"), dataTableGetIntInvoke); methodBlock.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), itemNrDecl)); ALocalLvalue itemNrLink1 = new ALocalLvalue(new TIdentifier("itemNr")); ALocalLvalue itemNrLink2 = new ALocalLvalue(new TIdentifier("itemNr")); ALvalueExp itemNrLink2Exp = new ALvalueExp(itemNrLink2); AIntConstExp intConst = new AIntConstExp(new TIntegerLiteral("1")); ABinopExp binop1 = new ABinopExp(itemNrLink2Exp, new APlusBinop(new TPlus("+")), intConst); AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), itemNrLink1, binop1); methodBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment)); ASimpleInvokeExp dataTableSetIntInvoke = new ASimpleInvokeExp(new TIdentifier("DataTableSetInt"), new ArrayList()); ABooleanConstExp trueConst2 = new ABooleanConstExp(new ATrueBool()); dataTableSetIntInvoke.GetArgs().Add(trueConst2); AStringConstExp stringConst2 = new AStringConstExp(new TStringLiteral("\"Objects\\\\Count\"")); dataTableSetIntInvoke.GetArgs().Add(stringConst2); ALocalLvalue itemNrLink3 = new ALocalLvalue(new TIdentifier("itemNr")); ALvalueExp itemNrLink3Exp = new ALvalueExp(itemNrLink3); dataTableSetIntInvoke.GetArgs().Add(itemNrLink3Exp); methodBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), dataTableSetIntInvoke)); ASimpleInvokeExp dataTableSetBoolInvoke = new ASimpleInvokeExp(new TIdentifier("DataTableSetBool"), new ArrayList()); ABooleanConstExp trueConst3 = new ABooleanConstExp(new ATrueBool()); dataTableSetBoolInvoke.GetArgs().Add(trueConst3); AStringConstExp stringConst3 = new AStringConstExp(new TStringLiteral("\"Objects\\\\\"")); ASimpleInvokeExp intToStringInvoke1 = new ASimpleInvokeExp(new TIdentifier("IntToString"), new ArrayList()); ALocalLvalue itemNrLink4 = new ALocalLvalue(new TIdentifier("itemNr")); ALvalueExp itemNrLink4Exp = new ALvalueExp(itemNrLink4); intToStringInvoke1.GetArgs().Add(itemNrLink4Exp); ABinopExp binop2 = new ABinopExp(stringConst3, new APlusBinop(new TPlus("+")), intToStringInvoke1); AStringConstExp stringConst4 = new AStringConstExp(new TStringLiteral("\"\\\\Exists\"")); ABinopExp binop3 = new ABinopExp(binop2, new APlusBinop(new TPlus("+")), stringConst4); dataTableSetBoolInvoke.GetArgs().Add(binop3); ABooleanConstExp trueConst4 = new ABooleanConstExp(new ATrueBool()); dataTableSetBoolInvoke.GetArgs().Add(trueConst4); methodBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), dataTableSetBoolInvoke)); AStringConstExp stringConst5 = new AStringConstExp(new TStringLiteral("\"Objects\\\\\"")); ASimpleInvokeExp intToStringInvoke2 = new ASimpleInvokeExp(new TIdentifier("IntToString"), new ArrayList()); ALocalLvalue itemNrLink5 = new ALocalLvalue(new TIdentifier("itemNr")); ALvalueExp itemNrLink5Exp = new ALvalueExp(itemNrLink5); intToStringInvoke2.GetArgs().Add(itemNrLink5Exp); ABinopExp binop4 = new ABinopExp(stringConst5, new APlusBinop(new TPlus("+")), intToStringInvoke2); methodBlock.GetStatements().Add(new AValueReturnStm(new TReturn("return"), binop4)); AASourceFile sourceFile = Util.GetAncestor<AASourceFile>(node); sourceFile.GetDecl().Add(method); data.Locals[methodBlock] = new List<AALocalDecl>() { itemNrDecl }; data.LocalLinks[itemNrLink1] = data.LocalLinks[itemNrLink2] = data.LocalLinks[itemNrLink3] = data.LocalLinks[itemNrLink4] = data.LocalLinks[itemNrLink5] = itemNrDecl; data.SimpleMethodLinks[dataTableSetIntInvoke] = data.Libraries.Methods.First(m => m.GetName().Text == dataTableSetIntInvoke.GetName().Text); data.SimpleMethodLinks[dataTableGetIntInvoke] = data.Libraries.Methods.First(m => m.GetName().Text == dataTableGetIntInvoke.GetName().Text); data.SimpleMethodLinks[dataTableSetBoolInvoke] = data.Libraries.Methods.First(m => m.GetName().Text == dataTableSetBoolInvoke.GetName().Text); data.SimpleMethodLinks[intToStringInvoke1] = data.SimpleMethodLinks[intToStringInvoke2] = data.Libraries.Methods.First(m => m.GetName().Text == intToStringInvoke1.GetName().Text); data.ExpTypes[stringConst1] = data.ExpTypes[stringConst2] = data.ExpTypes[stringConst3] = data.ExpTypes[stringConst4] = data.ExpTypes[stringConst5] = data.ExpTypes[binop2] = data.ExpTypes[binop3] = data.ExpTypes[binop4] = data.ExpTypes[intToStringInvoke1] = data.ExpTypes[intToStringInvoke2] = new ANamedType(new TIdentifier("string"), null); data.ExpTypes[trueConst1] = data.ExpTypes[trueConst2] = data.ExpTypes[trueConst3] = data.ExpTypes[trueConst4] = new ANamedType(new TIdentifier("bool"), null); data.LvalueTypes[itemNrLink1] = data.LvalueTypes[itemNrLink2] = data.LvalueTypes[itemNrLink3] = data.LvalueTypes[itemNrLink4] = data.LvalueTypes[itemNrLink5] = data.ExpTypes[itemNrLink2Exp] = data.ExpTypes[itemNrLink3Exp] = data.ExpTypes[itemNrLink4Exp] = data.ExpTypes[itemNrLink5Exp] = data.ExpTypes[binop1] = data.ExpTypes[assignment] = data.ExpTypes[dataTableGetIntInvoke] = new ANamedType(new TIdentifier("int"), null); data.ExpTypes[dataTableSetBoolInvoke] = data.ExpTypes[dataTableSetIntInvoke] = new AVoidType(new TVoid("void")); newObjectMethod = method; return newObjectMethod; }
public static AMethodDecl CreateNewArrayMethod(Node node, SharedData data) { if (newArrayMethod != null) return newArrayMethod; if (newObjectMethod == null) CreateNewObjectMethod(node, data); /* Insert * string CreateNewArray(int length) { string id = CreateNewObject(); DataTableSetInt(true, id + "\\Length", length); return id; } */ AALocalDecl lengthDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("int"), null), new TIdentifier("length"), null); AABlock methodBlock = new AABlock(); AMethodDecl method = new AMethodDecl(new APublicVisibilityModifier(), null, null, null, null, null, new ANamedType(new TIdentifier("string"), null), new TIdentifier("CreateNewArray"), new ArrayList() { lengthDecl }, methodBlock); ASimpleInvokeExp createNewObjectInvoke = new ASimpleInvokeExp(new TIdentifier("CreateNewObject"), new ArrayList()); AALocalDecl idDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("string"), null), new TIdentifier("id"), createNewObjectInvoke); methodBlock.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), idDecl)); ASimpleInvokeExp dataTableSetIntInvoke = new ASimpleInvokeExp(new TIdentifier("DataTableSetInt"), new ArrayList()); ABooleanConstExp trueConst = new ABooleanConstExp(new ATrueBool()); dataTableSetIntInvoke.GetArgs().Add(trueConst); ALocalLvalue idLink1 = new ALocalLvalue(new TIdentifier("id")); ALvalueExp idLink1Exp = new ALvalueExp(idLink1); AStringConstExp lengthText = new AStringConstExp(new TStringLiteral("\"\\\\Length\"")); ABinopExp binopExp = new ABinopExp(idLink1Exp, new APlusBinop(new TPlus("+")), lengthText); dataTableSetIntInvoke.GetArgs().Add(binopExp); ALocalLvalue lenghtLink = new ALocalLvalue(new TIdentifier("length")); ALvalueExp lengthLinkExp = new ALvalueExp(lenghtLink); dataTableSetIntInvoke.GetArgs().Add(lengthLinkExp); methodBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), dataTableSetIntInvoke)); ALocalLvalue idLink2 = new ALocalLvalue(new TIdentifier("id")); ALvalueExp idLink2Exp = new ALvalueExp(idLink2); methodBlock.GetStatements().Add(new AValueReturnStm(new TReturn("return"), idLink2Exp)); AASourceFile sourceFile = Util.GetAncestor<AASourceFile>(node); sourceFile.GetDecl().Add(method); data.Methods.Add(new SharedData.DeclItem<AMethodDecl>(sourceFile, method)); data.Locals[methodBlock] = new List<AALocalDecl> { lengthDecl, idDecl }; data.LocalLinks[lenghtLink] = lengthDecl; data.LocalLinks[idLink1] = idDecl; data.LocalLinks[idLink2] = idDecl; data.SimpleMethodLinks[dataTableSetIntInvoke] = data.Libraries.Methods.First(m => m.GetName().Text == dataTableSetIntInvoke.GetName().Text); data.ExpTypes[createNewObjectInvoke] = data.ExpTypes[lengthText] = data.LvalueTypes[idLink1] = data.LvalueTypes[idLink2] = data.ExpTypes[idLink1Exp] = data.ExpTypes[idLink2Exp] = data.ExpTypes[binopExp] = new ANamedType(new TIdentifier("string"), null); data.ExpTypes[trueConst] = new ANamedType(new TIdentifier("bool"), null); data.LvalueTypes[lenghtLink] = data.ExpTypes[lengthLinkExp] = new ANamedType(new TIdentifier("int"), null); data.ExpTypes[dataTableSetIntInvoke] = new AVoidType(new TVoid("void")); data.SimpleMethodLinks[createNewObjectInvoke] = newObjectMethod; newArrayMethod = method; return newArrayMethod; }
public override void CaseASimpleInvokeExp(ASimpleInvokeExp node) { //If any pointers are passed to the method, they are now exposed foreach (PExp arg in node.GetArgs()) { if (arg is ALvalueExp) { currentPointer.Clear(); arg.Apply(this); if (currentPointer.Count > 0) { //Each pointer that is a prefix foreach (List<PointerType> pointer in GetPrefixes(currentPointer)) { if (!Contains(exposedPointers, pointer)) exposedPointers.Add(pointer); } } } } AMethodDecl method = data.SimpleMethodLinks[node]; if (method.GetName().Text == "Wait" || data.Libraries.Methods.Contains(method)) foreach (List<PointerType> exposedPointer in exposedPointers) { setPointers.Remove(exposedPointer); } OutASimpleInvokeExp(node); }
public override void CaseAPointerLvalue(APointerLvalue node) { //Build the list currentPointer.Clear(); base.CaseAPointerLvalue(node); //Todo: insert runtime check here //if (currentPointer.Count == 0 || !setPointers.Contains(MakePointer(currentPointer))) if (!isSet) { PStm pStm = Util.GetAncestor<PStm>(node); if (pStm != null) { AABlock pBlock = (AABlock) pStm.Parent(); /* * if (<pointer> == null) * { * UIDisplayMessage(PlayerGroupAll, messageAreaDebug, StringToText(<filename>[<lineNr>:<pos>] + " null pointer exception")); * int i = 1 / 0; * } */ AASourceFile currentSourceFile = Util.GetAncestor<AASourceFile>(node); node.GetBase().Apply(new MoveMethodDeclsOut("pointerVar", data)); PExp pointer = Util.MakeClone(node.GetBase(), data); ABinopExp cond = new ABinopExp(pointer, new AEqBinop(new TEq("==")), new ANullExp()); AABlock ifBlock = new AABlock(); ASimpleInvokeExp playerGroupAllInvoke = new ASimpleInvokeExp(new TIdentifier("PlayerGroupAll"), new ArrayList()); AFieldLvalue messageAreaDebugLink = new AFieldLvalue(new TIdentifier("c_messageAreaDebug")); ALvalueExp messageAreaDebugLinkExp = new ALvalueExp(messageAreaDebugLink); ASimpleInvokeExp stringToTextInvoke = new ASimpleInvokeExp(new TIdentifier("StringToText"), new ArrayList() { new AStringConstExp( new TStringLiteral("\"" + currentSourceFile . GetName () . Text + "[" + node. GetTokens () . Line + "," + node. GetTokens () . Pos + "]: Null pointer exception\"")) }); ASimpleInvokeExp displayMessageInvoke = new ASimpleInvokeExp( new TIdentifier("UIDisplayMessage"), new ArrayList() {playerGroupAllInvoke, messageAreaDebugLinkExp, stringToTextInvoke}); ifBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), displayMessageInvoke)); ABinopExp iDeclInit = new ABinopExp(new AIntConstExp(new TIntegerLiteral("1")), new ADivideBinop(new TDiv("/")), new AIntConstExp(new TIntegerLiteral("0"))); AALocalDecl iDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("int"), null), new TIdentifier("i"), iDeclInit); ifBlock.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), iDecl)); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new AIfThenStm(new TLParen("("), cond, new ABlockStm(new TLBrace("{"), ifBlock))); data.Locals[ifBlock] = new List<AALocalDecl>(){iDecl}; data.ExpTypes[cond.GetRight()] = new ANullType(); data.ExpTypes[cond] = new ANamedType(new TIdentifier("bool"), null); data.ExpTypes[playerGroupAllInvoke] = new ANamedType(new TIdentifier("playergroup"), null); data.ExpTypes[messageAreaDebugLinkExp] = data.LvalueTypes[messageAreaDebugLink] = data.ExpTypes[iDeclInit] = data.ExpTypes[iDeclInit.GetLeft()] = data.ExpTypes[iDeclInit.GetRight()] = new ANamedType(new TIdentifier("int"), null); data.ExpTypes[stringToTextInvoke] = new ANamedType(new TIdentifier("text"), null); data.ExpTypes[(PExp) stringToTextInvoke.GetArgs()[0]] = new ANamedType(new TIdentifier("string"), null); data.ExpTypes[displayMessageInvoke] = new AVoidType(new TVoid("void")); data.SimpleMethodLinks[playerGroupAllInvoke] = data.Libraries.Methods.Find(m => m.GetName().Text == playerGroupAllInvoke.GetName().Text); data.SimpleMethodLinks[displayMessageInvoke] = data.Libraries.Methods.Find(m => m.GetName().Text == displayMessageInvoke.GetName().Text); data.SimpleMethodLinks[stringToTextInvoke] = data.Libraries.Methods.Find(m => m.GetName().Text == stringToTextInvoke.GetName().Text); data.FieldLinks[messageAreaDebugLink] = data.Libraries.Fields.Find(f => f.GetName().Text == messageAreaDebugLink.GetName().Text); if (currentPointer.Count > 0) { setPointers.Add(MakePointer(currentPointer)); } } } currentPointer.Add(new PointerPointer()); currentPointer = MakePointer(currentPointer); isSet = Contains(setPointers, currentPointer); isExposed = Contains(exposedPointers, currentPointer); //If the currentPointer is in null pointers, report error.. and then again - we might not reach this statement - warning, and runtime check //If the currentPointer is not in setPointers, insert runtime check }
public override void CaseADelegateInvokeExp(ADelegateInvokeExp node) { //Build a list of the possible methods AASourceFile currentFile = Util.GetAncestor<AASourceFile>(node); List<AMethodDecl> methods = new List<AMethodDecl>(); ANamedType type = (ANamedType) finalTrans.data.ExpTypes[node.GetReceiver()]; AMethodDecl delegateMethod = finalTrans.data.DelegateTypeLinks[type]; foreach (KeyValuePair<ADelegateExp, AMethodDecl> delegateCreationPair in finalTrans.data.DelegateCreationMethod) { if (TypeChecking.Assignable(delegateCreationPair.Key.GetType(), type)) { if (!methods.Contains(delegateCreationPair.Value)) methods.Add(delegateCreationPair.Value); } } MoveMethodDeclsOut mover; if (methods.Count == 0) { //Can only remove it if the return value is unused if (!(node.Parent() is AExpStm)) { finalTrans.errors.Add(new ErrorCollection.Error(node.GetToken(), currentFile, LocRM.GetString("Delegates_Text1"))); throw new ParserException(node.GetToken(), "Delegates.OutADelegateInvokeExp"); } mover = new MoveMethodDeclsOut("delegateVar", finalTrans.data); foreach (Node arg in node.GetArgs()) { arg.Apply(mover); } node.Parent().Parent().RemoveChild(node.Parent()); foreach (PStm stm in mover.NewStatements) { stm.Apply(this); } return; } if (methods.Count == 1) { ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("renameMe"), new ArrayList()); while (node.GetArgs().Count > 0) { invoke.GetArgs().Add(node.GetArgs()[0]); } //If we have a struct method, add the pointer from the delegate if (finalTrans.data.StructMethods.Any(str => str.Value.Contains(methods[0]))) { AStructDecl targetStr = finalTrans.data.StructMethods.First(str => str.Value.Contains(methods[0])).Key; AMethodDecl getPointerDecl = GetPointerMethod(targetStr.GetDimention() != null); ASimpleInvokeExp getPointerInvoke = new ASimpleInvokeExp(new TIdentifier("renameMe"), new ArrayList(){node.GetReceiver()}); invoke.GetArgs().Add(getPointerInvoke); finalTrans.data.SimpleMethodLinks[getPointerInvoke] = getPointerDecl; finalTrans.data.ExpTypes[getPointerInvoke] = getPointerDecl.GetReturnType(); } finalTrans.data.SimpleMethodLinks[invoke] = methods[0]; finalTrans.data.ExpTypes[invoke] = methods[0].GetReturnType(); node.ReplaceBy(invoke); return; } //Multiple methods. Make /* * <Methods moved out from reciever> * string delegate = GetMethodPart(<reciever>); * if (delegate == "...") * { * Foo(...); * } * else if (delegate == "...") * { * Bar(..., GetPointerPart(<reciever>); * } * else if(...) * ... * else * { * UIDisplayMessage(PlayerGroupAll(), c_messageAreaDebug, StringToText("[<file>:<line>]: No methods matched delegate.")); * int i = 1/0; * return; * } * */ AABlock block = new AABlock(new ArrayList(), new TRBrace("}")); mover = new MoveMethodDeclsOut("delegateVar", finalTrans.data); node.GetReceiver().Apply(mover); AMethodDecl methodPartMethod = GetMethodMethod(); ASimpleInvokeExp methodPartInvoke = new ASimpleInvokeExp(new TIdentifier("GetMethodPart"), new ArrayList() { Util.MakeClone(node.GetReceiver(), finalTrans.data) }); finalTrans.data.SimpleMethodLinks[methodPartInvoke] = methodPartMethod; finalTrans.data.ExpTypes[methodPartInvoke] = methodPartMethod.GetReturnType(); AALocalDecl methodPartDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("string"), null), new TIdentifier("methodPart"), methodPartInvoke); block.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), methodPartDecl)); //If the invoke's return value is used, get the lvalue PLvalue leftSide; if (node.Parent() is AALocalDecl) { leftSide = new ALocalLvalue(new TIdentifier("renameMe")); finalTrans.data.LocalLinks[(ALocalLvalue) leftSide] = (AALocalDecl) node.Parent(); finalTrans.data.LvalueTypes[leftSide] = new ANamedType(new TIdentifier("string"), null); PStm pStm = Util.GetAncestor<PStm>(node); AABlock pBlock = (AABlock) pStm.Parent(); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm) + 1, new ABlockStm(new TLBrace("{"), block)); node.Parent().RemoveChild(node); } else if (node.Parent() is AAssignmentExp) { AAssignmentExp assignExp = (AAssignmentExp) node.Parent(); leftSide = assignExp.GetLvalue(); leftSide.Apply(mover); PStm pStm = Util.GetAncestor<PStm>(node); pStm.ReplaceBy(new ABlockStm(new TLBrace("{"), block)); } else if (node.Parent() is AExpStm) { //No assignments needed leftSide = null; node.Parent().ReplaceBy(new ABlockStm(new TLBrace("{"), block)); } else { //Create a new local AALocalDecl leftSideDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(delegateMethod.GetReturnType(), finalTrans.data), new TIdentifier("delegateVar"), null); ALocalLvalue leftSideLink = new ALocalLvalue(new TIdentifier("delegateVar")); ALvalueExp leftSideLinkExp = new ALvalueExp(leftSideLink); PStm pStm = Util.GetAncestor<PStm>(node); AABlock pBlock = (AABlock)pStm.Parent(); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ABlockStm(new TLBrace("{"), block)); node.ReplaceBy(leftSideLinkExp); finalTrans.data.LocalLinks[leftSideLink] = leftSideDecl; finalTrans.data.LvalueTypes[leftSideLink] = finalTrans.data.ExpTypes[leftSideLinkExp] = leftSideDecl.GetType(); leftSide = leftSideLink; block.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), leftSideDecl)); } ABlockStm elseBranch; //Make final else branch /* { * UIDisplayMessage(PlayerGroupAll(), c_messageAreaDebug, StringToText("<file>[<line>, <pos>]: No methods matched delegate.")); * IntToString(1/0); * return; * } */ { AABlock innerBlock = new AABlock(new ArrayList(), new TRBrace("}")); ASimpleInvokeExp playerGroupInvoke = new ASimpleInvokeExp(new TIdentifier("PlayerGroupAll"), new ArrayList()); AFieldLvalue messageAreaLink = new AFieldLvalue(new TIdentifier("c_messageAreaDebug")); ALvalueExp messageAreaLinkExp = new ALvalueExp(messageAreaLink); AStringConstExp stringConst = new AStringConstExp( new TStringLiteral("\"" + currentFile.GetName().Text.Replace('\\', '/') + "[" + node.GetToken().Line + ", " + node.GetToken().Pos + "]: Got a null delegate.\"")); ASimpleInvokeExp stringToTextInvoke = new ASimpleInvokeExp(new TIdentifier("StringToText"), new ArrayList() {stringConst}); ASimpleInvokeExp displayMessageInvoke = new ASimpleInvokeExp(new TIdentifier("UIDisplayMessage"), new ArrayList() { playerGroupInvoke, messageAreaLinkExp, stringToTextInvoke }); AIntConstExp intConst1 = new AIntConstExp(new TIntegerLiteral("1")); AIntConstExp intConst2 = new AIntConstExp(new TIntegerLiteral("0")); ABinopExp binop = new ABinopExp(intConst1, new ADivideBinop(new TDiv("/")), intConst2); ASimpleInvokeExp intToStringInvoke = new ASimpleInvokeExp(new TIdentifier("IntToString"), new ArrayList() {binop}); innerBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), displayMessageInvoke)); innerBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), intToStringInvoke)); //innerBlock.GetStatements().Add(new AVoidReturnStm(new TReturn("return"))); elseBranch = new ABlockStm(new TLBrace("{"), innerBlock); finalTrans.data.SimpleMethodLinks[playerGroupInvoke] = finalTrans.data.Libraries.Methods.First(m => m.GetName().Text == playerGroupInvoke.GetName().Text); finalTrans.data.SimpleMethodLinks[stringToTextInvoke] = finalTrans.data.Libraries.Methods.First(m => m.GetName().Text == stringToTextInvoke.GetName().Text); finalTrans.data.SimpleMethodLinks[displayMessageInvoke] = finalTrans.data.Libraries.Methods.First(m => m.GetName().Text == displayMessageInvoke.GetName().Text); finalTrans.data.SimpleMethodLinks[intToStringInvoke] = finalTrans.data.Libraries.Methods.First(m => m.GetName().Text == intToStringInvoke.GetName().Text); finalTrans.data.FieldLinks[messageAreaLink] = finalTrans.data.Libraries.Fields.First(m => m.GetName().Text == messageAreaLink.GetName().Text); finalTrans.data.ExpTypes[playerGroupInvoke] = finalTrans.data.SimpleMethodLinks[playerGroupInvoke].GetReturnType(); finalTrans.data.LvalueTypes[messageAreaLink] = finalTrans.data.ExpTypes[messageAreaLinkExp] = finalTrans.data.FieldLinks[messageAreaLink].GetType(); finalTrans.data.ExpTypes[stringToTextInvoke] = finalTrans.data.SimpleMethodLinks[stringToTextInvoke].GetReturnType(); finalTrans.data.ExpTypes[stringConst] = finalTrans.data.ExpTypes[intToStringInvoke] = new ANamedType(new TIdentifier("string"), null); finalTrans.data.ExpTypes[displayMessageInvoke] = new AVoidType(); finalTrans.data.ExpTypes[intConst1] = finalTrans.data.ExpTypes[intConst2] = finalTrans.data.ExpTypes[binop] = new ANamedType(new TIdentifier("int"), null); } foreach (AMethodDecl method in methods) { /* * if (delegate == "...") * { * Foo(...); * } * else if (delegate == "...") * { * Bar(..., GetPointerPart(<reciever>); * } * else if(...) * ... */ AABlock innerBlock = new AABlock(new ArrayList(), new TRBrace("}")); ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier(method.GetName().Text), new ArrayList()); for (int i = 0; i < node.GetArgs().Count; i++) { PExp arg = (PExp) node.GetArgs()[i]; invoke.GetArgs().Add(Util.MakeClone(arg, finalTrans.data)); } //If we have a struct method, add the pointer from the delegate if (finalTrans.data.StructMethods.Any(str => str.Value.Contains(method))) { AStructDecl targetStr = finalTrans.data.StructMethods.First(str => str.Value.Contains(method)).Key; AMethodDecl getPointerDecl = GetPointerMethod(targetStr.GetDimention() != null); ASimpleInvokeExp getPointerInvoke = new ASimpleInvokeExp(new TIdentifier("renameMe"), new ArrayList() { Util.MakeClone(node.GetReceiver(), data) }); invoke.GetArgs().Add(getPointerInvoke); finalTrans.data.SimpleMethodLinks[getPointerInvoke] = getPointerDecl; finalTrans.data.ExpTypes[getPointerInvoke] = getPointerDecl.GetReturnType(); } finalTrans.data.SimpleMethodLinks[invoke] = method; finalTrans.data.ExpTypes[invoke] = method.GetReturnType(); if (leftSide == null) { innerBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), invoke)); } else { AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), Util.MakeClone(leftSide, finalTrans.data), invoke); finalTrans.data.ExpTypes[assignment] = finalTrans.data.ExpTypes[invoke]; innerBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment)); } ALocalLvalue methodPartLink = new ALocalLvalue(new TIdentifier("methodPart")); ALvalueExp methodPartLinkExp = new ALvalueExp(methodPartLink); AStringConstExp stringConst = new AStringConstExp(new TStringLiteral("\"" + GetName(method) + "\"")); finalTrans.data.LocalLinks[methodPartLink] = methodPartDecl; finalTrans.data.LvalueTypes[methodPartLink] = finalTrans.data.ExpTypes[methodPartLinkExp] = finalTrans.data.ExpTypes[stringConst] = new ANamedType(new TIdentifier("string"), null); ABinopExp binop = new ABinopExp(methodPartLinkExp, new AEqBinop(new TEq("==")), stringConst); finalTrans.data.ExpTypes[binop] = new ANamedType(new TIdentifier("bool"), null); AIfThenElseStm ifThenElse = new AIfThenElseStm(new TLParen("("), binop, new ABlockStm(new TLBrace("{"), innerBlock), elseBranch); elseBranch = new ABlockStm(new TLBrace("{"), new AABlock(new ArrayList() { ifThenElse }, new TRBrace("}"))); } block.GetStatements().Add(elseBranch); }
public override void CaseADeleteStm(ADeleteStm node) { List<Node> visitMeNext = new List<Node>(); APointerType pointer = (APointerType) data.ExpTypes[node.GetExp()]; //Call deconstructor if it exists { AMethodDecl deconstructor = null; if (pointer.GetType() is ANamedType && data.StructTypeLinks.ContainsKey((ANamedType) pointer.GetType())) { AStructDecl str = data.StructTypeLinks[(ANamedType) pointer.GetType()]; deconstructor = data.DeconstructorMap[data.StructDeconstructor[str]]; } else //Look for enrichment deconstructor { foreach (AEnrichmentDecl enrichment in data.Enrichments) { if (Util.TypesEqual(pointer.GetType(), enrichment.GetType(), data)) { foreach (PDecl decl in enrichment.GetDecl()) { if (decl is ADeconstructorDecl) { deconstructor = data.DeconstructorMap[(ADeconstructorDecl) decl]; break; } } if (deconstructor != null) break; } } } if (deconstructor != null) { /* * Convert delete <exp>; to * * var deleteVar = <exp>; * Deconstructor(deleteVar); * delete deleteVar; */ AALocalDecl deleteVarDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType( new TIdentifier(Util.IsIntPointer(node, pointer. GetType(), data) ? "int" : "string"), null), new TIdentifier("deleteVar"), node.GetExp()); ALocalLvalue deleteVarRef = new ALocalLvalue(new TIdentifier("deleteVar")); ALvalueExp deleteVarRefExp = new ALvalueExp(deleteVarRef); node.SetExp(deleteVarRefExp); AABlock pBlock = (AABlock) node.Parent(); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(node), new ALocalDeclStm(new TSemicolon(";"), deleteVarDecl)); data.LocalLinks[deleteVarRef] = deleteVarDecl; data.LvalueTypes[deleteVarRef] = data.ExpTypes[deleteVarRefExp] = data.ExpTypes[deleteVarDecl.GetInit()]; deleteVarRef = new ALocalLvalue(new TIdentifier("deleteVar")); deleteVarRefExp = new ALvalueExp(deleteVarRef); ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier(deconstructor.GetName().Text), new ArrayList() {deleteVarRefExp}); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(node), new AExpStm(new TSemicolon(";"), invoke)); data.LocalLinks[deleteVarRef] = deleteVarDecl; data.LvalueTypes[deleteVarRef] = data.ExpTypes[deleteVarRefExp] = data.ExpTypes[deleteVarDecl.GetInit()]; data.SimpleMethodLinks[invoke] = deconstructor; data.ExpTypes[invoke] = deconstructor.GetReturnType(); visitMeNext.Add(deleteVarDecl); } } if (pointer.GetType() is AArrayTempType || pointer.GetType() is ADynamicArrayType) { //If struct array, delete all struct data PType baseType; if (pointer.GetType() is AArrayTempType) baseType = ((AArrayTempType) pointer.GetType()).GetType(); else baseType = ((ADynamicArrayType)pointer.GetType()).GetType(); PExp pointerString = node.GetExp(); if (Util.IsBulkCopy(baseType)) { node.GetExp().Apply(new MoveMethodDeclsOut("pointerVar", data)); pointerString = node.GetExp(); ANamedType aBaseType = (ANamedType) baseType; /* Add the following * * string deleteMe = node.getExp(); <-- no * int i = 0; * while (i < array.length) * { * DeleteStruct<name>(deleteMe + StringToInt(i)); * i = i + 1; * } * */ //string deleteMe = node.getExp(); /*AALocalDecl deleteMeVar = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("string"), null), new TIdentifier("deleteMe"), node.GetExp());*/ //pointerString = deleteMeVar; //int i = 0; AALocalDecl iVar = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("int"), null), new TIdentifier("i"), new AIntConstExp(new TIntegerLiteral("0"))); //i < array.length ASimpleInvokeExp lenghCall = new ASimpleInvokeExp(new TIdentifier("DataTableGetInt"), new ArrayList()); lenghCall.GetArgs().Add(new ABooleanConstExp(new ATrueBool())); //ALocalLvalue deleteMeUse1 = new ALocalLvalue(new TIdentifier("deleteMeVar")); ABinopExp arrayLengthString = new ABinopExp(Util.MakeClone(pointerString, data), new APlusBinop(new TPlus("+")), new AStringConstExp( new TStringLiteral("\"\\\\Length\""))); lenghCall.GetArgs().Add(arrayLengthString); ALocalLvalue iUse1 = new ALocalLvalue(new TIdentifier("i")); ABinopExp cond = new ABinopExp(new ALvalueExp(iUse1), new ALtBinop(new TLt("<")), lenghCall); //DeleteStruct<name>(deleteMe + StringToInt(i)); //ALocalLvalue deleteMeUse2 = new ALocalLvalue(new TIdentifier("deleteMeVar")); ALocalLvalue iUse2 = new ALocalLvalue(new TIdentifier("i")); ASimpleInvokeExp intToString = new ASimpleInvokeExp(new TIdentifier("IntToString"), new ArrayList()); intToString.GetArgs().Add(new ALvalueExp(iUse2)); ABinopExp binopExp1 = new ABinopExp(Util.MakeClone(pointerString, data), new APlusBinop(new TPlus("+")), new AStringConstExp(new TStringLiteral("\"[\""))); ABinopExp binopExp2 = new ABinopExp(binopExp1, new APlusBinop(new TPlus("+")), intToString); ABinopExp binopExp3 = new ABinopExp(binopExp2, new APlusBinop(new TPlus("+")), new AStringConstExp(new TStringLiteral("\"]\""))); ASimpleInvokeExp deleteStructInvoke = new ASimpleInvokeExp(new TIdentifier("DeleteStruct" + aBaseType.AsIdentifierString()), new ArrayList()); deleteStructInvoke.GetArgs().Add(binopExp3); //i = i + 1; ALocalLvalue iUse3 = new ALocalLvalue(new TIdentifier("i")); ALocalLvalue iUse4 = new ALocalLvalue(new TIdentifier("i")); ABinopExp binopExp = new ABinopExp(new ALvalueExp(iUse4), new APlusBinop(new TPlus("+")), new AIntConstExp(new TIntegerLiteral("1"))); AAssignmentExp assign = new AAssignmentExp(new TAssign("="), iUse3, binopExp); //While (...){...} AABlock innerWhile = new AABlock(); innerWhile.GetStatements().Add(new AExpStm(new TSemicolon(";"), deleteStructInvoke)); innerWhile.GetStatements().Add(new AExpStm(new TSemicolon(";"), assign)); AWhileStm whileStm = new AWhileStm(new TLParen("("), cond, new ABlockStm(new TLBrace("{"), innerWhile)); AABlock pBlock = (AABlock) node.Parent(); //pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(node), new ALocalDeclStm(new TSemicolon(";"), deleteMeVar)); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(node), new ALocalDeclStm(new TSemicolon(";"), iVar)); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(node), whileStm); //visitMeNext.Add(deleteMeVar); visitMeNext.Add(whileStm); data.ExpTypes[iVar.GetInit()] = data.LvalueTypes[iUse1] = data.LvalueTypes[iUse2] = data.LvalueTypes[iUse3] = data.LvalueTypes[iUse4] = data.ExpTypes[cond.GetLeft()] = data.ExpTypes[lenghCall] = data.ExpTypes[(PExp) intToString.GetArgs()[0]] = data.ExpTypes[binopExp.GetLeft()] = data.ExpTypes[binopExp.GetRight()] = data.ExpTypes[binopExp] = data.ExpTypes[assign] = new ANamedType(new TIdentifier("int"), null); data.ExpTypes[(PExp) lenghCall.GetArgs()[0]] = data.ExpTypes[cond] = new ANamedType(new TIdentifier("bool"), null); data.ExpTypes[lenghCall] = // data.LvalueTypes[deleteMeUse1] = // data.LvalueTypes[deleteMeUse2] = data.ExpTypes[arrayLengthString.GetLeft()] = data.ExpTypes[arrayLengthString.GetRight()] = data.ExpTypes[arrayLengthString] = data.ExpTypes[intToString] = data.ExpTypes[binopExp1] = data.ExpTypes[binopExp1.GetLeft()] = data.ExpTypes[binopExp1.GetRight()] = data.ExpTypes[binopExp2] = data.ExpTypes[binopExp3] = data.ExpTypes[binopExp3.GetRight()] = data.ExpTypes[lenghCall] = data.ExpTypes[lenghCall] = data.ExpTypes[lenghCall] = data.ExpTypes[lenghCall] = new ANamedType(new TIdentifier("string"), null); data.ExpTypes[deleteStructInvoke] = new AVoidType(new TVoid("void")); data.Locals[pBlock].Add(iVar); //data.Locals[pBlock].Add(deleteMeVar); data.LocalLinks[iUse1] = data.LocalLinks[iUse2] = data.LocalLinks[iUse3] = data.LocalLinks[iUse4] = iVar; //data.LocalLinks[deleteMeUse1] = // data.LocalLinks[deleteMeUse2] = deleteMeVar; data.SimpleMethodLinks[lenghCall] = data.Libraries.Methods.First(method => method.GetName().Text == lenghCall.GetName().Text); data.SimpleMethodLinks[intToString] = data.Libraries.Methods.First(method => method.GetName().Text == intToString.GetName().Text); AStructDecl structDecl = data.StructTypeLinks[aBaseType]; if (!deleteStructMethod.ContainsKey(structDecl)) CreateDeleteStructMethod(node, structDecl, data); data.SimpleMethodLinks[deleteStructInvoke] = deleteStructMethod[structDecl]; } /* * Convert delete <exp> * to * DeleteArray(<exp>); * */ ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("DeleteArray"), new ArrayList(){pointerString}); /*if (pointerString == null) { invoke.GetArgs().Add(node.GetExp()); } else { ALocalLvalue local = new ALocalLvalue(new TIdentifier("pointerString")); invoke.GetArgs().Add(new ALvalueExp(local)); data.LocalLinks[local] = pointerString; data.LvalueTypes[local] = data.ExpTypes[(PExp) invoke.GetArgs()[0]] = new ANamedType(new TIdentifier("string"), null); }*/ data.ExpTypes[invoke] = new AVoidType(new TVoid("void")); if (deleteArrayMethod == null) CreateDeleteArrayMethod(node, data); data.SimpleMethodLinks[invoke] = deleteArrayMethod; visitMeNext.Add(invoke); node.ReplaceBy(new AExpStm(new TSemicolon(";"), invoke)); } else { //Not array type PExp pointerString = node.GetExp(); bool isIntPointer = Util.IsIntPointer(node, pointer.GetType(), data); bool createdStructDelete = false; if (Util.IsBulkCopy(pointer.GetType())) { node.GetExp().Apply(new MoveMethodDeclsOut("pointerVar", data)); pointerString = node.GetExp(); ANamedType aBaseType = (ANamedType) pointer.GetType(); /* Insert * * string deleteMeVar = node.getExp(); * DeleteStruct<name>(deleteMeVar); * */ /* AALocalDecl deleteMeVar = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("string"), null), new TIdentifier("deleteMe"), node.GetExp());*/ //pointerString = deleteMeVar; //ALocalLvalue deleteMeUse = new ALocalLvalue(new TIdentifier("deleteMeVar")); PExp deleteExp = Util.MakeClone(pointerString, data); AStructDecl structDecl = data.StructTypeLinks[aBaseType]; if (isIntPointer) { GlobalStructVars vars = CreateStructFields(node, structDecl, data); int allocateLimit = int.Parse(structDecl.GetIntDim().Text); if (vars.IdentifierArray != null) { int usedBits = allocateLimit == 0 ? 0 : ((int) Math.Floor(Math.Log(allocateLimit, 2)) + 1); int bitsLeft = 31 - usedBits; int biggestIdentifier = (1 << (bitsLeft + 1)) - 1; AIntConstExp bitsLeftConst = new AIntConstExp(new TIntegerLiteral(bitsLeft.ToString())); deleteExp = new ABinopExp(deleteExp, new ARBitShiftBinop(new TRBitShift(">>")), bitsLeftConst); data.ExpTypes[bitsLeftConst] = data.ExpTypes[deleteExp] = new ANamedType(new TIdentifier("int"), null); } } ASimpleInvokeExp deleteStructInvoke = new ASimpleInvokeExp(new TIdentifier("DeleteStruct" + aBaseType.AsIdentifierString()), new ArrayList()); deleteStructInvoke.GetArgs().Add(deleteExp); AABlock pBlock = (AABlock)node.Parent(); //pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(node), new ALocalDeclStm(new TSemicolon(";"), deleteMeVar)); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(node), new AExpStm(new TSemicolon(";"), deleteStructInvoke)); //visitMeNext.Add(deleteMeVar); visitMeNext.Add(deleteStructInvoke); /*data.ExpTypes[(PExp) deleteStructInvoke.GetArgs()[0]] = data.LvalueTypes[deleteMeUse] = new ANamedType(new TIdentifier("string"), null);*/ data.ExpTypes[deleteStructInvoke] = new AVoidType(new TVoid("void")); //data.Locals[pBlock].Add(deleteMeVar); //data.LocalLinks[deleteMeUse] = deleteMeVar; if (!deleteStructMethod.ContainsKey(structDecl)) CreateDeleteStructMethod(node, structDecl, data); data.SimpleMethodLinks[deleteStructInvoke] = deleteStructMethod[structDecl]; createdStructDelete = true; } if (!isIntPointer) { /* * Convert delete <exp> * to * DeleteSimple(<exp>); * */ ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("DeleteObject"), new ArrayList() {pointerString}); /*if (pointerString == null) { invoke.GetArgs().Add(node.GetExp()); } else { ALocalLvalue local = new ALocalLvalue(new TIdentifier("pointerString")); invoke.GetArgs().Add(new ALvalueExp(local)); data.LocalLinks[local] = pointerString; data.LvalueTypes[local] = data.ExpTypes[(PExp)invoke.GetArgs()[0]] = new ANamedType(new TIdentifier("string"), null); }*/ data.ExpTypes[invoke] = new AVoidType(new TVoid("void")); if (deleteObjectMethod == null) CreateDeleteObjectMethod(node, data); data.SimpleMethodLinks[invoke] = deleteObjectMethod; visitMeNext.Add(invoke); node.ReplaceBy(new AExpStm(new TSemicolon(";"), invoke)); } else if (createdStructDelete) { node.Parent().RemoveChild(node); } else { //There is an enrichment PExp deleteExp = pointerString; AEnrichmentDecl enrichmentDecl = data.EnrichmentTypeLinks[pointer.GetType()]; if (isIntPointer) { GlobalStructVars vars = CreateEnrichmentFields(node, enrichmentDecl, data); int allocateLimit = int.Parse(enrichmentDecl.GetIntDim().Text); if (vars.IdentifierArray != null) { int usedBits = allocateLimit == 0 ? 0 : ((int)Math.Floor(Math.Log(allocateLimit, 2)) + 1); int bitsLeft = 31 - usedBits; AIntConstExp bitsLeftConst = new AIntConstExp(new TIntegerLiteral(bitsLeft.ToString())); deleteExp = new ABinopExp(deleteExp, new ARBitShiftBinop(new TRBitShift(">>")), bitsLeftConst); data.ExpTypes[bitsLeftConst] = data.ExpTypes[deleteExp] = new ANamedType(new TIdentifier("int"), null); } } ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("DeleteObject"), new ArrayList() { deleteExp }); data.ExpTypes[invoke] = new AVoidType(new TVoid("void")); data.SimpleMethodLinks[invoke] = CreateDeleteEnrichmentMethod(node, enrichmentDecl, data); visitMeNext.Add(invoke); node.ReplaceBy(new AExpStm(new TSemicolon(";"), invoke)); } } bool hadPointerPreviously = hadPointer; PExp previosNameExp = nameExp; for (int i = 0; i < visitMeNext.Count; i++) { hadPointer = false; nameExp = null; visitMeNext[i].Apply(this); } hadPointer = hadPointerPreviously; nameExp = previosNameExp; }
public override void CaseASimpleInvokeExp(ASimpleInvokeExp node) { Write(node.GetName().Text + "("); bool first = true; foreach (PExp exp in node.GetArgs()) { if (!first) Write(", "); exp.Apply(this); first = false; } Write(")"); }
public override void OutASimpleInvokeExp(ASimpleInvokeExp node) { if (data.BulkCopyProcessedInvokes.Contains(node)) { base.OutASimpleInvokeExp(node); return; } //If anything needs to be put after the invoke, move it to it's own local decl or exp statement AMethodDecl method = data.SimpleMethodLinks[node]; if (!processedMethods.Contains(method)) CaseAMethodDecl(method); bool moveOut = Util.IsBulkCopy(data.ExpTypes[node]); PType type; if (!moveOut) for (int i = 0; i < node.GetArgs().Count; i++) { PExp arg = (PExp)node.GetArgs()[i]; AALocalDecl formal = (AALocalDecl)method.GetFormals()[i]; type = data.ExpTypes[arg]; if (Util.IsBulkCopy(type) || formal.GetRef() != null || formal.GetOut() != null) { moveOut = true; break; } } if (moveOut && !(node.Parent() is AExpStm || node.Parent() is AALocalDecl)) { PStm pStm = Util.GetAncestor<PStm>(node); AABlock pBlock = (AABlock) pStm.Parent(); //Can not be a void type, since it is not in an expStm AALocalDecl localDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(data.ExpTypes[node], data), new TIdentifier("bulkCopyVar"), null); ALocalLvalue bulkCopyVarRef = new ALocalLvalue(new TIdentifier("bulkCopyVar")); ALvalueExp bulkCopyVarRefExp = new ALvalueExp(bulkCopyVarRef); node.ReplaceBy(bulkCopyVarRefExp); localDecl.SetInit(node); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ALocalDeclStm(new TSemicolon(";"), localDecl)); data.LocalLinks[bulkCopyVarRef] = localDecl; data.LvalueTypes[bulkCopyVarRef] = data.ExpTypes[bulkCopyVarRefExp] = localDecl.GetType(); } //Replace bulk copy arguments with a new pointer for (int i = 0; i < node.GetArgs().Count; i++) { PExp arg = (PExp) node.GetArgs()[i]; AALocalDecl formal = (AALocalDecl) method.GetFormals()[i]; if (oldParameterTypes.ContainsKey(formal)) type = oldParameterTypes[formal];// data.ExpTypes[arg]; else type = formal.GetType(); if (Util.IsBulkCopy(type) || formal.GetRef() != null || formal.GetOut() != null) { if (formal.GetRef() != null && arg is ALvalueExp) { ALvalueExp aArg = (ALvalueExp) arg; if (aArg.GetLvalue() is APointerLvalue) { APointerLvalue pointer = (APointerLvalue) aArg.GetLvalue(); if (Util.TypesEqual(formal.GetType(), data.ExpTypes[pointer.GetBase()], data)) {//Just send the arg aArg.ReplaceBy(pointer.GetBase()); continue; } } } TurnDynamic(arg, formal, oldParameterTypes.ContainsKey(formal) ? oldParameterTypes[formal] : formal.GetType(), formal.GetOut() == null, formal.GetRef() != null || formal.GetOut() != null); } } //Do return stm type = data.ExpTypes[node]; if (Util.IsBulkCopy(type)) { PStm pStm = Util.GetAncestor<PStm>(node); AABlock pBlock = (AABlock)pStm.Parent(); bool isReturnUsed = !(node.Parent() is AExpStm); if (isReturnUsed) { //Make //var bulkCopyVar = <node>(...); //<usage>... *bulkCopyVar ... </usage> //delete bulkCopyVar; bool isArray = type is AArrayTempType; AALocalDecl newLocal = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new APointerType(new TStar("*"), isArray ? new ADynamicArrayType( new TLBracket("["), Util.MakeClone( ((AArrayTempType) type). GetType(), data)) : Util.MakeClone(type, data)), new TIdentifier("bulkCopyVar"), null); data.ExpTypes[node] = newLocal.GetType(); ALocalLvalue newLocalRef; ALvalueExp newLocalRefExp; newLocalRef = new ALocalLvalue(new TIdentifier("bulkCopyVar")); newLocalRefExp = new ALvalueExp(newLocalRef); APointerLvalue newLocalPointer = new APointerLvalue(new TStar("*"), newLocalRefExp); ALvalueExp newLocalPointerExp = new ALvalueExp(newLocalPointer); node.ReplaceBy(newLocalPointerExp); data.LocalLinks[newLocalRef] = newLocal; data.LvalueTypes[newLocalRef] = data.ExpTypes[newLocalRefExp] = newLocal.GetType(); data.LvalueTypes[newLocalPointer] = data.ExpTypes[newLocalPointerExp] = ((APointerType) newLocal.GetType()).GetType(); newLocal.SetInit(node); newLocalRef = new ALocalLvalue(new TIdentifier("bulkCopyVar")); newLocalRefExp = new ALvalueExp(newLocalRef); data.LocalLinks[newLocalRef] = newLocal; data.LvalueTypes[newLocalRef] = data.ExpTypes[newLocalRefExp] = newLocal.GetType(); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ALocalDeclStm(new TSemicolon(";"), newLocal)); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm) + 1, new ADeleteStm(new TDelete("delete"), newLocalRefExp)); } else { //Make delete <node>(...); pStm.ReplaceBy(new ADeleteStm(new TDelete("delete"), node)); } } base.OutASimpleInvokeExp(node); }
public override void OutANonstaticInvokeExp(ANonstaticInvokeExp node) { List<AMethodDecl> candidates = new List<AMethodDecl>(); List<AMethodDecl> implicitCandidates = new List<AMethodDecl>(); List<AMethodDecl> matchingNames = new List<AMethodDecl>(); List<AMethodDecl> delegateCandidates = new List<AMethodDecl>(); List<PType> argTypes = new List<PType>(); foreach (PExp exp in node.GetArgs()) { argTypes.Add(data.ExpTypes[exp]); } PExp baseExp; bool needsVistit = false; Node reciever = node.GetReceiver(); bool visitBaseExp = false; if (node.GetReceiver() is ALvalueExp && ((ALvalueExp)node.GetReceiver()).GetLvalue() is AAmbiguousNameLvalue) { visitBaseExp = true; reciever = ((AAmbiguousNameLvalue) ((ALvalueExp) node.GetReceiver()).GetLvalue()).GetAmbiguous(); } bool matchResize; GetTargets(node.GetName().Text, node.GetName(), reciever, null, argTypes, candidates, out matchResize, implicitCandidates, matchingNames, out baseExp, delegateCandidates, data, errors); if (visitBaseExp && baseExp != null) { node.GetArgs().Add(baseExp); baseExp.Apply(this); node.GetArgs().Remove(baseExp); } if (matchResize) { AArrayResizeExp replacer = new AArrayResizeExp(node.GetName(), baseExp, (PExp) node.GetArgs()[0]); node.ReplaceBy(replacer); data.ExpTypes[replacer] = new ANamedType(new TIdentifier("void"), null); return; } if (implicitCandidates.Count > 0) { //Do the implicit casts for (int i = 0; i < node.GetArgs().Count; i++) { PType argType = data.ExpTypes[(PExp)node.GetArgs()[i]]; AALocalDecl formal = (AALocalDecl)implicitCandidates[0].GetFormals()[i]; PType formalType = formal.GetType(); if (formal.GetOut() != null && !Assignable(formalType, argType) || formal.GetRef() != null && !(Assignable(argType, formalType) && Assignable(formalType, argType)) || formal.GetOut() == null && formal.GetRef() == null && !Assignable(argType, formalType)) { PExp exp = (PExp)node.GetArgs()[i]; ACastExp cast = new ACastExp(new TLParen("("), Util.MakeClone(formalType, data), null); exp.ReplaceBy(cast); cast.SetExp(exp); OutACastExp(cast); } } } if (delegateCandidates.Count > 0) {//Target is a delegate invoke ADelegateInvokeExp replacer = new ADelegateInvokeExp(node.GetName(), baseExp, new ArrayList()); while (node.GetArgs().Count > 0) { replacer.GetArgs().Add(node.GetArgs()[0]); } data.ExpTypes[replacer] = delegateCandidates[0].GetReturnType(); node.ReplaceBy(replacer); return; } AMethodDecl candidate = candidates.Count == 1 ? candidates[0] : implicitCandidates[0]; if (baseExp == null) { //Replace with a simple invoke to it. ASimpleInvokeExp replacementInvoke = new ASimpleInvokeExp(node.GetName(), new ArrayList()); while (node.GetArgs().Count > 0) { replacementInvoke.GetArgs().Add(node.GetArgs()[0]); } data.SimpleMethodLinks[replacementInvoke] = candidate; data.ExpTypes[replacementInvoke] = candidate.GetReturnType(); node.ReplaceBy(replacementInvoke); CheckInvoke(replacementInvoke, candidate); return; } node.SetReceiver(baseExp); data.StructMethodLinks[node] = candidate; data.ExpTypes[node] = candidate.GetReturnType(); if (candidate.GetInline() != null) { AMethodDecl pMethod = Util.GetAncestor<AMethodDecl>(node); AConstructorDecl pConstructor = Util.GetAncestor<AConstructorDecl>(node); APropertyDecl pProperty = Util.GetAncestor<APropertyDecl>(node); if (pMethod == null && pConstructor == null && pProperty == null && !Util.HasAncestor<ADeconstructorDecl>(node)) { errors.Add(new ErrorCollection.Error(node.GetName(), currentSourceFile, LocRM.GetString("ErrorText133"))); } else if (pMethod != null && !InlineMethodCalls[pMethod].Contains(candidate)) InlineMethodCalls[pMethod].Add(candidate); } base.OutANonstaticInvokeExp(node); }
public override void CaseANewExp(ANewExp node) { //Call new object or new array ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("invoke"), new ArrayList()); ANamedType pointerType = new ANamedType(new TIdentifier("string"), null); if (node.GetType() is AArrayTempType) { if (newArrayMethod == null) CreateNewArrayMethod(node, data); node.GetType().Apply(this); AArrayTempType type = (AArrayTempType) node.GetType(); invoke.GetArgs().Add(Util.MakeClone(type.GetDimention(), data)); data.SimpleMethodLinks[invoke] = newArrayMethod; } else if (Util.IsIntPointer(node, node.GetType(), data)) { if (node.GetType() is ANamedType && data.StructTypeLinks.ContainsKey((ANamedType) node.GetType())) data.SimpleMethodLinks[invoke] = CreateNewObjectMethod(node, data.StructTypeLinks[(ANamedType) node.GetType()], data); else { data.SimpleMethodLinks[invoke] = CreateNewObjectMethod(node, data.EnrichmentTypeLinks[node.GetType()], data); } pointerType = new ANamedType(new TIdentifier("int"), null); } else { if (newObjectMethod == null) CreateNewObjectMethod(node, data); data.SimpleMethodLinks[invoke] = newObjectMethod; } node.ReplaceBy(invoke); data.ExpTypes[invoke] = pointerType; //Call initializer if (data.ConstructorLinks.ContainsKey(node)) { PStm pStm = Util.GetAncestor<PStm>(invoke); AABlock pblock = (AABlock) pStm.Parent(); PLvalue lvalue; ALvalueExp lvalueExp; PStm stm; AAssignmentExp assignment = null; AALocalDecl localDecl = null; if (invoke.Parent() is AAssignmentExp) { AAssignmentExp parent = (AAssignmentExp) invoke.Parent(); assignment = parent; /*lvalue = parent.GetLvalue(); lvalue.Apply(new MoveMethodDeclsOut("pointerVar", data)); lvalue = Util.MakeClone(lvalue, data);*/ } else if (invoke.Parent() is AALocalDecl) { AALocalDecl parent = (AALocalDecl) invoke.Parent(); localDecl = parent; /*lvalue = new ALocalLvalue(new TIdentifier(parent.GetName().Text)); data.LocalLinks[(ALocalLvalue) lvalue] = parent; data.LvalueTypes[lvalue] = parent.GetType();*/ } else { //Move the new invocation out into a local decl, and use that localDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(pointerType, data), new TIdentifier("newVar"), null); ALocalLvalue localLvalue = new ALocalLvalue(new TIdentifier("newVar")); lvalueExp = new ALvalueExp(localLvalue); invoke.ReplaceBy(lvalueExp); localDecl.SetInit(invoke); stm = new ALocalDeclStm(new TSemicolon(";"), localDecl); pblock.GetStatements().Insert(pblock.GetStatements().IndexOf(pStm), stm); pStm = stm; //lvalue = new ALocalLvalue(new TIdentifier("newVar")); //data.LocalLinks[(ALocalLvalue) lvalue] = data.LocalLinks[localLvalue] = localDecl; //data.LvalueTypes[lvalue] = data.LvalueTypes[localLvalue] = data.ExpTypes[lvalueExp] = localDecl.GetType(); } ASimpleInvokeExp oldInvoke = invoke; invoke = new ASimpleInvokeExp(new TIdentifier("renameMe"), new ArrayList()); while (node.GetArgs().Count > 0) { invoke.GetArgs().Add(node.GetArgs()[0]); } if (assignment != null) { assignment.SetExp(invoke); invoke.GetArgs().Add(oldInvoke); } else { localDecl.SetInit(invoke); invoke.GetArgs().Add(oldInvoke); } //lvalueExp = new ALvalueExp(lvalue); //invoke.GetArgs().Add(lvalueExp); //stm = new AExpStm(new TSemicolon(";"), invoke); //pblock.GetStatements().Insert(pblock.GetStatements().IndexOf(pStm) + 1, stm); //data.ExpTypes[lvalueExp] = data.LvalueTypes[lvalue]; data.SimpleMethodLinks[invoke] = data.ConstructorMap[data.ConstructorLinks[node]]; data.ExpTypes[invoke] = data.ConstructorMap[data.ConstructorLinks[node]].GetReturnType(); invoke.Apply(this); } }
private void CheckInvoke(ASimpleInvokeExp node, AMethodDecl target) { if (target.GetInline() != null) { AMethodDecl pMethod = Util.GetAncestor<AMethodDecl>(node); AConstructorDecl pConstructor = Util.GetAncestor<AConstructorDecl>(node); ADeconstructorDecl pDeconstructor = Util.GetAncestor<ADeconstructorDecl>(node); if (pMethod == null && !Util.HasAncestor<AConstructorDecl>(node) && !Util.HasAncestor<ADeconstructorDecl>(node) && !Util.HasAncestor<APropertyDecl>(node)) { errors.Add(new ErrorCollection.Error(node.GetName(), currentSourceFile, LocRM.GetString("ErrorText131"))); } else if (pMethod != null && !InlineMethodCalls[pMethod].Contains(target)) InlineMethodCalls[pMethod].Add(target); } //For each formal marked as ref or out, the argument must be a non-const variable for (int i = 0; i < node.GetArgs().Count; i++) { AALocalDecl formal = (AALocalDecl)target.GetFormals()[i]; if (formal.GetRef() != null || formal.GetOut() != null) { PExp exp = (PExp)node.GetArgs()[i]; while (true) { PLvalue lvalue; if (exp is ALvalueExp) { lvalue = ((ALvalueExp)exp).GetLvalue(); } else if (exp is AAssignmentExp) { lvalue = ((AAssignmentExp)exp).GetLvalue(); } else { errors.Add(new ErrorCollection.Error(node.GetName(), currentSourceFile, LocRM.GetString("ErrorText129") + (i + 1) + LocRM.GetString("ErrorText130"))); break; } if (lvalue is ALocalLvalue) { if (data.LocalLinks[(ALocalLvalue)lvalue].GetConst() != null) errors.Add(new ErrorCollection.Error(node.GetName(), currentSourceFile, LocRM.GetString("ErrorText129") + (i + 1) + LocRM.GetString("ErrorText132"))); break; } if (lvalue is AFieldLvalue) { if (data.FieldLinks[(AFieldLvalue)lvalue].GetConst() != null) errors.Add(new ErrorCollection.Error(node.GetName(), currentSourceFile, LocRM.GetString("ErrorText129") + (i + 1) + LocRM.GetString("ErrorText132"))); break; } if (lvalue is AStructFieldLvalue) { if (data.StructMethodFieldLinks[(AStructFieldLvalue)lvalue].GetConst() != null) errors.Add(new ErrorCollection.Error(node.GetName(), currentSourceFile, LocRM.GetString("ErrorText129") + (i + 1) + LocRM.GetString("ErrorText132"))); break; } if (lvalue is AThisLvalue) break; if (lvalue is AStructLvalue) { exp = ((AStructLvalue)lvalue).GetReceiver(); continue; } if (lvalue is AArrayLvalue) { exp = ((AArrayLvalue)lvalue).GetBase(); continue; } if (lvalue is APointerLvalue) { exp = ((APointerLvalue)lvalue).GetBase(); continue; } throw new Exception("Unexpected lvalue"); } } } }
private PExp CreateDynaicSetStm(string type, PExp target, PExp arg) { string upperType = char.ToUpper(type[0]) + type.Substring(1); //Create a data table get string exp ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("DataTableSet" + upperType), new ArrayList()); invoke.GetArgs().Add(new ABooleanConstExp(new ATrueBool())); invoke.GetArgs().Add(target); invoke.GetArgs().Add(arg); data.ExpTypes[invoke] = new AVoidType(new TVoid("void")); data.ExpTypes[(PExp)invoke.GetArgs()[0]] = new ANamedType(new TIdentifier("bool"), null); data.SimpleMethodLinks[invoke] = data.Libraries.Methods.First(method => method.GetName().Text == invoke.GetName().Text); return invoke; }
public override void OutAAProgram(AAProgram node) { if (strings.Count == 0) return; //Obfuscate all strings List<string> obfuscated = new List<string>(); foreach (AStringConstExp stringConstExp in strings) { TStringLiteral token = stringConstExp.GetStringLiteral(); string s = token.Text.Substring(1, token.Text.Length - 2); obfuscated.Add(Obfuscate(s)); } //Set invokes instead of string constants, and move varaiabes down List<AFieldDecl> ignoredFields = new List<AFieldDecl>(); List<AFieldDecl> moveFieldsIn = new List<AFieldDecl>(); Dictionary<AFieldDecl, AMethodDecl> fieldMethods = new Dictionary<AFieldDecl, AMethodDecl>(); for (int i = 0; i < strings.Count; i++) { AStringConstExp stringExp = strings[i]; Token token = stringExp.GetStringLiteral(); bool inDeobfuscator = Util.GetAncestor<AMethodDecl>(stringExp) == finalTrans.data.DeobfuscateMethod; if (inDeobfuscator) { AFieldDecl field = finalTrans.data.UnobfuscatedStrings[stringExp]; AStringConstExp newStringConst = new AStringConstExp(stringExp.GetStringLiteral()); field.SetInit(newStringConst); AFieldLvalue fieldRef = new AFieldLvalue(new TIdentifier(field.GetName().Text, token.Line, token.Pos)); finalTrans.data.FieldLinks[fieldRef] = field; stringExp.ReplaceBy(new ALvalueExp(fieldRef)); } else { AFieldDecl field; if (!finalTrans.data.ObfuscatedStrings.ContainsKey(stringExp)) { int line = -finalTrans.data.ObfuscatedStrings.Count - 1; field = new AFieldDecl(new APublicVisibilityModifier(), null, new TConst("const", line, 0), new ANamedType(new TIdentifier("string", line, 1), null), new TIdentifier("Galaxy_pp_stringO" + finalTrans.data.ObfuscatedStrings.Count), null); //If the strings are the same - point them to same field bool newField = true; foreach (AStringConstExp oldStringConstExp in finalTrans.data.ObfuscatedStrings.Keys) { if (stringExp.GetStringLiteral().Text == oldStringConstExp.GetStringLiteral().Text) { field = finalTrans.data.ObfuscatedStrings[oldStringConstExp]; newField = false; break; } } if (newField) { AASourceFile file = (AASourceFile)finalTrans.data.DeobfuscateMethod.Parent(); file.GetDecl().Insert(file.GetDecl().IndexOf(finalTrans.data.DeobfuscateMethod) + 1, field); finalTrans.data.Fields.Add(new SharedData.DeclItem<AFieldDecl>(file, field)); } finalTrans.data.ObfuscatedStrings.Add(stringExp, field); } field = finalTrans.data.ObfuscatedStrings[stringExp]; string obfuscatedString = obfuscated[i]; ASimpleInvokeExp invoke = new ASimpleInvokeExp(); invoke.SetName(new TIdentifier(finalTrans.data.DeobfuscateMethod.GetName().Text, stringExp.GetStringLiteral().Line, stringExp.GetStringLiteral().Pos)); AStringConstExp newStringConst = new AStringConstExp(new TStringLiteral("\"" + obfuscatedString + "\"")); invoke.GetArgs().Add(newStringConst); finalTrans.data.SimpleMethodLinks[invoke] = finalTrans.data.DeobfuscateMethod; if (Util.GetAncestor<PStm>(stringExp) == null && false) { ignoredFields.Add(field); /*if (Util.GetAncestor<ASimpleInvokeExp>(stringExp) == null) stringExp.ReplaceBy(invoke);*/ //Add obfuscate call to this location); continue; /*ASimpleInvokeExp invoke = new ASimpleInvokeExp(); invoke.SetName(new TIdentifier(finalTrans.data.DeobfuscateMethod.GetName().Text, stringExp.GetStringLiteral().Line, stringExp.GetStringLiteral().Pos)); AStringConstExp newStringConst = new AStringConstExp(new TStringLiteral("\"" + obfuscatedString + "\"")); invoke.GetArgs().Add(newStringConst); stringExp.ReplaceBy(invoke); finalTrans.data.SimpleMethodLinks[invoke] = finalTrans.data.DeobfuscateMethod; continue;*/ } if (field.GetInit() == null) { /*field.SetInit(invoke); field.SetConst(null);*/ if ( stringExp.GetStringLiteral().Text.Remove(0, 1).Substring(0, stringExp.GetStringLiteral().Text. Length - 2) == "") { //Make method /* string <field>Method() { return ""; } * */ ANullExp nullExp = new ANullExp(); field.SetInit(nullExp); field.SetConst(null); AStringConstExp stringConst = new AStringConstExp(new TStringLiteral("\"\"")); AMethodDecl method = new AMethodDecl(new APublicVisibilityModifier(), null, null, null, null, null, new ANamedType(new TIdentifier("string"), null), new TIdentifier("Get" + field.GetName()), new ArrayList(), new AABlock( new ArrayList() { new AValueReturnStm(new TReturn("return"), stringConst) }, new TRBrace("}"))); AASourceFile pFile = (AASourceFile)field.Parent(); pFile.GetDecl().Insert(pFile.GetDecl().IndexOf(field) + 1, method); finalTrans.data.ExpTypes[stringConst] = new ANamedType(new TIdentifier("string"), null); finalTrans.data.ExpTypes[nullExp] = new ANamedType(new TIdentifier("null"), null); fieldMethods[field] = method; } else { //Make method /* string <field>Method() { if (field == null) { field = Invoke; } if (field == null) { return Invoke; } return field; } */ ANullExp nullExp1 = new ANullExp(); field.SetInit(nullExp1); field.SetConst(null); ANullExp nullExp2 = new ANullExp(); AFieldLvalue fieldRef1 = new AFieldLvalue(new TIdentifier(field.GetName().Text)); AFieldLvalue fieldRef2 = new AFieldLvalue(new TIdentifier(field.GetName().Text)); AFieldLvalue fieldRef3 = new AFieldLvalue(new TIdentifier(field.GetName().Text)); ALvalueExp fieldRef1Exp = new ALvalueExp(fieldRef1); ALvalueExp fieldRef3Exp = new ALvalueExp(fieldRef3); ABinopExp binop1 = new ABinopExp(fieldRef1Exp, new AEqBinop(new TEq("==")), nullExp2); AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), fieldRef2, invoke); AIfThenStm ifStm1 = new AIfThenStm(new TLParen("("), binop1, new ABlockStm(new TLBrace("{"), new AABlock( new ArrayList() { new AExpStm(new TSemicolon(";"), assignment) }, new TRBrace("}")))); /*ANullExp nullExp3 = new ANullExp(); AFieldLvalue fieldRef4 = new AFieldLvalue(new TIdentifier(field.GetName().Text)); ALvalueExp fieldRef4Exp = new ALvalueExp(fieldRef4); AStringConstExp invokeArgClone = new AStringConstExp(new TStringLiteral("\"" + obfuscatedString + "\"")); ASimpleInvokeExp invokeClone = new ASimpleInvokeExp(new TIdentifier(invoke.GetName().Text), new ArrayList() { invokeArgClone }); finalTrans.data.SimpleMethodLinks[invokeClone] = finalTrans.data.DeobfuscateMethod; ABinopExp binop2 = new ABinopExp(fieldRef4Exp, new AEqBinop(new TEq("==")), nullExp3); AIfThenStm ifStm2 = new AIfThenStm(new TLParen("("), binop2, new ABlockStm(new TLBrace("{"), new AABlock( new ArrayList() { new AValueReturnStm(new TReturn("return"), invokeClone) }, new TRBrace("}"))));*/ AMethodDecl method = new AMethodDecl(new APublicVisibilityModifier(), null, null, null, null, null, new ANamedType(new TIdentifier("string"), null), new TIdentifier("Get" + field.GetName()), new ArrayList(), new AABlock( new ArrayList() { ifStm1, //ifStm2, new AValueReturnStm(new TReturn("return"), fieldRef3Exp) }, new TRBrace("}"))); AASourceFile pFile = (AASourceFile) field.Parent(); pFile.GetDecl().Insert(pFile.GetDecl().IndexOf(field) + 1, method); finalTrans.data.FieldLinks[fieldRef1] = finalTrans.data.FieldLinks[fieldRef2] = finalTrans.data.FieldLinks[fieldRef3] = /*finalTrans.data.FieldLinks[fieldRef4] = */field; finalTrans.data.LvalueTypes[fieldRef1] = finalTrans.data.LvalueTypes[fieldRef2] = finalTrans.data.LvalueTypes[fieldRef3] = //finalTrans.data.LvalueTypes[fieldRef4] = finalTrans.data.ExpTypes[fieldRef1Exp] = finalTrans.data.ExpTypes[fieldRef3Exp] = //finalTrans.data.ExpTypes[fieldRef4Exp] = finalTrans.data.ExpTypes[assignment] = field.GetType(); finalTrans.data.ExpTypes[nullExp1] = finalTrans.data.ExpTypes[nullExp2] = /*finalTrans.data.ExpTypes[nullExp3] =*/ new ANamedType(new TIdentifier("null"), null); finalTrans.data.ExpTypes[binop1] = /*finalTrans.data.ExpTypes[binop2] = */new ANamedType(new TIdentifier("bool"), null); fieldMethods[field] = method; } /* AFieldLvalue fieldRef = new AFieldLvalue(new TIdentifier(field.GetName().Text, token.Line, token.Pos)); finalTrans.data.FieldLinks[fieldRef] = field;*/ //stringExp.ReplaceBy(new ALvalueExp(fieldRef)); } ASimpleInvokeExp invoke2 = new ASimpleInvokeExp(new TIdentifier(fieldMethods[field].GetName().Text), new ArrayList()); finalTrans.data.SimpleMethodLinks[invoke2] = fieldMethods[field]; stringExp.ReplaceBy(invoke2); //If we are in a field, move it in if (Util.GetAncestor<AFieldDecl>(invoke2) != null) moveFieldsIn.Add(Util.GetAncestor<AFieldDecl>(invoke2)); } } foreach (AFieldDecl field in finalTrans.data.ObfuscationFields) { if (field.GetInit() == null && field.Parent() != null) { field.Parent().RemoveChild(field); } } //A constant field, or a field used by a constant field cannot be moved in List<AFieldDecl> constantFields = new List<AFieldDecl>(); foreach (SharedData.DeclItem<AFieldDecl> field in finalTrans.data.Fields) { if (field.Decl.GetConst() != null) constantFields.Add(field.Decl); } for (int i = 0; i < constantFields.Count; i++) { GetFieldLvalues lvalues = new GetFieldLvalues(); constantFields[i].Apply(lvalues); foreach (AFieldLvalue lvalue in lvalues.Lvalues) { AFieldDecl field = finalTrans.data.FieldLinks[lvalue]; if (!constantFields.Contains(field)) constantFields.Add(field); } } moveFieldsIn.RemoveAll(constantFields.Contains); Dictionary<AFieldDecl, List<AFieldDecl>> dependancies = new Dictionary<AFieldDecl, List<AFieldDecl>>(); //Order the fields so any dependancies are instansiated first foreach (AFieldDecl field in moveFieldsIn) { dependancies.Add(field, new List<AFieldDecl>()); GetFieldLvalues lvalues = new GetFieldLvalues(); field.Apply(lvalues); foreach (AFieldLvalue lvalue in lvalues.Lvalues) { AFieldDecl dependancy = finalTrans.data.FieldLinks[lvalue]; if (!dependancies[field].Contains(dependancy)) dependancies[field].Add(dependancy); } } List<PStm> newStatements = new List<PStm>(); while (dependancies.Keys.Count > 0) { AFieldDecl field = dependancies.FirstOrDefault(f1 => f1.Value.Count == 0).Key ?? dependancies.Keys.First(f => true); AFieldLvalue fieldRef = new AFieldLvalue(new TIdentifier(field.GetName().Text)); AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), fieldRef, field.GetInit()); field.SetInit(null); newStatements.Add(new AExpStm(new TSemicolon(";"), assignment)); finalTrans.data.FieldLinks[fieldRef] = field; finalTrans.data.LvalueTypes[fieldRef] = finalTrans.data.ExpTypes[assignment] = field.GetType(); foreach (KeyValuePair<AFieldDecl, List<AFieldDecl>> dependancy in dependancies) { if (dependancy.Value.Contains(field)) dependancy.Value.Remove(field); } dependancies.Remove(field); } AABlock initBody = (AABlock) finalTrans.mainEntry.GetBlock(); for (int i = newStatements.Count - 1; i >= 0; i--) { initBody.GetStatements().Insert(0, newStatements[i]); } }
public static List<AABlock> Inline(ASimpleInvokeExp node, FinalTransformations finalTrans) { /*if (Util.GetAncestor<AMethodDecl>(node) != null && Util.GetAncestor<AMethodDecl>(node).GetName().Text == "UIChatFrame_LeaveChannel") node = node;*/ SharedData data = finalTrans.data; //If this node is inside the condition of a while, replace it with a new local var, //make a clone before the while, one before each continue in the while, and one at the end of the while //(unless the end is a return or break) AABlock pBlock; if (Util.HasAncestor<AWhileStm>(node)) { AWhileStm whileStm = Util.GetAncestor<AWhileStm>(node); if (Util.IsAncestor(node, whileStm.GetCondition())) { List<ASimpleInvokeExp> toInline = new List<ASimpleInvokeExp>(); //Above while AALocalDecl replaceVarDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(data.ExpTypes[node], data), new TIdentifier("whileVar"), null); ALocalLvalue replaceVarRef = new ALocalLvalue(new TIdentifier("whileVar")); ALvalueExp replaceVarRefExp = new ALvalueExp(replaceVarRef); data.LocalLinks[replaceVarRef] = replaceVarDecl; data.ExpTypes[replaceVarRefExp] = data.LvalueTypes[replaceVarRef] = replaceVarDecl.GetType(); node.ReplaceBy(replaceVarRefExp); replaceVarDecl.SetInit(node); pBlock = (AABlock) whileStm.Parent(); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(whileStm), new ALocalDeclStm(new TSemicolon(";"), replaceVarDecl)); toInline.Add(node); //In the end of the while PStm lastStm = whileStm.GetBody(); while (lastStm is ABlockStm) { AABlock block = (AABlock) ((ABlockStm) lastStm).GetBlock(); if (block.GetStatements().Count == 0) { lastStm = null; break; } lastStm = (PStm) block.GetStatements()[block.GetStatements().Count - 1]; } if (lastStm == null || !(lastStm is AValueReturnStm || lastStm is AVoidReturnStm || lastStm is ABreakStm)) { lastStm = whileStm.GetBody(); AABlock block; if (lastStm is ABlockStm) { block = (AABlock)((ABlockStm)lastStm).GetBlock(); } else { block = new AABlock(new ArrayList(), new TRBrace("}")); block.GetStatements().Add(lastStm); whileStm.SetBody(new ABlockStm(new TLBrace("{"), block)); } replaceVarRef = new ALocalLvalue(new TIdentifier("whileVar")); ASimpleInvokeExp clone = (ASimpleInvokeExp)Util.MakeClone(node, data); toInline.Add(clone); AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), replaceVarRef, clone); data.LocalLinks[replaceVarRef] = replaceVarDecl; data.ExpTypes[assignment] = data.LvalueTypes[replaceVarRef] = replaceVarDecl.GetType(); block.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment)); } //After each continue CloneBeforeContinue cloner = new CloneBeforeContinue(node, replaceVarDecl, data); whileStm.GetBody().Apply(cloner); toInline.AddRange(cloner.replacementExpressions); List<AABlock> visitBlocks = new List<AABlock>(); foreach (ASimpleInvokeExp invoke in toInline) { visitBlocks.AddRange(Inline(invoke, finalTrans)); } return visitBlocks; } } AMethodDecl decl = finalTrans.data.SimpleMethodLinks[node]; FindAssignedToFormals assignedToFormalsFinder = new FindAssignedToFormals(finalTrans.data); decl.Apply(assignedToFormalsFinder); List<AALocalDecl> assignedToFormals = assignedToFormalsFinder.AssignedFormals; /* * inline int foo(int a) * { * int b = 2; * int c; * ... * while(...) * { * ... * break; * ... * return c; * } * ... * return 2; * } * * bar(foo(<arg for a>)); * -> * * { * bool inlineMethodReturned = false; * int inlineReturner; * int a = <arg for a>; * while (!inlineMethodReturned) * { * int b = 2; * int c; * ... * while(...) * { * ... * break * ... * inlineReturner = c; * inlineMethodReturned = true; * break; * } * if (inlineMethodReturned) * { * break; * } * ... * inlineReturner = 2; * inlineMethodReturned = true; * break; * break; * } * bar(inlineReturner); * } * * */ AABlock outerBlock = new AABlock(); PExp exp = new ABooleanConstExp(new AFalseBool()); finalTrans.data.ExpTypes[exp] = new ANamedType(new TIdentifier("bool"), null); AALocalDecl hasMethodReturnedVar = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("bool"), null), new TIdentifier("hasInlineReturned"), exp); finalTrans.data.GeneratedVariables.Add(hasMethodReturnedVar); PStm stm = new ALocalDeclStm(new TSemicolon(";"), hasMethodReturnedVar); outerBlock.GetStatements().Add(stm); AALocalDecl methodReturnerVar = null; if (!(decl.GetReturnType() is AVoidType)) { methodReturnerVar = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(decl.GetReturnType(), finalTrans.data), new TIdentifier("inlineReturner"), null); stm = new ALocalDeclStm(new TSemicolon(";"), methodReturnerVar); outerBlock.GetStatements().Add(stm); } AABlock afterBlock = new AABlock(); //A dictionary from the formals of the inline method to a cloneable replacement lvalue Dictionary<AALocalDecl, PLvalue> Parameters = new Dictionary<AALocalDecl, PLvalue>(); Dictionary<AALocalDecl, PExp> ParameterExps = new Dictionary<AALocalDecl, PExp>(); for (int i = 0; i < decl.GetFormals().Count; i++) { AALocalDecl formal = (AALocalDecl)decl.GetFormals()[i]; PExp arg = (PExp)node.GetArgs()[0]; PLvalue lvalue; //if ref, dont make a new var if (formal.GetRef() != null && arg is ALvalueExp) { arg.Apply(new MoveMethodDeclsOut("inlineVar", finalTrans.data)); arg.Parent().RemoveChild(arg); lvalue = ((ALvalueExp) arg).GetLvalue(); } else if (!assignedToFormals.Contains(formal) && Util.IsLocal(arg, finalTrans.data)) { lvalue = new ALocalLvalue(new TIdentifier("I hope I dont make it")); finalTrans.data.LvalueTypes[lvalue] = formal.GetType(); finalTrans.data.LocalLinks[(ALocalLvalue) lvalue] = formal; ParameterExps[formal] = arg; arg.Parent().RemoveChild(arg); } else { AAssignmentExp assExp = null; if (formal.GetOut() != null) { //Dont initialize with arg, but assign arg after arg.Apply(new MoveMethodDeclsOut("inlineVar", finalTrans.data)); lvalue = ((ALvalueExp)arg).GetLvalue(); assExp = new AAssignmentExp(new TAssign("="), lvalue, null); finalTrans.data.ExpTypes[assExp] = finalTrans.data.LvalueTypes[lvalue]; arg.Parent().RemoveChild(arg); arg = null; } AALocalDecl parameter = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(formal.GetType(), finalTrans.data), new TIdentifier(formal.GetName().Text), arg); stm = new ALocalDeclStm(new TSemicolon(";"), parameter); outerBlock.GetStatements().Add(stm); lvalue = new ALocalLvalue(new TIdentifier(parameter.GetName().Text)); finalTrans.data.LvalueTypes[lvalue] = parameter.GetType(); finalTrans.data.LocalLinks[(ALocalLvalue)lvalue] = parameter; if (formal.GetOut() != null) { //Dont initialize with arg, but assign arg after ALvalueExp lvalueExp = new ALvalueExp(Util.MakeClone(lvalue, finalTrans.data)); finalTrans.data.ExpTypes[lvalueExp] = finalTrans.data.LvalueTypes[lvalue]; assExp.SetExp(lvalueExp); afterBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assExp)); } } Parameters.Add(formal, lvalue); } AABlock innerBlock = (AABlock)decl.GetBlock().Clone(); exp = new ABooleanConstExp(new ATrueBool()); finalTrans.data.ExpTypes[exp] = new ANamedType(new TIdentifier("bool"), null); ABlockStm innerBlockStm = new ABlockStm(new TLBrace("{"), innerBlock); bool needWhile = CheckIfWhilesIsNeeded.IsWhileNeeded(decl.GetBlock()); if (needWhile) stm = new AWhileStm(new TLParen("("), exp, innerBlockStm); else stm = innerBlockStm; outerBlock.GetStatements().Add(stm); outerBlock.GetStatements().Add(new ABlockStm(new TLBrace("{"), afterBlock)); //Clone method contents to inner block. CloneMethod cloneFixer = new CloneMethod(finalTrans, Parameters, ParameterExps, innerBlockStm); decl.GetBlock().Apply(cloneFixer); foreach (KeyValuePair<PLvalue, PExp> pair in cloneFixer.ReplaceUsAfter) { PLvalue lvalue = pair.Key; PExp replacement = Util.MakeClone(pair.Value, finalTrans.data); ALvalueExp lvalueParent = (ALvalueExp) lvalue.Parent(); lvalueParent.ReplaceBy(replacement); } innerBlockStm.Apply(new FixTypes(finalTrans.data)); innerBlock.Apply(new FixReturnsAndWhiles(hasMethodReturnedVar, methodReturnerVar, finalTrans.data, needWhile)); GetNonBlockStm stmFinder = new GetNonBlockStm(false); innerBlock.Apply(stmFinder); if (needWhile && (stmFinder.Stm == null || !(stmFinder.Stm is ABreakStm))) innerBlock.GetStatements().Add(new ABreakStm(new TBreak("break"))); //Insert before current statement ABlockStm outerBlockStm = new ABlockStm(new TLBrace("{"), outerBlock); PStm pStm = Util.GetAncestor<PStm>(node); pBlock = (AABlock)pStm.Parent(); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), outerBlockStm); if (node.Parent() == pStm && pStm is AExpStm) { pBlock.RemoveChild(pStm); } else { PLvalue lvalue = new ALocalLvalue(new TIdentifier(methodReturnerVar.GetName().Text)); finalTrans.data.LvalueTypes[lvalue] = methodReturnerVar.GetType(); finalTrans.data.LocalLinks[(ALocalLvalue)lvalue] = methodReturnerVar; exp = new ALvalueExp(lvalue); finalTrans.data.ExpTypes[exp] = methodReturnerVar.GetType(); node.ReplaceBy(exp); } return new List<AABlock>() { outerBlock }; }