EnterBlockDefinition() public method

public EnterBlockDefinition ( ScopeBuilder locals, System.Linq.Expressions bfcVariable, System.Linq.Expressions selfVariable, System.Linq.Expressions runtimeScopeVariable, System.Linq.Expressions redoLabel ) : void
locals ScopeBuilder
bfcVariable System.Linq.Expressions
selfVariable System.Linq.Expressions
runtimeScopeVariable System.Linq.Expressions
redoLabel System.Linq.Expressions
return void
Example #1
0
        internal MSA.Expression/*!*/ Transform(AstGenerator/*!*/ gen, bool isLambda) {
            ScopeBuilder scope = DefineLocals(gen.CurrentScope);

            // define hidden parameters and RHS-placeholders (#1..#n will be used as RHS of a parallel assignment):
            MSA.ParameterExpression blockParameter, selfParameter;
            var parameters = DefineParameters(out selfParameter, out blockParameter);

            MSA.ParameterExpression scopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyBlockScope));
            MSA.LabelTarget redoLabel = Ast.Label();

            gen.EnterBlockDefinition(
                scope,
                blockParameter,
                selfParameter,
                scopeVariable,
                redoLabel
            );

            MSA.Expression paramInit = MakeParametersInitialization(gen, parameters);
            MSA.ParameterExpression blockUnwinder, filterVariable;

            MSA.Expression traceCall, traceReturn;
			if (gen.TraceEnabled) {
                int firstStatementLine = _body.Count > 0 ? _body.First.Location.Start.Line : Location.End.Line;
                int lastStatementLine = _body.Count > 0 ? _body.Last.Location.End.Line : Location.End.Line;

                traceCall = Methods.TraceBlockCall.OpCall(scopeVariable, blockParameter, gen.SourcePathConstant, AstUtils.Constant(firstStatementLine));
                traceReturn = Methods.TraceBlockReturn.OpCall(scopeVariable, blockParameter, gen.SourcePathConstant, AstUtils.Constant(lastStatementLine));
            } else {
                traceCall = traceReturn = Ast.Empty();
            }

            MSA.Expression body = AstUtils.Try(
                paramInit,
                traceCall,
                Ast.Label(redoLabel),
                AstUtils.Try(
                    gen.TransformStatements(_body, ResultOperation.Return)
                ).Catch(blockUnwinder = Ast.Parameter(typeof(BlockUnwinder), "#u"),
                    // redo:
                    AstUtils.IfThen(Ast.Field(blockUnwinder, BlockUnwinder.IsRedoField), Ast.Goto(redoLabel)),

                    // next:
                    gen.Return(Ast.Field(blockUnwinder, BlockUnwinder.ReturnValueField))
                )
            ).Filter(filterVariable = Ast.Parameter(typeof(Exception), "#e"),
                Methods.FilterBlockException.OpCall(scopeVariable, filterVariable)
            ).Finally(
                traceReturn,
                Ast.Empty()
            );

            body = gen.AddReturnTarget(
                scope.CreateScope(
                    scopeVariable,
                    Methods.CreateBlockScope.OpCall(new AstExpressions {
                        scope.MakeLocalsStorage(),
                        scope.GetVariableNamesExpression(),
                        blockParameter, 
                        selfParameter,
                        EnterInterpretedFrameExpression.Instance
                    }),
                    body
                )
            );

            gen.LeaveBlockDefinition();

            int parameterCount = ParameterCount;
            var attributes = _parameters.GetBlockSignatureAttributes();

            var dispatcher = Ast.Constant(
                BlockDispatcher.Create(parameterCount, attributes, gen.SourcePath, Location.Start.Line), typeof(BlockDispatcher)
            );

            return Ast.Coalesce(
                (isLambda ? Methods.InstantiateLambda : Methods.InstantiateBlock).OpCall(gen.CurrentScopeVariable, gen.CurrentSelfVariable, dispatcher),
                (isLambda ? Methods.DefineLambda : Methods.DefineBlock).OpCall(gen.CurrentScopeVariable, gen.CurrentSelfVariable, dispatcher,
                    BlockDispatcher.CreateLambda(
                        body,
                        RubyStackTraceBuilder.EncodeMethodName(gen.CurrentMethod.MethodName, gen.SourcePath, Location, gen.DebugMode),
                        parameters,
                        parameterCount,
                        attributes
                    )
                )
            );
        }
Example #2
0
        internal override MSA.Expression /*!*/ Transform(AstGenerator /*!*/ gen)
        {
            MSA.Expression parentScope = gen.CurrentScopeVariable;
            ScopeBuilder   scope       = new ScopeBuilder();

            // define hidden parameters and RHS-placeholders (#1..#n will be used as RHS of a parallel assignment):
            MSA.Expression            blockParameter, selfParameter;
            MSA.ParameterExpression[] parameters = DefineParameters(out selfParameter, out blockParameter);

            MSA.Expression  scopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyBlockScope));
            MSA.LabelTarget redoLabel     = Ast.Label();

            gen.EnterBlockDefinition(
                scope,
                blockParameter,
                selfParameter,
                scopeVariable,
                redoLabel
                );

            if (_definedScope != null)
            {
                _definedScope.TransformLocals(scope);
            }

            MSA.Expression          paramInit     = MakeParametersInitialization(gen, parameters);
            MSA.ParameterExpression blockUnwinder = scope.DefineHiddenVariable("#unwinder", typeof(BlockUnwinder));

            MSA.Expression loop = AstFactory.Infinite(null, redoLabel,
                                                      AstUtils.Try(
                                                          gen.TransformStatements(_body, ResultOperation.Return)
                                                          ).Catch(blockUnwinder,
                                                                  // redo:
                                                                  AstUtils.IfThen(Ast.Field(blockUnwinder, BlockUnwinder.IsRedoField), Ast.Continue(redoLabel)),

                                                                  // next:
                                                                  gen.Return(Ast.Field(blockUnwinder, BlockUnwinder.ReturnValueField))
                                                                  )
                                                      );

            if (gen.TraceEnabled)
            {
                int firstStatementLine = _body.Count > 0 ? _body[0].Location.Start.Line : Location.End.Line;
                int lastStatementLine  = _body.Count > 0 ? _body[_body.Count - 1].Location.End.Line : Location.End.Line;

                loop = Ast.TryFinally(
                    Ast.Block(
                        Methods.TraceBlockCall.OpCall(scopeVariable, blockParameter, Ast.Convert(Ast.Constant(gen.SourceUnit.Path), typeof(string)), Ast.Constant(firstStatementLine)),
                        loop
                        ),
                    Methods.TraceBlockReturn.OpCall(scopeVariable, blockParameter, Ast.Convert(Ast.Constant(gen.SourceUnit.Path), typeof(string)), Ast.Constant(lastStatementLine))
                    );
            }

            MSA.Expression body = Ast.Block(
                Ast.Assign(scopeVariable,
                           Methods.CreateBlockScope.OpCall(scope.VisibleVariables(), parentScope, blockParameter, selfParameter)
                           ),

                paramInit,

                loop,

                Ast.Empty()
                );

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

            int parameterCount = _parameters.LeftValues.Count;

            var attributes = _parameters.GetBlockSignatureAttributes();

            return(Methods.DefineBlock.OpCall(
                       gen.CurrentScopeVariable,
                       gen.CurrentRfcVariable,
                       gen.CurrentSelfVariable,
                       Ast.Lambda(
                           BlockDispatcher.GetDelegateType(parameterCount, attributes),
                           body,
                           gen.EncodeMethodName(gen.CurrentMethod.MethodName, Location),
                           new ReadOnlyCollection <MSA.ParameterExpression>(parameters)
                           ),
                       Ast.Constant(parameterCount),
                       Ast.Constant(attributes)
                       ));
        }
Example #3
0
        internal MSA.Expression /*!*/ Transform(AstGenerator /*!*/ gen, bool isLambda)
        {
            ScopeBuilder scope = DefineLocals(gen.CurrentScope);

            // define hidden parameters and RHS-placeholders (#1..#n will be used as RHS of a parallel assignment):
            MSA.ParameterExpression blockParameter, selfParameter;
            var parameters = DefineParameters(out selfParameter, out blockParameter);

            MSA.ParameterExpression scopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyBlockScope));
            MSA.LabelTarget         redoLabel     = Ast.Label();

            gen.EnterBlockDefinition(
                scope,
                blockParameter,
                selfParameter,
                scopeVariable,
                redoLabel
                );

            MSA.Expression          paramInit = MakeParametersInitialization(gen, parameters);
            MSA.ParameterExpression blockUnwinder, filterVariable;

            MSA.Expression traceCall, traceReturn;
            if (gen.TraceEnabled)
            {
                int firstStatementLine = _body.Count > 0 ? _body.First.Location.Start.Line : Location.End.Line;
                int lastStatementLine  = _body.Count > 0 ? _body.Last.Location.End.Line : Location.End.Line;

                traceCall   = Methods.TraceBlockCall.OpCall(scopeVariable, blockParameter, gen.SourcePathConstant, AstUtils.Constant(firstStatementLine));
                traceReturn = Methods.TraceBlockReturn.OpCall(scopeVariable, blockParameter, gen.SourcePathConstant, AstUtils.Constant(lastStatementLine));
            }
            else
            {
                traceCall = traceReturn = Ast.Empty();
            }

            MSA.Expression body = AstUtils.Try(
                paramInit,
                traceCall,
                Ast.Label(redoLabel),
                AstUtils.Try(
                    gen.TransformStatements(_body, ResultOperation.Return)
                    ).Catch(blockUnwinder = Ast.Parameter(typeof(BlockUnwinder), "#u"),
                            // redo:
                            AstUtils.IfThen(Ast.Field(blockUnwinder, BlockUnwinder.IsRedoField), Ast.Goto(redoLabel)),

                            // next:
                            gen.Return(Ast.Field(blockUnwinder, BlockUnwinder.ReturnValueField))
                            )
                ).Filter(filterVariable = Ast.Parameter(typeof(Exception), "#e"),
                         Methods.FilterBlockException.OpCall(scopeVariable, filterVariable)
                         ).Finally(
                traceReturn,
                Ast.Empty()
                );

            body = gen.AddReturnTarget(
                scope.CreateScope(
                    scopeVariable,
                    Methods.CreateBlockScope.OpCall(new AstExpressions {
                scope.MakeLocalsStorage(),
                scope.GetVariableNamesExpression(),
                blockParameter,
                selfParameter,
                EnterInterpretedFrameExpression.Instance
            }),
                    body
                    )
                );

            gen.LeaveBlockDefinition();

            int parameterCount = ParameterCount;
            var attributes = _parameters.GetBlockSignatureAttributes();

            var dispatcher = Ast.Constant(
                BlockDispatcher.Create(parameterCount, attributes, gen.SourcePath, Location.Start.Line), typeof(BlockDispatcher)
                );

            return(Ast.Coalesce(
                       (isLambda ? Methods.InstantiateLambda : Methods.InstantiateBlock).OpCall(gen.CurrentScopeVariable, gen.CurrentSelfVariable, dispatcher),
                       (isLambda ? Methods.DefineLambda : Methods.DefineBlock).OpCall(gen.CurrentScopeVariable, gen.CurrentSelfVariable, dispatcher,
                                                                                      BlockDispatcher.CreateLambda(
                                                                                          body,
                                                                                          RubyStackTraceBuilder.EncodeMethodName(gen.CurrentMethod.MethodName, gen.SourcePath, Location, gen.DebugMode),
                                                                                          parameters,
                                                                                          parameterCount,
                                                                                          attributes
                                                                                          )
                                                                                      )
                       ));
        }
Example #4
0
        internal override MSA.Expression/*!*/ Transform(AstGenerator/*!*/ gen) {
            MSA.Expression parentScope = gen.CurrentScopeVariable;
            ScopeBuilder scope = new ScopeBuilder();

            // define hidden parameters and RHS-placeholders (#1..#n will be used as RHS of a parallel assignment):
            MSA.Expression blockParameter, selfParameter;
            MSA.ParameterExpression[] parameters = DefineParameters(out selfParameter, out blockParameter);

            MSA.ParameterExpression scopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyBlockScope));
            MSA.LabelTarget redoLabel = Ast.Label();

            gen.EnterBlockDefinition(
                scope,
                blockParameter,
                selfParameter,
                scopeVariable,
                redoLabel
            );

            if (_definedScope != null) {
                _definedScope.TransformLocals(scope);
            }

            MSA.Expression paramInit = MakeParametersInitialization(gen, parameters);
            MSA.ParameterExpression blockUnwinder = scope.DefineHiddenVariable("#unwinder", typeof(BlockUnwinder));
            MSA.ParameterExpression filterVariable = scope.DefineHiddenVariable("#e", typeof(Exception));

            MSA.Expression traceCall, traceReturn;
			if (gen.TraceEnabled) {
                int firstStatementLine = _body.Count > 0 ? _body.First.Location.Start.Line : Location.End.Line;
                int lastStatementLine = _body.Count > 0 ? _body.Last.Location.End.Line : Location.End.Line;

                traceCall = Methods.TraceBlockCall.OpCall(scopeVariable, blockParameter, Ast.Convert(AstUtils.Constant(gen.SourceUnit.Path), typeof(string)), AstUtils.Constant(firstStatementLine));
                traceReturn = Methods.TraceBlockReturn.OpCall(scopeVariable, blockParameter, Ast.Convert(AstUtils.Constant(gen.SourceUnit.Path), typeof(string)), AstUtils.Constant(lastStatementLine));
            } else {
                traceCall = traceReturn = Ast.Empty();
            }

            MSA.Expression body = AstUtils.Try(
                Ast.Assign(scopeVariable,
                    Methods.CreateBlockScope.OpCall(
                        scope.VisibleVariables(), parentScope, blockParameter, selfParameter, EnterInterpretedFrameExpression.Instance
                    )
                ),

                paramInit,
                traceCall,
                Ast.Label(redoLabel),
                AstUtils.Try(
                    gen.TransformStatements(_body, ResultOperation.Return)
                ).Catch(blockUnwinder,
                    // redo:
                    AstUtils.IfThen(Ast.Field(blockUnwinder, BlockUnwinder.IsRedoField), Ast.Goto(redoLabel)),

                    // next:
                    gen.Return(Ast.Field(blockUnwinder, BlockUnwinder.ReturnValueField))
                )
            ).Filter(filterVariable,
                Methods.FilterBlockException.OpCall(scopeVariable, filterVariable)
            ).Finally(
                traceReturn,
                Methods.LeaveBlockFrame.OpCall(scopeVariable),
                LeaveInterpretedFrameExpression.Instance
            );

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

            int parameterCount = _parameters.LeftValues.Count;

            var attributes = _parameters.GetBlockSignatureAttributes();

            return Methods.DefineBlock.OpCall(
                gen.CurrentScopeVariable,
                gen.CurrentRfcVariable,
                gen.CurrentSelfVariable,
                BlockDispatcher.CreateLambda(
                    body,
                    RubyExceptionData.EncodeMethodName(gen.SourceUnit, gen.CurrentMethod.MethodName, Location), 
                    new ReadOnlyCollection<MSA.ParameterExpression>(parameters),
                    parameterCount,
                    attributes
                ),
                AstUtils.Constant(parameterCount),
                AstUtils.Constant(attributes)
            );
        }