예제 #1
0
        private MSA.Expression /*!*/ TransformBody(AstGenerator /*!*/ gen, MSA.Expression /*!*/ methodDefinitionVariable)
        {
            string encodedName = gen.EncodeMethodName(_name, Location);

            ScopeBuilder scope = new ScopeBuilder();

            MSA.Expression parentScope = gen.CurrentScopeVariable;

            MSA.ParameterExpression[] parameters            = DefineParameters(gen, scope);
            MSA.Expression            currentMethodVariable = scope.DefineHiddenVariable("#method", typeof(RubyMethodInfo));
            MSA.Expression            rfcVariable           = scope.DefineHiddenVariable("#rfc", typeof(RuntimeFlowControl));
            MSA.Expression            scopeVariable         = scope.DefineHiddenVariable("#scope", typeof(RubyMethodScope));
            MSA.Expression            selfParameter         = parameters[0];
            MSA.Expression            blockParameter        = parameters[1];

            gen.EnterMethodDefinition(
                scope,
                selfParameter,
                scopeVariable,
                blockParameter,
                rfcVariable,
                currentMethodVariable,
                _name,
                _parameters
                );

            DefinedScope.TransformLocals(scope);

            MSA.ParameterExpression unwinder = scope.DefineHiddenVariable("#unwinder", typeof(MethodUnwinder));

            MSA.Expression body = AstFactory.MakeUserMethodBody(
                gen, Location.End.Line,
                blockParameter,
                rfcVariable,
                unwinder,
                Ast.Block(
                    Ast.Assign(currentMethodVariable, methodDefinitionVariable),

                    Ast.Assign(scopeVariable, Methods.CreateMethodScope.OpCall(
                                   scope.VisibleVariables(), parentScope, currentMethodVariable, rfcVariable, selfParameter, blockParameter)
                               ),

                    _parameters.TransformOptionalsInitialization(gen),
                    gen.TraceEnabled ? Methods.TraceMethodCall.OpCall(scopeVariable, Ast.Convert(Ast.Constant(gen.SourceUnit.Path), typeof(string)), Ast.Constant(Location.Start.Line)) : Ast.Empty(),
                    Body.TransformResult(gen, ResultOperation.Return),
                    Ast.Empty()
                    ),
                ResultOperation.Return,
                (gen.Profiler != null) ? gen.Profiler.GetTickIndex(encodedName) : -1,
                (gen.Profiler != null) ? scope.DefineHiddenVariable("#stamp", typeof(long)) : null,
                gen.ReturnLabel
                );

            body = gen.AddReturnTarget(scope.CreateScope(body));
            gen.LeaveMethodDefinition();

            return(CreateLambda(
                       encodedName,
                       parameters,
                       body
                       ));
        }