Skip to content

Commit c5bed13

Browse files
committed
Add string concat support
1 parent fc4815c commit c5bed13

4 files changed

Lines changed: 44 additions & 15 deletions

File tree

il2cpp/GeneratorContext.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ internal class GeneratorContext
269269
private readonly HashSet<string> UsedMethodNames = new HashSet<string>();
270270
private readonly Dictionary<string, List<Tuple<string, bool>>> InitFldsMap = new Dictionary<string, List<Tuple<string, bool>>>();
271271
private uint TypeIDCounter;
272+
private uint StringTypeID;
272273

273274
public GeneratorContext(TypeManager typeMgr)
274275
{
@@ -345,9 +346,7 @@ public GenerateResult Generate()
345346
var transMap = new CompileUnitMerger(unitMap).Merge();
346347

347348
// 生成字符串常量单元
348-
TypeX strTyX = GetTypeByName("String");
349-
if (strTyX != null)
350-
StrGen.Generate(unitMap, GetTypeID(strTyX));
349+
StrGen.Generate(unitMap, GetStringTypeID());
351350

352351
// 生成初始化单元
353352
var unitInit = GenInitUnit(transMap);
@@ -356,6 +355,18 @@ public GenerateResult Generate()
356355
return new GenerateResult(this, unitMap.Values.ToList(), transMap);
357356
}
358357

358+
public uint GetStringTypeID()
359+
{
360+
if (StringTypeID == 0)
361+
{
362+
TypeX strTyX = GetTypeByName("String");
363+
Debug.Assert(strTyX != null);
364+
StringTypeID = GetTypeID(strTyX);
365+
}
366+
Debug.Assert(StringTypeID != 0);
367+
return StringTypeID;
368+
}
369+
359370
public int GetTypeLayoutOrder(TypeSig tySig)
360371
{
361372
switch (tySig.ElementType)

il2cpp/RuntimeInternals.cs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,20 @@ public static bool GenInternalMethod(MethodX metX, CodePrinter prt, GeneratorCon
2020
}
2121
else if (typeName == "String")
2222
{
23+
FieldX fldLen = metX.DeclType.Fields.FirstOrDefault(
24+
fld => fld.FieldType.ElementType == dnlib.DotNet.ElementType.I4);
25+
FieldX fldFirstChar = metX.DeclType.Fields.FirstOrDefault(
26+
fld => fld.FieldType.ElementType == dnlib.DotNet.ElementType.Char);
27+
2328
if (metName == "get_Length")
2429
{
25-
FieldX fldLen = metX.DeclType.Fields.FirstOrDefault(
26-
fld => fld.FieldType.ElementType == dnlib.DotNet.ElementType.I4);
2730
prt.AppendFormatLine(@"return arg_0->{0};",
2831
genContext.GetFieldName(fldLen));
2932

3033
return true;
3134
}
3235
else if (metName == "get_Chars")
3336
{
34-
FieldX fldLen = metX.DeclType.Fields.FirstOrDefault(
35-
fld => fld.FieldType.ElementType == dnlib.DotNet.ElementType.I4);
36-
FieldX fldFirstChar = metX.DeclType.Fields.FirstOrDefault(
37-
fld => fld.FieldType.ElementType == dnlib.DotNet.ElementType.Char);
38-
3937
prt.AppendFormatLine("IL2CPP_CHECK_RANGE(0, arg_0->{0}, arg_1);",
4038
genContext.GetFieldName(fldLen));
4139
prt.AppendFormatLine("return ((uint16_t*)&arg_0->{0})[arg_1];",
@@ -45,17 +43,22 @@ public static bool GenInternalMethod(MethodX metX, CodePrinter prt, GeneratorCon
4543
}
4644
else if (metName == "InternalMarvin32HashString")
4745
{
48-
FieldX fldLen = metX.DeclType.Fields.FirstOrDefault(
49-
fld => fld.FieldType.ElementType == dnlib.DotNet.ElementType.I4);
50-
FieldX fldFirstChar = metX.DeclType.Fields.FirstOrDefault(
51-
fld => fld.FieldType.ElementType == dnlib.DotNet.ElementType.Char);
52-
5346
prt.AppendFormatLine("return il2cpp_HashString(&arg_0->{0}, arg_0->{1});",
5447
genContext.GetFieldName(fldFirstChar),
5548
genContext.GetFieldName(fldLen));
5649

5750
return true;
5851
}
52+
else if (metName == "FastAllocateString")
53+
{
54+
prt.AppendFormatLine(
55+
"cls_String* str = (cls_String*)IL2CPP_NEW(sizeof(cls_Object) + sizeof(int32_t) + sizeof(uint16_t) * (arg_0 + 1), {0}, 1);",
56+
genContext.GetStringTypeID());
57+
prt.AppendFormatLine("str->{0} = arg_0;",
58+
genContext.GetFieldName(fldLen));
59+
prt.AppendLine("return str;");
60+
return true;
61+
}
5962
}
6063
else if (typeName == "System.Runtime.CompilerServices.RuntimeHelpers")
6164
{
@@ -115,6 +118,14 @@ public static bool GenInternalMethod(MethodX metX, CodePrinter prt, GeneratorCon
115118
return true;
116119
}
117120
}
121+
else if (typeName == "System.Buffer")
122+
{
123+
if (metName == "__Memmove")
124+
{
125+
prt.AppendLine("IL2CPP_MEMMOVE(arg_0, arg_1, arg_2);");
126+
return true;
127+
}
128+
}
118129
else if (typeName == "System.Math")
119130
{
120131
if (metName == "Abs")

runtime/il2cpp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
#define IL2CPP_ASSERT(_x) do { if (!(_x)) IL2CPP_TRAP; } while(0)
4040
#define IL2CPP_MEMCPY memcpy
41+
#define IL2CPP_MEMMOVE memmove
4142
#define IL2CPP_MEMSET memset
4243
#define IL2CPP_MEMCMP memcmp
4344
#define IL2CPP_ALLOCA alloca

test/testcase/CodeGenTests.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,12 @@ public static int Entry()
606606
strRep2[16] != ' ')
607607
return 10;
608608

609+
string aa = "Test";
610+
string bb = "拼接";
611+
string aabb = aa + bb;
612+
if (aabb != "Test拼接")
613+
return 11;
614+
609615
/*int a = 123;
610616
string sconcat = "测试" + a;
611617
if (sconcat != "测试123")

0 commit comments

Comments
 (0)