本文整理汇总了C#中System.Reflection.Emit.CodeGenerator.EmitBoxing方法的典型用法代码示例。如果您正苦于以下问题:C# CodeGenerator.EmitBoxing方法的具体用法?C# CodeGenerator.EmitBoxing怎么用?C# CodeGenerator.EmitBoxing使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类System.Reflection.Emit.CodeGenerator
的用法示例。
在下文中一共展示了CodeGenerator.EmitBoxing方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: Emit
/// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/>
internal override PhpTypeCode Emit(CodeGenerator codeGenerator)
{
Statistics.AST.AddNode("ListEx");
Debug.Assert(access == AccessType.Read || access == AccessType.None);
Debug.Assert(RValue != null); // the root of the lists structure must have RValue assigned. list(whatever) = RValue
codeGenerator.EmitBoxing(RValue.Emit(codeGenerator)); // put object on the top of the stack
LocalBuilder o1 = codeGenerator.IL.GetTemporaryLocal(Types.Object[0]); // temporary variable for object to be copied
EmitAssignList(codeGenerator, LValues, o1); // assign particular elements of the list, using the array from the stack
// return temporary local
codeGenerator.IL.ReturnTemporaryLocal(o1);
// the original top of the stack is replaced with the instance of array or null
if (access == AccessType.Read)
{
return PhpTypeCode.PhpArray; // return the top of the stack (null or array)
}
else
{
codeGenerator.IL.Emit(OpCodes.Pop); // remove the top of the stack, not used
return PhpTypeCode.Void;
}
}
示例2: Emit
/// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/>
internal override PhpTypeCode Emit(CodeGenerator/*!*/ codeGenerator)
{
Statistics.AST.AddNode("InstanceOfEx");
// emits load of expression value on the stack:
codeGenerator.EmitBoxing(expression.Emit(codeGenerator));
if (classNameRef.ResolvedType != null && typeArgsResolved)
{
// type is resolvable (doesn't mean known) //
classNameRef.ResolvedType.EmitInstanceOf(codeGenerator, null);
}
else
{
// type is unresolvable (there is some variable or the type is a generic parameter) //
codeGenerator.EmitInstanceOfOperator(null, classNameRef, null);
}
if (access == AccessType.None)
{
codeGenerator.IL.Emit(OpCodes.Pop);
return PhpTypeCode.Void;
}
else
{
return PhpTypeCode.Boolean;
}
}
示例3: EmitStrictEquality
/// <summary>
/// Emits strict equality operation.
/// </summary>
/// <param name="codeGenerator">A code generator.</param>
/// <returns>A type code of the result (boolean).</returns>
private PhpTypeCode EmitStrictEquality(CodeGenerator codeGenerator)
{
if (IsEmptyArrayEx(leftExpr))
{
EmitEmptyArrayStrictEquality(codeGenerator, rightExpr);
}
else if (IsEmptyArrayEx(rightExpr))
{
EmitEmptyArrayStrictEquality(codeGenerator, leftExpr);
}
else
{
// LOAD Operators.StrictEquality(box left,box right);
codeGenerator.EmitBoxing(leftExpr.Emit(codeGenerator));
codeGenerator.EmitBoxing(rightExpr.Emit(codeGenerator));
codeGenerator.IL.Emit(OpCodes.Call, Methods.Operators.StrictEquality);
}
return PhpTypeCode.Boolean;
}
示例4: Emit
/// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/>
internal override void Emit(CodeGenerator/*!*/ codeGenerator)
{
Statistics.AST.AddNode("SwitchStmt");
ILEmitter il = codeGenerator.IL;
// Note:
// SwitchStmt is now implemented in the most general (and unefficient) way. The whole switch
// is understood as a series of if-elseif-else statements.
Label exit_label = il.DefineLabel();
bool fall_through = false;
Label fall_through_label = il.DefineLabel();
Label last_default_label = il.DefineLabel();
DefaultItem last_default = GetLastDefaultItem();
LocalBuilder branch_to_lastdefault = null;
if (last_default != null)
{
branch_to_lastdefault = il.DeclareLocal(Types.Bool[0]);
il.LdcI4(0);
il.Stloc(branch_to_lastdefault);
}
codeGenerator.BranchingStack.BeginLoop(exit_label, exit_label,
codeGenerator.ExceptionBlockNestingLevel);
// marks a sequence point containing the discriminator evaluation:
codeGenerator.MarkSequencePoint(
switchValue.Position.FirstLine,
switchValue.Position.FirstColumn,
switchValue.Position.LastLine,
switchValue.Position.LastColumn + 1);
// Evaluate condition value and store the result into local variable
codeGenerator.EmitBoxing(switchValue.Emit(codeGenerator));
LocalBuilder condition_value = il.DeclareLocal(Types.Object[0]);
il.Stloc(condition_value);
foreach (SwitchItem item in switchItems)
{
item.MarkSequencePoint(codeGenerator);
// switch item is either CaseItem ("case xxx:") or DefaultItem ("default") item:
CaseItem case_item = item as CaseItem;
if (case_item != null)
{
Label false_label = il.DefineLabel();
// PhpComparer.Default.CompareEq(<switch expr. value>,<case value>);
/*changed to static method*/ //il.Emit(OpCodes.Ldsfld, Fields.PhpComparer_Default);
codeGenerator.EmitCompareEq(
cg => { cg.IL.Ldloc(condition_value); return PhpTypeCode.Object; },
cg => case_item.EmitCaseValue(cg));
// IF (!STACK) GOTO false_label;
il.Emit(OpCodes.Brfalse, false_label);
if (fall_through == true)
{
il.MarkLabel(fall_through_label, true);
fall_through = false;
}
case_item.EmitStatements(codeGenerator);
if (fall_through == false)
{
fall_through_label = il.DefineLabel();
fall_through = true;
}
il.Emit(OpCodes.Br, fall_through_label);
il.MarkLabel(false_label, true);
}
else
{
DefaultItem default_item = (DefaultItem)item;
// Only the last default branch defined in source code is used.
// So skip default while testing "case" items at runtime.
Label false_label = il.DefineLabel();
il.Emit(OpCodes.Br, false_label);
if (default_item == last_default)
{
il.MarkLabel(last_default_label, false);
}
if (fall_through == true)
{
il.MarkLabel(fall_through_label, true);
fall_through = false;
}
default_item.EmitStatements(codeGenerator);
if (fall_through == false)
{
fall_through_label = il.DefineLabel();
//.........这里部分代码省略.........
示例5: EmitNodeReadUnknown
/// <summary>
/// Emits code to load <see cref="PhpRuntimeChain"/> onto an evaluation stack. Supports operators chaining.
/// </summary>
/// <param name="codeGenerator"></param>
private PhpTypeCode EmitNodeReadUnknown(CodeGenerator codeGenerator)
{
ChainBuilder chain = codeGenerator.ChainBuilder;
PhpTypeCode result = PhpTypeCode.PhpRuntimeChain;
if (chain.IsArrayItem)
{
// 3: a_[x]_[x]
chain.Lengthen(); // for []
chain.EmitRTChainAddItem(this);
return result;
}
// 1,2,4,5,6,7
if (chain.IsMember)
{
// 4, 5
if (this.isMemberOf != null)
{
// 5: ...->a[]->...
// Lengthen chain for isMemberOf
chain.Lengthen(); // for hop over ->
PhpTypeCode res = isMemberOf.Emit(codeGenerator);
if (res != PhpTypeCode.PhpRuntimeChain)
{
codeGenerator.EmitBoxing(res);
chain.EmitCreateRTChain();
}
// Lengthen chain for own []
chain.Lengthen();
chain.IsArrayItem = true;
chain.IsLastMember = false;
chain.EmitRTChainAddItem(this);
chain.IsArrayItem = false;
return result;
}
// 4: a[x]->...
// Lengthen chain for itself
chain.Lengthen(); // for own []
chain.IsArrayItem = true;
chain.IsLastMember = true;
chain.EmitRTChainAddItem(this);
chain.IsArrayItem = false;
return result;
}
// 1, 2, 6, 7
if (this.isMemberOf != null)
{
// 6 , 7: ...->a[]_[]_ , ...->a_[]_
bool quiet_read = chain.QuietRead;
chain.Create();
chain.Begin();
chain.QuietRead = quiet_read;
chain.Lengthen(); // for hop over ->
PhpTypeCode res = isMemberOf.Emit(codeGenerator);
if (res != PhpTypeCode.PhpRuntimeChain)
{
codeGenerator.EmitBoxing(res);
chain.EmitCreateRTChain();
}
chain.IsArrayItem = true;
chain.IsLastMember = false;
chain.EmitRTChainAddItem(this);
chain.IsArrayItem = false;
chain.End();
return result;
}
// 1, 2
if (array is ItemUse || array is DirectStFldUse || array is IndirectStFldUse /* ??? */)
{
// 2: a[]_[]_
bool quiet_read = chain.QuietRead;
chain.Create();
chain.Begin();
chain.QuietRead = quiet_read;
chain.IsArrayItem = true;
chain.IsLastMember = true;
chain.EmitRTChainAddItem(this);
chain.IsArrayItem = false;
chain.End();
return result;
}
// 1: a_[x]_
chain.IsArrayItem = true;
chain.IsLastMember = true;
chain.EmitRTChainAddItem(this);
chain.IsArrayItem = false;
return result;
}
示例6: EmitBitOperation
/// <summary>
/// Emits bit operation <see cref="leftExpr"/> OP <see cref="rightExpr"/>.
/// </summary>
/// <param name="codeGenerator">A code generator.</param>
/// <param name="op">The operation.</param>
/// <returns>A type code of the result.</returns>
private PhpTypeCode EmitBitOperation(CodeGenerator/*!*/ codeGenerator, Operators.BitOp op)
{
ILEmitter il = codeGenerator.IL;
// LOAD Operators.BitOperation(box <leftSon>, box <rightSon>);
codeGenerator.EmitBoxing(leftExpr.Emit(codeGenerator));
codeGenerator.EmitBoxing(rightExpr.Emit(codeGenerator));
il.Emit(OpCodes.Ldc_I4, (int)op);
il.Emit(OpCodes.Call, Methods.Operators.BitOperation);
return PhpTypeCode.Object;
}
示例7: EmitLoadArgsOnEvalStack
internal void EmitLoadArgsOnEvalStack(CallSignature/*!*/node, CodeGenerator/*!*/ codeGenerator, PhpRoutine/*!*/ routine)
{
ILEmitter il = codeGenerator.IL;
int mandatory_count = (routine.Signature != null) ? routine.Signature.MandatoryParamCount : 0;
int formal_count = (routine.Signature != null) ? routine.Signature.ParamCount : 0;
int actual_count = node.Parameters.Count;
PhpTypeCode param_type;
// loads all actual parameters which are not superfluous:
for (int i = 0; i < Math.Min(actual_count, formal_count); i++)
{
var p = node.Parameters[i];
codeGenerator.EmitBoxing(param_type = p.NodeCompiler<ActualParamCompiler>().Emit(p, codeGenerator));
// Actual param emitter should emit "boxing" to a reference if its access type is ReadRef.
// That's why no operation is needed here and references should match.
Debug.Assert((routine.Signature == null || routine.Signature.IsAlias(i)) == (param_type == PhpTypeCode.PhpReference));
}
// loads missing mandatory arguments:
for (int i = actual_count; i < mandatory_count; i++)
{
// CALL PhpException.MissingArgument(<i+1>,<name>);
il.LdcI4(i + 1);
il.Emit(OpCodes.Ldstr, routine.FullName);
codeGenerator.EmitPhpException(Methods.PhpException.MissingArgument);
// LOAD null;
if (routine.Signature.IsAlias(i))
il.Emit(OpCodes.Newobj, Constructors.PhpReference_Void);
else
il.Emit(OpCodes.Ldnull);
}
// loads missing optional arguments:
for (int i = Math.Max(mandatory_count, actual_count); i < formal_count; i++)
{
// LOAD Arg.Default;
il.Emit(OpCodes.Ldsfld, Fields.Arg_Default);
}
}
示例8: EmitLoadOnPhpStack
/// <summary>
/// Emits IL instructions that load actual parameters and optionally add a new stack frame to
/// current <see cref="PHP.Core.ScriptContext.Stack"/>.
/// </summary>
/// <param name="codeGenerator">Code generator.</param>
/// <remarks>
/// Nothing is expected on the evaluation stack. Nothing is left on the evaluation stack.
/// </remarks>
internal void EmitLoadOnPhpStack(CodeGenerator/*!*/ codeGenerator)
{
List<ActualParam> parameters = this.parameters;
List<TypeRef> genericParams = this.genericParams;
PhpStackBuilder.EmitAddFrame(codeGenerator.IL, codeGenerator.ScriptContextPlace, genericParams.Count, parameters.Count,
delegate(ILEmitter il, int i)
{
// generic arguments:
genericParams[i].EmitLoadTypeDesc(codeGenerator, ResolveTypeFlags.UseAutoload | ResolveTypeFlags.ThrowErrors);
},
delegate(ILEmitter il, int i)
{
// regular arguments:
codeGenerator.EmitBoxing(parameters[i].Emit(codeGenerator));
}
);
}
示例9: EmitValue
/// <summary>
/// Emit IL instructions that load the value of array item at the stack and make a copy
/// of it if necessary.
/// </summary>
internal override PhpTypeCode EmitValue(CodeGenerator/*!*/ codeGenerator)
{
Debug.Assert(valueExpr != null);
Statistics.AST.AddNode("Array.ValueItem");
codeGenerator.EmitBoxing(valueExpr.Emit(codeGenerator));
codeGenerator.EmitVariableCopy(CopyReason.Assigned, valueExpr);
return PhpTypeCode.Object;
}
示例10: Emit
/// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/>
internal override PhpTypeCode Emit(CodeGenerator codeGenerator)
{
Statistics.AST.AddNode("TernaryEx");
Debug.Assert(access == AccessType.Read || access == AccessType.None);
Label end_label = codeGenerator.IL.DefineLabel();
if (trueExpr != null) // standard ternary operator
{
Label else_label = codeGenerator.IL.DefineLabel();
// IF (<(bool) condition>) THEN
codeGenerator.EmitConversion(condExpr, PhpTypeCode.Boolean);
codeGenerator.IL.Emit(OpCodes.Brfalse, else_label);
{
codeGenerator.EmitBoxing(trueExpr.Emit(codeGenerator));
codeGenerator.IL.Emit(OpCodes.Br, end_label);
}
// ELSE
codeGenerator.IL.MarkLabel(else_label, true);
{
codeGenerator.EmitBoxing(falseExpr.Emit(codeGenerator));
}
}
else
{ // ternary shortcut:
var il = codeGenerator.IL;
// condExpr ?? rightExpr
il.EmitBoxing(condExpr.Emit(codeGenerator));
// IF (<stack>):
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Call, Methods.Convert.ObjectToBoolean);
codeGenerator.IL.Emit(OpCodes.Brtrue, end_label);
// ELSE:
{
il.Emit(OpCodes.Pop);
il.EmitBoxing(falseExpr.Emit(codeGenerator));
}
}
// END IF;
codeGenerator.IL.MarkLabel(end_label, true);
if (access == AccessType.None)
{
codeGenerator.IL.Emit(OpCodes.Pop);
return PhpTypeCode.Void;
}
return PhpTypeCode.Object;
}
示例11: Emit
/// <summary>
/// Emits assignment.
/// </summary>
/// <remarks>
/// Pattern: a op= b
///
/// PREPARE a (prepared)
/// LOAD a (prepared,a)
/// LOAD b (prepared,a,b)
/// OP (prepared,result)
/// *DUP (prepared,result,result)
/// *STORE tmp (prepared,result) must be this stack here!
/// STORE a ()
/// *LOAD tmp (result)
///
/// * only if the resulting value needs to be propagated to the right
///
/// Note: There is a possible improvement: some store operations (SetVariable) may return the value set
/// which would replace DUP and second temp op.
/// </remarks>
internal override PhpTypeCode Emit(CodeGenerator/*!*/ codeGenerator)
{
Debug.Assert(access == AccessType.Read || access == AccessType.None || access == AccessType.ReadRef ||
access == AccessType.ReadUnknown);
Statistics.AST.AddNode("Assign.Value");
ILEmitter il = codeGenerator.IL;
AccessType old_selector = codeGenerator.AccessSelector;
codeGenerator.ChainBuilder.Create();
PhpTypeCode result;
if (operation == Operations.AssignValue)
{
//
// Access Type = ReadRef/ReadUnknown
// ---------------------------------
//
// f(&$x) { }
//
// f($a = $b);
// f($a = $b =& $c);
//
// Destination variable $a is prepared for reference write.
// A new reference is created and its value set to a deep copy of the result of RHS ($b, $b =& $c).
// RHS has Read access => it has been dereferenced.
//
// PREPARE a:
codeGenerator.AccessSelector = AccessType.Write;
lvalue.Emit(codeGenerator);
codeGenerator.AccessSelector = AccessType.None;
PhpTypeCode src_type_code = EmitSourceValRead(codeGenerator);
// RHS should have Read access => should be dereferenced
Debug.Assert(src_type_code != PhpTypeCode.PhpReference);
// LOAD BOX b
codeGenerator.EmitBoxing(src_type_code);
// makes a copy if necessary:
if (PhpTypeCodeEnum.IsDeeplyCopied(src_type_code))
codeGenerator.EmitVariableCopy(CopyReason.Assigned, rvalue);
}
else
{
// PREPARE a:
codeGenerator.AccessSelector = AccessType.Write;
lvalue.Emit(codeGenerator);
codeGenerator.AccessSelector = AccessType.None;
// LOAD b,a (rvalue must be processed first, than +-*/ with lvalue, since lvalu can be changed by rvalue expression)
//must be the second operand// EmitDestVarRead(codeGenerator);
PhpTypeCode right_type = EmitSourceValRead(codeGenerator);
var rvalue_tmp = codeGenerator.IL.GetTemporaryLocal(PhpTypeCodeEnum.ToType(right_type), false);
codeGenerator.IL.Emit(OpCodes.Stloc, rvalue_tmp);
EmitDestVarRead(codeGenerator);
codeGenerator.IL.Emit(OpCodes.Ldloc, rvalue_tmp);
codeGenerator.IL.ReturnTemporaryLocal(rvalue_tmp);
switch (operation)
{
#region Arithmetic
case Operations.AssignAdd:
{
switch (right_type)
{
case PhpTypeCode.Integer:
result = codeGenerator.EmitMethodCall(Methods.Operators.Add.Object_Int32);
break;
case PhpTypeCode.Double:
result = codeGenerator.EmitMethodCall(Methods.Operators.Add.Object_Double);
break;
default:
//.........这里部分代码省略.........
示例12: EmitReturnPhpReference
private void EmitReturnPhpReference(CodeGenerator codeGenerator)
{
ILEmitter il = codeGenerator.IL;
PhpTypeCode result;
if (expr != null)
{
result = expr.Emit(codeGenerator);
if (result != PhpTypeCode.PhpReference)
{
// return value is "boxed" to PhpReference:
if (result != PhpTypeCode.Void)
{
codeGenerator.EmitBoxing(result);
// We can box the value without making a copy since the result of the return expression
// is not accessible after returnign from the routine as it is a value (not a reference).
il.Emit(OpCodes.Newobj, Constructors.PhpReference_Object);
}
else
{
il.Emit(OpCodes.Newobj, Constructors.PhpReference_Void);
}
}
}
else
{
il.Emit(OpCodes.Newobj, Constructors.PhpReference_Void);
}
codeGenerator.EmitReturnBranch();
}
示例13: EmitReturnObject
/// <summary>
/// Return value is not deeply copied since the deep copy takes place when the caller accesses the value.
/// </summary>
private void EmitReturnObject(CodeGenerator/*!*/ codeGenerator)
{
ILEmitter il = codeGenerator.IL;
PhpTypeCode result;
if (expr != null)
{
result = expr.Emit(codeGenerator);
// dereference return value:
if (result == PhpTypeCode.PhpReference)
{
il.Emit(OpCodes.Ldfld, Fields.PhpReference_Value);
}
else if (result == PhpTypeCode.PhpArray)
{
// <array>.InplaceCopyOnReturn = true;
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Ldc_I4_1);
il.Emit(OpCodes.Call, Properties.PhpArray_InplaceCopyOnReturn.GetSetMethod());
}
else
{
codeGenerator.EmitBoxing(result);
}
}
else
{
il.Emit(OpCodes.Ldnull);
}
codeGenerator.EmitReturnBranch();
}
示例14: EmitEmptyArrayStrictEquality
/// <summary>
/// Emits strict equality to empty PHP array.
/// </summary>
/// <param name="codeGenerator">A code generator.</param>
/// <param name="expr">Expression to be compared against.</param>
private static void EmitEmptyArrayStrictEquality(CodeGenerator/*!*/codeGenerator, Expression/*!*/expr)
{
if (IsEmptyArrayEx(expr))
{
// array() === array()
// LOAD true
codeGenerator.IL.LoadBool(true);
}
else if (expr is Literal)
{
// array() === NULL|int|double|string|...
// LOAD false
codeGenerator.IL.LoadBool(false);
}
else
{
// array() === <expr>
// LOAD <expr>
var exprTypeCode = expr.Emit(codeGenerator);
// check whether <expr> type can be an array
switch (exprTypeCode)
{
case PhpTypeCode.Boolean:
case PhpTypeCode.DObject:
case PhpTypeCode.Double:
case PhpTypeCode.Integer:
case PhpTypeCode.LongInteger:
case PhpTypeCode.PhpBytes:
case PhpTypeCode.PhpString:
case PhpTypeCode.String:
// always FALSE
codeGenerator.IL.Emit(OpCodes.Pop);
codeGenerator.IL.LoadBool(false);
break;
case PhpTypeCode.PhpArray:
// compare (PhpArray)<expr> with array()
codeGenerator.IL.Emit(OpCodes.Call, Methods.Operators.StrictEmptyPhpArrayEquality_PhpArray);
break;
default:
// compare <expr> with array()
codeGenerator.EmitBoxing(exprTypeCode);
codeGenerator.IL.Emit(OpCodes.Call, Methods.Operators.StrictEmptyPhpArrayEquality);
break;
}
}
}
示例15: Emit
internal override PhpTypeCode Emit(CodeGenerator codeGenerator)
{
Debug.Assert(access == AccessType.Read || access == AccessType.None);
Statistics.AST.AddNode("Class.Concat." + expressions.Count);
PhpTypeCode result;
//
// For low numbers call specialized methods
switch (expressions.Count)
{
case 1:
result = expressions[0].Emit(codeGenerator);
if (result != PhpTypeCode.PhpBytes && result != PhpTypeCode.String)
{
var lbl = codeGenerator.IL.DefineLabel();
codeGenerator.EmitBoxing(result);
codeGenerator.IL.Emit(OpCodes.Dup);
codeGenerator.IL.Emit(OpCodes.Isinst,typeof(PhpBytes));
// IF (STACK)
codeGenerator.IL.Emit(OpCodes.Brtrue_S,lbl);
if (true)
{
codeGenerator.IL.Emit(OpCodes.Call, Methods.Convert.ObjectToString);
}
// ELSE
codeGenerator.IL.MarkLabel(lbl, true);
//END IF
result = PhpTypeCode.Object;
}
break;
case 2:
result = EmitConcat(codeGenerator, expressions[0], expressions[1]);
break;
default:
codeGenerator.EmitObjectArrayPopulation(expressions);
codeGenerator.IL.Emit(OpCodes.Call, Methods.Operators.Concat.ObjectArray);
result = PhpTypeCode.Object; // string, PhpBytes
break;
}
switch (access)
{
case AccessType.Read:
// do nothing
break;
case AccessType.None:
// pop result from stack
codeGenerator.IL.Emit(OpCodes.Pop);
result = PhpTypeCode.Void;
break;
}
return result;
}