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); }
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); }
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); }
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); }
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); }
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); }