本文整理汇总了C#中Jurassic.Compiler.ILGenerator.DeclareVariable方法的典型用法代码示例。如果您正苦于以下问题:C# ILGenerator.DeclareVariable方法的具体用法?C# ILGenerator.DeclareVariable怎么用?C# ILGenerator.DeclareVariable使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Jurassic.Compiler.ILGenerator
的用法示例。
在下文中一共展示了ILGenerator.DeclareVariable方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: 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);
}
示例2: GenerateCode
/// <summary>
/// Generates CIL for the statement.
/// </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)
{
// Generate code for the start of the statement.
var statementLocals = new StatementLocals();
GenerateStartOfStatement(generator, optimizationInfo, statementLocals);
// Emit the return value.
if (this.Value == null)
EmitHelpers.EmitUndefined(generator);
else
{
this.Value.GenerateCode(generator, optimizationInfo);
EmitConversion.ToAny(generator, this.Value.ResultType);
}
// Determine if this is the last statement in the function.
bool lastStatement = optimizationInfo.AbstractSyntaxTree is BlockStatement &&
((BlockStatement)optimizationInfo.AbstractSyntaxTree).Statements.Count > 0 &&
((BlockStatement)optimizationInfo.AbstractSyntaxTree).Statements[((BlockStatement)optimizationInfo.AbstractSyntaxTree).Statements.Count - 1] == this;
// The first return statement initializes the variable that holds the return value.
if (optimizationInfo.ReturnVariable == null)
optimizationInfo.ReturnVariable = generator.DeclareVariable(typeof(object), "returnValue");
// Store the return value in a variable.
generator.StoreVariable(optimizationInfo.ReturnVariable);
// There is no need to jump to the end of the function if this is the last statement.
if (lastStatement == false)
{
// The first return statement that needs to branch creates the return label. This is
// defined in FunctionmethodGenerator.GenerateCode() at the end of the function.
if (optimizationInfo.ReturnTarget == null)
optimizationInfo.ReturnTarget = generator.CreateLabel();
// Branch to the end of the function. Note: the return statement might be branching
// from inside a try { } or finally { } block to outside. EmitLongJump() handles this.
optimizationInfo.EmitLongJump(generator, optimizationInfo.ReturnTarget);
}
// Generate code for the end of the statement.
GenerateEndOfStatement(generator, optimizationInfo, statementLocals);
}
示例3: GetRegExpVariable
/// <summary>
/// Retrieves a variable that can be used to store a shared instance of a regular
/// expression.
/// </summary>
/// <param name="generator"> The IL generator used to create the variable. </param>
/// <param name="literal"> The regular expression literal. </param>
/// <returns> A varaible that can be used to store a shared instance of a regular
/// expression. </returns>
public ILLocalVariable GetRegExpVariable(ILGenerator generator, RegularExpressionLiteral literal)
{
if (literal == null)
throw new ArgumentNullException("literal");
// Create a new Dictionary if it hasn't been created before.
if (this.regularExpressionVariables == null)
this.regularExpressionVariables = new Dictionary<RegularExpressionLiteral, ILLocalVariable>();
// Check if the literal already exists in the dictionary.
ILLocalVariable variable;
if (this.regularExpressionVariables.TryGetValue(literal, out variable) == false)
{
// The literal does not exist - add it.
variable = generator.DeclareVariable(typeof(Library.RegExpInstance));
this.regularExpressionVariables.Add(literal, variable);
}
return variable;
}
示例4: 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);
}
//.........这里部分代码省略.........
示例5: 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)
{
// This method generates code to retrieve the value of a variable, given the name of
// variable and scope in which the variable is being referenced. The variable was
// not necessary declared in this scope - it might be declared in any of the parent
// scopes (together called a scope chain). The general algorithm is to start at the
// head of the chain and search backwards until the variable is found. There are
// two types of scopes: declarative scopes and object scopes. Object scopes are hard -
// it cannot be known at compile time whether the variable exists or not so runtime
// checks have to be inserted. Declarative scopes are easier - variables have to be
// declared and cannot be deleted. There is one tricky bit: new variables can be
// introduced into a declarative scope at runtime by a non-strict eval() statement.
// Even worse, variables that were introduced by means of an eval() *can* be deleted.
var scope = this.Scope;
ILLocalVariable scopeVariable = null;
var endOfGet = generator.CreateLabel();
do
{
if (scope is DeclarativeScope)
{
// The variable was declared in this scope.
var variable = scope.GetDeclaredVariable(this.Name);
if (variable != null)
{
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);
// Load the value from the variable.
generator.LoadVariable(variable.Store);
// Ensure that we match ResultType.
EmitConversion.Convert(generator, variable.Type, this.ResultType, optimizationInfo);
}
else
{
// scope.Values[index]
if (scopeVariable == null)
EmitHelpers.LoadScope(generator);
else
generator.LoadVariable(scopeVariable);
generator.CastClass(typeof(DeclarativeScope));
generator.Call(ReflectionHelpers.DeclarativeScope_Values);
generator.LoadInt32(variable.Index);
generator.LoadArrayElement(typeof(object));
}
// 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)
{
// Check the variable exists: if (scope.HasValue(variableName) == true) {
if (scopeVariable == null)
EmitHelpers.LoadScope(generator);
else
generator.LoadVariable(scopeVariable);
generator.CastClass(typeof(DeclarativeScope));
generator.LoadString(this.Name);
generator.Call(ReflectionHelpers.Scope_HasValue);
var hasValueClause = generator.CreateLabel();
generator.BranchIfFalse(hasValueClause);
// Load the value of the variable.
if (scopeVariable == null)
EmitHelpers.LoadScope(generator);
else
generator.LoadVariable(scopeVariable);
generator.CastClass(typeof(DeclarativeScope));
generator.LoadString(this.Name);
generator.Call(ReflectionHelpers.Scope_GetValue);
generator.Branch(endOfGet);
// }
generator.DefineLabelPosition(hasValueClause);
}
}
}
else
{
if (scope.ParentScope == null)
{
//.........这里部分代码省略.........
示例6: 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);
//.........这里部分代码省略.........
示例7: GenerateCode
/// <summary>
/// Generates CIL for the statement.
/// </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)
{
// Generate code for the start of the statement.
var statementLocals = new StatementLocals() { NonDefaultBreakStatementBehavior = true, NonDefaultSourceSpanBehavior = true };
GenerateStartOfStatement(generator, optimizationInfo, statementLocals);
// <initializer>
// if (<condition>)
// {
// <loop body>
// <increment>
// while (true) {
// if (<condition> == false)
// break;
//
// <body statements>
//
// continue-target:
// <increment>
// }
// }
// break-target:
// Set up some labels.
var continueTarget = generator.CreateLabel();
var breakTarget1 = generator.CreateLabel();
var breakTarget2 = generator.CreateLabel();
// Emit the initialization statement.
if (this.InitStatement != null)
this.InitStatement.GenerateCode(generator, optimizationInfo);
// Check the condition and jump to the end if it is false.
if (this.CheckConditionAtEnd == false && this.ConditionStatement != null)
{
optimizationInfo.MarkSequencePoint(generator, this.ConditionStatement.SourceSpan);
this.Condition.GenerateCode(generator, optimizationInfo);
EmitConversion.ToBool(generator, this.Condition.ResultType);
generator.BranchIfFalse(breakTarget1);
}
// Emit the loop body.
optimizationInfo.PushBreakOrContinueInfo(this.Labels, breakTarget1, continueTarget, false);
this.Body.GenerateCode(generator, optimizationInfo);
optimizationInfo.PopBreakOrContinueInfo();
// Increment the loop variable.
if (this.IncrementStatement != null)
this.IncrementStatement.GenerateCode(generator, optimizationInfo);
// Strengthen the variable types.
List<KeyValuePair<Scope.DeclaredVariable, RevertInfo>> previousVariableTypes = null;
var previousInsideTryCatchOrFinally = optimizationInfo.InsideTryCatchOrFinally;
if (optimizationInfo.OptimizeInferredTypes == true)
{
// Keep a record of the variable types before strengthening.
previousVariableTypes = new List<KeyValuePair<Scope.DeclaredVariable, RevertInfo>>();
var typedVariables = FindTypedVariables();
foreach (var variableAndType in typedVariables)
{
var variable = variableAndType.Key;
var variableInfo = variableAndType.Value;
if (variableInfo.Conditional == false && variableInfo.Type != variable.Type)
{
// Save the previous type so we can restore it later.
var previousType = variable.Type;
previousVariableTypes.Add(new KeyValuePair<Scope.DeclaredVariable, RevertInfo>(variable, new RevertInfo() { Type = previousType, Variable = variable.Store }));
// Load the existing value.
var nameExpression = new NameExpression(variable.Scope, variable.Name);
nameExpression.GenerateGet(generator, optimizationInfo, false);
// Store the typed value.
variable.Store = generator.DeclareVariable(variableInfo.Type);
variable.Type = variableInfo.Type;
nameExpression.GenerateSet(generator, optimizationInfo, previousType, false);
}
}
// The variables must be reverted even in the presence of exceptions.
if (previousVariableTypes.Count > 0)
{
generator.BeginExceptionBlock();
// Setting the InsideTryCatchOrFinally flag converts BR instructions into LEAVE
// instructions so that the finally block is executed correctly.
optimizationInfo.InsideTryCatchOrFinally = true;
}
}
// The inner loop starts here.
var startOfLoop = generator.DefineLabelPosition();
// Check the condition and jump to the end if it is false.
//.........这里部分代码省略.........
示例8: 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);
}
}
示例9: 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);
}
}
示例10: 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)
//.........这里部分代码省略.........