本文整理汇总了C#中Jurassic.Compiler.ILGenerator.Call方法的典型用法代码示例。如果您正苦于以下问题:C# ILGenerator.Call方法的具体用法?C# ILGenerator.Call怎么用?C# ILGenerator.Call使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Jurassic.Compiler.ILGenerator
的用法示例。
在下文中一共展示了ILGenerator.Call方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: 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)
{
// Generate a new method.
this.context.GenerateCode();
// Add the generated method to the nested function list.
if (optimizationInfo.NestedFunctions == null)
optimizationInfo.NestedFunctions = new List<GeneratedMethod>();
optimizationInfo.NestedFunctions.Add(this.context.GeneratedMethod);
// Add all the nested methods to the parent list.
if (this.context.GeneratedMethod.Dependencies != null)
{
foreach (var nestedFunctionExpression in this.context.GeneratedMethod.Dependencies)
optimizationInfo.NestedFunctions.Add(nestedFunctionExpression);
}
// Store the generated method in the cache.
long generatedMethodID = GeneratedMethod.Save(this.context.GeneratedMethod);
// Create a UserDefinedFunction.
// prototype
EmitHelpers.LoadScriptEngine(generator);
generator.Call(ReflectionHelpers.ScriptEngine_Function);
generator.Call(ReflectionHelpers.FunctionInstance_InstancePrototype);
// name
generator.LoadString(this.FunctionName);
// argumentNames
generator.LoadInt32(this.ArgumentNames.Count);
generator.NewArray(typeof(string));
for (int i = 0; i < this.ArgumentNames.Count; i++)
{
generator.Duplicate();
generator.LoadInt32(i);
generator.LoadString(this.ArgumentNames[i]);
generator.StoreArrayElement(typeof(string));
}
// scope
EmitHelpers.LoadScope(generator);
// bodyText
generator.LoadString(this.BodyText);
// body
generator.LoadInt64(generatedMethodID);
generator.Call(ReflectionHelpers.GeneratedMethod_Load);
// strictMode
generator.LoadBoolean(this.context.StrictMode);
// new UserDefinedFunction(ObjectInstance prototype, string name, IList<string> argumentNames, DeclarativeScope scope, Func<Scope, object, object[], object> body, bool strictMode)
generator.NewObject(ReflectionHelpers.UserDefinedFunction_Constructor);
}
示例2: ToNumber
/// <summary>
/// Pops the value on the stack, converts it to a double, then pushes the double result
/// onto the stack.
/// </summary>
/// <param name="generator"> The IL generator. </param>
/// <param name="fromType"> The type to convert from. </param>
public static void ToNumber(ILGenerator generator, PrimitiveType fromType)
{
// Check that a conversion is actually necessary.
if (fromType == PrimitiveType.Number)
return;
switch (fromType)
{
case PrimitiveType.Undefined:
// Converting from undefined produces NaN.
generator.Pop();
generator.LoadDouble(double.NaN);
break;
case PrimitiveType.Null:
// Converting from null produces 0.
generator.Pop();
generator.LoadDouble(0.0);
break;
case PrimitiveType.Bool:
// Converting from a boolean produces 0 if the boolean is false, or 1 if the boolean is true.
generator.ConvertToDouble();
break;
case PrimitiveType.Int32:
// Converting from int32 produces the same number.
generator.ConvertToDouble();
break;
case PrimitiveType.UInt32:
// Converting from a number produces the following:
generator.ConvertUnsignedToDouble();
break;
case PrimitiveType.String:
case PrimitiveType.ConcatenatedString:
case PrimitiveType.Any:
case PrimitiveType.Object:
// Otherwise, fall back to calling TypeConverter.ToNumber()
generator.Call(ReflectionHelpers.TypeConverter_ToNumber);
break;
default:
throw new NotImplementedException(string.Format("Unsupported primitive type: {0}", fromType));
}
}
示例3: 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() { NonDefaultSourceSpanBehavior = true };
GenerateStartOfStatement(generator, optimizationInfo, statementLocals);
// Unlike in .NET, in javascript there are no restrictions on what can appear inside
// try, catch and finally blocks. The one restriction which causes problems is the
// inability to jump out of .NET finally blocks. This is required when break, continue
// or return statements appear inside of a finally block. To work around this, when
// inside a finally block these instructions throw an exception instead.
// Setting the InsideTryCatchOrFinally flag converts BR instructions into LEAVE
// instructions so that the finally block is executed correctly.
var previousInsideTryCatchOrFinally = optimizationInfo.InsideTryCatchOrFinally;
optimizationInfo.InsideTryCatchOrFinally = true;
// Finally requires two exception nested blocks.
if (this.FinallyBlock != null)
generator.BeginExceptionBlock();
// Begin the exception block.
generator.BeginExceptionBlock();
// Generate code for the try block.
this.TryBlock.GenerateCode(generator, optimizationInfo);
// Generate code for the catch block.
if (this.CatchBlock != null)
{
// Begin a catch block. The exception is on the top of the stack.
generator.BeginCatchBlock(typeof(JavaScriptException));
// Create a new DeclarativeScope.
this.CatchScope.GenerateScopeCreation(generator, optimizationInfo);
// Store the error object in the variable provided.
generator.Call(ReflectionHelpers.JavaScriptException_ErrorObject);
var catchVariable = new NameExpression(this.CatchScope, this.CatchVariableName);
catchVariable.GenerateSet(generator, optimizationInfo, PrimitiveType.Any, false);
// Make sure the scope is reverted even if an exception is thrown.
generator.BeginExceptionBlock();
// Emit code for the statements within the catch block.
this.CatchBlock.GenerateCode(generator, optimizationInfo);
// Revert the scope.
generator.BeginFinallyBlock();
this.CatchScope.GenerateScopeDestruction(generator, optimizationInfo);
generator.EndExceptionBlock();
}
// Generate code for the finally block.
if (this.FinallyBlock != null)
{
generator.BeginFinallyBlock();
var branches = new List<ILLabel>();
var previousStackSize = optimizationInfo.LongJumpStackSizeThreshold;
optimizationInfo.LongJumpStackSizeThreshold = optimizationInfo.BreakOrContinueStackSize;
var previousCallback = optimizationInfo.LongJumpCallback;
optimizationInfo.LongJumpCallback = (generator2, label) =>
{
// It is not possible to branch out of a finally block - therefore instead of
// generating LEAVE instructions we throw an exception then catch it to transfer
// control out of the finally block.
generator2.LoadInt32(branches.Count);
generator2.NewObject(ReflectionHelpers.LongJumpException_Constructor);
generator2.Throw();
// Record any branches that are made within the finally code.
branches.Add(label);
};
// Emit code for the finally block.
this.FinallyBlock.GenerateCode(generator, optimizationInfo);
// End the main exception block.
generator.EndExceptionBlock();
// Begin a catch block to catch any LongJumpExceptions. The exception object is on
// the top of the stack.
generator.BeginCatchBlock(typeof(LongJumpException));
if (branches.Count > 0)
{
// switch (exception.RouteID)
// {
// case 0: goto label1;
// case 1: goto label2;
// }
ILLabel[] switchLabels = new ILLabel[branches.Count];
for (int i = 0; i < branches.Count; i++)
switchLabels[i] = generator.CreateLabel();
//.........这里部分代码省略.........
示例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: 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: GenerateScopeDestruction
/// <summary>
/// Generates code that restores the parent scope as the active scope.
/// </summary>
/// <param name="generator"> The generator to output the CIL to. </param>
/// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
internal void GenerateScopeDestruction(ILGenerator generator, OptimizationInfo optimizationInfo)
{
if (this.ExistsAtRuntime == false)
return;
// Modify the scope variable so it points at the parent scope.
EmitHelpers.LoadScope(generator);
generator.Call(ReflectionHelpers.Scope_ParentScope);
EmitHelpers.StoreScope(generator);
}
示例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 };
GenerateStartOfStatement(generator, optimizationInfo, statementLocals);
// We need a label for each case clause and one for the default case.
var jumpTargets = new ILLabel[this.CaseClauses.Count];
int defaultIndex = -1;
ILLabel endOfSwitch = generator.CreateLabel();
// Generate code for the switch value.
var startOfSwitch = generator.CreateLabel();
this.Value.GenerateCode(generator, optimizationInfo);
EmitConversion.ToAny(generator, this.Value.ResultType);
// Save the switch value in a variable.
var switchValue = generator.CreateTemporaryVariable(typeof(object));
generator.StoreVariable(switchValue);
for (int i = 0; i < this.CaseClauses.Count; i ++)
{
var caseClause = this.CaseClauses[i];
// Create a label for each clause.
jumpTargets[i] = generator.CreateLabel();
if (caseClause.Value == null)
{
// This is a default clause.
defaultIndex = i;
continue;
}
// TypeComparer.StrictEquals(switchValue, caseValue)
generator.LoadVariable(switchValue);
caseClause.Value.GenerateCode(generator, optimizationInfo);
EmitConversion.ToAny(generator, caseClause.Value.ResultType);
generator.Call(ReflectionHelpers.TypeComparer_StrictEquals);
// if (TypeComparer.StrictEquals(switchValue, caseValue) == true)
// goto case i
generator.BranchIfTrue(jumpTargets[i]);
}
// None of the cases matched, jump to the default clause or the end of the switch.
if (defaultIndex >= 0)
generator.Branch(jumpTargets[defaultIndex]);
else
generator.Branch(endOfSwitch);
for (int i = 0; i < this.CaseClauses.Count; i++)
{
// Define a label at the start of the case clause.
generator.DefineLabelPosition(jumpTargets[i]);
// Set up the information needed by the break statement.
optimizationInfo.PushBreakOrContinueInfo(this.Labels, endOfSwitch, null, labelledOnly: false);
// Emit the case clause statements.
foreach (var statement in this.CaseClauses[i].BodyStatements)
statement.GenerateCode(generator, optimizationInfo);
// Revert the information needed by the break statement.
optimizationInfo.PopBreakOrContinueInfo();
}
// Define a label for the end of the switch statement.
generator.DefineLabelPosition(endOfSwitch);
// Release the switch value variable for use elsewhere.
generator.ReleaseTemporaryVariable(switchValue);
// Generate code for the end of the statement.
GenerateEndOfStatement(generator, optimizationInfo, statementLocals);
}
示例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)
{
// Literals cannot have side-effects so if a return value is not expected then generate
// nothing.
//if (optimizationInfo.SuppressReturnValue == true)
// return;
if (this.Value is int)
generator.LoadInt32((int)this.Value);
else if (this.Value is double)
generator.LoadDouble((double)this.Value);
else if (this.Value is string)
generator.LoadString((string)this.Value);
else if (this.Value is bool)
generator.LoadBoolean((bool)this.Value);
else if (this.Value is RegularExpressionLiteral)
{
// RegExp
var sharedRegExpVariable = optimizationInfo.GetRegExpVariable(generator, (RegularExpressionLiteral)this.Value);
var label1 = generator.CreateLabel();
var label2 = generator.CreateLabel();
// if (sharedRegExp == null) {
generator.LoadVariable(sharedRegExpVariable);
generator.LoadNull();
generator.BranchIfNotEqual(label1);
// sharedRegExp = Global.RegExp.Construct(source, flags)
EmitHelpers.LoadScriptEngine(generator);
generator.Call(ReflectionHelpers.ScriptEngine_RegExp);
generator.LoadString(((RegularExpressionLiteral)this.Value).Pattern);
generator.LoadString(((RegularExpressionLiteral)this.Value).Flags);
generator.Call(ReflectionHelpers.RegExp_Construct);
generator.Duplicate();
generator.StoreVariable(sharedRegExpVariable);
// } else {
generator.Branch(label2);
generator.DefineLabelPosition(label1);
// Global.RegExp.Construct(sharedRegExp, flags)
EmitHelpers.LoadScriptEngine(generator);
generator.Call(ReflectionHelpers.ScriptEngine_RegExp);
generator.LoadVariable(sharedRegExpVariable);
generator.LoadNull();
generator.Call(ReflectionHelpers.RegExp_Construct);
// }
generator.DefineLabelPosition(label2);
}
else if (this.Value == Null.Value)
{
// Null.
EmitHelpers.EmitNull(generator);
}
else if (this.Value == Undefined.Value)
{
// Undefined.
EmitHelpers.EmitUndefined(generator);
}
else if (this.Value is List<Expression>)
{
// Construct an array literal.
var arrayLiteral = (List<Expression>)this.Value;
// Operands for ArrayConstructor.New() are: an ArrayConstructor instance (ArrayConstructor), an array (object[])
// ArrayConstructor
EmitHelpers.LoadScriptEngine(generator);
generator.Call(ReflectionHelpers.ScriptEngine_Array);
// object[]
generator.LoadInt32(arrayLiteral.Count);
generator.NewArray(typeof(object));
for (int i = 0; i < arrayLiteral.Count; i ++)
{
// Operands for StoreArrayElement() are: an array (object[]), index (int), value (object).
// Array
generator.Duplicate();
// Index
generator.LoadInt32(i);
// Value
var elementExpression = arrayLiteral[i];
if (elementExpression == null)
generator.LoadNull();
else
{
elementExpression.GenerateCode(generator, optimizationInfo);
EmitConversion.ToAny(generator, elementExpression.ResultType);
}
// Store the element value.
generator.StoreArrayElement(typeof(object));
}
//.........这里部分代码省略.........
示例9: 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>();
//.........这里部分代码省略.........
示例10: ToString
/// <summary>
/// Pops the value on the stack, converts it to a string, then pushes the result onto the
/// stack.
/// </summary>
/// <param name="generator"> The IL generator. </param>
/// <param name="fromType"> The type to convert from. </param>
public static void ToString(ILGenerator generator, PrimitiveType fromType)
{
// Check that a conversion is actually necessary.
if (fromType == PrimitiveType.String)
return;
switch (fromType)
{
case PrimitiveType.Undefined:
// Converting from undefined produces "undefined".
generator.Pop();
generator.LoadString("undefined");
break;
case PrimitiveType.Null:
// Converting from null produces "null".
generator.Pop();
generator.LoadString("null");
break;
case PrimitiveType.Bool:
// Converting from a boolean produces "false" if the boolean is false, or "true" if the boolean is true.
var elseClause = generator.CreateLabel();
var endOfIf = generator.CreateLabel();
generator.BranchIfFalse(elseClause);
generator.LoadString("true");
generator.Branch(endOfIf);
generator.DefineLabelPosition(elseClause);
generator.LoadString("false");
generator.DefineLabelPosition(endOfIf);
break;
case PrimitiveType.ConcatenatedString:
generator.Call(ReflectionHelpers.ConcatenatedString_ToString);
break;
case PrimitiveType.Int32:
case PrimitiveType.UInt32:
case PrimitiveType.Number:
case PrimitiveType.Any:
case PrimitiveType.Object:
// Otherwise, fall back to calling TypeConverter.ToString()
if (PrimitiveTypeUtilities.IsValueType(fromType))
generator.Box(fromType);
generator.Call(ReflectionHelpers.TypeConverter_ToString);
break;
default:
throw new NotImplementedException(string.Format("Unsupported primitive type: {0}", fromType));
}
}
示例11: GenerateScopeCreation
/// <summary>
/// Generates code that creates a new scope.
/// </summary>
/// <param name="generator"> The generator to output the CIL to. </param>
/// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
internal override void GenerateScopeCreation(ILGenerator generator, OptimizationInfo optimizationInfo)
{
// Create a new runtime object scope.
EmitHelpers.LoadScope(generator); // parent scope
if (this.ScopeObjectExpression == null)
{
EmitHelpers.LoadScriptEngine(generator);
generator.Call(ReflectionHelpers.ScriptEngine_Global);
}
else
{
this.ScopeObjectExpression.GenerateCode(generator, optimizationInfo);
EmitConversion.ToObject(generator, this.ScopeObjectExpression.ResultType);
}
generator.LoadBoolean(this.ProvidesImplicitThisValue);
generator.LoadBoolean(this.CanDeclareVariables);
generator.Call(ReflectionHelpers.ObjectScope_CreateRuntimeScope);
// Save the new scope.
EmitHelpers.StoreScope(generator);
}
示例12: ToPropertyKey
/// <summary>
/// Pops the value on the stack, converts it to a property key (either a symbol or a
/// string), then pushes the result onto the stack.
/// </summary>
/// <param name="generator"> The IL generator. </param>
/// <param name="fromType"> The type to convert from. </param>
public static void ToPropertyKey(ILGenerator generator, PrimitiveType fromType)
{
// Symbols are of type object.
if (fromType == PrimitiveType.Object || fromType == PrimitiveType.Any)
{
generator.Call(ReflectionHelpers.TypeConverter_ToPropertyKey);
return;
}
// Fall back to calling ToString().
ToString(generator, fromType);
}
示例13: ToPrimitive
/// <summary>
/// Pops the value on the stack, converts it to a primitive value, then pushes the result
/// onto the stack.
/// </summary>
/// <param name="generator"> The IL generator. </param>
/// <param name="fromType"> The type to convert from. </param>
/// <param name="preferredType"> Specifies whether toString() or valueOf() should be
/// preferred when converting to a primitive. </param>
public static void ToPrimitive(ILGenerator generator, PrimitiveType fromType, PrimitiveTypeHint preferredType)
{
switch (fromType)
{
case PrimitiveType.Undefined:
case PrimitiveType.Null:
case PrimitiveType.Bool:
case PrimitiveType.String:
case PrimitiveType.ConcatenatedString:
case PrimitiveType.Int32:
case PrimitiveType.UInt32:
case PrimitiveType.Number:
// These are primitives already.
break;
case PrimitiveType.Any:
case PrimitiveType.Object:
// Otherwise, fall back to calling TypeConverter.ToPrimitive()
generator.LoadInt32((int)preferredType);
generator.Call(ReflectionHelpers.TypeConverter_ToPrimitive);
break;
default:
throw new NotImplementedException(string.Format("Unsupported primitive type: {0}", fromType));
}
}
示例14: ToObject
/// <summary>
/// Pops the value on the stack, converts it to a javascript 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>
/// <param name="path"> The path of the javascript source file that is currently executing. </param>
/// <param name="function"> The name of the currently executing function. </param>
/// <param name="line"> The line number of the statement that is currently executing. </param>
public static void ToObject(ILGenerator generator, PrimitiveType fromType, string path, string function, int line)
{
// Check that a conversion is actually necessary.
if (fromType == PrimitiveType.Object)
return;
switch (fromType)
{
case PrimitiveType.Undefined:
// Converting from undefined always throws an exception.
EmitHelpers.EmitThrow(generator, ErrorType.TypeError, "Undefined cannot be converted to an object", path, function, line);
break;
case PrimitiveType.Null:
// Converting from null always throws an exception.
EmitHelpers.EmitThrow(generator, ErrorType.TypeError, "Null cannot be converted to an object", path, function, line);
break;
case PrimitiveType.Bool:
case PrimitiveType.Int32:
case PrimitiveType.UInt32:
case PrimitiveType.Number:
case PrimitiveType.String:
case PrimitiveType.ConcatenatedString:
case PrimitiveType.Any:
// Otherwise, fall back to calling TypeConverter.ToObject()
ToAny(generator, fromType);
var temp = generator.CreateTemporaryVariable(typeof(object));
generator.StoreVariable(temp);
EmitHelpers.LoadScriptEngine(generator);
generator.LoadVariable(temp);
generator.ReleaseTemporaryVariable(temp);
generator.LoadInt32(line);
generator.LoadStringOrNull(path);
generator.LoadStringOrNull(function);
generator.Call(ReflectionHelpers.TypeConverter_ToObject);
break;
default:
throw new NotImplementedException(string.Format("Unsupported primitive type: {0}", fromType));
}
}
示例15: GenerateTypeof
/// <summary>
/// Generates CIL for the typeof 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>
private void GenerateTypeof(ILGenerator generator, OptimizationInfo optimizationInfo)
{
// If a return value is not expected, generate only the side-effects.
/*if (optimizationInfo.SuppressReturnValue == true)
{
this.GenerateSideEffects(generator, optimizationInfo);
return;
}*/
if (this.Operand is NameExpression)
{
// Unresolvable references must return "undefined" rather than throw an error.
((NameExpression)this.Operand).GenerateGet(generator, optimizationInfo, false);
}
else
{
// Emit code for resolving the value of the operand.
this.Operand.GenerateCode(generator, optimizationInfo);
}
// Convert to System.Object.
EmitConversion.ToAny(generator, this.Operand.ResultType);
// Call TypeUtilities.TypeOf(operand).
generator.Call(ReflectionHelpers.TypeUtilities_TypeOf);
}