Warning: mkdir(): No space left on device in /var/www/tgoop/post.php on line 37

Warning: file_put_contents(aCache/aDaily/post/unsafecsharp/--): Failed to open stream: No such file or directory in /var/www/tgoop/post.php on line 50
Unity: Всё, что вы не знали о разработке@unsafecsharp P.261
UNSAFECSHARP Telegram 261
IL или как я разбираю джобы

Что такое IL? IL (или Intermediate Language) - это промежутный язык, который еще и не рантайм, но уже и не C#.
Его смысл в том, что это плюс-минус набор инструкций, по которым можно понять суть происходящего в методе.

Как оно выглядит?

IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld int32 C::a
IL_0007: ldc.i4.s 10
IL_0009: cgt
IL_000b: stloc.0
IL_000c: ldloc.0
IL_000d: brfalse.s IL_0018

IL_000f: nop
IL_0010: ldarg.0
IL_0011: call instance void C::A()
IL_0016: nop
IL_0017: nop

IL_0018: ldarg.0
IL_0019: call instance void C::A()
IL_001e: nop
IL_001f: ldarg.0
IL_0020: call instance void C::A()
IL_0025: nop
IL_0026: ret


Чем я пользуюсь? https://github.com/chromealex/ME.BECS/tree/main/Runwww.tgoop.com/Extensions/Mono.Reflection
Это не Mono.Cecil, но для моих задач подходит отлично.
Работа этой штуки сводится к тому, чтобы разобрать инструкции метода и сложить их в плюс-минус удобный список.

Давайте разберем задачу из прошлого поста:
Нам нужно посчитать количество вызовов метода.


var count = 0;
var targetMethod = typeof(Ent).GetMethod(nameof(Ent.New), ...);
var instructions = executeJobMethod.GetInstructions();
for (int i = 0; i < instructions.Count; ++i) {
var inst = instructions[i];
{
// тут можем обработать инструкцию
if (inst.Operand is System.Reflection.MethodInfo method && method == targetMethod) {
++count;
}
}
{
if (inst.Operand is System.Reflection.MethodInfo method) {
instructions.InsertRange(i + 1, method.GetInstructions());
}
}
}


Фактически в данный момент мы посчитали количество вызовов определенного метода в джобе рекурсивно заходя в каждый метод. У меня к этому коду еще добавлены различные аттрибуты, чтобы не заходить в ненужные методы и чтобы не попасть в рекурсию, но я уверен, что вы справитесь с этой задачей.

Как я говорил в прошлом посте, нам нужно считать не просто количество вызовов, но и посчитать количество вызовов в цикле (ну или определить, что они в принципе там есть).

Для этого нам нужно обратиться к OpCodes. Это по сути код операции у инструкции, которую мы сейчас обрабатываем.
Кодов очень много, но нас интересуют лишь коды бранчей.
Бранч - это ветка. Бранчи могут быть созданы в различных кейсах: это может быть if, может быть цикл foreach, for, while и т.д.
Код вида br* будет приводить к переходу (типа goto) к конкретной инструкции.
И тут начинается самое интересное. Любые циклы и условия - это одна и та же операция br*, но за одним исключением: вместе с этой операцией передается номер строки (например, IL_0007), куда нужно осуществить переход.
Так вот если адрес этого перехода меньше, чем адрес текущей инструкции - мы закончили итерацию цикла и возвращаемся назад.
А если инструкция br* ведет нас вперед, то это открытие условия или цикла.

В коде выше можно увидеть эту инструкцию в виде IL_000d: brfalse.s IL_0018. То есть мы переходим в 0018, что находится ниже, значит это условие, а не цикл.

Текущий код по поиску информации можно посмотреть здесь:
https://github.com/chromealex/ME.BECS/blob/a665a344e6957ff18945dd9862981d79910c0491/Editor/CodeGenerator/Generators/JobsEarlyInitCodeGenerator.cs#L437

#becs #il #jobs
35312🔥8👍3🤯3



tgoop.com/unsafecsharp/261
Create:
Last Update:

IL или как я разбираю джобы

Что такое IL? IL (или Intermediate Language) - это промежутный язык, который еще и не рантайм, но уже и не C#.
Его смысл в том, что это плюс-минус набор инструкций, по которым можно понять суть происходящего в методе.

Как оно выглядит?


IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld int32 C::a
IL_0007: ldc.i4.s 10
IL_0009: cgt
IL_000b: stloc.0
IL_000c: ldloc.0
IL_000d: brfalse.s IL_0018

IL_000f: nop
IL_0010: ldarg.0
IL_0011: call instance void C::A()
IL_0016: nop
IL_0017: nop

IL_0018: ldarg.0
IL_0019: call instance void C::A()
IL_001e: nop
IL_001f: ldarg.0
IL_0020: call instance void C::A()
IL_0025: nop
IL_0026: ret


Чем я пользуюсь? https://github.com/chromealex/ME.BECS/tree/main/Runwww.tgoop.com/Extensions/Mono.Reflection
Это не Mono.Cecil, но для моих задач подходит отлично.
Работа этой штуки сводится к тому, чтобы разобрать инструкции метода и сложить их в плюс-минус удобный список.

Давайте разберем задачу из прошлого поста:
Нам нужно посчитать количество вызовов метода.


var count = 0;
var targetMethod = typeof(Ent).GetMethod(nameof(Ent.New), ...);
var instructions = executeJobMethod.GetInstructions();
for (int i = 0; i < instructions.Count; ++i) {
var inst = instructions[i];
{
// тут можем обработать инструкцию
if (inst.Operand is System.Reflection.MethodInfo method && method == targetMethod) {
++count;
}
}
{
if (inst.Operand is System.Reflection.MethodInfo method) {
instructions.InsertRange(i + 1, method.GetInstructions());
}
}
}


Фактически в данный момент мы посчитали количество вызовов определенного метода в джобе рекурсивно заходя в каждый метод. У меня к этому коду еще добавлены различные аттрибуты, чтобы не заходить в ненужные методы и чтобы не попасть в рекурсию, но я уверен, что вы справитесь с этой задачей.

Как я говорил в прошлом посте, нам нужно считать не просто количество вызовов, но и посчитать количество вызовов в цикле (ну или определить, что они в принципе там есть).

Для этого нам нужно обратиться к OpCodes. Это по сути код операции у инструкции, которую мы сейчас обрабатываем.
Кодов очень много, но нас интересуют лишь коды бранчей.
Бранч - это ветка. Бранчи могут быть созданы в различных кейсах: это может быть if, может быть цикл foreach, for, while и т.д.
Код вида br* будет приводить к переходу (типа goto) к конкретной инструкции.
И тут начинается самое интересное. Любые циклы и условия - это одна и та же операция br*, но за одним исключением: вместе с этой операцией передается номер строки (например, IL_0007), куда нужно осуществить переход.
Так вот если адрес этого перехода меньше, чем адрес текущей инструкции - мы закончили итерацию цикла и возвращаемся назад.
А если инструкция br* ведет нас вперед, то это открытие условия или цикла.

В коде выше можно увидеть эту инструкцию в виде IL_000d: brfalse.s IL_0018. То есть мы переходим в 0018, что находится ниже, значит это условие, а не цикл.

Текущий код по поиску информации можно посмотреть здесь:
https://github.com/chromealex/ME.BECS/blob/a665a344e6957ff18945dd9862981d79910c0491/Editor/CodeGenerator/Generators/JobsEarlyInitCodeGenerator.cs#L437

#becs #il #jobs

BY Unity: Всё, что вы не знали о разработке




Share with your friend now:
tgoop.com/unsafecsharp/261

View MORE
Open in Telegram


Telegram News

Date: |

“[The defendant] could not shift his criminal liability,” Hui said. Step-by-step tutorial on desktop: Ng was convicted in April for conspiracy to incite a riot, public nuisance, arson, criminal damage, manufacturing of explosives, administering poison and wounding with intent to do grievous bodily harm between October 2019 and June 2020. Image: Telegram. On Tuesday, some local media outlets included Sing Tao Daily cited sources as saying the Hong Kong government was considering restricting access to Telegram. Privacy Commissioner for Personal Data Ada Chung told to the Legislative Council on Monday that government officials, police and lawmakers remain the targets of “doxxing” despite a privacy law amendment last year that criminalised the malicious disclosure of personal information.
from us


Telegram Unity: Всё, что вы не знали о разработке
FROM American