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 static void CopyArray(AbcCode code) { var prop = code.Abc.DefineName(QName.Global("concat")); code.Call(prop, 0); code.Coerce(AvmTypeCode.Array); }
public static void Getter(IMethod method, AbcCode code) { var prop = method.Association as IProperty; if (prop == null) { throw new InvalidOperationException(); } if (prop.Parameters.Count > 0) //indexer { if (IsTypedVector(method)) { code.GetProperty(code.Abc.NameArrayIndexer); code.Coerce(method.Type, true); } else { code.GetNativeArrayItem(); } } else { code.GetProperty(prop.Name); } }
private IEnumerable <IInstruction> SetNull(IType type, IVariable var) { EnsureType(type); var code = new AbcCode(_abc); code.PushNull(); code.Coerce(type, true); code.AddRange(StoreVariable(var)); return(code); }
public static void Ctor(IMethod method, AbcCode code) { var vec = method.DeclaringType.Data as IVectorType; if (vec == null) { throw new InvalidOperationException(); } code.Construct(method.Parameters.Count); code.Coerce(vec.Name); }
private void Call(AbcCode code, IMethod method, AbcMultiname prop, CallFlags flags) { if (prop == null) { throw new ArgumentNullException("prop"); } CallCore(code, method, prop, flags); if (MustCoerceReturnType(method)) { var type = method.Type; EnsureType(type); code.Coerce(type, true); } }
private static void TryUnboxNumber(AbcCode code, IType type) { const int varValue = 1; code.GetLocal(varValue); var ifNotNumber = code.IfType(AvmTypeCode.Number); code.ThrowInvalidCastException(); ifNotNumber.BranchTarget = code.Label(); code.GetLocal(varValue); if (!code.TryCastToSystemType(null, type.SystemType())) { code.Coerce(type, true); } code.ReturnValue(); }
public static void GetItem2(IMethod method, AbcCode code) { var p0 = method.Parameters[0].Type; if (p0.Name == "Namespace") { code.GetRuntimeProperty(); code.CoerceXMLList(); } else //namespace as Avm.String { code.Swap(); //stack [name, nsname] var ns = code[AvmTypeCode.Namespace]; code.FindPropertyStrict(ns); //stack [name, nsname, global] code.Swap(); //stack [name, global, nsname] code.ConstructProperty(ns, 1); //stack [name, ns] code.Coerce(ns); //stack [name, ns] code.Swap(); //stack [ns, name] code.GetRuntimeProperty(); code.CoerceXMLList(); } }
void RouteException(AbcCode code, ISehHandlerBlock block, int var) { var exceptionType = block.ExceptionType; if (block.PrevHandler == null) { //if err is AVM error then we translate it to System.Exception. //code.GetLocal(var); //code.As(AvmTypeCode.Error); //code.PushNull(); //var ifNotError = code.IfEquals(); code.GetLocal(var); code.As(SystemTypes.Exception, true); code.PushNull(); var ifExc = code.IfNotEquals(); code.GetLocal(var); code.As(AvmTypeCode.Error); code.PushNull(); var ifNotError = code.IfEquals(); CallToException(code, var); code.CoerceAnyType(); code.SetLocal(var); //check my exception var labelNotError = code.Label(); ifExc.BranchTarget = labelNotError; ifNotError.BranchTarget = labelNotError; } code.GetLocal(var); var handlerInfo = (SehHandlerInfo)block.Tag; handlerInfo.CheckExceptionLabel = code.Label(); //NOTE: Exception on stack can be routed from previous handlers code.SetLocal(var); code.GetLocal(var); code.As(exceptionType, true); code.PushNull(); var ifMyException = code.IfNotEquals(); //Routing to another exception handler or rethrow //Instruction routing = Label(); if (block.NextHandler == null) { code.GetLocal(var); code.Throw(); } else { code.GetLocal(var); handlerInfo.JumpToNextHandler = code.Goto(); } //Normal Execution: Prepare stack for handler var normal = code.Label(); ifMyException.BranchTarget = normal; code.GetLocal(var); code.Coerce(exceptionType, true); //21 instructions for first handler //11 instructions for other handlers }