Example #1
0
        public override ParamMarshal GenerateFunctionParamMarshal(Parameter param, int paramIndex,
                                                                  Function function = null)
        {
            var paramMarshal = new ParamMarshal {
                Name = param.Name, Param = param
            };

            var argName = Generator.GeneratedIdentifier(param.Name);

            Parameter effectiveParam = param;
            var       isRef          = param.IsOut || param.IsInOut;
            var       paramType      = param.Type;

            var ctx = new MarshalContext(Context, CurrentIndentation)
            {
                Parameter      = effectiveParam,
                ParameterIndex = paramIndex,
                ArgName        = argName,
                Function       = function
            };

            var marshal = new QuickJSMarshalManagedToNativePrinter(ctx);

            effectiveParam.Visit(marshal);

            if (string.IsNullOrEmpty(marshal.Context.Before))
            {
                throw new Exception($"Cannot marshal argument of function '{function.QualifiedOriginalName}'");
            }

            if (!string.IsNullOrWhiteSpace(marshal.Context.Before))
            {
                Write(marshal.Context.Before);
            }

            NewLine();

            paramMarshal.Name = argName;
            return(paramMarshal);
        }
Example #2
0
        private ParamMarshal GenerateFunctionParamMarshal(Parameter param, int paramIndex,
                                                          Function function = null)
        {
            var paramMarshal = new ParamMarshal {
                Name = param.Name, Param = param
            };

            if (param.Type is BuiltinType)
            {
                return(paramMarshal);
            }

            var argName = Generator.GeneratedIdentifier("arg") + paramIndex.ToString(CultureInfo.InvariantCulture);

            var isRef = param.IsOut || param.IsInOut;

            var paramType = param.Type;

            // Get actual type if the param type is a typedef but not a function type because function types have to be typedef.
            // We need to get the actual type this early before we visit any marshalling code to ensure we hit the marshalling
            // logic for the actual type and not the typedef.
            // This fixes issues where typedefs to primitive pointers are involved.
            FunctionType functionType;
            var          paramTypeAsTypedef = paramType as TypedefType;

            if (paramTypeAsTypedef != null && !paramTypeAsTypedef.Declaration.Type.IsPointerTo(out functionType))
            {
                paramType = param.Type.Desugar();
            }

            // Since both pointers and references to types are wrapped as CLI
            // tracking references when using in/out, we normalize them here to be able
            // to use the same code for marshaling.
            if (paramType is PointerType && isRef)
            {
                if (!paramType.IsReference())
                {
                    paramMarshal.Prefix = "&";
                }
                paramType = (paramType as PointerType).Pointee;
            }

            var effectiveParam = new Parameter(param)
            {
                QualifiedType = new QualifiedType(paramType)
            };

            var ctx = new MarshalContext(Context, CurrentIndentation)
            {
                Parameter      = effectiveParam,
                ParameterIndex = paramIndex,
                ArgName        = argName,
                Function       = function
            };

            var marshal = new CLIMarshalManagedToNativePrinter(ctx);

            effectiveParam.Visit(marshal);

            if (string.IsNullOrEmpty(marshal.Context.Return))
            {
                throw new Exception($"Cannot marshal argument of function '{function.QualifiedOriginalName}'");
            }

            if (isRef)
            {
                var typePrinter = new CppTypePrinter(Context)
                {
                    ResolveTypeMaps = false
                };
                var type = paramType.Visit(typePrinter);

                if (param.IsInOut)
                {
                    if (!string.IsNullOrWhiteSpace(marshal.Context.Before))
                    {
                        Write(marshal.Context.Before);
                    }

                    WriteLine("{0} {1} = {2};", type, argName, marshal.Context.Return);
                }
                else
                {
                    WriteLine("{0} {1};", type, argName);
                }
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(marshal.Context.Before))
                {
                    Write(marshal.Context.Before);
                }

                WriteLine("auto {0}{1} = {2};", marshal.VarPrefix, argName,
                          marshal.Context.Return);
                paramMarshal.Prefix = marshal.ArgumentPrefix;
            }

            paramMarshal.Name = argName;
            return(paramMarshal);
        }
Example #3
0
        private ParamMarshal GenerateFunctionParamMarshal(Parameter param, int paramIndex,
                                                          Function function = null)
        {
            var paramMarshal = new ParamMarshal {
                Name = param.Name, Param = param
            };

            if (param.Type is BuiltinType)
            {
                return(paramMarshal);
            }

            var argName = Generator.GeneratedIdentifier("arg") + paramIndex.ToString(CultureInfo.InvariantCulture);

            var isRef = param.IsOut || param.IsInOut;
            // Since both pointers and references to types are wrapped as CLI
            // tracking references when using in/out, we normalize them here to be able
            // to use the same code for marshaling.
            var paramType = param.Type;

            if (paramType is PointerType && isRef)
            {
                if (!paramType.IsReference())
                {
                    paramMarshal.Prefix = "&";
                }
                paramType = (paramType as PointerType).Pointee;
            }

            var effectiveParam = new Parameter(param)
            {
                QualifiedType = new QualifiedType(paramType)
            };

            var ctx = new MarshalContext(Context)
            {
                Parameter      = effectiveParam,
                ParameterIndex = paramIndex,
                ArgName        = argName,
                Function       = function
            };

            var marshal = new CLIMarshalManagedToNativePrinter(ctx);

            effectiveParam.Visit(marshal);

            if (string.IsNullOrEmpty(marshal.Context.Return))
            {
                throw new Exception(string.Format("Cannot marshal argument of function '{0}'",
                                                  function.QualifiedOriginalName));
            }

            if (isRef)
            {
                var typePrinter = new CppTypePrinter();
                var type        = paramType.Visit(typePrinter);

                if (param.IsInOut)
                {
                    if (!string.IsNullOrWhiteSpace(marshal.Context.Before))
                    {
                        Write(marshal.Context.Before);
                    }

                    WriteLine("{0} {1} = {2};", type, argName, marshal.Context.Return);
                }
                else
                {
                    WriteLine("{0} {1};", type, argName);
                }
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(marshal.Context.Before))
                {
                    Write(marshal.Context.Before);
                }

                WriteLine("auto {0}{1} = {2};", marshal.VarPrefix, argName,
                          marshal.Context.Return);
                paramMarshal.Prefix = marshal.ArgumentPrefix;
            }

            paramMarshal.Name = argName;
            return(paramMarshal);
        }
Example #4
0
        private ParamMarshal GenerateFunctionParamMarshal(Parameter param, int paramIndex,
                                                          Function function = null)
        {
            var paramMarshal = new ParamMarshal {
                Name = param.Name, Param = param
            };

            if (param.Type is BuiltinType)
            {
                return(paramMarshal);
            }

            var argName = "arg" + paramIndex.ToString(CultureInfo.InvariantCulture);

            if (param.IsOut || param.IsInOut)
            {
                var paramType = param.Type;
                if (paramType is PointerType)
                {
                    if (!paramType.IsReference())
                    {
                        paramMarshal.Prefix = "&";
                    }
                    paramType = (paramType as PointerType).Pointee;
                }

                var typePrinter = new CppTypePrinter(Driver.TypeDatabase);
                var type        = paramType.Visit(typePrinter);

                WriteLine("{0} {1};", type, argName);
            }
            else
            {
                var ctx = new MarshalContext(Driver)
                {
                    Parameter      = param,
                    ParameterIndex = paramIndex,
                    ArgName        = argName,
                    Function       = function
                };

                var marshal = new CLIMarshalManagedToNativePrinter(ctx);
                param.Visit(marshal);

                if (string.IsNullOrEmpty(marshal.Context.Return))
                {
                    throw new Exception(string.Format("Cannot marshal argument of function '{0}'",
                                                      function.QualifiedOriginalName));
                }

                if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
                {
                    Write(marshal.Context.SupportBefore);
                }

                WriteLine("auto {0}{1} = {2};", marshal.VarPrefix, argName,
                          marshal.Context.Return);
                argName = marshal.ArgumentPrefix + argName;
            }

            paramMarshal.Name = argName;
            return(paramMarshal);
        }
Example #5
0
        public virtual ParamMarshal GenerateFunctionParamMarshal(Parameter param, int paramIndex,
                                                                 Function function = null)
        {
            var paramMarshal = new ParamMarshal {
                Name = param.Name, Param = param
            };

            var argName = Generator.GeneratedIdentifier("arg") + paramIndex.ToString(CultureInfo.InvariantCulture);

            Parameter effectiveParam = param;
            var       isRef          = param.IsOut || param.IsInOut;
            var       paramType      = param.Type;

            // TODO: Use same name between generators
            var typeArgName = $"args[{paramIndex}]";

            if (this is QuickJSInvokes)
            {
                typeArgName = $"argv[{paramIndex}]";
            }

            var ctx = new MarshalContext(Context, CurrentIndentation)
            {
                Parameter      = effectiveParam,
                ParameterIndex = paramIndex,
                ArgName        = typeArgName,
                Function       = function
            };

            paramMarshal.Context = ctx;

            var marshal = GetMarshalManagedToNativePrinter(ctx);

            effectiveParam.Visit(marshal);

            if (string.IsNullOrEmpty(marshal.Context.Return))
            {
                throw new Exception($"Cannot marshal argument of function '{function.QualifiedOriginalName}'");
            }

            if (isRef)
            {
                var type = paramType.Visit(CTypePrinter);

                if (param.IsInOut)
                {
                    if (!string.IsNullOrWhiteSpace(marshal.Context.Before))
                    {
                        Write(marshal.Context.Before);
                        NeedNewLine();
                    }

                    WriteLine($"{type} {argName} = {marshal.Context.Return};");
                }
                else
                {
                    WriteLine($"{type} {argName};");
                }
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(marshal.Context.Before))
                {
                    Write(marshal.Context.Before);
                }

                WriteLine($"auto {marshal.Context.VarPrefix}{argName} = {marshal.Context.Return};");
                paramMarshal.Prefix = marshal.Context.ArgumentPrefix;
                NewLine();
            }

            paramMarshal.Name = argName;
            return(paramMarshal);
        }
Example #6
0
        private ParamMarshal GenerateFunctionParamMarshal(Parameter param, int paramIndex,
                                                          Function function = null)
        {
            var paramMarshal = new ParamMarshal {
                Name = param.Name, Param = param
            };

            if (param.Type is BuiltinType)
            {
                return(paramMarshal);
            }

            var argName = Generator.GeneratedIdentifier("arg") + paramIndex.ToString(CultureInfo.InvariantCulture);

            Parameter effectiveParam = param;
            var       isRef          = param.IsOut || param.IsInOut;
            var       paramType      = param.Type;

            var ctx = new MarshalContext(Context, CurrentIndentation)
            {
                Parameter      = effectiveParam,
                ParameterIndex = paramIndex,
                ArgName        = argName,
                Function       = function
            };

            var marshal = new CppMarshalManagedToNativePrinter(ctx);

            effectiveParam.Visit(marshal);

            if (string.IsNullOrEmpty(marshal.Context.Return))
            {
                throw new Exception($"Cannot marshal argument of function '{function.QualifiedOriginalName}'");
            }

            if (isRef)
            {
                var type = paramType.Visit(CTypePrinter);

                if (param.IsInOut)
                {
                    if (!string.IsNullOrWhiteSpace(marshal.Context.Before))
                    {
                        Write(marshal.Context.Before);
                    }

                    WriteLine($"{type} {argName} = {marshal.Context.Return};");
                }
                else
                {
                    WriteLine($"{type} {argName};");
                }
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(marshal.Context.Before))
                {
                    Write(marshal.Context.Before);
                }

                WriteLine($"auto {marshal.VarPrefix}{argName} = {marshal.Context.Return};");
                paramMarshal.Prefix = marshal.ArgumentPrefix;
            }

            paramMarshal.Name = argName;
            return(paramMarshal);
        }