本文整理汇总了C#中Jurassic.Compiler.ILGenerator.LoadVariable方法的典型用法代码示例。如果您正苦于以下问题:C# ILGenerator.LoadVariable方法的具体用法?C# ILGenerator.LoadVariable怎么用?C# ILGenerator.LoadVariable使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Jurassic.Compiler.ILGenerator
的用法示例。
在下文中一共展示了ILGenerator.LoadVariable方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: EmitDefaultValue
/// <summary>
/// Emits a default value of the given type.
/// </summary>
/// <param name="generator"> The IL generator. </param>
/// <param name="type"> The type of value to generate. </param>
public static void EmitDefaultValue(ILGenerator generator, Type type)
{
var temp = generator.CreateTemporaryVariable(type);
generator.LoadAddressOfVariable(temp);
generator.InitObject(temp.Type);
generator.LoadVariable(temp);
generator.ReleaseTemporaryVariable(temp);
}
示例2: GenerateSet
/// <summary>
/// Stores the value on the top of the stack in the reference.
/// </summary>
/// <param name="generator"> The generator to output the CIL to. </param>
/// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
/// <param name="valueType"> The primitive type of the value that is on the top of the stack. </param>
/// <param name="throwIfUnresolvable"> <c>true</c> to throw a ReferenceError exception if
/// the name is unresolvable; <c>false</c> to create a new property instead. </param>
public void GenerateSet(ILGenerator generator, OptimizationInfo optimizationInfo, PrimitiveType valueType, bool throwIfUnresolvable)
{
// The value is initially on the top of the stack but is stored in this variable
// at the last possible moment.
ILLocalVariable value = null;
var scope = this.Scope;
ILLocalVariable scopeVariable = null;
var endOfSet = generator.CreateLabel();
do
{
if (scope is DeclarativeScope)
{
// Get information about the variable.
var variable = scope.GetDeclaredVariable(this.Name);
if (variable != null)
{
// The variable was declared in this scope.
if (scope.ExistsAtRuntime == false)
{
// The scope has been optimized away. The value of the variable is stored
// in an ILVariable.
// Declare an IL local variable if no storage location has been allocated yet.
if (variable.Store == null)
variable.Store = generator.DeclareVariable(typeof(object), variable.Name);
if (value == null)
{
// The value to store is on the top of the stack - convert it to the
// storage type of the variable.
EmitConversion.Convert(generator, valueType, variable.Type, optimizationInfo);
}
else
{
// The value to store is in a temporary variable.
generator.LoadVariable(value);
EmitConversion.Convert(generator, PrimitiveType.Any, variable.Type, optimizationInfo);
}
// Store the value in the variable.
generator.StoreVariable(variable.Store);
}
else if (variable.Writable == true)
{
if (value == null)
{
// The value to store is on the top of the stack - convert it to an
// object and store it in a temporary variable.
EmitConversion.Convert(generator, valueType, PrimitiveType.Any, optimizationInfo);
value = generator.CreateTemporaryVariable(typeof(object));
generator.StoreVariable(value);
}
// scope.Values[index] = value
if (scopeVariable == null)
EmitHelpers.LoadScope(generator);
else
generator.LoadVariable(scopeVariable);
generator.CastClass(typeof(DeclarativeScope));
generator.Call(ReflectionHelpers.DeclarativeScope_Values);
generator.LoadInt32(variable.Index);
generator.LoadVariable(value);
generator.StoreArrayElement(typeof(object));
}
else
{
// The variable exists, but is read-only.
// Pop the value off the stack (if it is still there).
if (value == null)
generator.Pop();
}
// The variable was found - no need to search any more parent scopes.
break;
}
else
{
// The variable was not defined at compile time, but may have been
// introduced by an eval() statement.
if (optimizationInfo.MethodOptimizationHints.HasEval == true)
{
if (value == null)
{
// The value to store is on the top of the stack - convert it to an
// object and store it in a temporary variable.
EmitConversion.Convert(generator, valueType, PrimitiveType.Any, optimizationInfo);
value = generator.CreateTemporaryVariable(typeof(object));
generator.StoreVariable(value);
}
//.........这里部分代码省略.........
示例3: GenerateSet
/// <summary>
/// Stores the value on the top of the stack in the reference.
/// </summary>
/// <param name="generator"> The generator to output the CIL to. </param>
/// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
/// <param name="valueType"> The primitive type of the value that is on the top of the stack. </param>
/// <param name="throwIfUnresolvable"> <c>true</c> to throw a ReferenceError exception if
/// the name is unresolvable; <c>false</c> to create a new property instead. </param>
public void GenerateSet(ILGenerator generator, OptimizationInfo optimizationInfo, PrimitiveType valueType, bool throwIfUnresolvable)
{
string propertyName = null;
bool isArrayIndex = false;
//optimizationInfo = optimizationInfo.RemoveFlags(OptimizationFlags.SuppressReturnValue);
// Right-hand-side can be a property name (a.b)
if (this.OperatorType == OperatorType.MemberAccess)
{
var rhs = this.GetOperand(1) as NameExpression;
if (rhs == null)
throw new JavaScriptException(optimizationInfo.Engine, "SyntaxError", "Invalid member access");
propertyName = rhs.Name;
}
// Or a constant indexer (a['b'])
if (this.OperatorType == OperatorType.Index)
{
var rhs = this.GetOperand(1) as LiteralExpression;
if (rhs != null)
{
propertyName = TypeConverter.ToString(rhs.Value);
// Or a array index (a[0])
if (rhs.ResultType == PrimitiveType.Int32 || (propertyName != null && Library.ArrayInstance.ParseArrayIndex(propertyName) != uint.MaxValue))
isArrayIndex = true;
}
}
// Convert the value to an object and store it in a temporary variable.
var value = generator.CreateTemporaryVariable(typeof(object));
EmitConversion.ToAny(generator, valueType);
generator.StoreVariable(value);
if (isArrayIndex == true)
{
// Array indexer
// -------------
// xxx = object[index]
// Load the left-hand side and convert to an object instance.
var lhs = this.GetOperand(0);
lhs.GenerateCode(generator, optimizationInfo);
EmitConversion.ToObject(generator, lhs.ResultType);
// Load the right-hand side and convert to a uint32.
var rhs = this.GetOperand(1);
rhs.GenerateCode(generator, optimizationInfo);
EmitConversion.ToUInt32(generator, rhs.ResultType);
// Call the indexer.
generator.LoadVariable(value);
generator.LoadBoolean(optimizationInfo.StrictMode);
generator.Call(ReflectionHelpers.ObjectInstance_SetPropertyValue_Int);
}
else if (propertyName != null)
{
//// Load the left-hand side and convert to an object instance.
//var lhs = this.GetOperand(0);
//lhs.GenerateCode(generator, optimizationInfo);
//EmitConversion.ToObject(generator, lhs.ResultType);
//// Call the indexer.
//generator.LoadString(propertyName);
//generator.LoadVariable(value);
//generator.LoadBoolean(optimizationInfo.StrictMode);
//generator.Call(ReflectionHelpers.ObjectInstance_SetPropertyValue_String);
// Named property modification (e.g. x.property = y)
// -------------------------------------------------
// __object_cacheKey = null;
// __object_property_cachedIndex = 0;
// ...
// if (__object_cacheKey != object.InlineCacheKey)
// object.InlineSetPropertyValue("property", value, strictMode, out __object_property_cachedIndex, out __object_cacheKey)
// else
// object.InlinePropertyValues[__object_property_cachedIndex] = value;
// Load the left-hand side and convert to an object instance.
var lhs = this.GetOperand(0);
lhs.GenerateCode(generator, optimizationInfo);
EmitConversion.ToObject(generator, lhs.ResultType);
// TODO: share these variables somehow.
var cacheKey = generator.DeclareVariable(typeof(object));
var cachedIndex = generator.DeclareVariable(typeof(int));
// Store the object into a temp variable.
var objectInstance = generator.DeclareVariable(PrimitiveType.Object);
generator.StoreVariable(objectInstance);
// if (__object_cacheKey != object.InlineCacheKey)
//.........这里部分代码省略.........
示例4: GenerateCode
/// <summary>
/// Generates IL for the script.
/// </summary>
/// <param name="generator"> The generator to output the CIL to. </param>
/// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
protected override void GenerateCode(ILGenerator generator, OptimizationInfo optimizationInfo)
{
// Declare a variable to store the eval result.
optimizationInfo.EvalResult = generator.DeclareVariable(typeof(object));
if (this.StrictMode == true)
{
// Create a new scope.
this.InitialScope.GenerateScopeCreation(generator, optimizationInfo);
}
// Verify the scope is correct.
VerifyScope(generator);
// Initialize any declarations.
this.InitialScope.GenerateDeclarations(generator, optimizationInfo);
// Generate the main body of code.
this.AbstractSyntaxTree.GenerateCode(generator, optimizationInfo);
// Make the return value from the method the eval result.
generator.LoadVariable(optimizationInfo.EvalResult);
// If the result is null, convert it to undefined.
var end = generator.CreateLabel();
generator.Duplicate();
generator.BranchIfNotNull(end);
generator.Pop();
EmitHelpers.EmitUndefined(generator);
generator.DefineLabelPosition(end);
}
示例5: GenerateDelete
/// <summary>
/// Deletes the reference and pushes <c>true</c> if the delete succeeded, or <c>false</c>
/// if the delete failed.
/// </summary>
/// <param name="generator"> The generator to output the CIL to. </param>
/// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
public void GenerateDelete(ILGenerator generator, OptimizationInfo optimizationInfo)
{
// Deleting a variable is not allowed in strict mode.
if (optimizationInfo.StrictMode == true)
throw new JavaScriptException(optimizationInfo.Engine, ErrorType.SyntaxError, string.Format("Cannot delete {0} because deleting a variable or argument is not allowed in strict mode", this.Name), optimizationInfo.SourceSpan.StartLine, optimizationInfo.Source.Path, optimizationInfo.FunctionName);
var endOfDelete = generator.CreateLabel();
var scope = this.Scope;
ILLocalVariable scopeVariable = generator.CreateTemporaryVariable(typeof(Scope));
EmitHelpers.LoadScope(generator);
generator.StoreVariable(scopeVariable);
do
{
if (scope is DeclarativeScope)
{
var variable = scope.GetDeclaredVariable(this.Name);
if (variable != null)
{
// The variable is known at compile-time.
if (variable.Deletable == false)
{
// The variable cannot be deleted - return false.
generator.LoadBoolean(false);
}
else
{
// The variable can be deleted (it was declared inside an eval()).
// Delete the variable.
generator.LoadVariable(scopeVariable);
generator.CastClass(typeof(DeclarativeScope));
generator.LoadString(this.Name);
generator.Call(ReflectionHelpers.Scope_Delete);
}
break;
}
else
{
// The variable was not defined at compile time, but may have been
// introduced by an eval() statement.
if (optimizationInfo.MethodOptimizationHints.HasEval == true)
{
// Check the variable exists: if (scope.HasValue(variableName) == true) {
generator.LoadVariable(scopeVariable);
generator.CastClass(typeof(DeclarativeScope));
generator.LoadString(this.Name);
generator.Call(ReflectionHelpers.Scope_HasValue);
var hasValueClause = generator.CreateLabel();
generator.BranchIfFalse(hasValueClause);
// If the variable does exist, return true.
generator.LoadVariable(scopeVariable);
generator.CastClass(typeof(DeclarativeScope));
generator.LoadString(this.Name);
generator.Call(ReflectionHelpers.Scope_Delete);
generator.Branch(endOfDelete);
// }
generator.DefineLabelPosition(hasValueClause);
}
}
}
else
{
// Check if the property exists by calling scope.ScopeObject.HasProperty(propertyName)
generator.LoadVariable(scopeVariable);
generator.CastClass(typeof(ObjectScope));
generator.Call(ReflectionHelpers.ObjectScope_ScopeObject);
generator.Duplicate();
generator.LoadString(this.Name);
generator.Call(ReflectionHelpers.ObjectInstance_HasProperty);
// Jump past the delete if the property doesn't exist.
var endOfExistsCheck = generator.CreateLabel();
generator.BranchIfFalse(endOfExistsCheck);
// Call scope.ScopeObject.Delete(key, false)
generator.LoadString(this.Name);
generator.LoadBoolean(false);
generator.Call(ReflectionHelpers.ObjectInstance_Delete);
generator.Branch(endOfDelete);
generator.DefineLabelPosition(endOfExistsCheck);
generator.Pop();
// If the name is not defined, return true.
if (scope.ParentScope == null)
{
generator.LoadBoolean(true);
}
}
// Try the parent scope.
if (scope.ParentScope != null && scope.ExistsAtRuntime == true)
{
//.........这里部分代码省略.........
示例6: GenerateCompoundAssignment
/// <summary>
/// Generates CIL for a compound assignment expression.
/// </summary>
/// <param name="generator"> The generator to output the CIL to. </param>
/// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
/// <param name="target"> The target to modify. </param>
private void GenerateCompoundAssignment(ILGenerator generator, OptimizationInfo optimizationInfo, IReferenceExpression target)
{
// Evaluate the left hand side only once.
target.GenerateReference(generator, optimizationInfo);
target.DuplicateReference(generator, optimizationInfo); // For the GenerateSet, later on.
// Load the value to assign.
var compoundOperator = new BinaryExpression(GetCompoundBaseOperator(this.OperatorType), new ReferenceGetExpression(target), this.GetOperand(1));
compoundOperator.GenerateCode(generator, optimizationInfo);
// Store the resulting value so we can return it as the result of the expression.
var result = generator.CreateTemporaryVariable(compoundOperator.ResultType);
generator.Duplicate();
generator.StoreVariable(result);
// Store the value.
target.GenerateSet(generator, optimizationInfo, compoundOperator.ResultType, optimizationInfo.StrictMode);
// Restore the expression result.
generator.LoadVariable(result);
generator.ReleaseTemporaryVariable(result);
}
示例7: GenerateCode
/// <summary>
/// Generates CIL for the expression.
/// </summary>
/// <param name="generator"> The generator to output the CIL to. </param>
/// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
public override void GenerateCode(ILGenerator generator, OptimizationInfo optimizationInfo)
{
// Note: we use GetRawOperand() so that grouping operators are not ignored.
var operand = this.GetRawOperand(0);
// There is only one operand, and it can be either a reference or a function call.
// We need to split the operand into a function and some arguments.
// If the operand is a reference, it is equivalent to a function call with no arguments.
if (operand is FunctionCallExpression)
{
// Emit the function instance first.
var function = ((FunctionCallExpression)operand).Target;
function.GenerateCode(generator, optimizationInfo);
EmitConversion.ToAny(generator, function.ResultType);
}
else
{
// Emit the function instance first.
operand.GenerateCode(generator, optimizationInfo);
EmitConversion.ToAny(generator, operand.ResultType);
}
// Check the object really is a function - if not, throw an exception.
generator.IsInstance(typeof(Library.FunctionInstance));
generator.Duplicate();
var endOfTypeCheck = generator.CreateLabel();
generator.BranchIfNotNull(endOfTypeCheck);
// Throw an nicely formatted exception.
var targetValue = generator.CreateTemporaryVariable(typeof(object));
generator.StoreVariable(targetValue);
EmitHelpers.LoadScriptEngine(generator);
generator.LoadString("TypeError");
generator.LoadString("The new operator requires a function, found a '{0}' instead");
generator.LoadInt32(1);
generator.NewArray(typeof(object));
generator.Duplicate();
generator.LoadInt32(0);
generator.LoadVariable(targetValue);
generator.Call(ReflectionHelpers.TypeUtilities_TypeOf);
generator.StoreArrayElement(typeof(object));
generator.Call(ReflectionHelpers.String_Format);
generator.LoadInt32(optimizationInfo.SourceSpan.StartLine);
generator.LoadStringOrNull(optimizationInfo.Source.Path);
generator.LoadStringOrNull(optimizationInfo.FunctionName);
generator.NewObject(ReflectionHelpers.JavaScriptException_Constructor_Error);
generator.Throw();
generator.DefineLabelPosition(endOfTypeCheck);
generator.ReleaseTemporaryVariable(targetValue);
if (operand is FunctionCallExpression)
{
// Emit an array containing the function arguments.
((FunctionCallExpression)operand).GenerateArgumentsArray(generator, optimizationInfo);
}
else
{
// Emit an empty array.
generator.LoadInt32(0);
generator.NewArray(typeof(object));
}
// Call FunctionInstance.ConstructLateBound(argumentValues)
generator.Call(ReflectionHelpers.FunctionInstance_ConstructLateBound);
}
示例8: GenerateCode
/// <summary>
/// Generates CIL for the expression.
/// </summary>
/// <param name="generator"> The generator to output the CIL to. </param>
/// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
public override void GenerateCode(ILGenerator generator, OptimizationInfo optimizationInfo)
{
// Check if this is a direct call to eval().
if (this.Target is NameExpression && ((NameExpression)this.Target).Name == "eval")
{
GenerateEval(generator, optimizationInfo);
return;
}
// Emit the function instance first.
ILLocalVariable targetBase = null;
if (this.Target is MemberAccessExpression)
{
// The function is a member access expression (e.g. "Math.cos()").
// Evaluate the left part of the member access expression.
var baseExpression = ((MemberAccessExpression)this.Target).Base;
baseExpression.GenerateCode(generator, optimizationInfo);
EmitConversion.ToAny(generator, baseExpression.ResultType);
targetBase = generator.CreateTemporaryVariable(typeof(object));
generator.StoreVariable(targetBase);
// Evaluate the right part of the member access expression.
var memberAccessExpression = new MemberAccessExpression(((MemberAccessExpression)this.Target).Operator);
memberAccessExpression.Push(new TemporaryVariableExpression(targetBase));
memberAccessExpression.Push(((MemberAccessExpression)this.Target).GetOperand(1));
memberAccessExpression.GenerateCode(generator, optimizationInfo);
EmitConversion.ToAny(generator, this.Target.ResultType);
}
else
{
// Something else (e.g. "eval()").
this.Target.GenerateCode(generator, optimizationInfo);
EmitConversion.ToAny(generator, this.Target.ResultType);
}
// Check the object really is a function - if not, throw an exception.
generator.IsInstance(typeof(Library.FunctionInstance));
generator.Duplicate();
var endOfTypeCheck = generator.CreateLabel();
generator.BranchIfNotNull(endOfTypeCheck);
// Throw an nicely formatted exception.
generator.Pop();
EmitHelpers.EmitThrow(generator, "TypeError", string.Format("'{0}' is not a function", this.Target.ToString()));
generator.DefineLabelPosition(endOfTypeCheck);
// Pass in the path, function name and line.
generator.LoadStringOrNull(optimizationInfo.Source.Path);
generator.LoadStringOrNull(optimizationInfo.FunctionName);
generator.LoadInt32(optimizationInfo.SourceSpan.StartLine);
// Generate code to produce the "this" value. There are three cases.
if (this.Target is NameExpression)
{
// 1. The function is a name expression (e.g. "parseInt()").
// In this case this = scope.ImplicitThisValue, if there is one, otherwise undefined.
((NameExpression)this.Target).GenerateThis(generator);
}
else if (this.Target is MemberAccessExpression)
{
// 2. The function is a member access expression (e.g. "Math.cos()").
// In this case this = Math.
//var baseExpression = ((MemberAccessExpression)this.Target).Base;
//baseExpression.GenerateCode(generator, optimizationInfo);
//EmitConversion.ToAny(generator, baseExpression.ResultType);
generator.LoadVariable(targetBase);
}
else
{
// 3. Neither of the above (e.g. "(function() { return 5 })()")
// In this case this = undefined.
EmitHelpers.EmitUndefined(generator);
}
// Emit an array containing the function arguments.
GenerateArgumentsArray(generator, optimizationInfo);
// Call FunctionInstance.CallLateBound(thisValue, argumentValues)
generator.Call(ReflectionHelpers.FunctionInstance_CallWithStackTrace);
// Allow reuse of the temporary variable.
if (targetBase != null)
generator.ReleaseTemporaryVariable(targetBase);
}
示例9: ToBool
/// <summary>
/// Pops the value on the stack, converts it to a boolean, then pushes the boolean result
/// onto the stack.
/// </summary>
/// <param name="generator"> The IL generator. </param>
/// <param name="fromType"> The type to convert from. </param>
public static void ToBool(ILGenerator generator, PrimitiveType fromType)
{
// Check that a conversion is actually necessary.
if (fromType == PrimitiveType.Bool)
return;
switch (fromType)
{
case PrimitiveType.Undefined:
case PrimitiveType.Null:
// Converting from undefined or null produces false.
generator.Pop();
generator.LoadInt32(0);
break;
case PrimitiveType.Int32:
case PrimitiveType.UInt32:
// Converting from an integer produces true if the integer is non-zero.
generator.LoadInt32(0);
generator.CompareGreaterThanUnsigned();
break;
case PrimitiveType.Number:
// Converting from a number produces true if the number is non-zero and not NaN.
var temp = generator.CreateTemporaryVariable(fromType);
generator.StoreVariable(temp);
// input != 0
generator.LoadVariable(temp);
generator.LoadDouble(0.0);
generator.CompareEqual();
generator.LoadInt32(0);
generator.CompareEqual();
// input == input
generator.LoadVariable(temp);
generator.Duplicate();
generator.CompareEqual();
// &&
generator.CompareEqual();
// The temporary variable is no longer needed.
generator.ReleaseTemporaryVariable(temp);
break;
case PrimitiveType.String:
// Converting from a string produces true if the string is not empty.
generator.Call(ReflectionHelpers.String_Length);
generator.LoadInt32(0);
generator.CompareGreaterThan();
break;
case PrimitiveType.ConcatenatedString:
// Converting from a string produces true if the string is not empty.
generator.Call(ReflectionHelpers.ConcatenatedString_Length);
generator.LoadInt32(0);
generator.CompareGreaterThan();
break;
case PrimitiveType.Any:
case PrimitiveType.Object:
// Otherwise, fall back to calling TypeConverter.ToBoolean()
generator.Call(ReflectionHelpers.TypeConverter_ToBoolean);
break;
default:
throw new NotImplementedException(string.Format("Unsupported primitive type: {0}", fromType));
}
}
示例10: EmitConversionToObject
/// <summary>
/// Pops the value on the stack, converts it to an object, then pushes the result onto the
/// stack.
/// </summary>
/// <param name="generator"> The IL generator. </param>
/// <param name="fromType"> The type to convert from. </param>
internal static void EmitConversionToObject(ILGenerator generator, Type fromType)
{
// If the from type is a reference type, check for null.
ILLabel endOfNullCheck = null;
if (fromType.IsValueType == false)
{
var startOfElse = generator.CreateLabel();
endOfNullCheck = generator.CreateLabel();
generator.Duplicate();
generator.BranchIfNotNull(startOfElse);
generator.Pop();
EmitHelpers.EmitNull(generator);
generator.Branch(endOfNullCheck);
generator.DefineLabelPosition(startOfElse);
}
switch (Type.GetTypeCode(fromType))
{
case TypeCode.Boolean:
generator.Box(typeof(bool));
break;
case TypeCode.Byte:
generator.Box(typeof(int));
break;
case TypeCode.Char:
generator.LoadInt32(1);
generator.NewObject(ReflectionHelpers.String_Constructor_Char_Int);
break;
case TypeCode.DBNull:
throw new NotSupportedException("DBNull is not a supported return type.");
case TypeCode.Decimal:
generator.Call(ReflectionHelpers.Decimal_ToDouble);
generator.Box(typeof(double));
break;
case TypeCode.Double:
generator.Box(typeof(double));
break;
case TypeCode.Empty:
throw new NotSupportedException("Empty is not a supported return type.");
case TypeCode.Int16:
generator.Box(typeof(int));
break;
case TypeCode.Int32:
generator.Box(typeof(int));
break;
case TypeCode.Int64:
generator.ConvertToDouble();
generator.Box(typeof(double));
break;
case TypeCode.DateTime:
case TypeCode.Object:
// Check if the type must be wrapped with a ClrInstanceWrapper.
// Note: if the type is a value type it cannot be a primitive or it would
// have been handled elsewhere in the switch.
ILLabel endOfWrapCheck = null;
if (fromType.IsValueType == false)
{
generator.Duplicate();
generator.Call(ReflectionHelpers.TypeUtilities_IsPrimitiveOrObject);
endOfWrapCheck = generator.CreateLabel();
generator.BranchIfTrue(endOfWrapCheck);
}
// The type must be wrapped.
var temp = generator.CreateTemporaryVariable(fromType);
generator.StoreVariable(temp);
generator.LoadArgument(0);
generator.LoadVariable(temp);
if (fromType.IsValueType == true)
generator.Box(fromType);
generator.ReleaseTemporaryVariable(temp);
generator.NewObject(ReflectionHelpers.ClrInstanceWrapper_Constructor);
// End of wrap check.
if (fromType.IsValueType == false)
generator.DefineLabelPosition(endOfWrapCheck);
break;
case TypeCode.SByte:
generator.Box(typeof(int));
break;
case TypeCode.Single:
generator.Box(typeof(double));
break;
case TypeCode.String:
break;
case TypeCode.UInt16:
generator.Box(typeof(int));
break;
case TypeCode.UInt32:
generator.Box(typeof(uint));
break;
//.........这里部分代码省略.........
示例11: DuplicateReference
/// <summary>
/// Outputs the values needed to get or set this reference.
/// </summary>
/// <param name="generator"> The generator to output the CIL to. </param>
/// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
public void DuplicateReference(ILGenerator generator, OptimizationInfo optimizationInfo)
{
string propertyName = null;
TypeOfMemberAccess memberAccessType = DetermineTypeOfMemberAccess(optimizationInfo, out propertyName);
if (memberAccessType == TypeOfMemberAccess.ArrayIndex)
{
// Array indexer
var arg1 = generator.CreateTemporaryVariable(typeof(object));
var arg2 = generator.CreateTemporaryVariable(typeof(uint));
generator.StoreVariable(arg2);
generator.StoreVariable(arg1);
generator.LoadVariable(arg1);
generator.LoadVariable(arg2);
generator.LoadVariable(arg1);
generator.LoadVariable(arg2);
generator.ReleaseTemporaryVariable(arg1);
generator.ReleaseTemporaryVariable(arg2);
}
else if (memberAccessType == TypeOfMemberAccess.Static)
{
// Named property access
generator.Duplicate();
}
else
{
// Dynamic property access
var arg1 = generator.CreateTemporaryVariable(typeof(object));
var arg2 = generator.CreateTemporaryVariable(typeof(object));
generator.StoreVariable(arg2);
generator.StoreVariable(arg1);
generator.LoadVariable(arg1);
generator.LoadVariable(arg2);
generator.LoadVariable(arg1);
generator.LoadVariable(arg2);
generator.ReleaseTemporaryVariable(arg1);
generator.ReleaseTemporaryVariable(arg2);
}
}
示例12: GenerateSet
/// <summary>
/// Stores the value on the top of the stack in the reference.
/// </summary>
/// <param name="generator"> The generator to output the CIL to. </param>
/// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
/// <param name="valueType"> The primitive type of the value that is on the top of the stack. </param>
/// <param name="throwIfUnresolvable"> <c>true</c> to throw a ReferenceError exception if
/// the name is unresolvable; <c>false</c> to create a new property instead. </param>
public void GenerateSet(ILGenerator generator, OptimizationInfo optimizationInfo, PrimitiveType valueType, bool throwIfUnresolvable)
{
string propertyName = null;
TypeOfMemberAccess memberAccessType = DetermineTypeOfMemberAccess(optimizationInfo, out propertyName);
if (memberAccessType == TypeOfMemberAccess.ArrayIndex)
{
// Array indexer
// -------------
// xxx = object[index]
// Call the indexer.
EmitConversion.ToAny(generator, valueType);
generator.LoadBoolean(optimizationInfo.StrictMode);
generator.Call(ReflectionHelpers.ObjectInstance_SetPropertyValue_Int);
}
else if (memberAccessType == TypeOfMemberAccess.Static)
{
// Named property modification (e.g. x.property = y)
// -------------------------------------------------
// __object_cacheKey = null;
// __object_property_cachedIndex = 0;
// ...
// if (__object_cacheKey != object.InlineCacheKey)
// object.InlineSetPropertyValue("property", value, strictMode, out __object_property_cachedIndex, out __object_cacheKey)
// else
// object.InlinePropertyValues[__object_property_cachedIndex] = value;
// Convert the value to an object and store it in a temporary variable.
var value = generator.CreateTemporaryVariable(typeof(object));
EmitConversion.ToAny(generator, valueType);
generator.StoreVariable(value);
// TODO: share these variables somehow.
var cacheKey = generator.DeclareVariable(typeof(object));
var cachedIndex = generator.DeclareVariable(typeof(int));
// Store the object into a temp variable.
var objectInstance = generator.DeclareVariable(PrimitiveType.Object);
generator.StoreVariable(objectInstance);
// if (__object_cacheKey != object.InlineCacheKey)
generator.LoadVariable(cacheKey);
generator.LoadVariable(objectInstance);
generator.Call(ReflectionHelpers.ObjectInstance_InlineCacheKey);
var elseClause = generator.CreateLabel();
generator.BranchIfEqual(elseClause);
// xxx = object.InlineSetPropertyValue("property", value, strictMode, out __object_property_cachedIndex, out __object_cacheKey)
generator.LoadVariable(objectInstance);
generator.LoadString(propertyName);
generator.LoadVariable(value);
generator.LoadBoolean(optimizationInfo.StrictMode);
generator.LoadAddressOfVariable(cachedIndex);
generator.LoadAddressOfVariable(cacheKey);
generator.Call(ReflectionHelpers.ObjectInstance_InlineSetPropertyValue);
var endOfIf = generator.CreateLabel();
generator.Branch(endOfIf);
// else
generator.DefineLabelPosition(elseClause);
// object.InlinePropertyValues[__object_property_cachedIndex] = value;
generator.LoadVariable(objectInstance);
generator.Call(ReflectionHelpers.ObjectInstance_InlinePropertyValues);
generator.LoadVariable(cachedIndex);
generator.LoadVariable(value);
generator.StoreArrayElement(typeof(object));
// End of the if statement
generator.DefineLabelPosition(endOfIf);
// The temporary variable is no longer needed.
generator.ReleaseTemporaryVariable(value);
}
else
{
// Dynamic property access
// -----------------------
// xxx = object.Get(x)
// Call the indexer.
EmitConversion.ToAny(generator, valueType);
generator.LoadBoolean(optimizationInfo.StrictMode);
generator.Call(ReflectionHelpers.ObjectInstance_SetPropertyValue_Object);
}
}
示例13: GenerateGet
/// <summary>
/// Pushes the value of the reference onto the stack.
/// </summary>
/// <param name="generator"> The generator to output the CIL to. </param>
/// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
/// <param name="throwIfUnresolvable"> <c>true</c> to throw a ReferenceError exception if
/// the name is unresolvable; <c>false</c> to output <c>null</c> instead. </param>
public void GenerateGet(ILGenerator generator, OptimizationInfo optimizationInfo, bool throwIfUnresolvable)
{
string propertyName = null;
TypeOfMemberAccess memberAccessType = DetermineTypeOfMemberAccess(optimizationInfo, out propertyName);
if (memberAccessType == TypeOfMemberAccess.ArrayIndex)
{
// Array indexer
// -------------
// xxx = object[index]
// Call the indexer.
generator.Call(ReflectionHelpers.ObjectInstance_GetPropertyValue_Int);
}
else if (memberAccessType == TypeOfMemberAccess.Static)
{
// Named property access (e.g. x = y.property)
// -------------------------------------------
// __object_cacheKey = null;
// __object_property_cachedIndex = 0;
// ...
// if (__object_cacheKey != object.InlineCacheKey)
// xxx = object.InlineGetPropertyValue("property", out __object_property_cachedIndex, out __object_cacheKey)
// else
// xxx = object.InlinePropertyValues[__object_property_cachedIndex];
// TODO: share these variables somehow.
var cacheKey = generator.DeclareVariable(typeof(object));
var cachedIndex = generator.DeclareVariable(typeof(int));
// Store the object into a temp variable.
var objectInstance = generator.DeclareVariable(PrimitiveType.Object);
generator.StoreVariable(objectInstance);
// if (__object_cacheKey != object.InlineCacheKey)
generator.LoadVariable(cacheKey);
generator.LoadVariable(objectInstance);
generator.Call(ReflectionHelpers.ObjectInstance_InlineCacheKey);
var elseClause = generator.CreateLabel();
generator.BranchIfEqual(elseClause);
// value = object.InlineGetProperty("property", out __object_property_cachedIndex, out __object_cacheKey)
generator.LoadVariable(objectInstance);
generator.LoadString(propertyName);
generator.LoadAddressOfVariable(cachedIndex);
generator.LoadAddressOfVariable(cacheKey);
generator.Call(ReflectionHelpers.ObjectInstance_InlineGetPropertyValue);
var endOfIf = generator.CreateLabel();
generator.Branch(endOfIf);
// else
generator.DefineLabelPosition(elseClause);
// value = object.InlinePropertyValues[__object_property_cachedIndex];
generator.LoadVariable(objectInstance);
generator.Call(ReflectionHelpers.ObjectInstance_InlinePropertyValues);
generator.LoadVariable(cachedIndex);
generator.LoadArrayElement(typeof(object));
// End of the if statement
generator.DefineLabelPosition(endOfIf);
}
else
{
// Dynamic property access
// -----------------------
// xxx = object.Get(x)
// Call Get(object)
generator.Call(ReflectionHelpers.ObjectInstance_GetPropertyValue_Object);
}
}
示例14: GenerateGet
/// <summary>
/// Pushes the value of the reference onto the stack.
/// </summary>
/// <param name="generator"> The generator to output the CIL to. </param>
/// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
/// <param name="throwIfUnresolvable"> <c>true</c> to throw a ReferenceError exception if
/// the name is unresolvable; <c>false</c> to output <c>null</c> instead. </param>
public void GenerateGet(ILGenerator generator, OptimizationInfo optimizationInfo, bool throwIfUnresolvable)
{
string propertyName = null;
bool isArrayIndex = false;
// Right-hand-side can be a property name (a.b)
if (this.OperatorType == OperatorType.MemberAccess)
{
var rhs = this.GetOperand(1) as NameExpression;
if (rhs == null)
throw new JavaScriptException(optimizationInfo.Engine, "SyntaxError", "Invalid member access", optimizationInfo.SourceSpan.StartLine, optimizationInfo.Source.Path, optimizationInfo.FunctionName);
propertyName = rhs.Name;
}
// Or a constant indexer (a['b'])
if (this.OperatorType == OperatorType.Index)
{
var rhs = this.GetOperand(1) as LiteralExpression;
if (rhs != null && (PrimitiveTypeUtilities.IsNumeric(rhs.ResultType) || rhs.ResultType == PrimitiveType.String))
{
propertyName = TypeConverter.ToString(rhs.Value);
// Or a array index (a[0])
if (rhs.ResultType == PrimitiveType.Int32 || (propertyName != null && Library.ArrayInstance.ParseArrayIndex(propertyName) != uint.MaxValue))
isArrayIndex = true;
}
}
if (isArrayIndex == true)
{
// Array indexer
// -------------
// xxx = object[index]
// Load the left-hand side and convert to an object instance.
var lhs = this.GetOperand(0);
lhs.GenerateCode(generator, optimizationInfo);
EmitConversion.ToObject(generator, lhs.ResultType, optimizationInfo);
// Load the right-hand side and convert to a uint32.
var rhs = this.GetOperand(1);
rhs.GenerateCode(generator, optimizationInfo);
EmitConversion.ToUInt32(generator, rhs.ResultType);
// Call the indexer.
generator.Call(ReflectionHelpers.ObjectInstance_GetPropertyValue_Int);
}
else if (propertyName != null)
{
//// Load the left-hand side and convert to an object instance.
//var lhs = this.GetOperand(0);
//lhs.GenerateCode(generator, optimizationInfo);
//EmitConversion.ToObject(generator, lhs.ResultType);
//// Call Get(string)
//generator.LoadString(propertyName);
//generator.Call(ReflectionHelpers.ObjectInstance_GetPropertyValue_String);
// Named property access (e.g. x = y.property)
// -------------------------------------------
// __object_cacheKey = null;
// __object_property_cachedIndex = 0;
// ...
// if (__object_cacheKey != object.InlineCacheKey)
// xxx = object.InlineGetPropertyValue("property", out __object_property_cachedIndex, out __object_cacheKey)
// else
// xxx = object.InlinePropertyValues[__object_property_cachedIndex];
// Load the left-hand side and convert to an object instance.
var lhs = this.GetOperand(0);
lhs.GenerateCode(generator, optimizationInfo);
EmitConversion.ToObject(generator, lhs.ResultType, optimizationInfo);
// TODO: share these variables somehow.
var cacheKey = generator.DeclareVariable(typeof(object));
var cachedIndex = generator.DeclareVariable(typeof(int));
// Store the object into a temp variable.
var objectInstance = generator.DeclareVariable(PrimitiveType.Object);
generator.StoreVariable(objectInstance);
// if (__object_cacheKey != object.InlineCacheKey)
generator.LoadVariable(cacheKey);
generator.LoadVariable(objectInstance);
generator.Call(ReflectionHelpers.ObjectInstance_InlineCacheKey);
var elseClause = generator.CreateLabel();
generator.BranchIfEqual(elseClause);
// value = object.InlineGetProperty("property", out __object_property_cachedIndex, out __object_cacheKey)
generator.LoadVariable(objectInstance);
generator.LoadString(propertyName);
//.........这里部分代码省略.........
示例15: ToInteger
/// <summary>
/// Pops the value on the stack, converts it to an integer, then pushes the integer result
/// onto the stack.
/// </summary>
/// <param name="generator"> The IL generator. </param>
/// <param name="fromType"> The type to convert from. </param>
public static void ToInteger(ILGenerator generator, PrimitiveType fromType)
{
// Check that a conversion is actually necessary.
if (fromType == PrimitiveType.Int32 || fromType == PrimitiveType.UInt32 || fromType == PrimitiveType.Bool)
return;
switch (fromType)
{
case PrimitiveType.Undefined:
case PrimitiveType.Null:
// Converting from undefined or null produces 0.
generator.Pop();
generator.LoadInt32(0);
break;
case PrimitiveType.Number:
// Converting from a number produces the following:
// Any number between -2147483648 and +2147483647 -> itself
// Any number smaller than -2147483648 -> -2147483648
// Any number larger than +2147483647 -> +2147483647
// NaN -> 0
// bool isPositiveInfinity = input > 2147483647.0
var isPositiveInfinity = generator.CreateTemporaryVariable(typeof(bool));
generator.Duplicate();
generator.LoadDouble(2147483647.0);
generator.CompareGreaterThan();
generator.StoreVariable(isPositiveInfinity);
// bool notNaN = input == input
var notNaN = generator.CreateTemporaryVariable(typeof(bool));
generator.Duplicate();
generator.Duplicate();
generator.CompareEqual();
generator.StoreVariable(notNaN);
// input = (int)input
// Infinity -> -2147483648
// -Infinity -> -2147483648
// NaN -> -2147483648
generator.ConvertToInteger();
// input = input & -((int)notNaN)
generator.LoadVariable(notNaN);
generator.Negate();
generator.BitwiseAnd();
// input = input - (int)isPositiveInfinity
generator.LoadVariable(isPositiveInfinity);
generator.Subtract();
// The temporary variables are no longer needed.
generator.ReleaseTemporaryVariable(notNaN);
generator.ReleaseTemporaryVariable(isPositiveInfinity);
break;
case PrimitiveType.String:
case PrimitiveType.ConcatenatedString:
case PrimitiveType.Any:
case PrimitiveType.Object:
// Otherwise, fall back to calling TypeConverter.ToInteger()
generator.Call(ReflectionHelpers.TypeConverter_ToInteger);
break;
default:
throw new NotImplementedException(string.Format("Unsupported primitive type: {0}", fromType));
}
}