internal sealed override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen) { string debugString = (IsSingletonDeclaration) ? "SINGLETON" : ((this is ClassDeclaration) ? "CLASS" : "MODULE") + " " + QualifiedName.Name; ScopeBuilder outerLocals = gen.CurrentScope; // definition needs to take place outside the defined lexical scope: MSA.Expression definition = MakeDefinitionExpression(gen); MSA.Expression selfVariable = outerLocals.DefineHiddenVariable("#module", typeof(RubyModule)); MSA.Expression rfcVariable = gen.CurrentRfcVariable; MSA.Expression parentScope = gen.CurrentScopeVariable; // inner locals: ScopeBuilder scope = new ScopeBuilder(); MSA.Expression scopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyScope)); gen.EnterModuleDefinition( scope, selfVariable, scopeVariable, IsSingletonDeclaration ); // first, transform locals defined within the module body: DefinedScope.TransformLocals(scope); // second, transform body: MSA.Expression transformedBody = Body.TransformRead(gen); // outer local: MSA.Expression resultVariable = outerLocals.DefineHiddenVariable("#result", transformedBody.Type); // begin with new scope // self = DefineModule/Class(... parent scope here ...) // <body> // end MSA.Expression result = AstFactory.Block( gen.DebugMarker(debugString), Ast.Assign(selfVariable, definition), scope.CreateScope( Ast.Block( Ast.Assign(scopeVariable, Methods.CreateModuleScope.OpCall(scope.VisibleVariables(), parentScope, rfcVariable, selfVariable)), Ast.Assign(resultVariable, transformedBody), Ast.Empty() ) ), gen.DebugMarker("END OF " + debugString), resultVariable ); gen.LeaveModuleDefinition(); return(result); }
internal MSA.Expression <T> /*!*/ Transform <T>(AstGenerator /*!*/ gen) { Debug.Assert(gen != null); ScopeBuilder scope = new ScopeBuilder(); MSA.ParameterExpression[] parameters; MSA.Expression selfVariable; MSA.Expression rfcVariable; MSA.Expression parentScope; MSA.Expression language; MSA.Expression runtimeScopeVariable; MSA.Expression moduleVariable; MSA.Expression blockParameter; MSA.Expression currentMethodVariable; if (gen.CompilerOptions.IsEval) { parameters = new MSA.ParameterExpression[6]; parameters[0] = Ast.Parameter(typeof(RubyScope), "#scope"); selfVariable = parameters[1] = Ast.Parameter(typeof(object), "#self"); parameters[2] = Ast.Parameter(typeof(RubyModule), "#module"); blockParameter = parameters[3] = Ast.Parameter(typeof(Proc), "#block"); currentMethodVariable = parameters[4] = Ast.Parameter(typeof(RubyMethodInfo), "#method"); rfcVariable = parameters[5] = Ast.Parameter(typeof(RuntimeFlowControl), "#rfc"); if (gen.CompilerOptions.IsModuleEval) { runtimeScopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyScope)); parentScope = parameters[0]; moduleVariable = parameters[2]; } else { runtimeScopeVariable = parameters[0]; moduleVariable = null; parentScope = null; } language = null; } else { parameters = new MSA.ParameterExpression[2]; parentScope = parameters[0] = Ast.Parameter(typeof(Scope), "#globalScope"); language = parameters[1] = Ast.Parameter(typeof(LanguageContext), "#language"); selfVariable = scope.DefineHiddenVariable("#self", typeof(object)); rfcVariable = scope.DefineHiddenVariable("#rfc", typeof(RuntimeFlowControl)); runtimeScopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyScope)); blockParameter = null; currentMethodVariable = null; moduleVariable = null; } gen.EnterSourceUnit( scope, selfVariable, runtimeScopeVariable, blockParameter, rfcVariable, currentMethodVariable, gen.CompilerOptions.TopLevelMethodName, // method name null // parameters ); _definedScope.TransformLocals(scope); MSA.Expression scopeFactoryCall; if (gen.CompilerOptions.IsEval) { if (gen.CompilerOptions.IsModuleEval) { scopeFactoryCall = Methods.CreateModuleEvalScope.OpCall( scope.VisibleVariables(), parentScope, selfVariable, moduleVariable ); } else { scopeFactoryCall = null; } } else if (!gen.CompilerOptions.IsIncluded) { scopeFactoryCall = Methods.CreateMainTopLevelScope.OpCall(scope.VisibleVariables(), parentScope, language, selfVariable, rfcVariable, Ast.Constant(gen.SourceUnit.Path, typeof(string)), Ast.Constant(_dataOffset)); } else if (gen.CompilerOptions.IsWrapped) { scopeFactoryCall = Methods.CreateWrappedTopLevelScope.OpCall(scope.VisibleVariables(), parentScope, language, selfVariable, rfcVariable); } else { scopeFactoryCall = Methods.CreateTopLevelScope.OpCall(scope.VisibleVariables(), parentScope, language, selfVariable, rfcVariable); } MSA.Expression prologue, body; if (scopeFactoryCall != null) { prologue = Ast.Assign(runtimeScopeVariable, scopeFactoryCall); } else { prologue = null; } if (gen.SourceUnit.Kind == SourceCodeKind.InteractiveCode) { var resultVariable = scope.DefineHiddenVariable("#result", typeof(object)); var epilogue = Methods.PrintInteractiveResult.OpCall(runtimeScopeVariable, Ast.Dynamic(ConvertToSAction.Instance, typeof(MutableString), gen.CurrentScopeVariable, Ast.Dynamic(RubyCallAction.Make("inspect", RubyCallSignature.WithScope(0)), typeof(object), gen.CurrentScopeVariable, resultVariable ) ) ); body = gen.TransformStatements(prologue, _statements, epilogue, ResultOperation.Store(resultVariable)); } else { body = gen.TransformStatements(prologue, _statements, ResultOperation.Return); } body = gen.AddReturnTarget(scope.CreateScope(body)); gen.LeaveSourceUnit(); return(Ast.Lambda <T>( body, RubyExceptionData.TopLevelMethodName, parameters )); }
internal MSA.LambdaExpression/*!*/ TransformBody(AstGenerator/*!*/ gen, RubyScope/*!*/ declaringScope, RubyModule/*!*/ declaringModule) { string encodedName = RubyExceptionData.EncodeMethodName(_name, gen.SourcePath, Location); ScopeBuilder scope = new ScopeBuilder(); MSA.ParameterExpression[] parameters = DefineParameters(gen, scope); var currentMethodVariable = scope.DefineHiddenVariable("#method", typeof(RubyMethodInfo)); var rfcVariable = scope.DefineHiddenVariable("#rfc", typeof(RuntimeFlowControl)); var scopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyMethodScope)); var selfParameter = parameters[0]; var blockParameter = parameters[1]; gen.EnterMethodDefinition( scope, selfParameter, scopeVariable, blockParameter, rfcVariable, _name, _parameters ); DefinedScope.TransformLocals(scope); // profiling: MSA.Expression profileStart, profileEnd; if (gen.Profiler != null) { int profileTickIndex = gen.Profiler.GetTickIndex(encodedName); var stampVariable = scope.DefineHiddenVariable("#stamp", typeof(long)); profileStart = Ast.Assign(stampVariable, Methods.Stopwatch_GetTimestamp.OpCall()); profileEnd = Methods.UpdateProfileTicks.OpCall(AstUtils.Constant(profileTickIndex), stampVariable); } else { profileStart = profileEnd = AstUtils.Empty(); } // tracing: MSA.Expression traceCall, traceReturn; if (gen.TraceEnabled) { traceCall = Methods.TraceMethodCall.OpCall( scopeVariable, gen.SourcePathConstant, AstUtils.Constant(Location.Start.Line) ); traceReturn = Methods.TraceMethodReturn.OpCall( gen.CurrentScopeVariable, gen.SourcePathConstant, AstUtils.Constant(Location.End.Line) ); } else { traceCall = traceReturn = AstUtils.Empty(); } MSA.ParameterExpression unwinder = scope.DefineHiddenVariable("#unwinder", typeof(Exception)); MSA.Expression body = AstUtils.Try( profileStart, // scope initialization: Ast.Assign(rfcVariable, Methods.CreateRfcForMethod.OpCall(AstUtils.Convert(blockParameter, typeof(Proc)))), Ast.Assign(scopeVariable, Methods.CreateMethodScope.OpCall( scope.VisibleVariables(), Ast.Constant(declaringScope, typeof(RubyScope)), Ast.Constant(declaringModule, typeof(RubyModule)), Ast.Constant(_name), rfcVariable, selfParameter, blockParameter, EnterInterpretedFrameExpression.Instance )), _parameters.TransformOptionalsInitialization(gen), traceCall, Body.TransformResult(gen, ResultOperation.Return) ).Filter(unwinder, Methods.IsMethodUnwinderTargetFrame.OpCall(scopeVariable, unwinder), Ast.Return(gen.ReturnLabel, Methods.GetMethodUnwinderReturnValue.OpCall(unwinder)) ).Finally( // leave frame: Methods.LeaveMethodFrame.OpCall(rfcVariable), LeaveInterpretedFrameExpression.Instance, profileEnd, traceReturn ); body = gen.AddReturnTarget(scope.CreateScope(body)); gen.LeaveMethodDefinition(); return CreateLambda(encodedName, parameters, body); }
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) )); }
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) ); }
private MSA.Expression/*!*/ TransformBody(AstGenerator/*!*/ gen, MSA.Expression/*!*/ methodDefinitionVariable) { string encodedName = RubyExceptionData.EncodeMethodName(gen.SourceUnit, _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(AstUtils.Constant(gen.SourceUnit.Path), typeof(string)), AstUtils.Constant(Location.Start.Line)) : AstUtils.Empty(), Body.TransformResult(gen, ResultOperation.Return), AstUtils.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 ); }
internal sealed override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen) { string debugString = (IsSingletonDeclaration) ? "SINGLETON" : ((this is ClassDeclaration) ? "CLASS" : "MODULE") + " " + QualifiedName.Name; ScopeBuilder outerLocals = gen.CurrentScope; // definition needs to take place outside the defined lexical scope: MSA.Expression definition = MakeDefinitionExpression(gen); MSA.Expression selfVariable = outerLocals.DefineHiddenVariable("#module", typeof(RubyModule)); MSA.Expression rfcVariable = gen.CurrentRfcVariable; MSA.Expression parentScope = gen.CurrentScopeVariable; // inner locals: ScopeBuilder scope = new ScopeBuilder(); MSA.Expression scopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyScope)); gen.EnterModuleDefinition( scope, selfVariable, scopeVariable, IsSingletonDeclaration ); // first, transform locals defined within the module body: DefinedScope.TransformLocals(scope); // second, transform body: MSA.Expression transformedBody = Body.TransformRead(gen); // outer local: MSA.Expression resultVariable = outerLocals.DefineHiddenVariable("#result", transformedBody.Type); // begin with new scope // self = DefineModule/Class(... parent scope here ...) // <body> // end MSA.Expression result = AstFactory.Block( gen.DebugMarker(debugString), Ast.Assign(selfVariable, definition), scope.CreateScope( Ast.Block( Ast.Assign(scopeVariable, Methods.CreateModuleScope.OpCall(scope.VisibleVariables(), parentScope, rfcVariable, selfVariable)), Ast.Assign(resultVariable, transformedBody), AstUtils.Empty() ) ), gen.DebugMarker("END OF " + debugString), resultVariable ); gen.LeaveModuleDefinition(); return result; }
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 )); }