本文整理汇总了C#中IronRuby.Runtime.Calls.MetaObjectBuilder.GetTemporary方法的典型用法代码示例。如果您正苦于以下问题:C# MetaObjectBuilder.GetTemporary方法的具体用法?C# MetaObjectBuilder.GetTemporary怎么用?C# MetaObjectBuilder.GetTemporary使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类IronRuby.Runtime.Calls.MetaObjectBuilder
的用法示例。
在下文中一共展示了MetaObjectBuilder.GetTemporary方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: Build
protected override bool Build(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, bool defaultFallback) {
RubyModule currentDeclaringModule;
string currentMethodName;
var scope = args.Scope;
object target;
scope.GetSuperCallTarget(out currentDeclaringModule, out currentMethodName, out target);
var targetExpression = metaBuilder.GetTemporary(typeof(object), "#super-self");
metaBuilder.AddCondition(
Methods.IsSuperCallTarget.OpCall(
AstUtils.Convert(args.MetaScope.Expression, typeof(RubyScope)),
AstUtils.Constant(currentDeclaringModule),
AstUtils.Constant(currentMethodName),
targetExpression
)
);
args.SetTarget(targetExpression, target);
Debug.Assert(currentDeclaringModule != null);
RubyMemberInfo method;
RubyMemberInfo methodMissing = null;
// we need to lock the hierarchy of the target class:
var targetClass = scope.RubyContext.GetImmediateClassOf(target);
using (targetClass.Context.ClassHierarchyLocker()) {
// initialize all methods in ancestors:
targetClass.InitializeMethodsNoLock();
// target is stored in a local, therefore it cannot be part of the restrictions:
metaBuilder.TreatRestrictionsAsConditions = true;
metaBuilder.AddTargetTypeTest(target, targetClass, targetExpression, args.MetaContext,
new[] { Symbols.MethodMissing } // currentMethodName is resolved for super, which cannot be an instance singleton
);
metaBuilder.TreatRestrictionsAsConditions = false;
method = targetClass.ResolveSuperMethodNoLock(currentMethodName, currentDeclaringModule).InvalidateSitesOnOverride().Info;
if (method == null) {
// MRI: method_missing is called for the targetClass, not for the super:
methodMissing = targetClass.ResolveMethodMissingForSite(currentMethodName, RubyMethodVisibility.None);
}
}
if (method != null) {
method.BuildSuperCall(metaBuilder, args, currentMethodName, currentDeclaringModule);
} else {
return RubyCallAction.BuildMethodMissingCall(metaBuilder, args, currentMethodName, methodMissing, RubyMethodVisibility.None, true, defaultFallback);
}
return true;
}
示例2: BuildMethodMissingCallNoFlow
internal override void BuildMethodMissingCallNoFlow(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, string/*!*/ name) {
var globalScope = args.TargetClass.GlobalScope;
var context = globalScope.Context;
if (name.LastCharacter() == '=') {
var normalizedArgs = RubyOverloadResolver.NormalizeArguments(metaBuilder, args, 1, 1);
if (!metaBuilder.Error) {
var scopeVar = metaBuilder.GetTemporary(typeof(Scope), "#scope");
metaBuilder.AddInitialization(
Ast.Assign(scopeVar, Methods.GetGlobalScopeFromScope.OpCall(AstUtils.Convert(args.MetaScope.Expression, typeof(RubyScope))))
);
var interopSetter = context.MetaBinderFactory.InteropSetMember(name.Substring(0, name.Length - 1));
metaBuilder.SetMetaResult(
interopSetter.Bind(
new DynamicMetaObject(
scopeVar,
BindingRestrictions.Empty,
globalScope.Scope
),
new[] { normalizedArgs[0] }
),
true
);
}
} else {
RubyOverloadResolver.NormalizeArguments(metaBuilder, args, 0, 0);
Expression errorExpr = metaBuilder.Error ? Ast.Throw(metaBuilder.Result, typeof(object)) : null;
var scopeVar = metaBuilder.GetTemporary(typeof(Scope), "#scope");
var scopeLookupResultVar = metaBuilder.GetTemporary(typeof(object), "#result");
metaBuilder.AddInitialization(
Ast.Assign(scopeVar, Methods.GetGlobalScopeFromScope.OpCall(AstUtils.Convert(args.MetaScope.Expression, typeof(RubyScope))))
);
Expression scopeLookupResultExpr = errorExpr ?? scopeLookupResultVar;
Expression fallbackExp;
if (name == "scope") {
fallbackExp = errorExpr ?? args.TargetExpression;
} else {
// super(methodName, ...args...) - ignore argument error:
args.InsertMethodName(name);
fallbackExp = AstUtils.LightDynamic(
context.MetaBinderFactory.Call(Symbols.MethodMissing,
new RubyCallSignature(
args.Signature.ArgumentCount + 1,
args.Signature.Flags | RubyCallFlags.HasImplicitSelf | RubyCallFlags.IsSuperCall
)
),
typeof(object),
args.GetCallSiteArguments(args.TargetExpression)
);
}
var scopeLookup = Ast.NotEqual(
Ast.Assign(scopeLookupResultVar, AstUtils.LightDynamic(RubyMetaBinderFactory.InteropTryGetMemberExact(name), typeof(object), scopeVar)),
Expression.Constant(OperationFailed.Value)
);
string unmanagled = RubyUtils.TryUnmangleMethodName(name);
if (unmanagled != null) {
scopeLookup = Ast.OrElse(
scopeLookup,
Ast.NotEqual(
Ast.Assign(scopeLookupResultVar, AstUtils.LightDynamic(RubyMetaBinderFactory.InteropTryGetMemberExact(unmanagled), typeof(object), scopeVar)),
Expression.Constant(OperationFailed.Value)
)
);
}
metaBuilder.Result = Ast.Condition(
scopeLookup,
scopeLookupResultExpr,
fallbackExp
);
}
}
示例3: BuildCall
/// <summary>
/// From control flow perspective it "calls" the proc.
/// </summary>
internal static void BuildCall(
MetaObjectBuilder/*!*/ metaBuilder,
Expression/*!*/ procExpression, // proc object
Expression/*!*/ selfExpression, // self passed to the proc
CallArguments/*!*/ args // user arguments passed to the proc
) {
var bfcVariable = metaBuilder.GetTemporary(typeof(BlockParam), "#bfc");
metaBuilder.Result = Ast.Block(
Ast.Assign(bfcVariable, Methods.CreateBfcForProcCall.OpCall(AstUtils.Convert(procExpression, typeof(Proc)))),
Methods.MethodProcCall.OpCall(bfcVariable,
AstFactory.YieldExpression(
args.RubyContext,
args.GetSimpleArgumentExpressions(),
args.GetSplattedArgumentExpression(),
args.GetRhsArgumentExpression(),
bfcVariable,
selfExpression
)
)
);
}
示例4: BuildOverriddenInitializerCall
private static void BuildOverriddenInitializerCall(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, RubyMemberInfo/*!*/ initializer) {
var instanceExpr = metaBuilder.Result;
metaBuilder.Result = null;
var instanceVariable = metaBuilder.GetTemporary(instanceExpr.Type, "#instance");
// We know an exact type of the new instance and that there is no singleton for that instance.
// We also have the exact method we need to call ("initialize" is a RubyMethodInfo/RubyLambdaMethodInfo).
// => no tests are necessary:
args.SetTarget(instanceVariable, null);
if (initializer is RubyMethodInfo || initializer is RubyLambdaMethodInfo) {
initializer.BuildCallNoFlow(metaBuilder, args, Symbols.Initialize);
} else {
// TODO: we need more refactoring of RubyMethodGroupInfo.BuildCall to be able to inline this:
metaBuilder.Result = AstUtils.LightDynamic(
RubyCallAction.Make(args.RubyContext, "initialize",
new RubyCallSignature(
args.Signature.ArgumentCount,
(args.Signature.Flags & ~RubyCallFlags.IsInteropCall) | RubyCallFlags.HasImplicitSelf
)
),
args.GetCallSiteArguments(instanceVariable)
);
}
if (!metaBuilder.Error) {
// PropagateRetrySingleton(instance = new <type>(), instance.initialize(<args>))
metaBuilder.Result = Methods.PropagateRetrySingleton.OpCall(
Ast.Assign(instanceVariable, instanceExpr),
metaBuilder.Result
);
// we need to handle break, which unwinds to a proc-converter that could be this method's frame:
if (args.Signature.HasBlock) {
metaBuilder.ControlFlowBuilder = RubyMethodInfo.RuleControlFlowBuilder;
}
}
}
示例5: ApplyBlockFlowHandlingInternal
/// <summary>
/// Takes current result and wraps it into try-filter(MethodUnwinder)-finally block that ensures correct "break" behavior for
/// library method calls with block given in bfcVariable (BlockParam).
/// </summary>
internal static void ApplyBlockFlowHandlingInternal(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args) {
if (metaBuilder.Error) {
return;
}
Expression expression = metaBuilder.Result;
Expression bfcVariable = metaBuilder.BfcVariable;
// Method call with proc can invoke control flow that returns an arbitrary value from the call, so we need to type result to Object.
// Otherwise, the result could only be result of targetExpression unless its return type is void.
Type resultType = (bfcVariable != null) ? typeof(object) : expression.Type;
Expression resultVariable;
if (resultType != typeof(void)) {
resultVariable = metaBuilder.GetTemporary(resultType, "#result");
} else {
resultVariable = Expression.Empty();
}
if (expression.Type != typeof(void)) {
expression = Ast.Assign(resultVariable, AstUtils.Convert(expression, resultType));
}
// a non-null proc is being passed to the callee:
if (bfcVariable != null) {
ParameterExpression methodUnwinder = metaBuilder.GetTemporary(typeof(MethodUnwinder), "#unwinder");
expression = AstFactory.Block(
Ast.Assign(bfcVariable, Methods.CreateBfcForLibraryMethod.OpCall(AstUtils.Convert(args.GetBlockExpression(), typeof(Proc)))),
AstUtils.Try(
expression
).Filter(methodUnwinder, Methods.IsProcConverterTarget.OpCall(bfcVariable, methodUnwinder),
Ast.Assign(resultVariable, Ast.Field(methodUnwinder, MethodUnwinder.ReturnValueField))
).Finally(
Methods.LeaveProcConverter.OpCall(bfcVariable)
),
resultVariable
);
}
metaBuilder.Result = expression;
}
示例6: BuildCallNoFlow
/// <summary>
/// Resolves an library method overload and builds call expression.
/// The resulting expression on meta-builder doesn't handle block control flow yet.
/// </summary>
internal static void BuildCallNoFlow(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, string/*!*/ name,
IList<MethodBase>/*!*/ overloads, bool includeSelf, bool selfIsInstance) {
var bindingTarget = ResolveOverload(name, overloads, args, includeSelf, selfIsInstance);
if (bindingTarget.Success) {
bool calleeHasBlockParam = HasBlockParameter(bindingTarget.Method);
// Allocates a variable holding BlockParam. At runtime the BlockParam is created with a new RFC instance that
// identifies the library method frame as a proc-converter target of a method unwinder triggered by break from a block.
//
// NOTE: We check for null block here -> test fore that fact is added in MakeActualArgs
if (metaBuilder.BfcVariable == null && args.Signature.HasBlock && args.GetBlock() != null && calleeHasBlockParam) {
metaBuilder.BfcVariable = metaBuilder.GetTemporary(typeof(BlockParam), "#bfc");
}
var actualArgs = MakeActualArgs(metaBuilder, args, includeSelf, selfIsInstance, calleeHasBlockParam, true);
var parameterBinder = new RubyParameterBinder(args.RubyContext.Binder, args.MetaContext.Expression, args.Signature.HasScope);
var targetExpression = bindingTarget.MakeExpression(parameterBinder, actualArgs);
metaBuilder.Result = targetExpression;
} else {
metaBuilder.SetError(
Methods.MakeInvalidArgumentTypesError.OpCall(Ast.Constant(name))
);
}
}
示例7: RuleControlFlowBuilder
/// <summary>
/// Takes current result and wraps it into try-filter(MethodUnwinder)-finally block that ensures correct "break" behavior for
/// Ruby method calls with a block given in arguments.
///
/// Sets up a RFC frame similarly to MethodDeclaration.
/// </summary>
public static void RuleControlFlowBuilder(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args) {
Debug.Assert(args.Signature.HasBlock);
if (metaBuilder.Error) {
return;
}
// TODO (improvement):
// We don't special case null block here, although we could (we would need a test for that then).
// We could also statically know (via call-site flag) that the current method is not a proc-converter (passed by ref),
// which would make such calls faster.
var rfcVariable = metaBuilder.GetTemporary(typeof(RuntimeFlowControl), "#rfc");
var resultVariable = metaBuilder.GetTemporary(typeof(object), "#result");
MSA.ParameterExpression unwinder;
metaBuilder.Result = Ast.Block(
// initialize frame (RFC):
Ast.Assign(rfcVariable, Methods.CreateRfcForMethod.OpCall(AstUtils.Convert(args.GetBlockExpression(), typeof(Proc)))),
AstUtils.Try(
Ast.Assign(resultVariable, metaBuilder.Result)
).Filter(unwinder = Ast.Parameter(typeof(MethodUnwinder), "#unwinder"),
Ast.Equal(Ast.Field(unwinder, MethodUnwinder.TargetFrameField), rfcVariable),
// return unwinder.ReturnValue;
Ast.Assign(resultVariable, Ast.Field(unwinder, MethodUnwinder.ReturnValueField))
).Finally(
// we need to mark the RFC dead snce the block might escape and break later:
Methods.LeaveMethodFrame.OpCall(rfcVariable)
),
resultVariable
);
}
示例8: Build
protected override bool Build(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, bool defaultFallback)
{
RubyModule currentDeclaringModule;
string currentMethodName;
var scope = args.Scope;
var scopeExpr = AstUtils.Convert(args.MetaScope.Expression, typeof(RubyScope));
RubyScope targetScope;
int scopeNesting = scope.GetSuperCallTarget(out currentDeclaringModule, out currentMethodName, out targetScope);
if (scopeNesting == -1) {
metaBuilder.AddCondition(Methods.IsSuperOutOfMethodScope.OpCall(scopeExpr));
metaBuilder.SetError(Methods.MakeTopLevelSuperException.OpCall());
return true;
}
object target = targetScope.SelfObject;
var targetExpression = metaBuilder.GetTemporary(typeof(object), "#super-self");
var assignTarget = Ast.Assign(
targetExpression,
Methods.GetSuperCallTarget.OpCall(scopeExpr, AstUtils.Constant(scopeNesting))
);
if (_signature.HasImplicitArguments && targetScope.Kind == ScopeKind.BlockMethod) {
metaBuilder.AddCondition(Ast.NotEqual(assignTarget, Ast.Field(null, Fields.NeedsUpdate)));
metaBuilder.SetError(Methods.MakeImplicitSuperInBlockMethodError.OpCall());
return true;
}
// If we need to update we return RubyOps.NeedsUpdate instance that will cause the subsequent conditions to fail:
metaBuilder.AddInitialization(assignTarget);
args.SetTarget(targetExpression, target);
Debug.Assert(currentDeclaringModule != null);
RubyMemberInfo method;
RubyMemberInfo methodMissing = null;
// MRI bug: Uses currentDeclaringModule for method look-up so we can end up with an instance method of class C
// called on a target of another class. See http://redmine.ruby-lang.org/issues/show/2419.
// we need to lock the hierarchy of the target class:
var targetClass = scope.RubyContext.GetImmediateClassOf(target);
using (targetClass.Context.ClassHierarchyLocker()) {
// initialize all methods in ancestors:
targetClass.InitializeMethodsNoLock();
// target is stored in a local, therefore it cannot be part of the restrictions:
metaBuilder.TreatRestrictionsAsConditions = true;
metaBuilder.AddTargetTypeTest(target, targetClass, targetExpression, args.MetaContext,
new[] { Symbols.MethodMissing } // currentMethodName is resolved for super, which cannot be an instance singleton
);
metaBuilder.TreatRestrictionsAsConditions = false;
method = targetClass.ResolveSuperMethodNoLock(currentMethodName, currentDeclaringModule).InvalidateSitesOnOverride().Info;
if (_signature.ResolveOnly) {
metaBuilder.Result = AstUtils.Constant(method != null);
return true;
}
if (method == null) {
// MRI: method_missing is called for the targetClass, not for the super:
methodMissing = targetClass.ResolveMethodMissingForSite(currentMethodName, RubyMethodVisibility.None);
}
}
if (method != null) {
method.BuildSuperCall(metaBuilder, args, currentMethodName, currentDeclaringModule);
} else {
return RubyCallAction.BuildMethodMissingCall(metaBuilder, args, currentMethodName, methodMissing, RubyMethodVisibility.None, true, defaultFallback);
}
return true;
}
示例9: RuleControlFlowBuilder
/// <summary>
/// Takes current result and wraps it into try-filter(MethodUnwinder)-finally block that ensures correct "break" behavior for
/// library method calls with block given in bfcVariable (BlockParam).
/// </summary>
public static void RuleControlFlowBuilder(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args) {
if (metaBuilder.Error) {
return;
}
var metaBlock = args.GetMetaBlock();
Debug.Assert(metaBlock != null, "RuleControlFlowBuilder should only be used if the signature has a block");
// We construct CF only for non-nil blocks thus we need a test for it:
if (metaBlock.Value == null) {
metaBuilder.AddRestriction(Ast.Equal(metaBlock.Expression, AstUtils.Constant(null)));
return;
}
// don't need to test the exact type of the Proc since the code is subclass agnostic:
metaBuilder.AddRestriction(Ast.NotEqual(metaBlock.Expression, AstUtils.Constant(null)));
Expression bfcVariable = metaBuilder.BfcVariable;
Debug.Assert(bfcVariable != null);
// Method call with proc can invoke control flow that returns an arbitrary value from the call, so we need to type result to Object.
// Otherwise, the result could only be result of targetExpression unless its return type is void.
Expression resultVariable = metaBuilder.GetTemporary(typeof(object), "#result");
ParameterExpression unwinder;
metaBuilder.Result = Ast.Block(
Ast.Assign(bfcVariable, Methods.CreateBfcForLibraryMethod.OpCall(AstUtils.Convert(args.GetBlockExpression(), typeof(Proc)))),
AstUtils.Try(
Ast.Assign(resultVariable, AstUtils.Convert(metaBuilder.Result, typeof(object)))
).Filter(unwinder = Ast.Parameter(typeof(MethodUnwinder), "#unwinder"),
Methods.IsProcConverterTarget.OpCall(bfcVariable, unwinder),
Ast.Assign(resultVariable, Ast.Field(unwinder, MethodUnwinder.ReturnValueField)),
AstUtils.Default(typeof(object))
).Finally(
Methods.LeaveProcConverter.OpCall(bfcVariable)
),
resultVariable
);
}
示例10: BuildCallNoFlow
/// <summary>
/// Resolves an library method overload and builds call expression.
/// The resulting expression on meta-builder doesn't handle block control flow yet.
/// </summary>
internal static void BuildCallNoFlow(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, string/*!*/ name,
IList<MethodBase>/*!*/ overloads, SelfCallConvention callConvention) {
var bindingTarget = ResolveOverload(name, overloads, args, callConvention);
bool calleeHasBlockParam = bindingTarget.Success && HasBlockParameter(bindingTarget.Method);
// Allocates a variable holding BlockParam. At runtime the BlockParam is created with a new RFC instance that
// identifies the library method frame as a proc-converter target of a method unwinder triggered by break from a block.
if (args.Signature.HasBlock) {
var metaBlock = args.GetMetaBlock();
if (metaBlock.Value != null && calleeHasBlockParam) {
if (metaBuilder.BfcVariable == null) {
metaBuilder.BfcVariable = metaBuilder.GetTemporary(typeof(BlockParam), "#bfc");
}
metaBuilder.ControlFlowBuilder = RuleControlFlowBuilder;
}
// Block test - we need to test for a block regardless of whether it is actually passed to the method or not
// since the information that the block is not null is used for overload resolution.
if (metaBlock.Value == null) {
metaBuilder.AddRestriction(Ast.Equal(metaBlock.Expression, AstUtils.Constant(null)));
} else {
// don't need to test the exact type of the Proc since the code is subclass agnostic:
metaBuilder.AddRestriction(Ast.NotEqual(metaBlock.Expression, AstUtils.Constant(null)));
}
}
var actualArgs = MakeActualArgs(metaBuilder, args, callConvention, calleeHasBlockParam, true);
if (bindingTarget.Success) {
var parameterBinder = new RubyParameterBinder(args.RubyContext.Binder, args.MetaContext.Expression, args.Signature.HasScope);
metaBuilder.Result = bindingTarget.MakeExpression(parameterBinder, actualArgs);
} else {
metaBuilder.SetError(args.RubyContext.RubyBinder.MakeInvalidParametersError(bindingTarget).Expression);
}
}
示例11: BuildCall
/// <summary>
/// From control flow perspective it "calls" the proc.
/// </summary>
internal static void BuildCall(
MetaObjectBuilder/*!*/ metaBuilder,
Expression/*!*/ procExpression, // proc object
Expression/*!*/ selfExpression, // self passed to the proc
Expression callingMethodExpression, // RubyLambdaMethodInfo passed to the proc via BlockParam
CallArguments/*!*/ args // user arguments passed to the proc
) {
var bfcVariable = metaBuilder.GetTemporary(typeof(BlockParam), "#bfc");
var resultVariable = metaBuilder.GetTemporary(typeof(object), "#result");
metaBuilder.Result = AstFactory.Block(
Ast.Assign(bfcVariable,
(callingMethodExpression != null) ?
Methods.CreateBfcForMethodProcCall.OpCall(
AstUtils.Convert(procExpression, typeof(Proc)),
callingMethodExpression
) :
Methods.CreateBfcForProcCall.OpCall(
AstUtils.Convert(procExpression, typeof(Proc))
)
),
Ast.Assign(resultVariable, AstFactory.YieldExpression(
args.GetSimpleArgumentExpressions(),
args.GetSplattedArgumentExpression(),
args.GetRhsArgumentExpression(),
bfcVariable,
selfExpression
)),
Methods.MethodProcCall.OpCall(bfcVariable, resultVariable),
resultVariable
);
}