Skip to content

Commit

Permalink
Fixes to QuickJS marshaling.
Browse files Browse the repository at this point in the history
  • Loading branch information
tritao committed Sep 1, 2024
1 parent bf03942 commit 443c9a0
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 78 deletions.
118 changes: 42 additions & 76 deletions src/Generator/Generators/QuickJS/QuickJSMarshal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,34 +61,22 @@ public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)

var pointee = pointer.Pointee.Desugar();

PrimitiveType primitive;
var param = Context.Parameter;
if (param != null && (param.IsOut || param.IsInOut) &&
pointee.IsPrimitiveType(out primitive))
pointee.IsPrimitiveType(out _))
{
Context.Return.Write(Context.ReturnVarName);
return true;
}

if (pointee.IsPrimitiveType(out primitive))
if (pointee.IsPrimitiveType(out _))
{
var returnVarName = Context.ReturnVarName;

if (pointer.GetFinalQualifiedPointee().Qualifiers.IsConst !=
Context.ReturnType.Qualifiers.IsConst)
if (pointer.IsConstCharString())
{
var nativeTypePrinter = new CppTypePrinter(Context.Context)
{ PrintTypeQualifiers = false };
var returnType = Context.ReturnType.Type.Desugar();
var constlessPointer = new PointerType()
{
IsDependent = pointer.IsDependent,
Modifier = pointer.Modifier,
QualifiedPointee = new QualifiedType(returnType.GetPointee())
};
var nativeConstlessTypeName = constlessPointer.Visit(nativeTypePrinter, new TypeQualifiers());
returnVarName = string.Format("const_cast<{0}>({1})",
nativeConstlessTypeName, Context.ReturnVarName);
var retName = Generator.GeneratedIdentifier(Context.ReturnVarName);
Context.Before.Write($"JSValue {retName} = JS_NewString(ctx, {Context.ArgName});");
Context.Return.Write(retName);
return true;
}

if (pointer.Pointee is TypedefType)
Expand All @@ -101,19 +89,17 @@ public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
};
var nativeTypeName = desugaredPointer.Visit(typePrinter, quals);
Context.Return.Write("reinterpret_cast<{0}>({1})", nativeTypeName,
returnVarName);
Context.ReturnVarName);
}
else
Context.Return.Write(returnVarName);
Context.Return.Write(Context.ReturnVarName);

return true;
}

TypeMap typeMap = null;
Context.Context.TypeMaps.FindTypeMap(pointee, out typeMap);
Context.Context.TypeMaps.FindTypeMap(pointee, out var typeMap);

Class @class;
if (pointee.TryGetClass(out @class) && typeMap == null)
if (pointee.TryGetClass(out var @class) && typeMap == null)
{
var instance = (pointer.IsReference) ? "&" + Context.ReturnVarName
: Context.ReturnVarName;
Expand Down Expand Up @@ -149,7 +135,8 @@ public bool VisitPrimitiveType(PrimitiveType primitive)
switch (primitive)
{
case PrimitiveType.Void:
return true;
Context.Before.WriteLine($"JS_UNDEFINED;");
break;

case PrimitiveType.Bool:
Context.Before.WriteLine($"JS_NewBool(ctx, {Context.ArgName});");
Expand Down Expand Up @@ -205,17 +192,15 @@ public override bool VisitTypedefType(TypedefType typedef, TypeQualifiers quals)
{
var decl = typedef.Declaration;

TypeMap typeMap;
if (Context.Context.TypeMaps.FindTypeMap(decl.Type, out typeMap) &&
if (Context.Context.TypeMaps.FindTypeMap(decl.Type, out var typeMap) &&
typeMap.DoesMarshalling)
{
typeMap.Type = typedef;
typeMap.MarshalToManaged(Context);
return typeMap.IsValueType;
}

FunctionType function;
if (decl.Type.IsPointerTo(out function))
if (decl.Type.IsPointerTo(out FunctionType _))
{
var typeName = typePrinter.VisitDeclaration(decl);
var typeName2 = decl.Type.Visit(typePrinter);
Expand All @@ -228,8 +213,7 @@ public override bool VisitTypedefType(TypedefType typedef, TypeQualifiers quals)
public override bool VisitTemplateSpecializationType(TemplateSpecializationType template,
TypeQualifiers quals)
{
TypeMap typeMap;
if (Context.Context.TypeMaps.FindTypeMap(template, out typeMap) && typeMap.DoesMarshalling)
if (Context.Context.TypeMaps.FindTypeMap(template, out var typeMap) && typeMap.DoesMarshalling)
{
typeMap.Type = template;
typeMap.MarshalToManaged(Context);
Expand Down Expand Up @@ -382,8 +366,7 @@ public QuickJSMarshalManagedToNativePrinter(MarshalContext ctx)

public override bool VisitType(Type type, TypeQualifiers quals)
{
TypeMap typeMap;
if (Context.Context.TypeMaps.FindTypeMap(type, out typeMap) && typeMap.DoesMarshalling)
if (Context.Context.TypeMaps.FindTypeMap(type, out var typeMap) && typeMap.DoesMarshalling)
{
typeMap.MarshalToNative(Context);
return false;
Expand Down Expand Up @@ -443,8 +426,7 @@ public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
return VisitDelegateType(cppTypeName);
}

Enumeration @enum;
if (pointee.TryGetEnum(out @enum))
if (pointee.TryGetEnum(out var @enum))
{
var isRef = Context.Parameter.Usage == ParameterUsage.Out ||
Context.Parameter.Usage == ParameterUsage.InOut;
Expand All @@ -455,14 +437,24 @@ public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
return true;
}

Class @class;
if (pointee.TryGetClass(out @class) && @class.IsValueType)
if (pointee.TryGetClass(out var @class) && @class.IsValueType)
{
if (Context.Function == null)
Context.Return.Write("&");
return pointer.QualifiedPointee.Visit(this);
}

if (pointer.IsConstCharString())
{
var genName = Generator.GeneratedIdentifier(Context.Parameter.Name);
Context.Before.WriteLine($"auto {genName} = JS_ToCString(ctx, argv[{Context.ParameterIndex}]);");
Context.Before.WriteLine($"if ({genName} == NULL)");
Context.Before.WriteLineIndent("return JS_EXCEPTION;");
Context.Return.Write($"{genName}");
Context.Cleanup.WriteLine($"JS_FreeCString(ctx, {genName});");
return true;
}

var finalPointee = pointer.GetFinalPointee();
if (finalPointee.IsPrimitiveType())
{
Expand Down Expand Up @@ -569,6 +561,12 @@ public bool VisitPrimitiveType(PrimitiveType primitive)
Context.Return.Write($"{argName}");
return true;

case PrimitiveType.Null:
Context.Before.WriteLine($"if (!JS_IsNull(argv[{Context.ParameterIndex}]))");
Context.Before.WriteLineIndent("return JS_EXCEPTION;");
Context.Return.Write($"{argName}");
return true;

case PrimitiveType.WideChar:
default:
throw new NotImplementedException();
Expand All @@ -579,16 +577,14 @@ public override bool VisitTypedefType(TypedefType typedef, TypeQualifiers quals)
{
var decl = typedef.Declaration;

TypeMap typeMap;
if (Context.Context.TypeMaps.FindTypeMap(decl.Type, out typeMap) &&
if (Context.Context.TypeMaps.FindTypeMap(decl.Type, out var typeMap) &&
typeMap.DoesMarshalling)
{
typeMap.MarshalToNative(Context);
return typeMap.IsValueType;
}

FunctionType func;
if (decl.Type.IsPointerTo(out func))
if (decl.Type.IsPointerTo(out FunctionType _))
{
typePrinter.PushContext(TypePrinterContextKind.Native);
var declName = decl.Visit(typePrinter);
Expand All @@ -609,8 +605,7 @@ public override bool VisitTypedefType(TypedefType typedef, TypeQualifiers quals)
return true;
}

PrimitiveType primitive;
if (decl.Type.IsPrimitiveType(out primitive))
if (decl.Type.IsPrimitiveType(out _))
{
Context.Return.Write($"(::{typedef.Declaration.QualifiedOriginalName})");
}
Expand All @@ -621,8 +616,7 @@ public override bool VisitTypedefType(TypedefType typedef, TypeQualifiers quals)
public override bool VisitTemplateSpecializationType(TemplateSpecializationType template,
TypeQualifiers quals)
{
TypeMap typeMap;
if (Context.Context.TypeMaps.FindTypeMap(template, out typeMap) && typeMap.DoesMarshalling)
if (Context.Context.TypeMaps.FindTypeMap(template, out var typeMap) && typeMap.DoesMarshalling)
{
typeMap.Type = template;
typeMap.MarshalToNative(Context);
Expand Down Expand Up @@ -668,42 +662,14 @@ public override bool VisitClassDecl(Class @class)
private void MarshalRefClass(Class @class)
{
var type = Context.Parameter.Type.Desugar();
TypeMap typeMap;
if (Context.Context.TypeMaps.FindTypeMap(type, out typeMap) &&
if (Context.Context.TypeMaps.FindTypeMap(type, out var typeMap) &&
typeMap.DoesMarshalling)
{
typeMap.MarshalToNative(Context);
return;
}

if (!type.SkipPointerRefs().IsPointer())
{
Context.Return.Write("*");

if (Context.Parameter.Type.IsReference())
VarPrefix.Write("&");
}

var method = Context.Function as Method;
if (method != null
&& method.Conversion == MethodConversionKind.FunctionToInstanceMethod
&& Context.ParameterIndex == 0)
{
Context.Return.Write($"(::{@class.QualifiedOriginalName}*)");
Context.Return.Write(Helpers.InstanceIdentifier);
return;
}

var paramType = Context.Parameter.Type.Desugar();
var isPointer = paramType.SkipPointerRefs().IsPointer();
var deref = isPointer ? "->" : ".";
var instance = $"(::{@class.QualifiedOriginalName}*)" +
$"{Context.Parameter.Name}{deref}{Helpers.InstanceIdentifier}";

if (isPointer)
Context.Return.Write($"{Context.Parameter.Name} ? {instance} : nullptr");
else
Context.Return.Write($"{instance}");
Context.Return.Write($"({@class.QualifiedOriginalName}*) JS_GetOpaque(argv[{Context.ParameterIndex}], 0)");
}

private void MarshalValueClass(Class @class)
Expand Down
2 changes: 1 addition & 1 deletion tests/quickjs/premake5.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
local qjs_dir = path.getabsolute("../../deps/quickjs")
local qjs_dir = path.getabsolute("./quickjs")
local runtime = "../../src/Generator/Generators/QuickJS/Runtime"

workspace "qjs"
Expand Down
2 changes: 1 addition & 1 deletion tests/quickjs/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ rootdir="$dir/../.."
dotnet_configuration=Release
configuration=debug
platform=x64
jsinterp="$rootdir/deps/quickjs/qjs-debug"
jsinterp="$dir/quickjs/qjs"

red=`tput setaf 1`
green=`tput setaf 2`
Expand Down

0 comments on commit 443c9a0

Please sign in to comment.