Exemple #1
0
        private static void EmitStringArrayEpilogue(MethodDefinition wrapper, ParameterDefinition parameter, MethodBody body,
                                                    ILProcessor il, GeneratedVariableIdentifier generatedPtrVar)
        {
            if (generatedPtrVar == null)
            {
                throw new ArgumentNullException(nameof(generatedPtrVar));
            }

            // Note: only works for string vectors (1d arrays).
            // We do not (and will probably never) support 2d or higher string arrays
            var free = wrapper.Module.ImportReference(TypeBindingsBase.Methods.First(m => m.Name == "FreeStringArrayPtr"));

            // FreeStringArrayPtr(string_array_ptr, string_array.Length)

            // load string_array_ptr
            il.Emit(OpCodes.Ldloc, generatedPtrVar.Definition.Index);

            // load string_array.Length
            il.Emit(OpCodes.Ldarg, parameter.Index);
            il.Emit(OpCodes.Ldlen);
            il.Emit(OpCodes.Conv_I4);

            // call FreeStringArrayPtr
            il.Emit(OpCodes.Call, free);
        }
Exemple #2
0
        private static GeneratedVariableIdentifier EmitStringArrayParameter(MethodDefinition wrapper, ParameterDefinition parameter, MethodBody body,
                                                                            ILProcessor il)
        {
            // string[] masrhaling:
            // IntPtr ptr = MarshalStringArrayToPtr(strings);
            // try { calli }
            // finally { FreeStringArrayPtr(ptr); }
            var marshal_str_array_to_ptr = wrapper.Module.ImportReference(TypeBindingsBase.Methods.First(m => m.Name == "MarshalStringArrayToPtr"));

            // IntPtr ptr;
            var variableDefinition = new VariableDefinition(TypeIntPtr);

            body.Variables.Add(variableDefinition);
            int generatedPointerVarIndex = body.Variables.Count - 1;

            GeneratedVariableIdentifier stringArrayPtrVar = new GeneratedVariableIdentifier(body, variableDefinition, parameter.Name + "_string_array_ptr");

            // ptr = MarshalStringArrayToPtr(strings);
            il.Emit(OpCodes.Call, marshal_str_array_to_ptr);
            il.Emit(OpCodes.Stloc, generatedPointerVarIndex);
            il.Emit(OpCodes.Ldloc, generatedPointerVarIndex);

            // The finally block will be emitted in the function epilogue

            return(stringArrayPtrVar);
        }
Exemple #3
0
        private static void EmitStringEpilogue(MethodDefinition wrapper, ParameterDefinition parameter, MethodBody body,
                                               ILProcessor il, GeneratedVariableIdentifier generatedPtrVar)
        {
            var free = wrapper.Module.ImportReference(TypeBindingsBase.Methods.First(m => m.Name == "FreeStringPtr"));

            // FreeStringPtr(ptr)
            il.Emit(OpCodes.Ldloc, generatedPtrVar.Definition.Index);
            il.Emit(OpCodes.Call, free);
        }
Exemple #4
0
        private static void EmitStringOutEpilogue(MethodDefinition wrapper, MethodDefinition native,
                                                  ParameterDefinition parameter, MethodBody body, ILProcessor il, GeneratedVariableIdentifier generatedPtrVar)
        {
            if (generatedPtrVar == null)
            {
                throw new ArgumentNullException(nameof(generatedPtrVar));
            }

            // void GetShaderInfoLog(..., out String foo)
            // IntPtr foo_string_ptr;
            // try {
            //  foo_string_ptr = Marshal.AllocHGlobal(count + 1);
            //  glGetShaderInfoLog(..., foo_string_ptr);
            //  foo = MarshalPtrToString(foo_string_ptr);
            // }
            // finally {
            //  Marshal.FreeHGlobal(foo_string_ptr);
            // }

            // Make sure we have imported BindingsBase::MasrhalPtrToString and Marshal::FreeHGlobal
            var ptr_to_str   = wrapper.Module.ImportReference(TypeBindingsBase.Methods.First(m => m.Name == "MarshalPtrToString"));
            var free_hglobal = wrapper.Module.ImportReference(TypeMarshal.Methods.First(m => m.Name == "FreeHGlobal"));

            var block = new ExceptionHandler(ExceptionHandlerType.Finally);

            block.TryStart = body.Instructions[0];

            il.Emit(OpCodes.Ldarg, parameter.Index);
            il.Emit(OpCodes.Ldloc, generatedPtrVar.Definition.Index);
            il.Emit(OpCodes.Call, ptr_to_str);
            il.Emit(OpCodes.Stind_Ref);

            block.TryEnd       = body.Instructions.Last();
            block.HandlerStart = body.Instructions.Last();

            il.Emit(OpCodes.Ldloc, generatedPtrVar.Definition.Index);
            il.Emit(OpCodes.Call, free_hglobal);

            block.HandlerEnd = body.Instructions.Last();
        }
Exemple #5
0
        private static GeneratedVariableIdentifier EmitStringOutParameter(MethodDefinition method, ParameterDefinition parameter, MethodBody body, ILProcessor il)
        {
            // void GetShaderInfoLog(..., out String foo)
            // IntPtr foo_string_ptr;
            // try {
            //  foo_string_ptr = Marshal.AllocHGlobal(count + 1);
            //  glGetShaderInfoLog(..., foo_string_ptr);
            //  foo = MarshalPtrToString(foo_string_ptr);
            // }
            // finally {
            //  Marshal.FreeHGlobal(foo_string_ptr);
            // }

            // Pop off the string parameter that would of just been loaded
            il.Emit(OpCodes.Pop);

            // Make sure we have imported Marshal::AllocHGlobal
            var alloc_hglobal = method.Module.ImportReference(TypeMarshal.Methods.First(m => m.Name == "AllocHGlobal"));

            // IntPtr ptr;
            var variableDefinition = new VariableDefinition(TypeIntPtr);

            body.Variables.Add(variableDefinition);
            int stringPtrIndex = body.Variables.Count - 1;

            GeneratedVariableIdentifier stringPtrVar = new GeneratedVariableIdentifier(body, variableDefinition, parameter.Name + "_string_ptr");

            // ptr = Marshal.AllocHGlobal(count + 1);
            var count = GetCountAttribute(parameter);

            if (count == null)
            {
                // We need a count attribute so we know what size to make the
                // string buffer. Currently every string out parameter has a
                // count attribute but this check is in place to make things
                // clearer if this case is ever hit.
                throw new InvalidOperationException(string.Format("{0}({1}) doesn't have a count attribute", method.Name, parameter.Name));
            }

            if (count.Count != 0)
            {
                // Fixed size
                il.Emit(OpCodes.Ldc_I4, count.Count);
            }
            else if (count.Parameter != null)
            {
                // Parameter sized
                var countVariable = EmitCountVariable(method, body, il, count.Parameter);
                il.Emit(OpCodes.Ldloc, countVariable.Index);
            }
            else if (count.Computed != null)
            {
                if (method.Name == "GetActiveVarying")
                {
                    // GetActiveVaryingNV's name parameter has a count of "COMPSIZE(program,index,bufSize)" but really it should be bufSize.
                    var countVariable = EmitCountVariable(method, body, il, "bufSize");
                    il.Emit(OpCodes.Ldloc, countVariable.Index);
                }
                else
                {
                    // Computed counts are hard and require manual reading of the specification for each one.
                    throw new NotSupportedException(string.Format("{0}({1}) requires a computed count: {2}", method.Name, parameter.Name, count.Computed));
                }
            }

            il.Emit(OpCodes.Ldc_I4, 1);
            il.Emit(OpCodes.Add);
            il.Emit(OpCodes.Call, alloc_hglobal);
            il.Emit(OpCodes.Stloc, stringPtrIndex);
            il.Emit(OpCodes.Ldloc, stringPtrIndex);

            // We'll emit the try-finally block in the epilogue implementation,
            // because we haven't yet emitted all necessary instructions here.

            return(stringPtrVar);
        }