private static AbcMethod BuildEnumCinit(AbcFile abc, IType type) { if (type == null) { return(null); } if (!type.IsEnum) { return(null); } var method = new AbcMethod { ReturnType = abc.BuiltinTypes.Void }; var body = new AbcMethodBody(method); abc.AddMethod(method); var code = new AbcCode(abc); var generator = abc.Generator; foreach (var field in type.Fields.Where(field => field.IsConstant)) { code.LoadThis(); code.LoadConstant(field.Value); code.InitProperty(generator.FieldBuilder.GetFieldName(field)); } code.ReturnVoid(); body.Finish(code); return(method); }
public static Instruction Read(ILStream list, AbcMethodBody body, SwfReader reader) { int offset = (int)reader.Position; var code = (InstructionCode)reader.ReadUInt8(); var instruction = Instructions.GetInstruction(code); instruction.Offset = offset; var ops = instruction.Operands; if (code == InstructionCode.Lookupswitch) { instruction.Operands[0].Value = reader.ReadInt24(); //default case offset int n = (int)reader.ReadUIntEncoded(); //max_index ops[1].Value = n; var cases = new int[n + 1]; for (int i = 0; i <= n; ++i) { cases[i] = reader.ReadInt24(); } ops[2].Value = cases; } else if (ops != null) { int n = ops.Length; for (int i = 0; i < n; ++i) { var op = ops[i]; op.Read(body, reader); } } return(instruction); }
public static XElement ToXml(this AbcMethodBody body) { var labels = new HashSet <uint>(); body.ToXml(labels); return(body.ToXml(labels)); }
private void BuildBodyCore(AbcMethod target, IMethod source) { var targetBody = target.Body; if (targetBody == null) { targetBody = new AbcMethodBody(target); Abc.MethodBodies.Add(targetBody); } var sourceBody = source.Body; var codeProvider = new CodeProviderImpl(_generator, target); var translator = sourceBody.CreateTranslator(); if (translator == null) { throw new InvalidOperationException("No IL translator"); } var il = translator.Translate(source, sourceBody, codeProvider); targetBody.IL.Add(il); targetBody.Finish(Abc); }
public void Read(AbcMethodBody body, SwfReader reader) { while (reader.Position < reader.Length) { var i = Instruction.Read(this, body, reader); i.Index = Count; Add(i); } }
//Generates method for script initializer private AbcMethod DefineMainScriptInit(AbcScript script, AbcInstance instance) { #if DEBUG DebugService.LogInfo("DefineScriptInit started"); #endif var method = new AbcMethod(); bool notSwf = !IsSwf; //Note: entry point also can contains arguments //Note: but in swf entry point can not have arguments if (EntryPoint != null && notSwf) { method.ReturnType = _generator.TypeBuilder.BuildReturnType(EntryPoint.Type); _generator.MethodBuilder.BuildParameters(method, EntryPoint); } var body = new AbcMethodBody(method); _generator.Abc.AddMethod(method); _mainScriptBody = body; var code = new AbcCode(Abc); _mainScriptCode = code; code.PushThisScope(); code.InitClassProperties(script); //code.Trace("Initialization of " + instance.FullName); _insertIndexOfNewApi = code.Count; //code.AddRange(_newAPI); _generator.StaticCtors.Call(code, instance); if (notSwf) //abc? { _generator.NUnit.Main(code); CallEntryPoint(code); } else { code.ReturnVoid(); } //body.Finish(code); #if DEBUG DebugService.LogInfo("DefineScriptInit succeeded"); #endif return(method); }
public static XElement ToXml(this AbcMethodBody body, ISet <uint> labels) { var xBody = new XElement("body", new XAttribute("maxStack", body.MaxStack), new XAttribute("maxScopeDepth", body.MaxScopeDepth), new XAttribute("initScopeDepth", body.InitScopeDepth), new XAttribute("localCount", body.LocalCount) ); if (body.Traits.Count > 0) { xBody.Add(body.Traits.ToXml()); } Func <uint, string> labelFormatter = target => { labels.Add(target); return(string.Format("lbl_{0:x6}", target)); }; var writer = new XAbcOpcodeWriter(labelFormatter); var xCode = new XElement("code"); foreach (var instruction in body.Code) { var xInstruction = instruction.Opcode.AcceptVisitor(writer, instruction); if (labels.Contains(instruction.Offset)) { xInstruction.Add(new XAttribute("label", string.Format("lbl_{0:x6}", instruction.Offset))); } xCode.Add(xInstruction); } xBody.Add(xCode); if (body.Exceptions.Count != 0) { var xExcs = new XElement("exceptions"); foreach (var exc in body.Exceptions) { var xExc = new XElement("exception", new XAttribute("from", labelFormatter(exc.From)), new XAttribute("to", labelFormatter(exc.To)), new XAttribute("target", labelFormatter(exc.Target)), new XAttribute("excType", exc.ExceptionType.ToXml()), new XAttribute("varName", exc.VariableName.ToXml())); xExcs.Add(xExc); } xBody.Add(xExcs); } return(xBody); }
public CodeProviderImpl(AbcGenerator gen, AbcMethod abcMethod) { _generator = gen; _abc = gen.Abc; _method = abcMethod.Method; _body = abcMethod.Body; _declType = _method.DeclaringType; _asStatic = _method.AsStaticCall(); //This code enshures initial capacity for local registers _body.LocalCount = _method.Parameters.Count + 1; var body = _method.Body; if (body == null) { throw new InvalidOperationException("method has no body"); } if (HasPseudoThis) { _body.LocalCount++; } int n = VarCount; if (n == 0) { //NOTE: AVM constraint for LocalCount //if (local_count < info->param_count+1) //{ // must have enough locals to hold all parameters including this //toplevel->throwVerifyError(kCorruptABCError); //} _body.LocalCount++; } else { _body.LocalCount += n; } }
public void Read(AbcMethodBody body, SwfReader reader) { Value = Read(body, reader, Type); }
public static object Read(AbcMethodBody body, SwfReader reader, OperandType type) { switch (type) { case OperandType.U30: return((int)reader.ReadUIntEncoded()); case OperandType.S30: return(reader.ReadIntEncoded()); case OperandType.U8: return(reader.ReadUInt8()); case OperandType.U16: return(reader.ReadUInt16()); case OperandType.U24: return(reader.ReadUInt24()); case OperandType.U32: return(reader.ReadUInt32()); case OperandType.S24: case OperandType.BranchTarget: return(reader.ReadInt24()); case OperandType.ConstInt: { int index = (int)reader.ReadUIntEncoded(); return(reader.ABC.IntPool[index]); } case OperandType.ConstUInt: { int index = (int)reader.ReadUIntEncoded(); return(reader.ABC.UIntPool[index]); } case OperandType.ConstDouble: { int index = (int)reader.ReadUIntEncoded(); return(reader.ABC.DoublePool[index]); } case OperandType.ConstString: { int index = (int)reader.ReadUIntEncoded(); return(reader.ABC.StringPool[index]); } case OperandType.ConstMultiname: { int index = (int)reader.ReadUIntEncoded(); return(reader.ABC.Multinames[index]); } case OperandType.ConstNamespace: { int index = (int)reader.ReadUIntEncoded(); return(reader.ABC.Namespaces[index]); } case OperandType.MethodIndex: { int index = (int)reader.ReadUIntEncoded(); return(reader.ABC.Methods[index]); } case OperandType.ClassIndex: { int index = (int)reader.ReadUIntEncoded(); return(reader.ABC.Classes[index]); } case OperandType.ExceptionIndex: { int index = (int)reader.ReadUIntEncoded(); return(body.Exceptions[index]); } default: throw new ArgumentOutOfRangeException(); } }
private AbcMethod BuildCtorImpl(IMethod method, AbcInstance instance) { if (!method.IsConstructor) { return(null); } if (method.IsStatic) { return(null); } var type = method.DeclaringType; if (!type.IsArray) { return(null); } var ctor = new AbcMethod { ReturnType = Abc.BuiltinTypes.Void }; _generator.MethodBuilder.BuildParameters(ctor, method); string name1 = "arrctor_" + type.GetSigName(); var name = Abc.DefineName(QName.Global(name1)); var trait = AbcTrait.CreateMethod(ctor, name); instance.Traits.Add(trait); var body = new AbcMethodBody(ctor); Abc.AddMethod(ctor); var code = new AbcCode(Abc); code.PushThisScope(); code.ConstructSuper(); //check arguments int n = method.Parameters.Count; for (int i = 0; i < n; ++i) { code.GetLocal(i + 1); code.PushInt(0); var br = code.If(BranchOperator.GreaterThanOrEqual); var exceptionType = _generator.Corlib.GetType(CorlibTypeId.ArgumentOutOfRangeException); code.ThrowException(exceptionType); br.BranchTarget = code.Label(); } //m_rank = n code.LoadThis(); code.PushInt(n); code.SetProperty(Const.Array.Rank); int varSize = n + 1; for (int i = 0; i < n; ++i) { code.GetLocal(i + 1); } for (int i = 1; i < n; ++i) { code.Add(InstructionCode.Multiply_i); } code.SetLocal(varSize); //init m_value code.LoadThis(); code.CreateArrayVarSize(varSize); code.SetProperty(Const.Array.Value); //init m_lengths code.LoadThis(); for (int i = 0; i < n; ++i) { code.GetLocal(i + 1); } code.Add(InstructionCode.Newarray, n); code.SetProperty(Const.Array.Lengths); int varDimArr = varSize + 1; //init m_dims code.CreateArray(n - 1); code.SetLocal(varDimArr); //1, n, n * (n-1), ..., n * (n-1) * ... * n0 for (int i = n - 2; i >= 0; --i) { int leni = i + 2; code.GetLocal(varDimArr); code.PushInt(i); if (i != n - 2) { code.GetLocal(varDimArr); code.PushInt(i + 1); code.GetNativeArrayItem(); code.CoerceInt32(); //prev code.GetLocal(leni); code.Add(InstructionCode.Multiply_i); //prev * leni } else { code.GetLocal(leni); } code.SetNativeArrayItem(); } code.LoadThis(); code.GetLocal(varDimArr); code.SetProperty(Const.Array.Dims); var elemType = type.GetElementType(); InitFields(code, type, elemType, 0); if (InternalTypeExtensions.IsInitArray(elemType)) { code.InitArray(elemType, () => { code.LoadThis(); code.GetProperty(Const.Array.Value); }, varSize); } code.ReturnVoid(); body.Finish(code); return(ctor); }