[new] 支持WebGL

main
walon 2022-10-19 09:54:33 +08:00
parent 093f67296a
commit 15319a59fa
12 changed files with 208 additions and 10 deletions

View File

@ -15,6 +15,7 @@ namespace HybridCLR.Editor.ABI
case PlatformABI.Arm64: return "HYBRIDCLR_ABI_ARM_64";
case PlatformABI.Universal64: return "HYBRIDCLR_ABI_UNIVERSAL_64";
case PlatformABI.Universal32: return "HYBRIDCLR_ABI_UNIVERSAL_32";
case PlatformABI.WebGL32: return "HYBRIDCLR_ABI_WEBGL32";
default: throw new NotSupportedException();
}
}

View File

@ -5,5 +5,6 @@
Universal32,
Universal64,
Arm64,
WebGL32,
}
}

View File

@ -14,6 +14,8 @@ namespace HybridCLR.Editor.ABI
public virtual bool IsSupportHFA => false;
public virtual bool IsSupportSingletonStruct => false;
public TypeInfo GetNativeIntTypeInfo() => IsArch32 ? TypeInfo.s_i4 : TypeInfo.s_i8;
public ValueTypeSizeAligmentCalculator Calculator => IsArch32 ? ValueTypeSizeAligmentCalculator.Caculator32 : ValueTypeSizeAligmentCalculator.Caculator64;
@ -170,6 +172,78 @@ namespace HybridCLR.Editor.ABI
return false;
}
public static bool TryComputSingletonStruct(TypeSig type, out SingletonStruct result)
{
result = new SingletonStruct();
return TryComputSingletonStruct0(type, result) && result.Type != null;
}
public static bool TryComputSingletonStruct0(TypeSig type, SingletonStruct result)
{
TypeDef typeDef = type.ToTypeDefOrRef().ResolveTypeDefThrow();
if (typeDef.IsEnum)
{
if (result.Type == null)
{
result.Type = typeDef.GetEnumUnderlyingType();
return true;
}
else
{
return false;
}
}
List<TypeSig> klassInst = type.ToGenericInstSig()?.GenericArguments?.ToList();
GenericArgumentContext ctx = klassInst != null ? new GenericArgumentContext(klassInst, null) : null;
var fields = typeDef.Fields;// typeDef.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldDef field in fields)
{
if (field.IsStatic)
{
continue;
}
TypeSig ftype = ctx != null ? MetaUtil.Inflate(field.FieldType, ctx) : field.FieldType;
switch (ftype.ElementType)
{
case ElementType.TypedByRef: return false;
case ElementType.ValueType:
{
if (!TryComputSingletonStruct0(ftype, result))
{
return false;
}
break;
}
case ElementType.GenericInst:
{
if (!ftype.IsValueType)
{
goto default;
}
if (!TryComputSingletonStruct0(ftype, result))
{
return false;
}
break;
}
default:
{
if (result.Type != null)
{
return false;
}
result.Type = ftype;
break;
}
}
}
return true;
}
protected static TypeInfo CreateGeneralValueType(TypeSig type, int size, int aligment)
{
System.Diagnostics.Debug.Assert(size % aligment == 0);
@ -197,6 +271,10 @@ namespace HybridCLR.Editor.ABI
default: throw new NotSupportedException();
}
}
//else if(IsSupportSingletonStruct && TryComputSingletonStruct(type, out var ssTypeInfo))
//{
// return CreateTypeInfo(ssTypeInfo.Type);
//}
else
{
// 64位下结构体内存对齐规则是一样的

View File

@ -15,6 +15,7 @@ namespace HybridCLR.Editor.ABI
case PlatformABI.Arm64: return new TypeCreatorArm64();
case PlatformABI.Universal32: return new TypeCreatorUniversal32();
case PlatformABI.Universal64: return new TypeCreatorUniversal64();
case PlatformABI.WebGL32: return new TypeCreatorWebGL32();
default: throw new NotSupportedException(abi.ToString());
}
}

View File

@ -0,0 +1,34 @@
using dnlib.DotNet;
using HybridCLR.Editor.Meta;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HybridCLR.Editor.ABI
{
public class SingletonStruct
{
public TypeSig Type { get; set; }
}
public class TypeCreatorWebGL32 : TypeCreatorBase
{
public override bool IsArch32 => true;
public override bool IsSupportHFA => false;
public override bool IsSupportSingletonStruct => true;
protected override TypeInfo OptimizeSigType(TypeInfo type, bool returnType)
{
//if (type.PorType > ParamOrReturnType.STRUCTURE_ALIGN1 && type.PorType <= ParamOrReturnType.STRUCTURE_ALIGN4)
//{
// return new TypeInfo(ParamOrReturnType.STRUCTURE_ALIGN1, type.Size);
//}
return type;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4790a87aacda1a14d813570e9e0f35ca
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -81,7 +81,7 @@ namespace HybridCLR.Editor.BuildProcessors
if (jsonFiles.Length == 0)
{
Debug.LogError($"can not find file {SettingsUtil.ScriptingAssembliesJsonFile}");
//Debug.LogError($"can not find file {SettingsUtil.ScriptingAssembliesJsonFile}");
return;
}

View File

@ -74,6 +74,7 @@ namespace HybridCLR.Editor.MethodBridge
case PlatformABI.Universal32: return new PlatformGeneratorUniversal32();
case PlatformABI.Universal64: return new PlatformGeneratorUniversal64();
case PlatformABI.Arm64: return new PlatformGeneratorArm64();
case PlatformABI.WebGL32: return new PlatformGeneratorWebGL32();
default: throw new NotSupportedException();
}
}

View File

@ -14,14 +14,6 @@ namespace HybridCLR.Editor.MethodBridge
{
public override PlatformABI PlatformABI { get; } = PlatformABI.Universal32;
//protected override TypeInfo CreateValueType(TypeSig type, bool returnValue)
//{
// (int typeSize, int typeAligment) = ComputeSizeAndAligmentOfArch32(type);
// int actualAliment = typeAligment <= 4 ? 1 : 8;
// return CreateGeneralValueType(type, typeSize, actualAliment);
//}
public override void GenerateManaged2NativeMethod(MethodDesc method, List<string> lines)
{
string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" }));

View File

@ -0,0 +1,68 @@
using dnlib.DotNet;
using HybridCLR.Editor.ABI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace HybridCLR.Editor.MethodBridge
{
public class PlatformGeneratorWebGL32 : PlatformGeneratorBase
{
public override PlatformABI PlatformABI { get; } = PlatformABI.WebGL32;
public override void GenerateManaged2NativeMethod(MethodDesc method, List<string> lines)
{
string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" }));
string paramNameListStr = string.Join(", ", method.ParamInfos.Select(p => p.Managed2NativeParamValue(this.PlatformABI)).Concat(new string[] { "method" }));
lines.Add($@"
// {method.MethodDef}
static void __M2N_{method.CreateCallSigName()}(const MethodInfo* method, uint16_t* argVarIndexs, StackObject* localVarBase, void* ret)
{{
typedef {method.ReturnInfo.Type.GetTypeName()} (*NativeMethod)({paramListStr});
{(!method.ReturnInfo.IsVoid ? $"*({method.ReturnInfo.Type.GetTypeName()}*)ret = " : "")}((NativeMethod)(method->methodPointerCallByInterp))({paramNameListStr});
}}
");
}
public override void GenerateNative2ManagedMethod(MethodDesc method, List<string> lines)
{
int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.PlatformABI);
string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" }));
lines.Add($@"
// {method.MethodDef}
static {method.ReturnInfo.Type.GetTypeName()} __N2M_{method.CreateCallSigName()}({paramListStr})
{{
StackObject args[{Math.Max(totalQuadWordNum, 1)}] = {{{string.Join(", ", method.ParamInfos.Select(p => p.Native2ManagedParamValue(this.PlatformABI)))} }};
StackObject* ret = {(method.ReturnInfo.IsVoid ? "nullptr" : "args + " + method.ParamInfos.Count)};
Interpreter::Execute(method, args, ret);
{(!method.ReturnInfo.IsVoid ? $"return *({method.ReturnInfo.Type.GetTypeName()}*)ret;" : "")}
}}
");
}
public override void GenerateAdjustThunkMethod(MethodDesc method, List<string> lines)
{
int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.PlatformABI);
string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" }));
lines.Add($@"
// {method.MethodDef}
static {method.ReturnInfo.Type.GetTypeName()} __N2M_AdjustorThunk_{method.CreateCallSigName()}({paramListStr})
{{
StackObject args[{Math.Max(totalQuadWordNum, 1)}] = {{{string.Join(", ", method.ParamInfos.Select(p => (p.Index == 0 ? $"(uint64_t)(*(uint8_t**)&__arg{p.Index} + sizeof(Il2CppObject))" : p.Native2ManagedParamValue(this.PlatformABI))))} }};
StackObject* ret = {(method.ReturnInfo.IsVoid ? "nullptr" : "args + " + method.ParamInfos.Count)};
Interpreter::Execute(method, args, ret);
{(!method.ReturnInfo.IsVoid ? $"return *({method.ReturnInfo.Type.GetTypeName()}*)ret;" : "")}
}}
");
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2912d21f60f4c684785c31efcf2d9b29
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,6 +1,6 @@
{
"name": "com.focus-creative-games.hybridclr_unity",
"version": "0.6.1",
"version": "0.7.0",
"displayName": "HybridCLR",
"description": "Unity package for HybridCLR. It includes editor and runtime scripts and assets for HybridCLR",
"category": "Runtime",