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); }
/// <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); }
public override object Execute(ProtoCore.Runtime.Context c, Interpreter dsi) { Object retVal = base.Execute(c, dsi); List <ProtoCore.DSASM.StackValue> s = dsi.runtime.rmem.Stack; FFIObjectMarshler marshaller = Module.GetMarshaller(dsi.runtime.Core); marshaller.OnDispose(s.Last(), c, dsi); //Notify marshler for dispose. return(retVal); }
/// <summary> /// /// </summary> /// <param name="obj"></param> /// <param name="context"></param> /// <param name="dsi"></param> /// <param name="type"></param> /// <returns></returns> public override StackValue Marshal(object obj, ProtoCore.Runtime.Context context, Interpreter dsi, ProtoCore.Type type) { if (obj == null) { return(StackUtils.BuildNull()); } FFIObjectMarshler marshaler = null; StackValue retVal; Type objType = obj.GetType(); if (type.IsIndexable) { if (obj is System.Collections.ICollection) { System.Collections.ICollection collection = obj as System.Collections.ICollection; object[] array = new object[collection.Count]; collection.CopyTo(array, 0); return(PrimitiveMarshler.ConvertCSArrayToDSArray(this, array, context, dsi, type)); } else if (obj is System.Collections.IEnumerable) { System.Collections.IEnumerable enumerable = obj as System.Collections.IEnumerable; return(PrimitiveMarshler.ConvertCSArrayToDSArray(this, enumerable, context, dsi, type)); } } Array arr = obj as Array; if (null != arr) { return(PrimitiveMarshler.ConvertCSArrayToDSArray(this, arr, context, dsi, type)); } else if ((PrimitiveMarshler.IsPrimitiveDSType(type) || PrimitiveMarshler.IsPrimitiveObjectType(obj, type)) && mPrimitiveMarshalers.TryGetValue(objType, out marshaler)) { return(marshaler.Marshal(obj, context, dsi, type)); } else if (CLRObjectMap.TryGetValue(obj, out retVal)) { return(retVal); } return(CreateDSObject(obj, context, dsi)); }
public static StackValue ConvertCSArrayToDSArray(FFIObjectMarshler marshaler, IEnumerable enumerable, ProtoCore.Runtime.Context context, Interpreter dsi, ProtoCore.Type type) { var core = dsi.runtime.Core; List <StackValue> svs = new List <StackValue>(); //Create new dsType for marshaling the elements, by reducing the rank ProtoCore.Type dsType = new ProtoCore.Type { Name = type.Name, rank = type.rank - 1, UID = type.UID }; dsType.IsIndexable = dsType.rank > 0; foreach (var item in enumerable) { StackValue value = marshaler.Marshal(item, context, dsi, dsType); svs.Add(value); } var retVal = dsi.runtime.rmem.BuildArray(svs.ToArray()); return(retVal); }
/// <summary> /// /// </summary> /// <param name="csArray"></param> /// <param name="context"></param> /// <param name="dsi"></param> /// <returns></returns> public static StackValue ConvertCSArrayToDSArray(FFIObjectMarshler marshaler, Array csArray, ProtoCore.Runtime.Context context, Interpreter dsi, ProtoCore.Type type) { var core = dsi.runtime.Core; StackValue[] sv = new StackValue[csArray.Length]; int size = sv.Length; //Create new dsType for marshaling the elements, by reducing the rank ProtoCore.Type dsType = new ProtoCore.Type { Name = type.Name, rank = type.rank - 1, UID = type.UID }; dsType.IsIndexable = dsType.rank > 0; for (int i = 0; i < size; ++i) { StackValue value = marshaler.Marshal(csArray.GetValue(i), context, dsi, dsType); sv[i] = value; } var retVal = dsi.runtime.rmem.BuildArray(sv); return(retVal); }
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); }
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); }
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.AccessViolation, ex.InnerException.Message); } dsi.LogWarning(ProtoCore.Runtime.WarningID.AccessViolation, 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.InvalidArguments, msg); } else if (exc is System.ArgumentException) { dsi.LogWarning(ProtoCore.Runtime.WarningID.InvalidArguments, ErrorString(exc)); } else if (exc is System.NullReferenceException) { dsi.LogWarning(ProtoCore.Runtime.WarningID.AccessViolation, ErrorString(null)); } else { dsi.LogWarning(ProtoCore.Runtime.WarningID.AccessViolation, ErrorString(exc)); } } else { dsi.LogWarning(ProtoCore.Runtime.WarningID.AccessViolation, ErrorString(ex)); } } catch (System.Reflection.TargetParameterCountException ex) { if (ex.InnerException != null) { dsi.LogWarning(ProtoCore.Runtime.WarningID.AccessViolation, ex.InnerException.Message); } dsi.LogWarning(ProtoCore.Runtime.WarningID.AccessViolation, ex.Message); } catch (System.MethodAccessException ex) { if (ex.InnerException != null) { dsi.LogWarning(ProtoCore.Runtime.WarningID.AccessViolation, ex.InnerException.Message); } dsi.LogWarning(ProtoCore.Runtime.WarningID.AccessViolation, ex.Message); } catch (System.InvalidOperationException ex) { if (ex.InnerException != null) { dsi.LogWarning(ProtoCore.Runtime.WarningID.AccessViolation, ex.InnerException.Message); } dsi.LogWarning(ProtoCore.Runtime.WarningID.AccessViolation, ex.Message); } catch (System.NotSupportedException ex) { if (ex.InnerException != null) { dsi.LogWarning(ProtoCore.Runtime.WarningID.AccessViolation, ex.InnerException.Message); } dsi.LogWarning(ProtoCore.Runtime.WarningID.AccessViolation, 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.InvalidArguments, msg); } catch (System.ArgumentException ex) { if (ex.InnerException != null) { dsi.LogWarning(ProtoCore.Runtime.WarningID.InvalidArguments, ErrorString(ex.InnerException)); } else { dsi.LogWarning(ProtoCore.Runtime.WarningID.InvalidArguments, ErrorString(ex)); } } catch (Exception ex) { if (ex.InnerException != null) { dsi.LogWarning(ProtoCore.Runtime.WarningID.Default, ErrorString(ex.InnerException)); } dsi.LogWarning(ProtoCore.Runtime.WarningID.Default, ErrorString(ex)); } return(dsRetValue); }
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)); }