Пример #1
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);
        }
        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;
        }
Пример #3
0
        protected object InvokeFunctionPointerNoThrow(ProtoCore.Runtime.Context c, Interpreter dsi, object thisObject, object[] parameters)
        {
            object ret = null;
            StackValue dsRetValue = StackValue.Null;
            try
            {
                FFIObjectMarshler marshaller = Module.GetMarshaller(dsi.runtime.RuntimeCore);
                ret = InvokeFunctionPointer(thisObject, parameters);
                //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.Runtime.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.Reflection.TargetInvocationException ex)
            {
                if (ex.InnerException != null)
                {
                    System.Exception exc = ex.InnerException;
                    var exception = exc as ArgumentNullException;
                    if (exception != null)
                    {
                        var innerMessage = string.Format(Resources.ArgumentNullException, exception.ParamName);
                        var msg = string.Format(Resources.OperationFailType2, 
                            ReflectionInfo.DeclaringType.Name, 
                            ReflectionInfo.Name, 
                            innerMessage);

                        dsi.LogWarning(ProtoCore.Runtime.WarningID.kInvalidArguments, msg);
                    }
                    else if (exc is System.ArgumentException)
                        dsi.LogWarning(ProtoCore.Runtime.WarningID.kInvalidArguments, ErrorString(exc));
                    else if (exc is System.NullReferenceException)
                        dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ErrorString(null));
                    else
                        dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ErrorString(exc));
                }
                else
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ErrorString(ex));
            }
            catch (System.Reflection.TargetParameterCountException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.MethodAccessException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.InvalidOperationException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.NotSupportedException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.Message);
            }
            catch (ArgumentNullException ex)
            {
                var innerMessage = string.Format(Resources.ArgumentNullException, ex.ParamName);
                var msg = string.Format(Resources.OperationFailType2,
                    ReflectionInfo.DeclaringType.Name,
                    ReflectionInfo.Name,
                    innerMessage);

                dsi.LogWarning(ProtoCore.Runtime.WarningID.kInvalidArguments, msg);
            }
            catch (System.ArgumentException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kInvalidArguments, ErrorString(ex.InnerException));
                }
                else
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kInvalidArguments, ErrorString(ex));
            }
            catch (Exception ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kDefault, ErrorString(ex.InnerException));
                }
                dsi.LogWarning(ProtoCore.Runtime.WarningID.kDefault, 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);
            if (ReflectionInfo.KeepReferenceThis && thisObject != null)
            {
                referencedParameters.Add(s.Last());
            }

            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.
                //
                // Similarly, if the method has attribute [KeepReferenceThis],
                // it means the return object will reference to this object
                // internally, so we shouldn't dispose this object.
                //
                // The hack here is to treat them like properties 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.
                //
                // One case need to consider about is the type of return value.
                // If the return value is an array, we have to recursively go 
                // into the array and expand the element, instead of setting
                // these hidden information directly on the array.
                try
                {
                    SetReferenceObjects((StackValue)ret, referencedParameters, dsi.runtime);
                }
                catch (RunOutOfMemoryException)
                {
                    dsi.runtime.RuntimeCore.RuntimeStatus.LogWarning(ProtoCore.Runtime.WarningID.RunOutOfMemory, Resources.RunOutOfMemory);
                    return StackValue.Null;
                }
            }

            return ret;
        }