static void CreateCdRslArray(AbcCode code, IList <RslItem> rsls) { int n = rsls.Count; for (int i = 0; i < n; ++i) { var rsl = rsls[i]; code.PushString("rsls"); code.PushStringArray(new[] { rsl.Uri }); code.PushString("policyFiles"); code.PushStringArray(rsl.PolicyFiles); code.PushString("digests"); string digest = rsl.Swc.GetLibraryDigest(null, rsl.HashType, rsl.IsSigned); if (string.IsNullOrEmpty(digest)) { throw Errors.RSL.UnableToResolveLibraryDigest.CreateException(rsl.LocalPath); } code.PushStringArray(new[] { digest }); code.PushString("types"); code.PushStringArray(new[] { rsl.HashType }); code.PushString("isSigned"); code.PushNativeBool(rsl.IsSigned); code.Add(InstructionCode.Newarray, 1); code.NewObject(5); } code.Add(InstructionCode.Newarray, n); }
private static void ToFlatIndex(AbcCode code, int n, bool getter) { code.LoadThis(); if (getter) { code.LoadArguments(n); code.Add(InstructionCode.Newarray, n); } else { //Last argument is a value code.GetLocals(1, n - 1); code.Add(InstructionCode.Newarray, n - 1); } code.Call(ArrayMethodId.ToFlatIndex); }
/// <summary> /// Calls entry point (Main method). /// //NOTE: This method always adds return instruction /// </summary> /// <param name="code"></param> internal void CallEntryPoint(AbcCode code) { //Note: in swf entry point will be called in ctor of root sprite if (EntryPoint == null) { code.ReturnVoid(); return; } var main = EntryPoint.AbcMethod(); if (main == null) { throw new InvalidOperationException("Invalid entry point"); } code.Getlex(main); if (AbcGenConfig.ParameterlessEntryPoint) { code.Add(InstructionCode.Callpropvoid, main.TraitName, 0); code.ReturnVoid(); } else { //TODO: pass process args int n = EntryPoint.Parameters.Count; for (int i = 0; i < n; ++i) { //code.GetLocal(i + 1); code.PushNull(); } bool isVoid = EntryPoint.IsVoid(); if (isVoid || IsSwf) { code.Add(InstructionCode.Callpropvoid, main.Trait.Name, n); code.ReturnVoid(); } else { code.Add(InstructionCode.Callproperty, main.Trait.Name, n); code.ReturnValue(); } } }
public static InlineCall Create(AbcFile abc, IMethod method, InlineMethodInfo info) { var code = new AbcCode(abc); var targetType = info.TargetType != null?info.TargetType.Define(abc) : null; var name = info.Name.Define(abc); switch (info.Kind) { case InlineKind.Property: if (method.IsSetter()) { code.SetProperty(name); } else { code.GetProperty(name); code.Coerce(method.Type, true); } break; case InlineKind.Operator: { int n = method.Parameters.Count; if (n <= 1) { throw new InvalidOperationException(); } var op = info.Op; for (int i = 1; i < n; ++i) { code.Add(op); } code.Coerce(method.Type, true); } break; default: if (method.IsVoid()) { code.CallVoid(name, method.Parameters.Count); } else { code.Call(name, method.Parameters.Count); code.Coerce(method.Type, true); } break; } return(new InlineCall(method, targetType, name, code)); }
public IEnumerable <IInstruction> InvokeDelegate(IMethod method) { var code = new AbcCode(_abc) { { InstructionCode.Call, method.Parameters.Count } }; if (method.IsVoid()) { code.Add(InstructionCode.Pop); } return(code); }
public static void NewArray(IMethod method, AbcCode code) { if (method.Parameters.Count == 1) { //size is onto the stack code.Getlex(AvmTypeCode.Array); code.Swap(); code.Construct(1); code.CoerceArray(); return; } code.Add(InstructionCode.Newarray, 0); }
public static void Concat(IMethod method, AbcCode code) { int n = method.Parameters.Count; if (n <= 1) { throw new InvalidOperationException(); } for (int i = 1; i < n; ++i) { code.Add(InstructionCode.Add); } code.CoerceString(); }
private int SetTempVar(AbcCode code, bool keepStackState) { //NOTE: we duplicate value onto the stack to keep stack unchanged after this operation if (keepStackState) { code.Add(InstructionCode.Dup); } int var = NewTempVar(false); code.SetLocal(var); return(var); }
private bool SuperCall(AbcCode code, IMethod method) { if (IsConstructSuper(method)) { int n = method.Parameters.Count; if (ShouldPopBaseCtorCall(method)) { code.Pop(n + 1); } else { code.Add(InstructionCode.Constructsuper, n); } return(true); } return(false); }
static void CreateSimpleRslArray(AbcCode code, IList <RslItem> rsls) { int n = rsls.Count; for (int i = 0; i < n; ++i) { var rsl = rsls[i]; code.PushString("url"); code.PushString(rsl.Uri); code.PushString("size"); code.PushInt(-1); code.NewObject(2); } code.Add(InstructionCode.Newarray, n); }
void KillExceptionVariable(AbcCode code, CatchInfo ci) { if (!ci.IsVarKilled) { ci.IsVarKilled = true; if (ci.IsTempVar) { code.Add(KillTempVarCore(ci.ExceptionVar)); } else { //NOTE: Fix to avoid VerifyError when types can not be reconciled. //code.PushUndefined(); //code.SetLocal(ci.ExceptionVar); //code.Add(InstructionCode.Kill, ci.varExc); } } }
public static void ReferenceEquals(AbcCode code) { code.Add(InstructionCode.Strictequals); code.FixBool(); }
public static void op_Inequality(AbcCode code) { code.Add(InstructionCode.Equals); code.Add(InstructionCode.Not); code.FixBool(); }
public static void IsNull(AbcCode code) { code.PushNull(); code.Add(InstructionCode.Equals); code.FixBool(); }
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); }
public static void IsUndefined(AbcCode code) { code.PushUndefined(); code.Add(InstructionCode.Equals); code.FixBool(); }
private void CallCore(AbcCode code, IMethod method, AbcMultiname prop, bool super) { var abcMethod = method.AbcMethod(); if (abcMethod != null) { if (abcMethod.IsGetter) { code.Add(super ? InstructionCode.Getsuper : InstructionCode.Getproperty, prop); return; } if (abcMethod.IsSetter) { code.Add(super ? InstructionCode.Setsuper : InstructionCode.Setproperty, prop); return; } } int n = method.Parameters.Count; if (method.AsStaticCall()) { ++n; } bool isVoid = method.IsVoid(); if (CanUseCallStatic) { if (method.IsStaticCall() && method.IsManaged() && abcMethod != null && _abc.IsDefined(abcMethod)) { code.Add(InstructionCode.Callstatic, abcMethod, n); if (isVoid) { code.Pop(); } return; } } if (super) { if (isVoid) { code.Add(InstructionCode.Callsupervoid, prop, n); return; } code.Add(InstructionCode.Callsuper, prop, n); return; } if (isVoid) { code.Add(InstructionCode.Callpropvoid, prop, n); return; } code.Add(InstructionCode.Callproperty, prop, n); }
public static void Equals(AbcCode code) { code.Add(InstructionCode.Equals); code.FixBool(); }
public IEnumerable <IInstruction> Branch(BranchOperator op, IType left, IType right) { if (op.IsUnary()) { if (op == BranchOperator.Null) { var code = new AbcCode(_abc); //NOTE: old code - not working with nullable types //code.PushNull(); //code.Add(InstructionCode.Ifeq); code.IsNull(left, right); code.Add(InstructionCode.Iftrue); return(code); } if (op == BranchOperator.NotNull) { var code = new AbcCode(_abc); //NOTE: old code - not working with nullable types //code.PushNull(); //code.Add(InstructionCode.Ifne); code.IsNull(left, right); code.Add(InstructionCode.Iffalse); return(code); } if (left.IsDecimalOrInt64()) { var code = new AbcCode(_abc); bool isTrue = op == BranchOperator.True; var abcOp = _generator.Operators.BuildBoolOp(left, isTrue); //TODO: Should we enshure not null value onto the stack??? //AbcMethod abcOp = _generator.DefineTruthOperator(left, isTrue); //code.LoadStaticReceiver(abcOp); //code.Swap(); code.Call(abcOp); code.Add(isTrue ? InstructionCode.Iftrue : InstructionCode.Iffalse); return(code); } } else if (InternalTypeExtensions.IsDecimalOrInt64(left, right)) { var code = new AbcCode(_abc); var opm = _generator.Operators.Build(op, left, right); code.Call(opm); code.Add(InstructionCode.Iftrue); return(code); } switch (op) { case BranchOperator.True: return(If(InstructionCode.Iftrue)); case BranchOperator.False: return(If(InstructionCode.Iffalse)); case BranchOperator.Equality: return(If(InstructionCode.Ifeq)); case BranchOperator.Inequality: return(If(InstructionCode.Ifne)); case BranchOperator.LessThan: return(If(InstructionCode.Iflt)); case BranchOperator.LessThanOrEqual: return(If(InstructionCode.Ifle)); case BranchOperator.GreaterThan: return(If(InstructionCode.Ifgt)); case BranchOperator.GreaterThanOrEqual: return(If(InstructionCode.Ifge)); default: throw new NotSupportedException(); } }