예제 #1
0
        public override void Emit(IlBuilder builder)
        {
            base.Emit(builder);
            _symbolConversion?.Emit(builder);

            if (_method.IsInstance)
            {
                if (((Owner == null || Owner.IsStatic) && _thisPtr == null) || _staticCall)
                {
                    ErrorManager.ExitWithError(new Exception("Can't call instance function from static context"));
                }


                if (!_valueType)
                {
                    builder.PushValue(_thisPtr ?? Owner.ThisPointer);
                }
                else
                {
                    builder.PushAddress(_thisPtr as CodeSymbol);
                }
            }

            foreach (var p in _parameters)
            {
                builder.PushValue(p);
            }

            if (_method.IsVirtual && !_baseAccess)
            {
                if (_valueType)
                {
                    //NOTE: This is sometimes emitted while not needed, like with System.Int32.ToString(), as these methods appear
                    //as virtual but actually aren't. I don't know why, but it still works so whatever.
                    builder.EmitLine("constrained. " + _thisPtr.Type.Name);
                }

                builder.EmitOpCode(OpCodes.Callvirt, _method.FullSignature);
            }
            else
            {
                builder.EmitOpCode(OpCodes.Call, _method.FullSignature);
            }

            builder.ShrinkStack(_parameters.Length);

            if (_return != CodeType.Void)
            {
                if (!_expression)
                {
                    builder.EmitOpCode(OpCodes.Pop);
                }
                else
                {
                    builder.ExpandStack(1);
                }
            }
        }