简体   繁体   English

动态分配一个字段

[英]Dynamically assign a field

I'm trying to generate code for dynamically assigning field values to a dynamic class.我正在尝试生成用于将字段值动态分配给动态类的代码。 Basically, what I'd ideally be able to do is something to this effect:基本上,我理想情况下能够做的是达到以下效果:

il.Emit(OpCodes.Ldarg_0); // Object instance
il.Emit(OpCodes.Ldc_I4_0); // Value to assign to the field
il.Emit(OpCodes.Ld???, fieldInfo); // FieldInfo to assign the value to
il.Emit(OpCodes.Stfld); // Some kind of Stfld that pops the field and the value and assigns it

I was not able to find any instruction that would suit my needs.我找不到任何适合我需要的说明。 Another idea I had was to generate a setter method for each field and invoke that method, but I did not find a method to do that without converting it into a Delegate, which generated a lot of boilerplate code.我的另一个想法是为每个字段生成一个 setter 方法并调用该方法,但我没有找到一种方法可以在不将其转换为 Delegate 的情况下执行此操作,这会生成大量样板代码。

Does anyone have a better solution?有没有人有更好的解决方案?

EDIT: The issue is that the field that needs to be assigned has to be found on the stack, and somehow pop'd when the time to assign it comes.编辑:问题是需要分配的字段必须在堆栈中找到,并且在分配的时间到来时以某种方式弹出。 Unfortunately, none of the CIL instructions support popping a fieldInfo to assign to it, but maybe there are other solutions I had not thought about.不幸的是,没有一个 CIL 指令支持弹出一个 fieldInfo 来分配给它,但也许还有其他我没有想过的解决方案。

EDIT2: I'll give a bit more of the surrounding scenario, hopefully the context will make things clearer. EDIT2:我会给出更多的周围场景,希望上下文能让事情更清楚。

I'm trying to make a sort of "recompiler" from a stack-based vm bytecode to CIL.我正在尝试从基于堆栈的 vm 字节码到 CIL 制作一种“重新编译器”。 The bytecode in question does not access fields in a struct like the CIL does it, ie statically.有问题的字节码不会像 CIL 那样访问结构中的字段,即静态访问。 Instead, the reference to the field to be accessed is pushed on the stack, and the store instruction takes care of the rest.相反,对要访问的字段的引用被压入堆栈,而store指令负责其余的工作。

Here's a sample of what this bytecode might look like:以下是该字节码的示例:

PushFloat 0.0
PushField [someField]
SetField

What I'd like to obtain would be something like the code I've written above, but the CIL only supports assigning to fields which are known at codegen time.我想获得的内容类似于我上面编写的代码,但 CIL 仅支持分配给代码生成时已知的字段。

I've solved this by using ldflda and stind :我已经通过使用ldfldastind解决了这个问题:

il.Emit(OpCodes.Ldarg_0); // Object instance
il.Emit(OpCodes.Ldflda, fieldInfo); // Loads reference to field
il.Emit(OpCodes.Conv_U); // Converts to pointer
il.Emit(OpCodes.Ldc_I4_0); // Something to put in the field
il.Emit(OpCodes.Stind_I4); // Put the value in the field

Which appears to be doing roughly what I had initially set out to do.这似乎大致完成了我最初打算做的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM