Пример #1
0
        protected static void GenerateCodeForArgument(ILGenerator gen, CodeFlow cf, SpelNode argument, TypeDescriptor paramDesc)
        {
            cf.EnterCompilationScope();
            argument.GenerateCode(gen, cf);
            var lastDesc = cf.LastDescriptor();

            if (lastDesc == null)
            {
                throw new InvalidOperationException("No last descriptor");
            }

            var valueTypeOnStack = CodeFlow.IsValueType(lastDesc);

            // Check if need to box it for the method reference?
            if (valueTypeOnStack && paramDesc.IsReferenceType)
            {
                CodeFlow.InsertBoxIfNecessary(gen, lastDesc);
            }
            else if (paramDesc.IsValueType && !paramDesc.IsBoxed && !valueTypeOnStack)
            {
                gen.Emit(OpCodes.Unbox_Any, paramDesc.Value);
            }
            else
            {
                // This would be unnecessary in the case of subtyping (e.g. method takes Number but Integer passed in)
                CodeFlow.InsertCastClass(gen, paramDesc);
            }

            cf.ExitCompilationScope();
        }
Пример #2
0
        private void Walk(ILGenerator gen, CodeFlow cf, SpelNode operand)
        {
            if (operand is OpPlus plus)
            {
                Walk(gen, cf, plus.LeftOperand);
                Walk(gen, cf, plus.RightOperand);
            }
            else if (operand != null)
            {
                cf.EnterCompilationScope();
                operand.GenerateCode(gen, cf);
                if (cf.LastDescriptor() != TypeDescriptor.STRING)
                {
                    gen.Emit(OpCodes.Castclass, typeof(string));
                }

                cf.ExitCompilationScope();
                gen.Emit(OpCodes.Callvirt, _appendString);
            }
        }