本文整理汇总了C#中Jurassic.Compiler.ILGenerator.LoadArrayElement方法的典型用法代码示例。如果您正苦于以下问题:C# ILGenerator.LoadArrayElement方法的具体用法?C# ILGenerator.LoadArrayElement怎么用?C# ILGenerator.LoadArrayElement使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Jurassic.Compiler.ILGenerator
的用法示例。
在下文中一共展示了ILGenerator.LoadArrayElement方法的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: 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)
{
//.........这里部分代码省略.........
示例2: GenerateStub
/// <summary>
/// Generates a method that does type conversion and calls the bound method.
/// </summary>
/// <param name="generator"> The ILGenerator used to output the body of the method. </param>
/// <param name="argumentCount"> The number of arguments that will be passed to the delegate. </param>
/// <returns> A delegate that does type conversion and calls the method represented by this
/// object. </returns>
protected override void GenerateStub(ILGenerator generator, int argumentCount)
{
// Check for the correct number of arguments.
if (argumentCount != 1)
{
EmitHelpers.EmitThrow(generator, "TypeError", "Wrong number of arguments");
EmitHelpers.EmitDefaultValue(generator, PrimitiveType.Any);
generator.Complete();
return;
}
if (this.field.IsStatic == false)
{
generator.LoadArgument(1);
ClrBinder.EmitConversionToType(generator, this.field.DeclaringType, convertToAddress: true);
}
generator.LoadArgument(2);
generator.LoadInt32(0);
generator.LoadArrayElement(typeof(object));
ClrBinder.EmitConversionToType(generator, this.field.FieldType, convertToAddress: false);
generator.StoreField(this.field);
EmitHelpers.EmitUndefined(generator);
generator.Complete();
}
示例3: GenerateCode
//.........这里部分代码省略.........
generator.Branch(endOfIf);
generator.DefineLabelPosition(startOfFalse);
// thisObject = TypeConverter.ToObject(thisObject);
EmitHelpers.LoadThis(generator);
EmitConversion.ToObject(generator, PrimitiveType.Any);
// }
generator.DefineLabelPosition(endOfIf);
EmitHelpers.StoreThis(generator);
}
// Transfer the function name into the scope.
if (string.IsNullOrEmpty(this.Name) == false &&
this.ArgumentNames.Contains(this.Name) == false &&
optimizationInfo.MethodOptimizationHints.HasVariable(this.Name))
{
EmitHelpers.LoadFunction(generator);
var functionName = new NameExpression(this.InitialScope, this.Name);
functionName.GenerateSet(generator, optimizationInfo, PrimitiveType.Any, false);
}
// Transfer the arguments object into the scope.
if (this.MethodOptimizationHints.HasArguments == true && this.ArgumentNames.Contains("arguments") == false)
{
// prototype
EmitHelpers.LoadScriptEngine(generator);
generator.Call(ReflectionHelpers.ScriptEngine_Object);
generator.Call(ReflectionHelpers.FunctionInstance_InstancePrototype);
// callee
EmitHelpers.LoadFunction(generator);
generator.CastClass(typeof(Library.UserDefinedFunction));
// scope
EmitHelpers.LoadScope(generator);
generator.CastClass(typeof(DeclarativeScope));
// argumentValues
EmitHelpers.LoadArgumentsArray(generator);
generator.NewObject(ReflectionHelpers.Arguments_Constructor);
var arguments = new NameExpression(this.InitialScope, "arguments");
arguments.GenerateSet(generator, optimizationInfo, PrimitiveType.Any, false);
}
// Transfer the argument values into the scope.
// Note: the arguments array can be smaller than expected.
if (this.ArgumentNames.Count > 0)
{
var endOfArguments = generator.CreateLabel();
for (int i = 0; i < this.ArgumentNames.Count; i++)
{
// Check if a duplicate argument name exists.
bool duplicate = false;
for (int j = i + 1; j < this.ArgumentNames.Count; j++)
if (this.ArgumentNames[i] == this.ArgumentNames[j])
{
duplicate = true;
break;
}
if (duplicate == true)
continue;
// Check if an array element exists.
EmitHelpers.LoadArgumentsArray(generator);
generator.LoadArrayLength();
generator.LoadInt32(i);
generator.BranchIfLessThanOrEqual(endOfArguments);
// Store the array element in the scope.
EmitHelpers.LoadArgumentsArray(generator);
generator.LoadInt32(i);
generator.LoadArrayElement(typeof(object));
var argument = new NameExpression(this.InitialScope, this.ArgumentNames[i]);
argument.GenerateSet(generator, optimizationInfo, PrimitiveType.Any, false);
}
generator.DefineLabelPosition(endOfArguments);
}
// Initialize any declarations.
this.InitialScope.GenerateDeclarations(generator, optimizationInfo);
//EmitHelpers.LoadScope(generator);
//EmitConversion.ToObject(generator, PrimitiveType.Any);
//generator.Pop();
// Generate code for the body of the function.
this.AbstractSyntaxTree.GenerateCode(generator, optimizationInfo);
// Define the return target - this is where the return statement jumps to.
// ReturnTarget can be null if there were no return statements.
if (optimizationInfo.ReturnTarget != null)
generator.DefineLabelPosition(optimizationInfo.ReturnTarget);
// Load the return value. If the variable is null, there were no return statements.
if (optimizationInfo.ReturnVariable != null)
// Return the value stored in the variable. Will be null if execution hits the end
// of the function without encountering any return statements.
generator.LoadVariable(optimizationInfo.ReturnVariable);
else
// There were no return statements - return null.
generator.LoadNull();
}
示例4: GenerateGet
//.........这里部分代码省略.........
// 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);
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)
// 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 property name and convert to a string.
var rhs = this.GetOperand(1);
rhs.GenerateCode(generator, optimizationInfo);
EmitConversion.ToString(generator, rhs.ResultType);
// Call Get(string)
generator.Call(ReflectionHelpers.ObjectInstance_GetPropertyValue_String);
}
}
示例5: GenerateStub
/// <summary>
/// Generates a method that does type conversion and calls the bound method.
/// </summary>
/// <param name="generator"> The ILGenerator used to output the body of the method. </param>
/// <param name="argumentCount"> The number of arguments that will be passed to the delegate. </param>
/// <returns> A delegate that does type conversion and calls the method represented by this
/// object. </returns>
protected override void GenerateStub(ILGenerator generator, int argumentCount)
{
// Here is what we are going to generate.
//private static object SampleBinder(ScriptEngine engine, object thisObject, object[] arguments)
//{
// // Target function signature: int (bool, int, string, object).
// bool param1;
// int param2;
// string param3;
// object param4;
// param1 = arguments[0] != 0;
// param2 = TypeConverter.ToInt32(arguments[1]);
// param3 = TypeConverter.ToString(arguments[2]);
// param4 = Undefined.Value;
// return thisObject.targetMethod(param1, param2, param3, param4);
//}
// Find the target method.
var binderMethod = this.buckets[Math.Min(argumentCount, this.buckets.Length - 1)];
// Constrain the number of apparent arguments to within the required bounds.
int minArgumentCount = binderMethod.RequiredParameterCount;
int maxArgumentCount = binderMethod.RequiredParameterCount + binderMethod.OptionalParameterCount;
if (binderMethod.HasParamArray == true)
maxArgumentCount = int.MaxValue;
foreach (var argument in binderMethod.GenerateArguments(generator, Math.Min(Math.Max(argumentCount, minArgumentCount), maxArgumentCount)))
{
switch (argument.Source)
{
case BinderArgumentSource.ScriptEngine:
// Load the "engine" parameter passed by the client.
generator.LoadArgument(0);
break;
case BinderArgumentSource.ThisValue:
// Load the "this" parameter passed by the client.
generator.LoadArgument(1);
bool inheritsFromObjectInstance = typeof(ObjectInstance).IsAssignableFrom(argument.Type);
if (argument.Type.IsClass == true && inheritsFromObjectInstance == false &&
argument.Type != typeof(string) && argument.Type != typeof(object))
{
// If the "this" object is an unsupported class, pass it through unmodified.
generator.CastClass(argument.Type);
}
else
{
if (argument.Type != typeof(object))
{
// If the target "this" object type is not of type object, throw an error if
// the value is undefined or null.
generator.Duplicate();
var temp = generator.CreateTemporaryVariable(typeof(object));
generator.StoreVariable(temp);
generator.LoadArgument(0);
generator.LoadVariable(temp);
generator.LoadString(binderMethod.Name);
generator.Call(ReflectionHelpers.TypeUtilities_VerifyThisObject);
generator.ReleaseTemporaryVariable(temp);
}
// Convert to the target type.
EmitTypeConversion(generator, typeof(object), argument.Type);
if (argument.Type != typeof(ObjectInstance) && inheritsFromObjectInstance == true)
{
// EmitConversionToObjectInstance can emit null if the toType is derived from ObjectInstance.
// Therefore, if the value emitted is null it means that the "thisObject" is a type derived
// from ObjectInstance (e.g. FunctionInstance) and the value provided is a different type
// (e.g. ArrayInstance). In this case, throw an exception explaining that the function is
// not generic.
var endOfThrowLabel = generator.CreateLabel();
generator.Duplicate();
generator.BranchIfNotNull(endOfThrowLabel);
generator.LoadArgument(0);
EmitHelpers.EmitThrow(generator, "TypeError", string.Format("The method '{0}' is not generic", binderMethod.Name));
generator.DefineLabelPosition(endOfThrowLabel);
}
}
break;
case BinderArgumentSource.InputParameter:
if (argument.InputParameterIndex < argumentCount)
{
// Load the argument onto the stack.
generator.LoadArgument(2);
generator.LoadInt32(argument.InputParameterIndex);
generator.LoadArrayElement(typeof(object));
// Get some flags that apply to the parameter.
var parameterFlags = JSParameterFlags.None;
var parameterAttribute = argument.GetCustomAttribute<JSParameterAttribute>();
//.........这里部分代码省略.........
示例6: GenerateEval
/// <summary>
/// Generates CIL for a call to eval().
/// </summary>
/// <param name="generator"> The generator to output the CIL to. </param>
/// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
private void GenerateEval(ILGenerator generator, OptimizationInfo optimizationInfo)
{
// engine
EmitHelpers.LoadScriptEngine(generator);
// code
if (this.OperandCount < 2)
{
// No arguments were supplied.
generator.LoadNull();
}
else
{
// Take the first argument and convert it to a string.
GenerateArgumentsArray(generator, optimizationInfo);
generator.LoadInt32(0);
generator.LoadArrayElement(typeof(object));
}
// scope
EmitHelpers.LoadScope(generator);
// thisObject
EmitHelpers.LoadThis(generator);
// strictMode
generator.LoadBoolean(optimizationInfo.StrictMode);
// Call Global.Eval(engine, code, scope, thisValue, strictMode)
generator.Call(ReflectionHelpers.Global_Eval);
}
示例7: GenerateStub
/// <summary>
/// Generates a method that does type conversion and calls the bound method.
/// </summary>
/// <param name="generator"> The ILGenerator used to output the body of the method. </param>
/// <param name="argumentCount"> The number of arguments that will be passed to the delegate. </param>
/// <returns> A delegate that does type conversion and calls the method represented by this
/// object. </returns>
protected override void GenerateStub(ILGenerator generator, int argumentCount)
{
// Determine the methods that have the correct number of arguments.
var candidateMethods = new List<BinderMethod>();
foreach (var candidateMethod in this.targetMethods)
{
if (candidateMethod.IsArgumentCountCompatible(argumentCount) == true)
candidateMethods.Add(candidateMethod);
}
// Zero candidates means no overload had the correct number of arguments.
if (candidateMethods.Count == 0)
{
EmitHelpers.EmitThrow(generator, "TypeError", string.Format("No overload for method '{0}' takes {1} arguments", this.Name, argumentCount));
EmitHelpers.EmitDefaultValue(generator, PrimitiveType.Any);
generator.Complete();
return;
}
// Select the method to call at run time.
generator.LoadInt32(candidateMethods.Count);
generator.NewArray(typeof(RuntimeMethodHandle));
for (int i = 0; i < candidateMethods.Count; i ++)
{
generator.Duplicate();
generator.LoadInt32(i);
generator.LoadToken(candidateMethods[i]);
generator.StoreArrayElement(typeof(RuntimeMethodHandle));
}
generator.LoadArgument(0);
generator.LoadArgument(1);
generator.LoadArgument(2);
generator.Call(ReflectionHelpers.BinderUtilities_ResolveOverloads);
var endOfMethod = generator.CreateLabel();
for (int i = 0; i < candidateMethods.Count; i++)
{
// Check if this is the selected method.
ILLabel endOfIf = null;
if (i < candidateMethods.Count - 1)
{
generator.Duplicate();
generator.LoadInt32(i);
endOfIf = generator.CreateLabel();
generator.BranchIfNotEqual(endOfIf);
}
generator.Pop();
var targetMethod = candidateMethods[i];
// Convert the arguments.
foreach (var argument in targetMethod.GenerateArguments(generator, argumentCount))
{
// Load the input parameter value.
switch (argument.Source)
{
case BinderArgumentSource.ScriptEngine:
generator.LoadArgument(0);
break;
case BinderArgumentSource.ThisValue:
generator.LoadArgument(1);
break;
case BinderArgumentSource.InputParameter:
generator.LoadArgument(2);
generator.LoadInt32(argument.InputParameterIndex);
generator.LoadArrayElement(typeof(object));
break;
}
// Convert to the target type.
EmitConversionToType(generator, argument.Type, convertToAddress: argument.Source == BinderArgumentSource.ThisValue);
}
// Call the target method.
targetMethod.GenerateCall(generator);
// Convert the return value.
if (targetMethod.ReturnType == typeof(void))
EmitHelpers.EmitUndefined(generator);
else
EmitConversionToObject(generator, targetMethod.ReturnType);
// Branch to the end of the method if this was the selected method.
if (endOfIf != null)
{
generator.Branch(endOfMethod);
generator.DefineLabelPosition(endOfIf);
}
}
generator.DefineLabelPosition(endOfMethod);
generator.Complete();
}
示例8: 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);
}
}