예제 #1
0
        /// Evaluate the operation against stack
        public void Eval(IEvaluationContext context, Stack <object> stack)
        {
            var o = OperationHelper.PopArray(stack, _paramCount);

            // Find a general object type
            Type parent = null;

            foreach (var o1 in o)
            {
                parent = Utils.CommonBase(o1, parent);
            }

            if (parent == null || parent == typeof(object))
            {
                stack.Push(o);
            }
            else
            {
                Array a = (Array)Activator.CreateInstance(parent.MakeArrayType(), o.Length);
                for (int i = 0; i < a.Length; ++i)
                {
                    a.SetValue(o[i], i);
                }
                stack.Push(a);
            }
        }
예제 #2
0
        /// Evaluate the operation against stack
        public void Eval(IEvaluationContext context, Stack <object> stack)
        {
            string typeName = _typeName;
            object arrInit  = null;
            int    pc       = _paramCount;

            object[] o = null;
            int      c = 0;

            if (_isInitializerProvided)
            {
                arrInit = stack.Pop();
                if (!(arrInit is System.Collections.IEnumerable))
                {
                    throw new InvalidOperationException("Invalid array initializer");
                }

                bool empty = (typeName == "[]");
                if ((arrInit is Array) && !empty)
                {
                    c = ((Array)arrInit).Length;
                }
                else
                {
                    Type          tc = null;
                    List <object> rr = new List <object>();
                    foreach (var array in (arrInit as System.Collections.IEnumerable))
                    {
                        rr.Add(array);
                        if (empty)
                        {
                            tc = Utils.CommonBase(array, tc);
                        }
                    }
                    c       = rr.Count;
                    arrInit = rr;
                    if (tc != null)
                    {
                        typeName = tc.FullName + "[]";
                    }
                }
                pc--;
                if (pc == 0)
                {
                    o = new object[1] {
                        c
                    }
                }
                ;
            }
            if (pc > 0)
            {
                o = OperationHelper.PopArray(stack, pc);
            }

            object ret = null;

            if (string.IsNullOrEmpty(typeName))
            {
                ret = arrInit;
            }
            else
            {
                var tn = OperationHelper.ResolveType(context, typeName);
                if (tn == null)
                {
                    throw new TypeLoadException("Failed to resolve type '" + _typeName + "'");
                }
                if (!tn.IsArray && _isInitializerProvided)
                {
                    throw new InvalidOperationException("Initializers can only be provided to arrays");
                }
                if (!Utils.TryCreateInstance(tn, o, context.AccessPrivate, out ret))
                {
                    throw new InvalidOperationException("Failed to create object of type '" + _typeName + "'");
                }
            }
            if (_isInitializerProvided && !string.IsNullOrEmpty(typeName))
            {
                if (o != null && o.Length != 0 && (int)o[0] != c)
                {
                    throw new InvalidOperationException("Array initializer length does not match array size");
                }
                var par    = (Array)ret;
                var elType = par.GetType().GetElementType();
                c = 0;
                foreach (var array in (System.Collections.IEnumerable)arrInit)
                {
                    par.SetValue(Utils.To(elType, array), c++);
                }
            }
            stack.Push(ret);
        }
예제 #3
0
        /// Evaluate the operation against stack
        public void Eval(IEvaluationContext context, Stack <object> stack)
        {
            object[] p = OperationHelper.PopArray(stack, _paramCount);

            if (!_thisCall && !_id.Contains(".") && !_isProperty)
            {
                stack.Push(context.CallExternal(_id, p));
                return;
            }

            // ID is smth like x.y.z where we have no idea whether x is namespace,type, or object name. So we split it
            // and ask
            var parts = (!_id.Contains(".") && !string.IsNullOrEmpty(_id) && _paramCount != 0 && _isProperty)?((_id + ".").Split('.')):_id.Split('.');

            IEnumerable <TypeObjectPair> typeAndObjects = null;

            if (_thisCall)
            {
                var o = stack.Pop();
                typeAndObjects = new TypeObjectPair[] { new TypeObjectPair(o.GetType(), o) };
            }

            object sub;
            bool   success = false;

            for (int i = 0; i < parts.Length; ++i)
            {
                string currentPart = parts[i];
                if (typeAndObjects == null)
                {
                    string tn = string.Join(".", parts, 0, i + 1);
                    if (string.IsNullOrEmpty(tn))
                    {
                        typeAndObjects = context.GetNonameObjects();
                    }
                    else
                    {
                        if (context.TryGetExternal(tn, out sub))
                        {
                            success        = true;
                            typeAndObjects = (sub == null) ? null : new[] { new TypeObjectPair(sub.GetType(), sub) };
                        }
                        else
                        {
                            var t = context.FindType(tn);
                            if (t != null)
                            {
                                typeAndObjects = new[] { new TypeObjectPair(t, null) };
                                success        = true;
                            }
                        }
                    }
                }
                else
                {
                    success = false;
                    foreach (var to in typeAndObjects)
                    {
                        if (_isProperty || i != parts.Length - 1)
                        {
                            success = Utils.TryGetProperty(to.Object, to.Type, currentPart, (i == parts.Length - 1) ? p : null, context.AccessPrivate, out sub);
                        }
                        else
                        {
                            success = Utils.TryCallMethod(to.Object, to.Type, currentPart, (i == parts.Length - 1) ? p : null, context.AccessPrivate, out sub);
                        }
                        if (success)
                        {
                            typeAndObjects = null;
                            if (!object.ReferenceEquals(sub, null))
                            {
                                typeAndObjects = new[] { new TypeObjectPair(sub.GetType(), sub) }
                            }
                            ;
                            break;
                        }
                    }
                    if (!success)
                    {
                        // Last possible chance for COM objects where reflection does not work, but calling might!
                        if (i == parts.Length - 1)
                        {
                            foreach (var to in typeAndObjects)
                            {
                                if (to.Object == null)
                                {
                                    continue;
                                }

                                if (_isProperty)
                                {
                                    if (p.Length == 0)
                                    {
                                        stack.Push(Utils.GetProperty(to.Object, currentPart));
                                        return;
                                    }
                                }
                                else
                                {
                                    try
                                    {
                                        stack.Push(Utils.CallMethod(to.Object, currentPart, p));
                                    }
                                    catch (Exception e)
                                    {
                                        var comex = e as System.Runtime.InteropServices.COMException;
                                        var miex  = e as MissingMethodException;
                                        if (miex != null || (comex != null && ((uint)comex.ErrorCode == 0x80020006u || (uint)comex.ErrorCode == 0x80020005u)))
                                        {
                                            if (currentPart.StartsWith("set_", StringComparison.OrdinalIgnoreCase) && p.Length == 1)
                                            {
                                                Utils.SetPropertySimple(to.Object, currentPart.Substring(4), p[0]);
                                                stack.Push(null);
                                                return;
                                            }
                                            if (currentPart.StartsWith("get_", StringComparison.OrdinalIgnoreCase) && p.Length == 0)
                                            {
                                                stack.Push(Utils.GetProperty(to.Object, currentPart.Substring(4)));
                                                return;
                                            }
                                        }
                                        if (e is System.Reflection.TargetInvocationException && e.InnerException != null)
                                        {
                                            Utils.Rethrow(e.InnerException);
                                        }
                                        Utils.Rethrow(e);
                                    }
                                    return;
                                }
                            }
                        }
                        throw new MissingMemberException("Failed to resolve '" + currentPart + "' with " + p.Length + " arguments");
                    }
                }
            }
            if (!success)
            {
                throw new MissingMemberException("Failed to resolve '" + _id + "' with " + p.Length + " arguments");
            }
            if (typeAndObjects == null)
            {
                stack.Push(null);
            }
            else
            {
                foreach (var o in typeAndObjects)
                {
                    stack.Push(o.Object);
                    break;
                }
            }
        }