[new] 支持WebGL
parent
093f67296a
commit
15319a59fa
|
@ -15,6 +15,7 @@ namespace HybridCLR.Editor.ABI
|
||||||
case PlatformABI.Arm64: return "HYBRIDCLR_ABI_ARM_64";
|
case PlatformABI.Arm64: return "HYBRIDCLR_ABI_ARM_64";
|
||||||
case PlatformABI.Universal64: return "HYBRIDCLR_ABI_UNIVERSAL_64";
|
case PlatformABI.Universal64: return "HYBRIDCLR_ABI_UNIVERSAL_64";
|
||||||
case PlatformABI.Universal32: return "HYBRIDCLR_ABI_UNIVERSAL_32";
|
case PlatformABI.Universal32: return "HYBRIDCLR_ABI_UNIVERSAL_32";
|
||||||
|
case PlatformABI.WebGL32: return "HYBRIDCLR_ABI_WEBGL32";
|
||||||
default: throw new NotSupportedException();
|
default: throw new NotSupportedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,5 +5,6 @@
|
||||||
Universal32,
|
Universal32,
|
||||||
Universal64,
|
Universal64,
|
||||||
Arm64,
|
Arm64,
|
||||||
|
WebGL32,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,8 @@ namespace HybridCLR.Editor.ABI
|
||||||
|
|
||||||
public virtual bool IsSupportHFA => false;
|
public virtual bool IsSupportHFA => false;
|
||||||
|
|
||||||
|
public virtual bool IsSupportSingletonStruct => false;
|
||||||
|
|
||||||
public TypeInfo GetNativeIntTypeInfo() => IsArch32 ? TypeInfo.s_i4 : TypeInfo.s_i8;
|
public TypeInfo GetNativeIntTypeInfo() => IsArch32 ? TypeInfo.s_i4 : TypeInfo.s_i8;
|
||||||
|
|
||||||
public ValueTypeSizeAligmentCalculator Calculator => IsArch32 ? ValueTypeSizeAligmentCalculator.Caculator32 : ValueTypeSizeAligmentCalculator.Caculator64;
|
public ValueTypeSizeAligmentCalculator Calculator => IsArch32 ? ValueTypeSizeAligmentCalculator.Caculator32 : ValueTypeSizeAligmentCalculator.Caculator64;
|
||||||
|
@ -170,6 +172,78 @@ namespace HybridCLR.Editor.ABI
|
||||||
return false;
|
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)
|
protected static TypeInfo CreateGeneralValueType(TypeSig type, int size, int aligment)
|
||||||
{
|
{
|
||||||
System.Diagnostics.Debug.Assert(size % aligment == 0);
|
System.Diagnostics.Debug.Assert(size % aligment == 0);
|
||||||
|
@ -197,6 +271,10 @@ namespace HybridCLR.Editor.ABI
|
||||||
default: throw new NotSupportedException();
|
default: throw new NotSupportedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//else if(IsSupportSingletonStruct && TryComputSingletonStruct(type, out var ssTypeInfo))
|
||||||
|
//{
|
||||||
|
// return CreateTypeInfo(ssTypeInfo.Type);
|
||||||
|
//}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 64位下结构体内存对齐规则是一样的
|
// 64位下结构体内存对齐规则是一样的
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace HybridCLR.Editor.ABI
|
||||||
case PlatformABI.Arm64: return new TypeCreatorArm64();
|
case PlatformABI.Arm64: return new TypeCreatorArm64();
|
||||||
case PlatformABI.Universal32: return new TypeCreatorUniversal32();
|
case PlatformABI.Universal32: return new TypeCreatorUniversal32();
|
||||||
case PlatformABI.Universal64: return new TypeCreatorUniversal64();
|
case PlatformABI.Universal64: return new TypeCreatorUniversal64();
|
||||||
|
case PlatformABI.WebGL32: return new TypeCreatorWebGL32();
|
||||||
default: throw new NotSupportedException(abi.ToString());
|
default: throw new NotSupportedException(abi.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4790a87aacda1a14d813570e9e0f35ca
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -81,7 +81,7 @@ namespace HybridCLR.Editor.BuildProcessors
|
||||||
|
|
||||||
if (jsonFiles.Length == 0)
|
if (jsonFiles.Length == 0)
|
||||||
{
|
{
|
||||||
Debug.LogError($"can not find file {SettingsUtil.ScriptingAssembliesJsonFile}");
|
//Debug.LogError($"can not find file {SettingsUtil.ScriptingAssembliesJsonFile}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ namespace HybridCLR.Editor.MethodBridge
|
||||||
case PlatformABI.Universal32: return new PlatformGeneratorUniversal32();
|
case PlatformABI.Universal32: return new PlatformGeneratorUniversal32();
|
||||||
case PlatformABI.Universal64: return new PlatformGeneratorUniversal64();
|
case PlatformABI.Universal64: return new PlatformGeneratorUniversal64();
|
||||||
case PlatformABI.Arm64: return new PlatformGeneratorArm64();
|
case PlatformABI.Arm64: return new PlatformGeneratorArm64();
|
||||||
|
case PlatformABI.WebGL32: return new PlatformGeneratorWebGL32();
|
||||||
default: throw new NotSupportedException();
|
default: throw new NotSupportedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,14 +14,6 @@ namespace HybridCLR.Editor.MethodBridge
|
||||||
{
|
{
|
||||||
public override PlatformABI PlatformABI { get; } = PlatformABI.Universal32;
|
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)
|
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 paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" }));
|
||||||
|
|
|
@ -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;" : "")}
|
||||||
|
}}
|
||||||
|
");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2912d21f60f4c684785c31efcf2d9b29
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "com.focus-creative-games.hybridclr_unity",
|
"name": "com.focus-creative-games.hybridclr_unity",
|
||||||
"version": "0.6.1",
|
"version": "0.7.0",
|
||||||
"displayName": "HybridCLR",
|
"displayName": "HybridCLR",
|
||||||
"description": "Unity package for HybridCLR. It includes editor and runtime scripts and assets for HybridCLR",
|
"description": "Unity package for HybridCLR. It includes editor and runtime scripts and assets for HybridCLR",
|
||||||
"category": "Runtime",
|
"category": "Runtime",
|
||||||
|
|
Loading…
Reference in New Issue