You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Upon partial evaluation of c by capturing the value of c at enumeration time of res, we end up with a ConstantExpression of type int?. Unlike constants of non-nullable primitive types, the compiled expression tree does not emit IL instructions to construct the constant but stores the value in the Constants array of the Closure instance used by the compiled delegate. On desktop, this also prevents the overload of Compile taking in a MethodBuilder from successfully persisting such an expression tree because it refers to a "live constant" that cannot be represented in IL.
Note that this introduces boxing as well as allocation of an entry in the Constants array, which could be left as null in case it's empty. In case a lot of compiled expressions are kept resident in memory (cf. services for continuous computations I'm working on in Bing), this can have some impact.
Note that a case could be made for default values of value types as well (see the TimeSpan case), though checking whether a struct value matches the default value of the struct's type (in order to emit initobj) may be tricky (one way I could think of would be a non-virtual call to ValueType.Equals).
An improvement for nullable types of primitives would be to allow them in CanEmitILConstant and add support in TryEmitILConstant to emit the non-null value, followed by a newobj to construct the Nullable<T> atop of it.
The text was updated successfully, but these errors were encountered:
Found when performing closure elimination steps during expression rewriting a la:
Upon partial evaluation of
c
by capturing the value ofc
at enumeration time ofres
, we end up with aConstantExpression
of typeint?
. Unlike constants of non-nullable primitive types, the compiled expression tree does not emit IL instructions to construct the constant but stores the value in theConstants
array of theClosure
instance used by the compiled delegate. On desktop, this also prevents the overload ofCompile
taking in aMethodBuilder
from successfully persisting such an expression tree because it refers to a "live constant" that cannot be represented in IL.Note that this introduces boxing as well as allocation of an entry in the
Constants
array, which could be left asnull
in case it's empty. In case a lot of compiled expressions are kept resident in memory (cf. services for continuous computations I'm working on in Bing), this can have some impact.Repro:
Note that a case could be made for default values of value types as well (see the
TimeSpan
case), though checking whether a struct value matches the default value of the struct's type (in order to emitinitobj
) may be tricky (one way I could think of would be a non-virtual call toValueType.Equals
).An improvement for nullable types of primitives would be to allow them in
CanEmitILConstant
and add support inTryEmitILConstant
to emit the non-null value, followed by anewobj
to construct theNullable<T>
atop of it.The text was updated successfully, but these errors were encountered: