本文整理汇总了C#中Pchp.CodeAnalysis.CodeGen.CodeGenerator.EmitConvertToPhpValue方法的典型用法代码示例。如果您正苦于以下问题:C# CodeGenerator.EmitConvertToPhpValue方法的具体用法?C# CodeGenerator.EmitConvertToPhpValue怎么用?C# CodeGenerator.EmitConvertToPhpValue使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Pchp.CodeAnalysis.CodeGen.CodeGenerator
的用法示例。
在下文中一共展示了CodeGenerator.EmitConvertToPhpValue方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: EmitStrictEquality
internal static TypeSymbol EmitStrictEquality(CodeGenerator cg, TypeSymbol xtype, BoundExpression right)
{
TypeSymbol ytype;
switch (xtype.SpecialType)
{
case SpecialType.System_Boolean:
ytype = cg.Emit(right);
if (ytype.SpecialType == SpecialType.System_Boolean)
{
// bool == bool
cg.Builder.EmitOpCode(ILOpCode.Ceq);
return cg.CoreTypes.Boolean;
}
else if (
ytype.SpecialType == SpecialType.System_Double ||
ytype.SpecialType == SpecialType.System_Int32 ||
ytype.SpecialType == SpecialType.System_Int64 ||
ytype.SpecialType == SpecialType.System_String ||
ytype.IsOfType(cg.CoreTypes.IPhpArray) ||
ytype == cg.CoreTypes.PhpString ||
ytype == cg.CoreTypes.Object)
{
// bool == something else => false
cg.EmitPop(ytype);
cg.EmitPop(xtype);
cg.Builder.EmitBoolConstant(false);
return cg.CoreTypes.Boolean;
}
else
{
// bool == PhpValue
cg.EmitConvertToPhpValue(ytype, 0);
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.StrictCeq_bool_PhpValue)
.Expect(SpecialType.System_Boolean);
}
case SpecialType.System_Int32:
cg.Builder.EmitOpCode(ILOpCode.Conv_i8); // i4 -> i8
goto case SpecialType.System_Int64;
case SpecialType.System_Int64:
ytype = cg.Emit(right);
if (ytype.SpecialType == SpecialType.System_Int32)
{
cg.Builder.EmitOpCode(ILOpCode.Conv_i8); // i4 -> i8
ytype = cg.CoreTypes.Long;
}
if (ytype.SpecialType == SpecialType.System_Int64)
{
// i8 == i8
cg.Builder.EmitOpCode(ILOpCode.Ceq);
return cg.CoreTypes.Boolean;
}
else if (
ytype.SpecialType == SpecialType.System_Boolean ||
ytype.SpecialType == SpecialType.System_String ||
ytype.SpecialType == SpecialType.System_Double ||
ytype.IsOfType(cg.CoreTypes.IPhpArray) ||
ytype == cg.CoreTypes.Object ||
ytype == cg.CoreTypes.PhpString)
{
// i8 == something else => false
cg.EmitPop(ytype);
cg.EmitPop(xtype);
cg.Builder.EmitBoolConstant(false);
return cg.CoreTypes.Boolean;
}
else
{
// i8 == PhpValue
cg.EmitConvertToPhpValue(ytype, 0);
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.StrictCeq_long_PhpValue)
.Expect(SpecialType.System_Boolean);
}
case SpecialType.System_Double:
ytype = cg.Emit(right);
if (ytype.SpecialType == SpecialType.System_Double)
{
// r8 == r8
cg.Builder.EmitOpCode(ILOpCode.Ceq);
return cg.CoreTypes.Boolean;
}
else if (
ytype.SpecialType == SpecialType.System_Boolean ||
ytype.SpecialType == SpecialType.System_String ||
ytype.SpecialType == SpecialType.System_Int64 ||
ytype.SpecialType == SpecialType.System_Int32 ||
ytype.IsOfType(cg.CoreTypes.IPhpArray) ||
ytype == cg.CoreTypes.Object ||
ytype == cg.CoreTypes.PhpString)
{
// r8 == something else => false
cg.EmitPop(ytype);
cg.EmitPop(xtype);
cg.Builder.EmitBoolConstant(false);
return cg.CoreTypes.Boolean;
}
//.........这里部分代码省略.........
示例2: EmitSub
/// <summary>
/// Emits subtraction operator.
/// </summary>
internal static TypeSymbol EmitSub(CodeGenerator cg, TypeSymbol xtype, BoundExpression right, TypeSymbol resultTypeOpt = null)
{
var il = cg.Builder;
xtype = cg.EmitConvertIntToLong(xtype); // int|bool -> int64
TypeSymbol ytype;
switch (xtype.SpecialType)
{
case SpecialType.System_Int64:
ytype = cg.EmitConvertIntToLong(cg.Emit(right));
if (ytype.SpecialType == SpecialType.System_Int64)
{
// i8 - i8 : number
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Subtract_long_long)
.Expect(cg.CoreTypes.PhpNumber);
}
else if (ytype.SpecialType == SpecialType.System_Double)
{
// i8 - r8 : r8
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Subtract_long_double)
.Expect(cg.CoreTypes.Double);
}
else if (ytype == cg.CoreTypes.PhpNumber)
{
// i8 - number : number
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Subtract_long_number)
.Expect(cg.CoreTypes.PhpNumber);
}
else
{
ytype = cg.EmitConvertToPhpValue(ytype, 0);
// i8 - value : value
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Subtract_long_value)
.Expect(cg.CoreTypes.PhpNumber);
}
case SpecialType.System_Double:
ytype = cg.EmitConvertNumberToDouble(right); // bool|int|long|number -> double
if (ytype.SpecialType == SpecialType.System_Double)
{
// r8 - r8 : r8
il.EmitOpCode(ILOpCode.Sub);
return cg.CoreTypes.Double;
}
throw new NotImplementedException($"Sub(double, {ytype.Name})");
default:
if (xtype == cg.CoreTypes.PhpNumber)
{
ytype = cg.EmitConvertIntToLong(cg.Emit(right));
if (ytype.SpecialType == SpecialType.System_Int64)
{
// number - i8 : number
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Subtract_number_long)
.Expect(cg.CoreTypes.PhpNumber);
}
else if (ytype.SpecialType == SpecialType.System_Double)
{
// number - r8 : double
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Subtract_number_double)
.Expect(SpecialType.System_Double);
}
else if (ytype == cg.CoreTypes.PhpNumber)
{
// number - number : number
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Subtract_number_number)
.Expect(cg.CoreTypes.PhpNumber);
}
throw new NotImplementedException($"Sub(PhpNumber, {ytype.Name})");
}
else if (xtype == cg.CoreTypes.PhpValue)
{
ytype = cg.EmitConvertIntToLong(cg.Emit(right));
if (ytype.SpecialType == SpecialType.System_Int64)
{
// value - i8 : number
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Subtract_value_long)
.Expect(cg.CoreTypes.PhpNumber);
}
else if (ytype.SpecialType == SpecialType.System_Double)
{
// value - r8 : r8
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Subtract_value_double)
.Expect(SpecialType.System_Double);
}
else if (ytype == cg.CoreTypes.PhpNumber)
{
// value - number : number
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Subtract_value_number)
.Expect(cg.CoreTypes.PhpNumber);
}
else if (ytype == cg.CoreTypes.PhpValue)
{
// value - value : number
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Subtract_value_value)
//.........这里部分代码省略.........
示例3: EmitEquality
/// <summary>
/// Emits check for values equality.
/// Lefts <c>bool</c> on top of evaluation stack.
/// </summary>
internal static TypeSymbol EmitEquality(CodeGenerator cg, TypeSymbol xtype, BoundExpression right)
{
TypeSymbol ytype;
switch (xtype.SpecialType)
{
case SpecialType.System_Boolean:
// bool == y.ToBoolean()
cg.EmitConvert(right, cg.CoreTypes.Boolean);
cg.Builder.EmitOpCode(ILOpCode.Ceq);
return cg.CoreTypes.Boolean;
case SpecialType.System_Int32:
// i4 -> i8
cg.Builder.EmitOpCode(ILOpCode.Conv_i8);
goto case SpecialType.System_Int64;
case SpecialType.System_Int64:
ytype = cg.Emit(right);
//
if (ytype.SpecialType == SpecialType.System_Int32)
{
cg.Builder.EmitOpCode(ILOpCode.Conv_i8); // i4 -> i8
ytype = cg.CoreTypes.Long;
}
//
if (ytype.SpecialType == SpecialType.System_Int64)
{
// i8 == i8
cg.Builder.EmitOpCode(ILOpCode.Ceq);
return cg.CoreTypes.Boolean;
}
else if (ytype.SpecialType == SpecialType.System_Double)
{
// i8 == r8
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.Ceq_long_double)
.Expect(SpecialType.System_Boolean);
}
else if (ytype.SpecialType == SpecialType.System_Boolean)
{
// i8 == bool
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.Ceq_long_bool)
.Expect(SpecialType.System_Boolean);
}
else if (ytype.SpecialType == SpecialType.System_String)
{
// i8 == string
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.Ceq_long_string)
.Expect(SpecialType.System_Boolean);
}
// value
ytype = cg.EmitConvertToPhpValue(ytype, 0);
// compare(i8, value) == 0
cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.Compare_long_value);
cg.EmitLogicNegation();
return cg.CoreTypes.Boolean;
case SpecialType.System_Double:
ytype = cg.EmitConvertNumberToDouble(right); // bool|long|int -> double
if (ytype.SpecialType == SpecialType.System_Double)
{
// r8 == r8
cg.Builder.EmitOpCode(ILOpCode.Ceq);
return cg.CoreTypes.Boolean;
}
else if (ytype.SpecialType == SpecialType.System_String)
{
// r8 == string
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.Ceq_double_string)
.Expect(SpecialType.System_Boolean);
}
// value
ytype = cg.EmitConvertToPhpValue(ytype, 0);
// compare(double, value) == 0
cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.Compare_double_value);
cg.EmitLogicNegation();
return cg.CoreTypes.Boolean;
case SpecialType.System_String:
ytype = cg.Emit(right);
if (ytype.SpecialType == SpecialType.System_Int32)
//.........这里部分代码省略.........
示例4: Emit
internal override TypeSymbol Emit(CodeGenerator cg)
{
MethodSymbol ctorsymbol;
if (_arguments.Length == 0)
{
// <ctx>.Exit();
ctorsymbol = cg.CoreMethods.Ctors.ScriptDiedException;
}
else
{
// LOAD <status>
var t = cg.Emit(_arguments[0].Value);
switch (t.SpecialType)
{
case SpecialType.System_Int32:
cg.Builder.EmitOpCode(ILOpCode.Conv_i8); // i4 -> i8
goto case SpecialType.System_Int64;
case SpecialType.System_Int64:
ctorsymbol = cg.CoreMethods.Ctors.ScriptDiedException_Long;
break;
default:
cg.EmitConvertToPhpValue(t, 0);
ctorsymbol = cg.CoreMethods.Ctors.ScriptDiedException_PhpValue;
break;
}
}
//
cg.EmitCall(ILOpCode.Newobj, ctorsymbol);
cg.Builder.EmitThrow(false);
//
return cg.CoreTypes.Void;
}
示例5: if
void IBoundReference.EmitStore(CodeGenerator cg, TypeSymbol valueType)
{
// Template: array[index]
var isphparr = (this.Array.ResultType == cg.CoreTypes.PhpArray); // whether the target is instance of PhpArray, otherwise it is an IPhpArray and we have to use .callvirt
if (Access.IsWriteRef)
{
// PhpAlias
if (valueType != cg.CoreTypes.PhpAlias)
{
cg.EmitConvertToPhpValue(valueType, 0);
cg.Emit_PhpValue_MakeAlias();
}
// .SetItemAlias(key, alias) or .AddValue(PhpValue.Create(alias))
if (this.Index != null)
{
if (isphparr)
cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpArray.SetItemAlias_IntStringKey_PhpAlias);
else
cg.EmitCall(ILOpCode.Callvirt, cg.CoreMethods.IPhpArray.SetItemAlias_IntStringKey_PhpAlias);
}
else
{
cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpValue.Create_PhpAlias);
if (isphparr)
cg.EmitCall(ILOpCode.Callvirt, cg.CoreMethods.IPhpArray.AddValue_PhpValue);
else
cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpArray.AddValue_PhpValue);
}
}
else if (Access.IsUnset)
{
if (this.Index == null)
throw new InvalidOperationException();
// .RemoveKey(key)
if (isphparr)
cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpArray.RemoveKey_IntStringKey);
else
cg.EmitCall(ILOpCode.Callvirt, cg.CoreMethods.IPhpArray.RemoveKey_IntStringKey);
}
else
{
Debug.Assert(Access.IsWrite);
cg.EmitConvertToPhpValue(valueType, 0);
// .SetItemValue(key, value) or .AddValue(value)
if (this.Index != null)
{
if (isphparr)
cg.EmitCall(ILOpCode.Callvirt, cg.CoreMethods.IPhpArray.SetItemValue_IntStringKey_PhpValue);
else
cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpArray.SetItemValue_IntStringKey_PhpValue);
}
else
{
if (isphparr)
cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpArray.AddValue_PhpValue);
else
cg.EmitCall(ILOpCode.Callvirt, cg.CoreMethods.IPhpArray.AddValue_PhpValue);
}
}
}
示例6: EmitDiv
internal static TypeSymbol EmitDiv(CodeGenerator cg, TypeSymbol xtype, BoundExpression right, TypeSymbol resultTypeOpt = null)
{
var il = cg.Builder;
xtype = cg.EmitConvertIntToLong(xtype); // int|bool -> int64
TypeSymbol ytype;
switch (xtype.SpecialType)
{
case SpecialType.System_Double:
ytype = cg.EmitConvertNumberToDouble(right); // bool|int|long|number -> double
if (ytype.SpecialType == SpecialType.System_Double)
{
il.EmitOpCode(ILOpCode.Div);
return xtype; // r8
}
// double / value : double
cg.EmitConvertToPhpValue(ytype, 0);
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.Div_double_PhpValue);
case SpecialType.System_Int64:
ytype = cg.EmitConvertIntToLong(cg.Emit(right)); // bool|int -> long
if (ytype == cg.CoreTypes.PhpNumber)
{
// long / number : number
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Division_long_number)
.Expect(cg.CoreTypes.PhpNumber);
}
// long / value : number
cg.EmitConvertToPhpValue(ytype, 0);
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.Div_long_PhpValue);
default:
if (xtype == cg.CoreTypes.PhpNumber)
{
ytype = cg.EmitConvertIntToLong(cg.Emit(right)); // bool|int -> long
if (ytype == cg.CoreTypes.PhpNumber)
{
// nmumber / number : number
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Division_number_number)
.Expect(cg.CoreTypes.PhpNumber);
}
}
// x -> PhpValue
xtype = cg.EmitConvertToPhpValue(xtype, 0);
cg.EmitConvert(right, cg.CoreTypes.PhpValue);
ytype = cg.CoreTypes.PhpValue;
// value / value : number
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.Div_PhpValue_PhpValue);
}
}
示例7: EmitPow
internal static TypeSymbol EmitPow(CodeGenerator cg, TypeSymbol xtype, FlowAnalysis.TypeRefMask xtype_hint, BoundExpression right)
{
var il = cg.Builder;
TypeSymbol ytype;
xtype = cg.EmitConvertIntToLong(xtype); // int|bool -> long
switch (xtype.SpecialType)
{
case SpecialType.System_Int64:
ytype = cg.EmitConvertIntToLong(cg.Emit(right)); // int|bool -> long
if (ytype.SpecialType == SpecialType.System_Int64)
{
// i8 ** i8 : number
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Pow_long_long);
}
else if (ytype.SpecialType == SpecialType.System_Double)
{
// i8 ** r8 : r8
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Pow_long_double);
}
else if (ytype == cg.CoreTypes.PhpNumber)
{
// i8 ** number : number
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Pow_long_number);
}
// y -> PhpValue
cg.EmitConvert(ytype, right.TypeRefMask, cg.CoreTypes.PhpValue);
ytype = cg.CoreTypes.PhpValue;
// i8 ** value : number
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Pow_long_value);
case SpecialType.System_Double:
ytype = cg.EmitConvertNumberToDouble(right); // int|bool|long|number -> double
if (ytype.SpecialType == SpecialType.System_Double)
{
// r8 ** r8 : r8
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Pow_double_double);
}
// y -> PhpValue
cg.EmitConvert(ytype, right.TypeRefMask, cg.CoreTypes.PhpValue);
ytype = cg.CoreTypes.PhpValue;
// r8 ** value : r8
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Pow_double_value);
default:
if (xtype == cg.CoreTypes.PhpNumber)
{
ytype = cg.EmitConvertIntToLong(cg.Emit(right)); // int|bool -> long
if (ytype == cg.CoreTypes.Double)
{
// number ** r8 : r8
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Pow_number_double);
}
if (ytype.SpecialType == SpecialType.System_Int64)
{
// y -> number
ytype = cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Create_Long);
}
if (ytype == cg.CoreTypes.PhpNumber)
{
// number ** number : number
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Pow_number_number);
}
// y -> PhpValue
ytype = cg.EmitConvertToPhpValue(ytype, right.TypeRefMask);
// number ** value : number
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Pow_number_value);
}
// x -> PhpValue
xtype = cg.EmitConvertToPhpValue(xtype, xtype_hint);
cg.EmitConvert(right, cg.CoreTypes.PhpValue);
ytype = cg.CoreTypes.PhpValue;
// value ** value : number
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpNumber.Pow_value_value);
}
}
示例8: Generate
internal override void Generate(CodeGenerator cg)
{
Debug.Assert(this.Enumeree != null);
// get the enumerator,
// bind actual MoveNext() and CurrentValue and CurrentKey
// Template: using(
// a) enumerator = enumeree.GetEnumerator()
// b) enumerator = Operators.GetEnumerator(enumeree)
// ) ...
cg.EmitSequencePoint(this.Enumeree.PhpSyntax);
var enumereeType = cg.Emit(this.Enumeree);
Debug.Assert(enumereeType.SpecialType != SpecialType.System_Void);
var getEnumeratorMethod = enumereeType.LookupMember<MethodSymbol>(WellKnownMemberNames.GetEnumeratorMethodName);
TypeSymbol enumeratorType;
if (enumereeType.IsOfType(cg.CoreTypes.PhpArray))
{
cg.Builder.EmitBoolConstant(_aliasedValues);
// PhpArray.GetForeachtEnumerator(bool)
enumeratorType = cg.EmitCall(ILOpCode.Callvirt, cg.CoreMethods.PhpArray.GetForeachEnumerator_Boolean); // TODO: IPhpArray
}
// TODO: IPhpEnumerable
// TODO: IPhpArray
// TODO: Iterator
else if (getEnumeratorMethod != null && getEnumeratorMethod.ParameterCount == 0 && enumereeType.IsReferenceType)
{
// enumeree.GetEnumerator()
enumeratorType = cg.EmitCall(getEnumeratorMethod.IsVirtual ? ILOpCode.Callvirt : ILOpCode.Call, getEnumeratorMethod);
}
else
{
cg.EmitConvertToPhpValue(enumereeType, 0);
cg.Builder.EmitBoolConstant(_aliasedValues);
cg.EmitCallerRuntimeTypeHandle();
// Operators.GetForeachEnumerator(PhpValue, bool, RuntimeTypeHandle)
enumeratorType = cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.GetForeachEnumerator_PhpValue_Bool_RuntimeTypeHandle);
}
//
_current = enumeratorType.LookupMember<PropertySymbol>(WellKnownMemberNames.CurrentPropertyName); // TODO: Err if no Current
_currentValue = enumeratorType.LookupMember<PropertySymbol>(_aliasedValues ? "CurrentValueAliased" : "CurrentValue");
_currentKey = enumeratorType.LookupMember<PropertySymbol>("CurrentKey");
_disposeMethod = enumeratorType.LookupMember<MethodSymbol>("Dispose", m => m.ParameterCount == 0 && !m.IsStatic);
//
_enumeratorLoc = cg.GetTemporaryLocal(enumeratorType);
cg.Builder.EmitLocalStore(_enumeratorLoc);
// bind methods
_moveNextMethod = enumeratorType.LookupMember<MethodSymbol>(WellKnownMemberNames.MoveNextMethodName); // TODO: Err if there is no MoveNext()
Debug.Assert(_moveNextMethod.ReturnType.SpecialType == SpecialType.System_Boolean);
Debug.Assert(_moveNextMethod.IsStatic == false);
if (_disposeMethod != null)
{
/* Template: try { body } finally { enumerator.Dispose }
*/
// try {
cg.Builder.AssertStackEmpty();
cg.Builder.OpenLocalScope(ScopeType.TryCatchFinally);
cg.Builder.OpenLocalScope(ScopeType.Try);
//
EmitBody(cg);
// }
cg.Builder.CloseLocalScope(); // /Try
// finally {
cg.Builder.OpenLocalScope(ScopeType.Finally);
// enumerator.Dispose() & cleanup
EmitDisposeAndClean(cg);
// }
cg.Builder.CloseLocalScope(); // /Finally
cg.Builder.CloseLocalScope(); // /TryCatchFinally
}
else
{
EmitBody(cg);
EmitDisposeAndClean(cg);
}
}
示例9: EmitLtGt
/// <summary>
/// Emits comparison operator pushing <c>bool</c> (<c>i4</c> of value <c>0</c> or <c>1</c>) onto the evaluation stack.
/// </summary>
/// <returns>Resulting type code pushed onto the top of evaliuation stack.</returns>
internal static TypeSymbol EmitLtGt(CodeGenerator cg, TypeSymbol xtype, BoundExpression right, bool lt)
{
TypeSymbol ytype;
var il = cg.Builder;
switch (xtype.SpecialType)
{
case SpecialType.System_Void:
// Operators.CompareNull(value)
throw new NotImplementedException();
case SpecialType.System_Int32:
// i4 -> i8
il.EmitOpCode(ILOpCode.Conv_i8);
goto case SpecialType.System_Int64;
case SpecialType.System_Int64:
ytype = cg.EmitConvertIntToLong(cg.Emit(right)); // bool|int -> long
if (ytype.SpecialType == SpecialType.System_Int64)
{
il.EmitOpCode(lt ? ILOpCode.Clt : ILOpCode.Cgt);
}
else if (ytype.SpecialType == SpecialType.System_Double)
{
// i8 <> r8
return cg.EmitCall(ILOpCode.Call, lt
? cg.CoreMethods.Operators.Clt_long_double
: cg.CoreMethods.Operators.Cgt_long_double);
}
else
{
ytype = cg.EmitConvertToPhpValue(ytype, 0);
// compare(i8, value) <> 0
cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.Compare_long_value);
il.EmitOpCode(ILOpCode.Ldc_i4_0, 1);
il.EmitOpCode(lt ? ILOpCode.Clt : ILOpCode.Cgt);
}
return cg.CoreTypes.Boolean;
case SpecialType.System_Double:
ytype = cg.EmitConvertNumberToDouble(right); // bool|int|long|number -> double
if (ytype.SpecialType == SpecialType.System_Double)
{
// r8 <> r8
il.EmitOpCode(lt ? ILOpCode.Clt : ILOpCode.Cgt);
}
else
{
// compare(r8, value)
ytype = cg.EmitConvertToPhpValue(ytype, 0);
cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.Compare_double_value);
// <> 0
il.EmitOpCode(ILOpCode.Ldc_i4_0, 1);
il.EmitOpCode(lt ? ILOpCode.Clt : ILOpCode.Cgt);
}
return cg.CoreTypes.Boolean;
case SpecialType.System_String:
ytype = cg.Emit(right);
if (ytype.SpecialType == SpecialType.System_String)
{
// compare(string, string)
cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.Compare_string_string);
}
else if (ytype.SpecialType == SpecialType.System_Int64)
{
// compare(string, long)
cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.Compare_string_long);
}
else if (ytype.SpecialType == SpecialType.System_Double)
{
// compare(string, double)
cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.Compare_string_double);
}
else
{
// compare(string, value)
ytype = cg.EmitConvertToPhpValue(ytype, 0);
cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.Compare_string_value);
}
// <> 0
il.EmitOpCode(ILOpCode.Ldc_i4_0, 1);
il.EmitOpCode(lt ? ILOpCode.Clt : ILOpCode.Cgt);
return cg.CoreTypes.Boolean;
case SpecialType.System_Boolean:
cg.EmitConvert(right, cg.CoreTypes.Boolean);
ytype = cg.CoreTypes.Boolean;
// compare(bool, bool)
cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.Compare_bool_bool);
//.........这里部分代码省略.........
示例10: EmitStore
public virtual void EmitStore(CodeGenerator cg, TypeSymbol valueType)
{
// STACK: <PhpArray> <key>
if (_access.IsWriteRef)
{
// PhpAlias
if (valueType != cg.CoreTypes.PhpAlias)
{
cg.EmitConvertToPhpValue(valueType, 0);
cg.Emit_PhpValue_MakeAlias();
}
// .SetItemAlias(key, alias)
cg.EmitCall(ILOpCode.Callvirt, cg.CoreMethods.PhpArray.SetItemAlias_IntStringKey_PhpAlias);
}
else if (_access.IsUnset)
{
Debug.Assert(valueType == null);
// .RemoveKey(key)
cg.EmitCall(ILOpCode.Callvirt, cg.CoreMethods.PhpArray.RemoveKey_IntStringKey);
}
else
{
Debug.Assert(_access.IsWrite);
cg.EmitConvertToPhpValue(valueType, 0);
// .SetItemValue(key, value)
cg.EmitCall(ILOpCode.Callvirt, cg.CoreMethods.PhpArray.SetItemValue_IntStringKey_PhpValue);
}
}
示例11: EmitLoad
//.........这里部分代码省略.........
if (cg.IsArrayOnly(_thint))
{
// uses typehint and accesses .Array directly if possible
// <place>.Array
_place.EmitLoadAddress(cg.Builder);
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpValue.get_Array)
.Expect(cg.CoreTypes.PhpArray);
}
else
{
// <place>.EnsureArray()
_place.EmitLoadAddress(cg.Builder);
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpValue.EnsureArray)
.Expect(cg.CoreTypes.IPhpArray);
}
}
else if (type.IsOfType(cg.CoreTypes.IPhpArray))
{
// Operators.EnsureArray(ref <place>)
_place.EmitLoadAddress(cg.Builder);
if (type == cg.CoreTypes.PhpArray)
{
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.EnsureArray_PhpArrayRef)
.Expect(cg.CoreTypes.PhpArray);
}
else
{
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.Operators.EnsureArray_IPhpArrayRef)
.Expect(cg.CoreTypes.IPhpArray);
}
}
throw new NotImplementedException("EnsureArray(" + type.Name + ")");
}
// Ensure Alias (&$x)
else if (_access.IsReadRef)
{
if (type == cg.CoreTypes.PhpAlias)
{
// TODO: <place>.AddRef()
return _place.EmitLoad(cg.Builder);
}
else if (type == cg.CoreTypes.PhpValue)
{
// return <place>.EnsureAlias()
_place.EmitLoadAddress(cg.Builder);
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpValue.EnsureAlias)
.Expect(cg.CoreTypes.PhpAlias);
}
else if (type == cg.CoreTypes.PhpNumber)
{
throw new NotImplementedException();
}
else
{
Debug.Assert(false, "value cannot be aliased");
// new PhpAlias((PhpValue)<place>, 1)
cg.EmitConvertToPhpValue(_place.EmitLoad(cg.Builder), 0);
return cg.Emit_PhpValue_MakeAlias();
}
}
// Read Value & Dereference eventually
else
{
if (type == cg.CoreTypes.PhpAlias)
{
_place.EmitLoad(cg.Builder);
if (_access.TargetType == cg.CoreTypes.PhpArray)
{
// <place>.Value.ToArray()
cg.Builder.EmitOpCode(ILOpCode.Ldflda);
cg.EmitSymbolToken(cg.CoreMethods.PhpAlias.Value, null);
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpValue.ToArray)
.Expect(cg.CoreTypes.PhpArray);
}
return cg.Emit_PhpAlias_GetValue();
}
else if (type == cg.CoreTypes.PhpValue)
{
if (_access.TargetType == cg.CoreTypes.PhpArray)
{
// <place>.ToArray()
_place.EmitLoadAddress(cg.Builder);
return cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpValue.ToArray)
.Expect(cg.CoreTypes.PhpArray);
}
// TODO: dereference if applicable (=> PhpValue.Alias.Value)
return _place.EmitLoad(cg.Builder);
}
else
{
return _place.EmitLoad(cg.Builder);
}
}
}
示例12: EmitInit
internal override void EmitInit(CodeGenerator cg)
{
// TODO: check callable, iterable
// TODO: ? if (cg.HasUnoptimizedLocals && $this) <locals>["this"] = ...
var srcparam = _symbol as SourceParameterSymbol;
if (srcparam != null)
{
var srcplace = new ParamPlace(_symbol);
var routine = srcparam.Routine;
if (cg.HasUnoptimizedLocals)
{
Debug.Assert(cg.LocalsPlaceOpt != null);
// copy parameter to <locals>[Name]
// <locals>[name] = value
cg.LocalsPlaceOpt.EmitLoad(cg.Builder); // <locals>
cg.EmitIntStringKey(new BoundLiteral(this.Name)); // [key]
cg.EmitConvertToPhpValue(srcplace.EmitLoad(cg.Builder), 0); // value
cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpArray.SetItemValue_IntStringKey_PhpValue);
//
_isUnoptimized = true;
}
else
{
// TODO: copy parameter by value in case of PhpValue, Array, PhpString
// create local variable in case of parameter type is not enough for its use within routine
if (_symbol.Type != cg.CoreTypes.PhpValue && _symbol.Type != cg.CoreTypes.PhpAlias)
{
var tmask = routine.ControlFlowGraph.GetLocalTypeMask(srcparam.Name);
var clrtype = cg.DeclaringCompilation.GetTypeFromTypeRef(routine, tmask);
if (clrtype != _symbol.Type) // Assert: only if clrtype is not covered by _symbol.Type
{
// TODO: performance warning
_lazyLocal = new BoundLocal(new SynthesizedLocalSymbol(routine, srcparam.Name, clrtype));
_lazyLocal.EmitInit(cg);
var localplace = _lazyLocal.Place(cg.Builder);
// <local> = <param>
localplace.EmitStorePrepare(cg.Builder);
cg.EmitConvert(srcplace.EmitLoad(cg.Builder), 0, clrtype);
localplace.EmitStore(cg.Builder);
}
}
}
}
}