本文整理汇总了C#中Jurassic.Compiler.ILGenerator.NewObject方法的典型用法代码示例。如果您正苦于以下问题:C# ILGenerator.NewObject方法的具体用法?C# ILGenerator.NewObject怎么用?C# ILGenerator.NewObject使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Jurassic.Compiler.ILGenerator
的用法示例。
在下文中一共展示了ILGenerator.NewObject方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: EmitThrow
/// <summary>
/// Emits a JavaScriptException.
/// </summary>
/// <param name="generator"> The IL generator. </param>
/// <param name="name"> The type of error to generate. </param>
/// <param name="message"> The error message. </param>
public static void EmitThrow(ILGenerator generator, string name, string message)
{
EmitHelpers.LoadScriptEngine(generator);
generator.LoadString(name);
generator.LoadString(message);
generator.NewObject(ReflectionHelpers.JavaScriptException_Constructor_Error);
generator.Throw();
}
示例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 code to throw the given value.
this.Value.GenerateCode(generator, optimizationInfo);
EmitConversion.ToAny(generator, this.Value.ResultType);
generator.LoadInt32(0);
generator.LoadNull();
generator.NewObject(ReflectionHelpers.JavaScriptException_Constructor_Object);
generator.Throw();
// Generate code for the end of the statement.
GenerateEndOfStatement(generator, optimizationInfo, statementLocals);
}
示例3: 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)
{
// Method signature: object FunctionDelegate(Compiler.Scope scope, object thisObject, Library.FunctionInstance functionObject, object[] arguments)
// Initialize the scope (note: the initial scope for a function is always declarative).
this.InitialScope.GenerateScopeCreation(generator, optimizationInfo);
// Verify the scope is correct.
VerifyScope(generator);
// In ES3 the "this" value must be an object. See 10.4.3 in the spec.
if (this.StrictMode == false && this.MethodOptimizationHints.HasThis == true)
{
// if (thisObject == null || thisObject == Null.Value || thisObject == Undefined.Value)
EmitHelpers.LoadThis(generator);
generator.LoadNull();
generator.CompareEqual();
EmitHelpers.LoadThis(generator);
EmitHelpers.EmitNull(generator);
generator.CompareEqual();
generator.BitwiseOr();
EmitHelpers.LoadThis(generator);
EmitHelpers.EmitUndefined(generator);
generator.CompareEqual();
generator.BitwiseOr();
// {
var startOfFalse = generator.CreateLabel();
generator.BranchIfFalse(startOfFalse);
// thisObject = engine.Global;
EmitHelpers.LoadScriptEngine(generator);
generator.Call(ReflectionHelpers.ScriptEngine_Global);
// } else {
var endOfIf = generator.CreateLabel();
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;
//.........这里部分代码省略.........
示例4: GenerateDeclarations
/// <summary>
/// Generates code that initializes the variable and function declarations.
/// </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 virtual void GenerateDeclarations(ILGenerator generator, OptimizationInfo optimizationInfo)
{
// Initialize the declared variables and functions.
foreach (var variable in this.variables.Values)
{
// When a scope is reused, i.e. with an eval(), do not reinitialize the variables.
if (variable.Initialized == true)
continue;
if (variable.ValueAtTopOfScope != null)
{
// Emit the initialization code.
if (this is ObjectScope)
{
// Determine the property attributes.
var attributes = Library.PropertyAttributes.Enumerable;
if (variable.Writable == true)
attributes |= Library.PropertyAttributes.Writable;
if (variable.Deletable == true)
attributes |= Library.PropertyAttributes.Configurable;
// bool DefineProperty(string propertyName, PropertyDescriptor descriptor, bool throwOnError)
EmitHelpers.LoadScope(generator);
generator.CastClass(typeof(ObjectScope));
generator.Call(ReflectionHelpers.ObjectScope_ScopeObject);
generator.LoadString(variable.Name);
variable.ValueAtTopOfScope.GenerateCode(generator, optimizationInfo);
EmitConversion.Convert(generator, variable.ValueAtTopOfScope.ResultType, PrimitiveType.Any, optimizationInfo);
generator.LoadInt32((int)attributes);
generator.NewObject(ReflectionHelpers.PropertyDescriptor_Constructor2);
generator.LoadBoolean(false);
generator.Call(ReflectionHelpers.ObjectInstance_DefineProperty);
generator.Pop();
}
else
{
variable.ValueAtTopOfScope.GenerateCode(generator, optimizationInfo);
var name = new NameExpression(this, variable.Name);
name.GenerateSet(generator, optimizationInfo, variable.ValueAtTopOfScope.ResultType, false);
}
// Mark the variable as having been initialized.
variable.Initialized = true;
}
}
}
示例5: 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);
}
示例6: 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);
}
示例7: EmitThrow
/// <summary>
/// Emits a JavaScriptException.
/// </summary>
/// <param name="generator"> The IL generator. </param>
/// <param name="name"> The type of error to generate. </param>
/// <param name="message"> The error message. </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 EmitThrow(ILGenerator generator, string name, string message, string path, string function, int line)
{
EmitHelpers.LoadScriptEngine(generator);
generator.LoadString(name);
generator.LoadString(message);
generator.LoadInt32(line);
generator.LoadStringOrNull(path);
generator.LoadStringOrNull(function);
generator.NewObject(ReflectionHelpers.JavaScriptException_Constructor_Error);
generator.Throw();
}
示例8: GenerateIn
/// <summary>
/// Generates CIL for the in operator.
/// </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 GenerateIn(ILGenerator generator, OptimizationInfo optimizationInfo)
{
// Emit the left-hand side expression and convert it to a string.
this.Left.GenerateCode(generator, optimizationInfo);
EmitConversion.ToString(generator, this.Left.ResultType);
// Store the left-hand side expression in a temporary variable.
var temp = generator.CreateTemporaryVariable(typeof(string));
generator.StoreVariable(temp);
// Emit the right-hand side expression.
this.Right.GenerateCode(generator, optimizationInfo);
EmitConversion.ToAny(generator, this.Right.ResultType);
// Check the right-hand side is a javascript object - if not, throw an exception.
generator.IsInstance(typeof(Library.ObjectInstance));
generator.Duplicate();
var endOfTypeCheck = generator.CreateLabel();
generator.BranchIfNotNull(endOfTypeCheck);
// Throw an nicely formatted exception.
var rightValue = generator.CreateTemporaryVariable(typeof(object));
generator.StoreVariable(rightValue);
EmitHelpers.LoadScriptEngine(generator);
generator.LoadString("TypeError");
generator.LoadString("The in operator expected an object, but found '{0}' instead");
generator.LoadInt32(1);
generator.NewArray(typeof(object));
generator.Duplicate();
generator.LoadInt32(0);
generator.LoadVariable(rightValue);
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(rightValue);
// Load the left-hand side expression from the temporary variable.
generator.LoadVariable(temp);
// Call ObjectInstance.HasProperty(object)
generator.Call(ReflectionHelpers.ObjectInstance_HasProperty);
// Allow the temporary variable to be reused.
generator.ReleaseTemporaryVariable(temp);
}
示例9: GenerateCode
//.........这里部分代码省略.........
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));
}
// ArrayConstructor.New(object[])
generator.Call(ReflectionHelpers.Array_New);
}
else if (this.Value is Dictionary<string, object>)
{
// This is an object literal.
var properties = (Dictionary<string, object>)this.Value;
// Create a new object.
EmitHelpers.LoadScriptEngine(generator);
generator.Call(ReflectionHelpers.ScriptEngine_Object);
generator.Call(ReflectionHelpers.Object_Construct);
foreach (var keyValuePair in properties)
{
string propertyName = keyValuePair.Key;
object propertyValue = keyValuePair.Value;
generator.Duplicate();
generator.LoadString(propertyName);
if (propertyValue is Expression)
{
// Add a new property to the object.
var dataPropertyValue = (Expression)propertyValue;
dataPropertyValue.GenerateCode(generator, optimizationInfo);
// Support the inferred function displayName property.
if (dataPropertyValue is FunctionExpression)
((FunctionExpression)dataPropertyValue).GenerateDisplayName(generator, optimizationInfo, propertyName, false);
EmitConversion.ToAny(generator, dataPropertyValue.ResultType);
generator.LoadBoolean(optimizationInfo.StrictMode);
generator.Call(ReflectionHelpers.ObjectInstance_SetPropertyValue_String);
}
else if (propertyValue is Parser.ObjectLiteralAccessor)
{
// Add a new getter/setter to the object.
var accessorValue = (Parser.ObjectLiteralAccessor)propertyValue;
if (accessorValue.Getter != null)
{
accessorValue.Getter.GenerateCode(generator, optimizationInfo);
// Support the inferred function displayName property.
accessorValue.Getter.GenerateDisplayName(generator, optimizationInfo, "get " + propertyName, true);
EmitConversion.ToAny(generator, accessorValue.Getter.ResultType);
}
else
generator.LoadNull();
if (accessorValue.Setter != null)
{
accessorValue.Setter.GenerateCode(generator, optimizationInfo);
// Support the inferred function displayName property.
accessorValue.Setter.GenerateDisplayName(generator, optimizationInfo, "set " + propertyName, true);
EmitConversion.ToAny(generator, accessorValue.Setter.ResultType);
}
else
generator.LoadNull();
generator.LoadInt32((int)Library.PropertyAttributes.FullAccess);
generator.NewObject(ReflectionHelpers.PropertyDescriptor_Constructor3);
generator.LoadBoolean(false);
generator.Call(ReflectionHelpers.ObjectInstance_DefineProperty);
generator.Pop();
}
else
throw new InvalidOperationException("Invalid property value type in object literal.");
}
}
else
throw new NotImplementedException("Unknown literal type.");
}
示例10: ToConcatenatedString
/// <summary>
/// Pops the value on the stack, converts it to a concatenated 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 ToConcatenatedString(ILGenerator generator, PrimitiveType fromType)
{
// Check that a conversion is actually necessary.
if (fromType == PrimitiveType.ConcatenatedString)
return;
switch (fromType)
{
case PrimitiveType.Undefined:
case PrimitiveType.Null:
case PrimitiveType.Bool:
case PrimitiveType.String:
// Convert as per ToString, then create a new ConcatenatedString instance.
ToString(generator, fromType);
generator.NewObject(ReflectionHelpers.ConcatenatedString_Constructor_String);
break;
case PrimitiveType.Int32:
case PrimitiveType.UInt32:
case PrimitiveType.Number:
case PrimitiveType.Any:
case PrimitiveType.Object:
// Otherwise, fall back to calling TypeConverter.ToConcatenatedString()
if (PrimitiveTypeUtilities.IsValueType(fromType))
generator.Box(fromType);
generator.Call(ReflectionHelpers.TypeConverter_ToConcatenatedString);
break;
default:
throw new NotImplementedException(string.Format("Unsupported primitive type: {0}", fromType));
}
}
示例11: 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;
//.........这里部分代码省略.........
示例12: EmitConversionToType
/// <summary>
/// Pops the value on the stack, converts it from an object to the given type, then pushes
/// the result onto the stack.
/// </summary>
/// <param name="generator"> The IL generator. </param>
/// <param name="toType"> The type to convert to. </param>
/// <param name="convertToAddress"> <c>true</c> if the value is intended for use as an
/// instance pointer; <c>false</c> otherwise. </param>
internal static void EmitConversionToType(ILGenerator generator, Type toType, bool convertToAddress)
{
// Convert Null.Value to null if the target type is a reference type.
ILLabel endOfNullCheck = null;
if (toType.IsValueType == false)
{
var startOfElse = generator.CreateLabel();
endOfNullCheck = generator.CreateLabel();
generator.Duplicate();
EmitHelpers.EmitNull(generator);
generator.BranchIfNotEqual(startOfElse);
generator.Pop();
generator.LoadNull();
generator.Branch(endOfNullCheck);
generator.DefineLabelPosition(startOfElse);
}
switch (Type.GetTypeCode(toType))
{
case TypeCode.Boolean:
EmitConversion.ToBool(generator, PrimitiveType.Any);
break;
case TypeCode.Byte:
EmitConversion.ToInt32(generator, PrimitiveType.Any);
break;
case TypeCode.Char:
EmitConversion.ToString(generator, PrimitiveType.Any);
generator.Duplicate();
generator.Call(ReflectionHelpers.String_Length);
generator.LoadInt32(1);
var endOfCharCheck = generator.CreateLabel();
generator.BranchIfEqual(endOfCharCheck);
EmitHelpers.EmitThrow(generator, "TypeError", "Cannot convert string to char - the string must be exactly one character long");
generator.DefineLabelPosition(endOfCharCheck);
generator.LoadInt32(0);
generator.Call(ReflectionHelpers.String_GetChars);
break;
case TypeCode.DBNull:
throw new NotSupportedException("DBNull is not a supported parameter type.");
case TypeCode.Decimal:
EmitConversion.ToNumber(generator, PrimitiveType.Any);
generator.NewObject(ReflectionHelpers.Decimal_Constructor_Double);
break;
case TypeCode.Double:
EmitConversion.ToNumber(generator, PrimitiveType.Any);
break;
case TypeCode.Empty:
throw new NotSupportedException("Empty is not a supported return type.");
case TypeCode.Int16:
EmitConversion.ToInt32(generator, PrimitiveType.Any);
break;
case TypeCode.Int32:
EmitConversion.ToInt32(generator, PrimitiveType.Any);
break;
case TypeCode.Int64:
EmitConversion.ToNumber(generator, PrimitiveType.Any);
generator.ConvertToInt64();
break;
case TypeCode.DateTime:
case TypeCode.Object:
// Check if the type must be unwrapped.
generator.Duplicate();
generator.IsInstance(typeof(Jurassic.Library.ClrInstanceWrapper));
var endOfUnwrapCheck = generator.CreateLabel();
generator.BranchIfFalse(endOfUnwrapCheck);
// Unwrap the wrapped instance.
generator.Call(ReflectionHelpers.ClrInstanceWrapper_GetWrappedInstance);
generator.DefineLabelPosition(endOfUnwrapCheck);
// Value types must be unboxed.
if (toType.IsValueType == true)
{
if (convertToAddress == true)
// Unbox.
generator.Unbox(toType);
else
// Unbox and copy to the stack.
generator.UnboxAny(toType);
//// Calling methods on value required the address of the value type, not the value type itself.
//if (argument.Source == BinderArgumentSource.ThisValue && argument.Type.IsValueType == true)
//{
// var temp = generator.CreateTemporaryVariable(argument.Type);
// generator.StoreVariable(temp);
// generator.LoadAddressOfVariable(temp);
// generator.ReleaseTemporaryVariable(temp);
//}
}
//.........这里部分代码省略.........