Пример #1
0
        public override object Execute(ProtoCore.Runtime.Context c, Interpreter dsi)
        {
            List <StackValue> s          = dsi.runtime.rmem.Stack;
            FFIObjectMarshler marshaller = Module.GetMarshaller(dsi.runtime.RuntimeCore);

            Object retVal = null;

            if (ReflectionInfo.IsWrapperOf(CLRModuleType.DisposeMethod))
            {
                // For those FFI objects that are disposable but don't provide
                // Dispose() method in their classes, they will share a same
                // Dispose() method from CLRModuleType.DisposeMethod. We need
                // to manually dispose them.
                var thisObject = marshaller.UnMarshal(s.Last(), c, dsi, typeof(IDisposable));
                if (thisObject != null && thisObject is IDisposable)
                {
                    var disposable = thisObject as IDisposable;
                    disposable.Dispose();
                }
            }
            else
            {
                retVal = base.Execute(c, dsi);
            }
            marshaller.OnDispose(s.Last(), c, dsi); //Notify marshler for dispose.

            return(retVal);
        }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dsObject"></param>
        /// <param name="context"></param>
        /// <param name="dsi"></param>
        /// <returns></returns>
        public static T[] ConvertDSArrayToCSArray <T>(FFIObjectMarshler marshaler, StackValue dsObject, ProtoCore.Runtime.Context context, Interpreter dsi)
        {
            StackValue[] arr   = dsi.runtime.rmem.GetArrayElements(dsObject);
            int          count = arr.Length;

            T[]  array   = new T[count];
            Type objType = typeof(T);

            for (int idx = 0; idx < count; ++idx)
            {
                object obj = marshaler.UnMarshal(arr[idx], context, dsi, objType);
                if (null == obj)
                {
                    if (objType.IsValueType)
                    {
                        throw new System.InvalidCastException(string.Format("Null value cannot be cast to {0}", objType.Name));
                    }

                    array[idx] = default(T);
                }
                else
                {
                    array[idx] = (T)obj;
                }
            }

            return(array);
        }
Пример #3
0
        public override object Execute(ProtoCore.Runtime.Context c, Interpreter dsi)
        {
            int nParamCount     = mArgTypes.Length;
            int paramCount      = mArgTypes.Length;
            int envSize         = IsDNI ? 2 : 0;
            int totalParamCount = paramCount + envSize;

            List <Object> parameters            = new List <object>();
            List <ProtoCore.DSASM.StackValue> s = dsi.runtime.rmem.Stack;
            Object            thisObject        = null;
            FFIObjectMarshler marshaller        = Module.GetMarshaller(dsi.runtime.Core);

            if (!ReflectionInfo.IsStatic)
            {
                try
                {
                    thisObject = marshaller.UnMarshal(s.Last(), c, dsi, ReflectionInfo.DeclaringType);
                }
                catch (InvalidOperationException)
                {
                    string message = String.Format(ProtoCore.RuntimeData.WarningMessage.kFFIFailedToObtainThisObject, ReflectionInfo.DeclaringType.Name, ReflectionInfo.Name);
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, message);
                    return(null);
                }

                if (thisObject == null)
                {
                    return(null); //Can't call a method on null object.
                }
            }

            ParameterInfo[] paraminfos = ReflectionInfo.GetParameters();
            for (int i = 0; i < mArgTypes.Length; ++i)
            {
                // Comment Jun: FFI function stack frames do not contain locals
                int locals   = 0;
                int relative = 0 - ProtoCore.DSASM.StackFrame.kStackFrameSize - locals - i - 1;
                ProtoCore.DSASM.StackValue opArg = dsi.runtime.rmem.GetAtRelative(relative);
                try
                {
                    Type   paramType = paraminfos[i].ParameterType;
                    object param     = marshaller.UnMarshal(opArg, c, dsi, paramType);


                    //null is passed for a value type, so we must return null
                    //rather than interpreting any value from null. fix defect 1462014
                    if (!paramType.IsGenericType && paramType.IsValueType && param == null)
                    {
                        throw new System.InvalidCastException(string.Format("Null value cannot be cast to {0}", paraminfos[i].ParameterType.Name));
                    }

                    parameters.Add(param);
                }
                catch (System.InvalidCastException ex)
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.Message);
                    return(null);
                }
                catch (InvalidOperationException)
                {
                    string message = String.Format(ProtoCore.RuntimeData.WarningMessage.kFFIFailedToObtainObject, paraminfos[i].ParameterType.Name, ReflectionInfo.DeclaringType.Name, ReflectionInfo.Name);
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, message);
                    return(null);
                }
            }

            object     ret        = null;
            StackValue dsRetValue = StackUtils.BuildNull();

            try
            {
                ret = InvokeFunctionPointer(thisObject, parameters.Count > 0 ? parameters.ToArray() : null);
                //Reduce to singleton if the attribute is specified.
                ret        = ReflectionInfo.ReduceReturnedCollectionToSingleton(ret);
                dsRetValue = marshaller.Marshal(ret, c, dsi, mReturnType);
            }
            catch (DllNotFoundException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogSemanticError(ex.InnerException.Message);
                }
                dsi.LogSemanticError(ex.Message);
            }
            catch (System.Reflection.TargetException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.Reflection.TargetInvocationException ex)
            {
                if (ex.InnerException != null)
                {
                    System.Exception exc = ex.InnerException;
                    if (exc is System.ArgumentException)
                    {
                        dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kInvalidArguments, ErrorString(exc));
                    }
                    else if (exc is System.NullReferenceException)
                    {
                        dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ErrorString(null));
                    }
                    else
                    {
                        dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ErrorString(exc));
                    }
                }
                else
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ErrorString(ex));
                }
            }
            catch (System.Reflection.TargetParameterCountException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.MethodAccessException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.InvalidOperationException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.NotSupportedException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.ArgumentException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kInvalidArguments, ErrorString(ex.InnerException));
                }
                else
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kInvalidArguments, ErrorString(ex));
                }
            }
            catch (Exception ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogSemanticError(ErrorString(ex.InnerException));
                }
                dsi.LogSemanticError(ErrorString(ex));
            }

            return(dsRetValue);
        }
Пример #4
0
        public override object Execute(ProtoCore.Runtime.Context c, Interpreter dsi)
        {
            List <Object>     parameters = new List <object>();
            List <StackValue> s          = dsi.runtime.rmem.Stack;
            Object            thisObject = null;
            FFIObjectMarshler marshaller = Module.GetMarshaller(dsi.runtime.RuntimeCore);

            if (!ReflectionInfo.IsStatic)
            {
                try
                {
                    thisObject = marshaller.UnMarshal(s.Last(), c, dsi, ReflectionInfo.DeclaringType);
                }
                catch (InvalidOperationException)
                {
                    string message = String.Format(Resources.kFFIFailedToObtainThisObject, ReflectionInfo.DeclaringType.Name, ReflectionInfo.Name);
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.AccessViolation, message);
                    return(null);
                }

                if (thisObject == null)
                {
                    return(null); //Can't call a method on null object.
                }
            }

            FFIParameterInfo[] paraminfos           = ReflectionInfo.GetParameters();
            List <StackValue>  referencedParameters = new List <StackValue>();

            for (int i = 0; i < mArgTypes.Length; ++i)
            {
                // Comment Jun: FFI function stack frames do not contain locals
                int        locals   = 0;
                int        relative = 0 - ProtoCore.DSASM.StackFrame.StackFrameSize - locals - i - 1;
                StackValue opArg    = dsi.runtime.rmem.GetAtRelative(relative);
                try
                {
                    Type   paramType = paraminfos[i].Info.ParameterType;
                    object param     = null;
                    if (opArg.IsDefaultArgument)
                    {
                        param = Type.Missing;
                    }
                    else
                    {
                        param = marshaller.UnMarshal(opArg, c, dsi, paramType);
                    }

                    if (paraminfos[i].KeepReference && opArg.IsReferenceType)
                    {
                        referencedParameters.Add(opArg);
                    }

                    //null is passed for a value type, so we must return null
                    //rather than interpreting any value from null. fix defect 1462014
                    if (!paramType.IsGenericType && paramType.IsValueType && param == null)
                    {
                        //This is going to cause a cast exception. This is a very frequently called problem, so we want to short-cut the execution

                        dsi.LogWarning(ProtoCore.Runtime.WarningID.AccessViolation,
                                       string.Format(Resources.FailedToCastFromNull, paraminfos[i].Info.ParameterType.Name));

                        return(null);
                        //throw new System.InvalidCastException(string.Format("Null value cannot be cast to {0}", paraminfos[i].ParameterType.Name));
                    }

                    parameters.Add(param);
                }
                catch (System.InvalidCastException ex)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.AccessViolation, ex.Message);
                    return(null);
                }
                catch (InvalidOperationException)
                {
                    string message = String.Format(Resources.kFFIFailedToObtainObject, paraminfos[i].Info.ParameterType.Name, ReflectionInfo.DeclaringType.Name, ReflectionInfo.Name);
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.AccessViolation, message);
                    return(null);
                }
            }

            var ret   = InvokeFunctionPointerNoThrow(c, dsi, thisObject, parameters.Count > 0 ? parameters.ToArray() : null);
            int count = referencedParameters.Count;

            if (count > 0 && (ret is StackValue))
            {
                // If there is a parameter who has attribute [KeepReference],
                // it means this parameter will cross the DesignScript boundary
                // and be referenced by C# object. Therefore, when its DS
                // wrapper object is out of scope, we shouldn't dispose it;
                // otherwise that C# object will reference to an invalid object.
                //
                // The hack here is to treat it like a property in the return
                // object. Note all DS wrapper objects are dummy objects who
                // haven't any members. By allocating extra space on the heap,
                // we store the reference in the return object so that the
                // parameter will have the same lifecycle as the return object.
                var pointer = (StackValue)ret;
                if (pointer.IsPointer)
                {
                    var dsObject = dsi.runtime.rmem.Heap.ToHeapObject <DSObject>(pointer);
                    if (dsObject != null)
                    {
                        int startIndex = dsObject.Count;
                        try
                        {
                            dsObject.ExpandBySize(count);
                            Validity.Assert(dsObject.Count >= referencedParameters.Count);

                            for (int i = 0; i < referencedParameters.Count; i++)
                            {
                                dsObject.SetValueAtIndex(startIndex + i, referencedParameters[i], dsi.runtime.RuntimeCore);
                            }
                        }
                        catch (RunOutOfMemoryException)
                        {
                            dsi.runtime.RuntimeCore.RuntimeStatus.LogWarning(ProtoCore.Runtime.WarningID.RunOutOfMemory, Resources.RunOutOfMemory);
                            return(StackValue.Null);
                        }
                    }
                }
            }
            return(ret);
        }
Пример #5
0
        public override object Execute(ProtoCore.Runtime.Context c, Interpreter dsi)
        {
            List <Object>     parameters = new List <object>();
            List <StackValue> s          = dsi.runtime.rmem.Stack;
            Object            thisObject = null;
            FFIObjectMarshler marshaller = Module.GetMarshaller(dsi.runtime.RuntimeCore);

            if (!ReflectionInfo.IsStatic)
            {
                try
                {
                    thisObject = marshaller.UnMarshal(s.Last(), c, dsi, ReflectionInfo.DeclaringType);
                }
                catch (InvalidOperationException)
                {
                    string message = String.Format(Resources.kFFIFailedToObtainThisObject, ReflectionInfo.DeclaringType.Name, ReflectionInfo.Name);
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, message);
                    return(null);
                }

                if (thisObject == null)
                {
                    return(null); //Can't call a method on null object.
                }
            }

            ParameterInfo[] paraminfos = ReflectionInfo.GetParameters();
            for (int i = 0; i < mArgTypes.Length; ++i)
            {
                // Comment Jun: FFI function stack frames do not contain locals
                int        locals   = 0;
                int        relative = 0 - ProtoCore.DSASM.StackFrame.kStackFrameSize - locals - i - 1;
                StackValue opArg    = dsi.runtime.rmem.GetAtRelative(relative);
                try
                {
                    Type   paramType = paraminfos[i].ParameterType;
                    object param     = null;
                    if (opArg.IsDefaultArgument)
                    {
                        param = Type.Missing;
                    }
                    else
                    {
                        param = marshaller.UnMarshal(opArg, c, dsi, paramType);
                    }

                    //null is passed for a value type, so we must return null
                    //rather than interpreting any value from null. fix defect 1462014
                    if (!paramType.IsGenericType && paramType.IsValueType && param == null)
                    {
                        //This is going to cause a cast exception. This is a very frequently called problem, so we want to short-cut the execution

                        dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation,
                                       string.Format(Resources.FailedToCastFromNull, paraminfos[i].ParameterType.Name));

                        return(null);
                        //throw new System.InvalidCastException(string.Format("Null value cannot be cast to {0}", paraminfos[i].ParameterType.Name));
                    }

                    parameters.Add(param);
                }
                catch (System.InvalidCastException ex)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.Message);
                    return(null);
                }
                catch (InvalidOperationException)
                {
                    string message = String.Format(Resources.kFFIFailedToObtainObject, paraminfos[i].ParameterType.Name, ReflectionInfo.DeclaringType.Name, ReflectionInfo.Name);
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, message);
                    return(null);
                }
            }

            return(InvokeFunctionPointerNoThrow(c, dsi, thisObject, parameters.Count > 0 ? parameters.ToArray() : null));
        }