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; }
public ScopeBuilder(AstParameters parameters, int firstClosureParam, int localCount, ScopeBuilder parent, LexicalScope/*!*/ lexicalScope) { Debug.Assert(parent == null || parent.LexicalScope == lexicalScope.OuterScope); #if DEBUG _id = Interlocked.Increment(ref _Id); #endif _parent = parent; _parameters = parameters; _localCount = localCount; _firstClosureParam = firstClosureParam; _lexicalScope = lexicalScope; _hiddenVariables = new AstParameters(); _localsTuple = DefineHiddenVariable("#locals", MakeLocalsTupleType()); _outermostClosureReferredTo = this; }
private MSA.ParameterExpression[]/*!*/ DefineParameters(AstGenerator/*!*/ gen, ScopeBuilder/*!*/ scope) { // user defined locals/args: MSA.ParameterExpression[] parameters = DefinedScope.TransformParameters(_parameters, HiddenParameterCount); scope.AddVisibleParameters(parameters, HiddenParameterCount); parameters[0] = Ast.Parameter(typeof(object), "#self"); if (_parameters.Block != null) { // map user defined proc parameter to the special param #1: parameters[1] = _parameters.Block.TransformBlockParameterDefinition(); } else { parameters[1] = Ast.Parameter(typeof(Proc), "#block"); } return 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 MSA.ParameterExpression/*!*/ GetClosure(int definitionDepth) { Debug.Assert(definitionDepth >= 0); int delta = _lexicalScope.Depth - definitionDepth - 1; if (delta == -1) { return _localsTuple; } if (_closures == null) { _closures = new List<MSA.ParameterExpression>(); } while (delta >= _closures.Count) { // next closure builder that hasn't been accessed yet: _outermostClosureReferredTo = _outermostClosureReferredTo.Parent; _closures.Add(DefineHiddenVariable("#closure" + delta, _outermostClosureReferredTo._localsTuple.Type)); } return _closures[delta]; }
public ScopeBuilder(int localCount, ScopeBuilder parent, LexicalScope/*!*/ lexicalScope) : this(null, -1, localCount, parent, lexicalScope) { }
public void EnterSourceUnit( ScopeBuilder/*!*/ locals, MSA.Expression/*!*/ selfParameter, MSA.ParameterExpression/*!*/ runtimeScopeVariable, MSA.Expression blockParameter, string methodName, Parameters parameters) { Assert.NotNull(locals, selfParameter, runtimeScopeVariable); Debug.Assert(_currentElement == null && _currentLoop == null && _currentRescue == null && _currentVariableScope == null && _currentModule == null && _currentBlock == null && _currentMethod == null); EnterMethodDefinition( locals, selfParameter, runtimeScopeVariable, blockParameter, methodName, parameters); }
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 )); }
public ModuleScope(ScopeBuilder/*!*/ builder, MSA.Expression/*!*/ selfVariable, MSA.ParameterExpression/*!*/ runtimeScopeVariable, bool isSingleton) : base(builder, selfVariable, runtimeScopeVariable) { _isSingleton = isSingleton; }
public void EnterMethodDefinition( ScopeBuilder/*!*/ locals, MSA.Expression/*!*/ selfParameter, MSA.ParameterExpression/*!*/ runtimeScopeVariable, MSA.Expression blockParameter, string/*!*/ methodName, Parameters parameters) { Assert.NotNull(locals, selfParameter, runtimeScopeVariable); MethodScope method = new MethodScope( locals, selfParameter, runtimeScopeVariable, blockParameter, methodName, parameters ); method.Parent = _currentElement; method.ParentRescue = _currentRescue; method.ParentLoop = _currentLoop; method.ParentBlock = _currentBlock; method.ParentVariableScope = _currentVariableScope; method.ParentMethod = _currentMethod; _currentElement = method; _currentRescue = null; _currentLoop = null; _currentBlock = null; _currentVariableScope = method; _currentMethod = method; }
public VariableScope(ScopeBuilder/*!*/ locals, MSA.Expression/*!*/ selfVariable, MSA.ParameterExpression/*!*/ runtimeScopeVariable) { Assert.NotNull(selfVariable, runtimeScopeVariable); _builder = locals; _runtimeScopeVariable = runtimeScopeVariable; _selfVariable = selfVariable; }
public BlockScope(ScopeBuilder/*!*/ builder, MSA.Expression/*!*/ selfVariable, MSA.ParameterExpression/*!*/ runtimeScopeVariable, MSA.Expression/*!*/ bfcVariable, MSA.LabelTarget/*!*/ redoLabel) : base(builder, selfVariable, runtimeScopeVariable) { Assert.NotNull(bfcVariable, redoLabel); _bfcVariable = bfcVariable; _redoLabel = redoLabel; }
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) )); }
public void EnterFileInitializer( ScopeBuilder/*!*/ locals, MSA.Expression/*!*/ selfVariable, MSA.ParameterExpression/*!*/ runtimeScopeVariable) { VariableScope scope = new VariableScope(locals, selfVariable, runtimeScopeVariable); scope.Parent = _currentElement; scope.ParentVariableScope = _currentVariableScope; _currentElement = scope; _currentVariableScope = scope; }
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 MSA.LambdaExpression /*!*/ TransformBody(AstGenerator /*!*/ gen, RubyScope /*!*/ declaringScope, RubyModule /*!*/ declaringModule) { string encodedName = RubyStackTraceBuilder.EncodeMethodName(_name, gen.SourcePath, Location, gen.DebugMode); AstParameters parameters; ScopeBuilder scope = DefineLocals(out parameters); var scopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyMethodScope)); var selfParameter = parameters[0]; var blockParameter = parameters[1]; // exclude block parameter even if it is explicitly specified: int visiblePrameterCountAndSignatureFlags = (parameters.Count - 2) << 2; if (_parameters.Block != null) { visiblePrameterCountAndSignatureFlags |= RubyMethodScope.HasBlockFlag; } if (_parameters.Array != null) { visiblePrameterCountAndSignatureFlags |= RubyMethodScope.HasUnsplatFlag; } gen.EnterMethodDefinition( scope, selfParameter, scopeVariable, blockParameter, _name, _parameters ); // 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; MSA.Expression body = AstUtils.Try( profileStart, _parameters.TransformOptionalsInitialization(gen), traceCall, Body.TransformResult(gen, ResultOperation.Return) ).Filter(unwinder = Ast.Parameter(typeof(Exception), "#u"), Methods.IsMethodUnwinderTargetFrame.OpCall(scopeVariable, unwinder), Ast.Return(gen.ReturnLabel, Methods.GetMethodUnwinderReturnValue.OpCall(unwinder)) ).Finally( // leave frame: Methods.LeaveMethodFrame.OpCall(scopeVariable), Ast.Empty(), profileEnd, traceReturn ); body = gen.AddReturnTarget( scope.CreateScope( scopeVariable, Methods.CreateMethodScope.OpCall(new AstExpressions { scope.MakeLocalsStorage(), scope.GetVariableNamesExpression(), Ast.Constant(visiblePrameterCountAndSignatureFlags), Ast.Constant(declaringScope, typeof(RubyScope)), Ast.Constant(declaringModule, typeof(RubyModule)), Ast.Constant(_name), selfParameter, blockParameter, EnterInterpretedFrameExpression.Instance }), body ) ); gen.LeaveMethodDefinition(); return(CreateLambda(encodedName, parameters, body)); }
public ScopeBuilder(int localCount, ScopeBuilder parent, LexicalScope /*!*/ lexicalScope) : this(null, -1, localCount, parent, lexicalScope) { }
internal MSA.Expression <T> /*!*/ Transform <T>(AstGenerator /*!*/ gen) { Debug.Assert(gen != null); ScopeBuilder scope = DefineLocals(); MSA.ParameterExpression[] parameters; MSA.ParameterExpression selfVariable; MSA.ParameterExpression runtimeScopeVariable; MSA.ParameterExpression blockParameter; if (gen.CompilerOptions.FactoryKind == TopScopeFactoryKind.None || gen.CompilerOptions.FactoryKind == TopScopeFactoryKind.ModuleEval) { parameters = new MSA.ParameterExpression[4]; runtimeScopeVariable = 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"); } else { parameters = new MSA.ParameterExpression[2]; runtimeScopeVariable = parameters[0] = Ast.Parameter(typeof(RubyScope), "#scope"); selfVariable = parameters[1] = Ast.Parameter(typeof(object), "#self"); blockParameter = null; } gen.EnterSourceUnit( scope, selfVariable, runtimeScopeVariable, blockParameter, gen.CompilerOptions.TopLevelMethodName, // method name for blocks null // parameters for super calls ); MSA.Expression body; if (_statements.Count > 0) { if (gen.PrintInteractiveResult) { var resultVariable = scope.DefineHiddenVariable("#result", typeof(object)); var epilogue = Methods.PrintInteractiveResult.OpCall(runtimeScopeVariable, AstUtils.LightDynamic(ConvertToSAction.Make(gen.Context), typeof(MutableString), CallSiteBuilder.InvokeMethod(gen.Context, "inspect", RubyCallSignature.WithScope(0), gen.CurrentScopeVariable, resultVariable ) ) ); body = gen.TransformStatements(null, _statements, epilogue, ResultOperation.Store(resultVariable)); } else { body = gen.TransformStatements(_statements, ResultOperation.Return); } // TODO: var exceptionVariable = Ast.Parameter(typeof(Exception), "#exception"); body = AstUtils.Try( body ).Filter(exceptionVariable, Methods.TraceTopLevelCodeFrame.OpCall(runtimeScopeVariable, exceptionVariable), Ast.Empty() ); } else { body = AstUtils.Constant(null); } // scope initialization: MSA.Expression prologue; switch (gen.CompilerOptions.FactoryKind) { case TopScopeFactoryKind.None: case TopScopeFactoryKind.ModuleEval: prologue = Methods.InitializeScopeNoLocals.OpCall(runtimeScopeVariable, EnterInterpretedFrameExpression.Instance); break; case TopScopeFactoryKind.Hosted: case TopScopeFactoryKind.File: case TopScopeFactoryKind.WrappedFile: prologue = Methods.InitializeScope.OpCall( runtimeScopeVariable, scope.MakeLocalsStorage(), scope.GetVariableNamesExpression(), EnterInterpretedFrameExpression.Instance ); break; case TopScopeFactoryKind.Main: prologue = Methods.InitializeScope.OpCall( runtimeScopeVariable, scope.MakeLocalsStorage(), scope.GetVariableNamesExpression(), EnterInterpretedFrameExpression.Instance ); if (_dataOffset >= 0) { prologue = Ast.Block( prologue, Methods.SetDataConstant.OpCall( runtimeScopeVariable, gen.SourcePathConstant, AstUtils.Constant(_dataOffset) ) ); } break; default: throw Assert.Unreachable; } // BEGIN blocks: if (gen.FileInitializers != null) { var b = new AstBlock(); b.Add(prologue); b.Add(gen.FileInitializers); b.Add(body); body = b; } body = gen.AddReturnTarget(scope.CreateScope(body)); gen.LeaveSourceUnit(); return(Ast.Lambda <T>(body, GetEncodedName(gen), parameters)); }
internal void TransformDefinition(ScopeBuilder/*!*/ locals) { if (_transformed == null) { _transformed = locals.DefineVariable(Name); } }
private ScopeBuilder /*!*/ DefineLocals(ScopeBuilder /*!*/ parentBuilder) { return(new ScopeBuilder(_definedScope.AllocateClosureSlotsForLocals(0), parentBuilder, _definedScope)); }
public FrameScope(ScopeBuilder/*!*/ builder, MSA.Expression/*!*/ selfVariable, MSA.ParameterExpression/*!*/ runtimeScopeVariable) : base(builder, selfVariable, runtimeScopeVariable) { _uniqueId = Interlocked.Increment(ref _UniqueId); }
internal override MSA.Expression /*!*/ Transform(AstGenerator /*!*/ gen) { 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 = _parameters.LeftValues.Count; var attributes = _parameters.GetBlockSignatureAttributes(); var dispatcher = Ast.Constant( BlockDispatcher.Create(parameterCount, attributes, gen.SourcePath, Location.Start.Line), typeof(BlockDispatcher) ); return(Ast.Coalesce( Methods.InstantiateBlock.OpCall(gen.CurrentScopeVariable, gen.CurrentSelfVariable, dispatcher), Methods.DefineBlock.OpCall(gen.CurrentScopeVariable, gen.CurrentSelfVariable, dispatcher, BlockDispatcher.CreateLambda( body, RubyStackTraceBuilder.EncodeMethodName(gen.CurrentMethod.MethodName, gen.SourcePath, Location, gen.DebugMode), parameters, parameterCount, attributes ) ) )); }
public MethodScope( ScopeBuilder/*!*/ builder, MSA.Expression/*!*/ selfVariable, MSA.ParameterExpression/*!*/ runtimeScopeVariable, MSA.Expression blockVariable, string methodName, Parameters parameters) : base(builder, selfVariable, runtimeScopeVariable) { _blockVariable = blockVariable; _methodName = methodName; _parameters = parameters; }
public FrameScope(ScopeBuilder /*!*/ builder, MSA.Expression /*!*/ selfVariable, MSA.ParameterExpression /*!*/ runtimeScopeVariable) : base(builder, selfVariable, runtimeScopeVariable) { _uniqueId = Interlocked.Increment(ref _UniqueId); }
public void EnterBlockDefinition( ScopeBuilder/*!*/ locals, MSA.Expression/*!*/ bfcVariable, MSA.Expression/*!*/ selfVariable, MSA.ParameterExpression/*!*/ runtimeScopeVariable, MSA.LabelTarget/*!*/ redoLabel) { Assert.NotNull(locals, bfcVariable, selfVariable); Assert.NotNull(redoLabel); BlockScope block = new BlockScope(locals, selfVariable, runtimeScopeVariable, bfcVariable, redoLabel); block.Parent = _currentElement; block.ParentRescue = _currentRescue; block.ParentLoop = _currentLoop; block.ParentBlock = _currentBlock; block.ParentVariableScope = _currentVariableScope; _currentElement = block; _currentRescue = null; _currentLoop = null; _currentBlock = block; _currentVariableScope = block; }
public ModuleScope(ScopeBuilder /*!*/ builder, MSA.Expression /*!*/ selfVariable, MSA.ParameterExpression /*!*/ runtimeScopeVariable, bool isSingleton) : base(builder, selfVariable, runtimeScopeVariable) { _isSingleton = isSingleton; }
public void EnterModuleDefinition( ScopeBuilder/*!*/ locals, MSA.Expression/*!*/ selfVariable, MSA.ParameterExpression/*!*/ runtimeScopeVariable, bool isSingleton) { Assert.NotNull(locals, selfVariable, runtimeScopeVariable); ModuleScope module = new ModuleScope(locals, selfVariable, runtimeScopeVariable, isSingleton); module.Parent = _currentElement; module.ParentVariableScope = _currentVariableScope; module.ParentModule = _currentModule; _currentElement = module; _currentVariableScope = module; _currentModule = module; }
public MethodScope( ScopeBuilder/*!*/ builder, MSA.Expression/*!*/ selfVariable, MSA.Expression/*!*/ runtimeScopeVariable, MSA.Expression blockVariable, MSA.Expression/*!*/ rfcVariable, MSA.Expression currentMethodVariable, string methodName, Parameters parameters) : base(builder, selfVariable, runtimeScopeVariable) { Assert.NotNull(rfcVariable); _blockVariable = blockVariable; _rfcVariable = rfcVariable; _methodName = methodName; _parameters = parameters; _currentMethodVariable = currentMethodVariable; }
private ScopeBuilder/*!*/ DefineLocals(ScopeBuilder/*!*/ parentBuilder) { return new ScopeBuilder(_definedScope.AllocateClosureSlotsForLocals(0), parentBuilder, _definedScope); }
private MSA.ParameterExpression[] /*!*/ DefineParameters(AstGenerator /*!*/ gen, ScopeBuilder /*!*/ scope) { // user defined locals/args: MSA.ParameterExpression[] parameters = DefinedScope.TransformParameters(_parameters, HiddenParameterCount); scope.AddVisibleParameters(parameters, HiddenParameterCount); parameters[0] = Ast.Parameter(typeof(object), "#self"); if (_parameters.Block != null) { // map user defined proc parameter to the special param #1: parameters[1] = _parameters.Block.TransformBlockParameterDefinition(); } else { parameters[1] = Ast.Parameter(typeof(Proc), "#block"); } return(parameters); }