public MSA.Expression /*!*/ MakeLocalsStorage() { // TODO: use a factory instead of Ast.New to improve interpreter perf: MSA.Expression result = Ast.Assign( _localsTuple, LiftedVisibleVariableCount == 0 ? (MSA.Expression)Ast.Constant(null, _localsTuple.Type) : Ast.New(_localsTuple.Type) ); if (_parameters != null) { var initializers = new AstExpressions(); initializers.Add(result); // parameters map to the initial elements of the array: for (int i = _firstClosureParam, j = 0; i < _parameters.Count; i++, j++) { initializers.Add(Ast.Assign(GetVariableAccessor(_localsTuple, j), _parameters[i])); } initializers.Add(_localsTuple); result = Ast.Block(initializers); } return(result); }
private MSA.Expression /*!*/ MakeParametersInitialization(AstGenerator /*!*/ gen, AstParameters /*!*/ parameters) { var result = new AstExpressions( _parameters.LeftValues.Count + (_parameters.UnsplattedValue != null ? 1 : 0) + 1 ); bool paramsInArray = HasFormalParametersInArray; for (int i = 0; i < _parameters.LeftValues.Count; i++) { var parameter = paramsInArray ? (MSA.Expression) Ast.ArrayAccess(parameters[HiddenParameterCount], AstUtils.Constant(i)) : parameters[HiddenParameterCount + i]; result.Add(_parameters.LeftValues[i].TransformWrite(gen, parameter)); } if (_parameters.UnsplattedValue != null) { // the last parameter is unsplat: var parameter = parameters[parameters.Count - 1]; result.Add(_parameters.UnsplattedValue.TransformWrite(gen, parameter)); } result.Add(AstUtils.Empty()); return(Ast.Block(result)); }
public override DynamicMetaObject /*!*/ Bind(DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ args) { Debug.Assert(args.Length > 1); var exprs = new AstExpressions(); exprs.Add(AstUtils.LightDynamic(_getMember, typeof(object), target.Expression)); exprs.Add(args.ToExpressions()); return(new DynamicMetaObject(AstUtils.LightDynamic(_setIndex, typeof(object), exprs), BindingRestrictions.Empty)); }
public override DynamicMetaObject /*!*/ FallbackInvoke(DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ args, DynamicMetaObject errorSuggestion) { AstExpressions exprs = new AstExpressions(); exprs.Add(target.Expression); exprs.Add(args.ToExpressions()); return(new DynamicMetaObject( AstUtils.LightDynamic(_context.MetaBinderFactory.InteropReturn(CallInfo), typeof(object), exprs), target.Restrictions.Merge(BindingRestrictions.Combine(args)) )); }
internal AstExpressions /*!*/ TransformMapletsToExpressions(IList <Maplet> /*!*/ maplets, AstExpressions /*!*/ result) { Assert.NotNullItems(maplets); Assert.NotNull(result); foreach (Maplet entry in maplets) { result.Add(entry.Key.TransformRead(this)); result.Add(entry.Value.TransformRead(this)); } return(result); }
private void BuildCall(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, string /*!*/ name) { var actualArgs = RubyOverloadResolver.NormalizeArguments(metaBuilder, args, 0, Int32.MaxValue); if (metaBuilder.Error) { return; } metaBuilder.AddRestriction( Ast.Equal( Ast.Property(Ast.Convert(args.TargetExpression, typeof(Win32API)), VersionProperty), Ast.Constant(_version) ) ); if (_function == IntPtr.Zero) { metaBuilder.SetError(Ast.Throw(new Func <Exception>(UninitializedFunctionError).Method.OpCall(), typeof(object))); return; } if (_signature.Length != actualArgs.Count) { metaBuilder.SetError(Ast.Throw(new Func <int, int, Exception>(InvalidParameterCountError).Method.OpCall( Ast.Constant(_signature.Length), Ast.Constant(actualArgs.Count)), typeof(object) )); return; } var calliArgs = new AstExpressions(); calliArgs.Add(Ast.Property(Ast.Convert(args.TargetExpression, typeof(Win32API)), FunctionProperty)); for (int i = 0; i < actualArgs.Count; i++) { calliArgs.Add(MarshalArgument(metaBuilder, actualArgs[i], _signature[i])); } metaBuilder.Result = Ast.Call(EmitCalliStub(), calliArgs); // MRI returns 0 if void return type is given: if (_returnType == ArgType.None) { metaBuilder.Result = Ast.Block(metaBuilder.Result, AstUtils.Constant(0)); } }
internal ReadOnlyCollection <Expression> /*!*/ GetCallSiteArguments(Expression /*!*/ targetExpression) { // context, target, arguments: var result = new AstExpressions(CallSiteArgumentCount); if (_hasScopeOrContextArg) { result.Add(_signature.HasScope ? MetaScope.Expression : MetaContext.Expression); } result.Add(targetExpression); for (int j = FirstArgumentIndex; j < _args.Length; j++) { result.Add(_args[j].Expression); } return(result.ToReadOnlyCollection()); }
internal void AddInitialization(Expression /*!*/ expression) { if (_initializations == null) { _initializations = new AstExpressions(); } _initializations.Add(expression); }
public MSA.Expression /*!*/ CreateScope(MSA.Expression /*!*/ scopeVariable, MSA.Expression /*!*/ scopeInitializer, MSA.Expression /*!*/ body) { // #locals variable already assigned (in MakeClosureDefinition). // We need to initialize #closureN variables. if (_closures != null) { if (_closures.Count == 1) { return(Ast.Block(_hiddenVariables, Ast.Block( Ast.Assign( _closures[0], AstUtils.Convert(Methods.GetParentLocals.OpCall(Ast.Assign(scopeVariable, scopeInitializer)), _closures[0].Type) ), body ))); } else { var result = new AstExpressions(); MSA.Expression tempScope = DefineHiddenVariable("#s", typeof(RubyScope)); result.Add(Ast.Assign(scopeVariable, scopeInitializer)); for (int i = 0; i < _closures.Count; i++) { result.Add( Ast.Assign( _closures[i], AstUtils.Convert( Methods.GetLocals.OpCall(Ast.Assign(tempScope, Methods.GetParentScope.OpCall(i == 0 ? scopeVariable : tempScope))), _closures[i].Type ) ) ); } result.Add(body); return(Ast.Block(_hiddenVariables, result)); } } else { return(Ast.Block(_hiddenVariables, Ast.Block(Ast.Assign(scopeVariable, scopeInitializer), body))); } }
public AstExpressions /*!*/ GetSimpleArgumentExpressions() { int count = SimpleArgumentCount; var result = new AstExpressions(count); for (int i = 0, j = GetSimpleArgumentIndex(0); i < count; j++, i++) { result.Add(_args[j].Expression); } return(result); }
internal AstExpressions /*!*/ TranformExpressions(IList <Expression> /*!*/ arguments, AstExpressions /*!*/ result) { Assert.NotNullItems(arguments); Assert.NotNull(result); foreach (Expression arg in arguments) { result.Add(arg.TransformRead(this)); } return(result); }
private AstExpressions /*!*/ MakeSimpleArgumentExpressionList(AstGenerator /*!*/ gen) { var args = new AstExpressions(); if (_expressions != null) { gen.TranformExpressions(_expressions, args); } if (_maplets != null) { args.Add(gen.TransformToHashConstructor(_maplets)); } return(args); }
internal static MSA.Expression /*!*/ YieldExpression( RubyContext /*!*/ context, ICollection <MSA.Expression> /*!*/ arguments, MSA.Expression splattedArgument, MSA.Expression rhsArgument, MSA.Expression blockArgument, MSA.Expression /*!*/ bfcVariable, MSA.Expression /*!*/ selfArgument) { Assert.NotNull(arguments, bfcVariable, selfArgument); bool hasArgumentArray; var opMethod = Methods.Yield(arguments.Count, splattedArgument != null, rhsArgument != null, out hasArgumentArray); var args = new AstExpressions(); foreach (var arg in arguments) { args.Add(AstUtils.Box(arg)); } if (hasArgumentArray) { args = new AstExpressions { Ast.NewArrayInit(typeof(object), args) }; } if (splattedArgument != null) { args.Add(AstUtils.LightDynamic(ExplicitSplatAction.Make(context), typeof(IList), splattedArgument)); } if (rhsArgument != null) { args.Add(AstUtils.Box(rhsArgument)); } args.Add(blockArgument != null ? AstUtils.Convert(blockArgument, typeof(Proc)) : AstFactory.NullOfProc); args.Add(AstUtils.Box(selfArgument)); args.Add(bfcVariable); return(Ast.Call(opMethod, args)); }
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)); }
public AstExpressions/*!*/ GetSimpleArgumentExpressions() { int count = SimpleArgumentCount; var result = new AstExpressions(count); for (int i = 0, j = GetSimpleArgumentsIndex(0); i < count; j++, i++) { result.Add(_args[j].Expression); } return result; }
private MSA.Expression/*!*/ MakeParametersInitialization(AstGenerator/*!*/ gen, AstParameters/*!*/ parameters) { var result = new AstExpressions( _parameters.LeftValues.Count + (_parameters.UnsplattedValue != null ? 1 : 0) + 1 ); bool paramsInArray = HasFormalParametersInArray; for (int i = 0; i < _parameters.LeftValues.Count; i++) { var parameter = paramsInArray ? (MSA.Expression) Ast.ArrayAccess(parameters[HiddenParameterCount], AstUtils.Constant(i)) : parameters[HiddenParameterCount + i]; result.Add(_parameters.LeftValues[i].TransformWrite(gen, parameter)); } if (_parameters.UnsplattedValue != null) { // the last parameter is unsplat: var parameter = parameters[parameters.Count - 1]; result.Add(_parameters.UnsplattedValue.TransformWrite(gen, parameter)); } result.Add(AstUtils.Empty()); return Ast.Block(result); }
internal AstExpressions/*!*/ TransformMapletsToExpressions(IList<Maplet>/*!*/ maplets, AstExpressions/*!*/ result) { Assert.NotNullItems(maplets); Assert.NotNull(result); foreach (Maplet entry in maplets) { result.Add(entry.Key.TransformRead(this)); result.Add(entry.Value.TransformRead(this)); } return result; }
private MSA.Expression/*!*/ TransformStatementsToExpression(Statements statements, bool toBoolean, bool positive) { if (statements == null || statements.Count == 0) { return toBoolean ? AstUtils.Constant(!positive) : AstUtils.Constant(null); } var last = toBoolean ? statements.Last.TransformCondition(this, positive) : statements.Last.TransformReadStep(this); if (statements.Count == 1) { return last; } var result = new AstExpressions(statements.Count); foreach (var statement in statements.AllButLast) { result.Add(statement.Transform(this)); } result.Add(last); return Ast.Block(result); }
public MSA.Expression/*!*/ MakeLocalsStorage() { MSA.Expression result = Ast.Assign( _localsTuple, LiftedVisibleVariableCount == 0 ? (MSA.Expression)Ast.Constant(null, _localsTuple.Type) : Ast.New(_localsTuple.Type) ); if (_parameters != null) { var initializers = new AstExpressions(); initializers.Add(result); // parameters map to the initial elements of the array: for (int i = _firstClosureParam, j = 0; i < _parameters.Count; i++, j++) { initializers.Add(Ast.Assign(GetVariableAccessor(_localsTuple, j), _parameters[i])); } initializers.Add(_localsTuple); result = Ast.Block(initializers); } return result; }
public override DynamicMetaObject/*!*/ FallbackInvoke(DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ args, DynamicMetaObject errorSuggestion) { AstExpressions exprs = new AstExpressions(); exprs.Add(target.Expression); exprs.Add(args.ToExpressions()); return new DynamicMetaObject( AstUtils.LightDynamic(_context.MetaBinderFactory.InteropReturn(CallInfo), typeof(object), exprs), target.Restrictions.Merge(BindingRestrictions.Combine(args)) ); }
internal static MSA.Expression/*!*/ YieldExpression( RubyContext/*!*/ context, AstExpressions/*!*/ arguments, MSA.Expression splattedArgument, MSA.Expression rhsArgument, MSA.Expression/*!*/ bfcVariable, MSA.Expression/*!*/ selfArgument) { Assert.NotNull(arguments, bfcVariable, selfArgument); bool hasArgumentArray; var opMethod = Methods.Yield(arguments.Count, splattedArgument != null, rhsArgument != null, out hasArgumentArray); var args = new AstExpressions(); foreach (var arg in arguments) { args.Add(AstUtils.Box(arg)); } if (hasArgumentArray) { args = new AstExpressions { Ast.NewArrayInit(typeof(object), args) }; } if (splattedArgument != null) { args.Add(AstUtils.LightDynamic(SplatAction.Make(context), typeof(IList), splattedArgument)); } if (rhsArgument != null) { args.Add(AstUtils.Box(rhsArgument)); } args.Add(AstUtils.Box(selfArgument)); args.Add(bfcVariable); return Ast.Call(opMethod, args); }
private AstExpressions/*!*/ MakeSimpleArgumentExpressionList(AstGenerator/*!*/ gen) { var args = new AstExpressions(); if (_expressions != null) { gen.TranformExpressions(_expressions, args); } if (_maplets != null) { args.Add(gen.TransformToHashConstructor(_maplets)); } return args; }
internal ReadOnlyCollection<Expression>/*!*/ GetCallSiteArguments(Expression/*!*/ targetExpression) { // context, target, arguments: var result = new AstExpressions(CallSiteArgumentCount); if (_hasScopeOrContextArg) { result.Add(_signature.HasScope ? MetaScope.Expression : MetaContext.Expression); } result.Add(targetExpression); for (int j = FirstArgumentIndex; j < _args.Length; j++) { result.Add(_args[j].Expression); } return result.ToReadOnlyCollection(); }
private void BuildCall(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, string/*!*/ name) { var actualArgs = RubyOverloadResolver.NormalizeArguments(metaBuilder, args, 0, Int32.MaxValue); if (metaBuilder.Error) { return; } metaBuilder.AddRestriction( Ast.Equal( Ast.Property(Ast.Convert(args.TargetExpression, typeof(Win32API)), VersionProperty), Ast.Constant(_version) ) ); if (_function == IntPtr.Zero) { metaBuilder.SetError(Ast.Throw(new Func<Exception>(UninitializedFunctionError).Method.OpCall(), typeof(object))); return; } if (_signature.Length != actualArgs.Count) { metaBuilder.SetError(Ast.Throw(new Func<int, int, Exception>(InvalidParameterCountError).Method.OpCall( Ast.Constant(_signature.Length), Ast.Constant(actualArgs.Count)), typeof(object) )); return; } var calliArgs = new AstExpressions(); calliArgs.Add(Ast.Property(Ast.Convert(args.TargetExpression, typeof(Win32API)), FunctionProperty)); for (int i = 0; i < actualArgs.Count; i++) { calliArgs.Add(MarshalArgument(metaBuilder, actualArgs[i], _signature[i])); } metaBuilder.Result = Ast.Call(EmitCalliStub(), calliArgs); // MRI returns 0 if void return type is given: if (_returnType == ArgType.None) { metaBuilder.Result = Ast.Block(metaBuilder.Result, AstUtils.Constant(0)); } }
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 AstExpressions/*!*/ TranformExpressions(IList<Expression>/*!*/ arguments, AstExpressions/*!*/ result) { Assert.NotNullItems(arguments); Assert.NotNull(result); foreach (Expression arg in arguments) { result.Add(arg.TransformRead(this)); } return result; }
public override DynamicMetaObject/*!*/ Bind(DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ args) { Debug.Assert(args.Length > 1); var exprs = new AstExpressions(); exprs.Add(AstUtils.LightDynamic(_getMember, typeof(object), target.Expression)); exprs.Add(args.ToExpressions()); return new DynamicMetaObject(AstUtils.LightDynamic(_setIndex, typeof(object), exprs), BindingRestrictions.Empty); }
internal MSA.Expression/*!*/ TransformStatements(MSA.Expression prologue, Statements/*!*/ statements, MSA.Expression epilogue, ResultOperation resultOperation) { Assert.NotNull(statements); int count = statements.Count + (prologue != null ? 1 : 0) + (epilogue != null ? 1 : 0); if (count == 0) { if (resultOperation.IsIgnore) { return AstUtils.Empty(); } else if (resultOperation.Variable != null) { return Ast.Assign(resultOperation.Variable, AstUtils.Constant(null, resultOperation.Variable.Type)); } else { return Ast.Return(CurrentFrame.ReturnLabel, AstUtils.Constant(null)); } } else if (count == 1) { if (prologue != null) { return prologue; } if (epilogue != null) { return epilogue; } if (resultOperation.IsIgnore) { return statements.First.Transform(this); } else { return statements.First.TransformResult(this, resultOperation); } } else { var result = new AstExpressions(count + 1); if (prologue != null) { result.Add(prologue); } // transform all but the last statement if it is an expression stmt: foreach (var statement in statements.AllButLast) { result.Add(statement.Transform(this)); } if (statements.Count > 0) { if (resultOperation.IsIgnore) { result.Add(statements.Last.Transform(this)); } else { result.Add(statements.Last.TransformResult(this, resultOperation)); } } if (epilogue != null) { result.Add(epilogue); } result.Add(AstUtils.Empty()); return Ast.Block(result); } }
public static AstExpressions/*!*/ Expressions(MSA.Expression/*!*/ expression) { var result = new AstExpressions(); result.Add(expression); return result; }
public MSA.Expression/*!*/ CreateScope(MSA.Expression/*!*/ scopeVariable, MSA.Expression/*!*/ scopeInitializer, MSA.Expression/*!*/ body) { // #locals variable already assigned (in MakeClosureDefinition). // We need to initialize #closureN variables. if (_closures != null) { if (_closures.Count == 1) { return Ast.Block(_hiddenVariables, Ast.Block( Ast.Assign( _closures[0], AstUtils.Convert(Methods.GetParentLocals.OpCall(Ast.Assign(scopeVariable, scopeInitializer)), _closures[0].Type) ), body )); } else { var result = new AstExpressions(); MSA.Expression tempScope = DefineHiddenVariable("#s", typeof(RubyScope)); result.Add(Ast.Assign(scopeVariable, scopeInitializer)); for (int i = 0; i < _closures.Count; i++) { result.Add( Ast.Assign( _closures[i], AstUtils.Convert( Methods.GetLocals.OpCall(Ast.Assign(tempScope, Methods.GetParentScope.OpCall(i == 0 ? scopeVariable : tempScope))), _closures[i].Type ) ) ); } result.Add(body); return Ast.Block(_hiddenVariables, result); } } else { return Ast.Block(_hiddenVariables, Ast.Block(Ast.Assign(scopeVariable, scopeInitializer), body)); } }