/// 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); } }
/// 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); }
/// 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; } } }