private TransformOptionalsInitialization ( |
||
gen | ||
Результат |
private MSA.Expression /*!*/ MakeParametersInitialization(AstGenerator /*!*/ gen, AstParameters /*!*/ parameters) { var result = new AstExpressions( ParameterCount + (_parameters.Optional.Length > 0 ? 1 : 0) + (_parameters.Unsplat != null ? 1 : 0) + (_parameters.Block != null ? 1 : 0) + 1 ); // TODO: we can skip parameters that are locals (need to be defined as parameters, not as #n): var paramsArray = HasFormalParametersInArray ? parameters[HiddenParameterCount] : null; int parameterIndex = 0; for (int i = 0; i < _parameters.Mandatory.Length; i++) { result.Add(_parameters.Mandatory[i].TransformWrite(gen, GetParameterAccess(parameters, paramsArray, parameterIndex))); parameterIndex++; } if (_parameters.Optional.Length > 0) { for (int i = 0; i < _parameters.Optional.Length; i++) { result.Add(_parameters.Optional[i].Left.TransformWrite(gen, GetParameterAccess(parameters, paramsArray, parameterIndex))); parameterIndex++; } result.Add(_parameters.TransformOptionalsInitialization(gen)); } if (_parameters.Unsplat != null) { // the last parameter is unsplat: result.Add(_parameters.Unsplat.TransformWrite(gen, parameters[parameters.Count - (_parameters.Block != null ? 2 : 1)])); } if (_parameters.Block != null) { result.Add(_parameters.Block.TransformWrite(gen, parameters[parameters.Count - 1])); parameterIndex++; } result.Add(AstUtils.Empty()); return(Ast.Block(result)); }
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.Unsplat != 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)); }