本文整理汇总了C#中Jurassic.Compiler.ILGenerator.LoadString方法的典型用法代码示例。如果您正苦于以下问题:C# ILGenerator.LoadString方法的具体用法?C# ILGenerator.LoadString怎么用?C# ILGenerator.LoadString使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Jurassic.Compiler.ILGenerator
的用法示例。
在下文中一共展示了ILGenerator.LoadString方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的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: 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)
{
// 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 property name and convert to a string.
var rhs = this.GetOperand(1);
if (this.OperatorType == OperatorType.MemberAccess && rhs is NameExpression)
generator.LoadString((rhs as NameExpression).Name);
else
{
rhs.GenerateCode(generator, optimizationInfo);
EmitConversion.ToString(generator, rhs.ResultType);
}
// Call Delete()
generator.LoadBoolean(optimizationInfo.StrictMode);
generator.Call(ReflectionHelpers.ObjectInstance_Delete);
// If the return value is not wanted then pop it from the stack.
//if (optimizationInfo.SuppressReturnValue == true)
// generator.Pop();
}
示例3: EmitThrow
/// <summary>
/// Emits a JavaScriptException.
/// </summary>
/// <param name="generator"> The IL generator. </param>
/// <param name="type"> The type of error to generate, e.g. Error, RangeError, etc. </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, ErrorType type, string message, string path, string function, int line)
{
EmitHelpers.LoadScriptEngine(generator);
generator.LoadInt32((int)type);
generator.LoadString(message);
generator.LoadInt32(line);
generator.LoadStringOrNull(path);
generator.LoadStringOrNull(function);
generator.NewObject(ReflectionHelpers.JavaScriptException_Constructor_Error);
generator.Throw();
}
示例4: GenerateDisplayName
/// <summary>
/// Generates CIL to set the display name of the function. The function should be on top of 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="displayName"> The display name of the function. </param>
/// <param name="force"> <c>true</c> to set the displayName property, even if the function has a name already. </param>
public void GenerateDisplayName(ILGenerator generator, OptimizationInfo optimizationInfo, string displayName, bool force)
{
if (displayName == null)
throw new ArgumentNullException("displayName");
// We only infer names for functions if the function doesn't have a name.
if (force == true || string.IsNullOrEmpty(this.FunctionName))
{
// Statically set the display name.
this.context.DisplayName = displayName;
// Generate code to set the display name at runtime.
generator.Duplicate();
generator.LoadString("displayName");
generator.LoadString(displayName);
generator.LoadBoolean(false);
generator.Call(ReflectionHelpers.ObjectInstance_SetPropertyValue_String);
}
}
示例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)
{
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);
//.........这里部分代码省略.........
示例6: EmitValue
/// <summary>
/// Emits the given value. Only possible for certain types.
/// </summary>
/// <param name="generator"> The IL generator. </param>
/// <param name="value"> The value to emit. </param>
public static void EmitValue(ILGenerator generator, object value)
{
if (value == null)
generator.LoadNull();
else
{
switch (Type.GetTypeCode(value.GetType()))
{
case TypeCode.Boolean:
generator.LoadBoolean((bool)value);
break;
case TypeCode.Byte:
generator.LoadInt32((byte)value);
break;
case TypeCode.Char:
generator.LoadInt32((char)value);
break;
case TypeCode.Double:
generator.LoadDouble((double)value);
break;
case TypeCode.Int16:
generator.LoadInt32((short)value);
break;
case TypeCode.Int32:
generator.LoadInt32((int)value);
break;
case TypeCode.Int64:
generator.LoadInt64((long)value);
break;
case TypeCode.SByte:
generator.LoadInt32((sbyte)value);
break;
case TypeCode.Single:
generator.LoadDouble((float)value);
break;
case TypeCode.String:
generator.LoadString((string)value);
break;
case TypeCode.UInt16:
generator.LoadInt32((ushort)value);
break;
case TypeCode.UInt32:
generator.LoadInt32((uint)value);
break;
case TypeCode.UInt64:
generator.LoadInt64((ulong)value);
break;
case TypeCode.Object:
case TypeCode.Empty:
case TypeCode.DateTime:
case TypeCode.DBNull:
case TypeCode.Decimal:
throw new NotImplementedException(string.Format("Cannot emit the value '{0}'", value));
}
}
}
示例7: GenerateSet
//.........这里部分代码省略.........
// 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)
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);
}
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);
// Load the property name and convert to a string.
var rhs = this.GetOperand(1);
rhs.GenerateCode(generator, optimizationInfo);
EmitConversion.ToString(generator, rhs.ResultType);
// Call the indexer.
generator.LoadVariable(value);
generator.LoadBoolean(optimizationInfo.StrictMode);
generator.Call(ReflectionHelpers.ObjectInstance_SetPropertyValue_String);
}
// The temporary variable is no longer needed.
generator.ReleaseTemporaryVariable(value);
}
示例8: GenerateThis
/// <summary>
/// Generates code to push the "this" value for a function call.
/// </summary>
/// <param name="generator"> The generator to output the CIL to. </param>
public void GenerateThis(ILGenerator generator)
{
// Optimization: if there are no with scopes, simply emit undefined.
bool scopeChainHasWithScope = false;
var scope = this.Scope;
do
{
if (scope is ObjectScope && ((ObjectScope)scope).ProvidesImplicitThisValue == true)
{
scopeChainHasWithScope = true;
break;
}
scope = scope.ParentScope;
} while (scope != null);
if (scopeChainHasWithScope == false)
{
// No with scopes in the scope chain, use undefined as the "this" value.
EmitHelpers.EmitUndefined(generator);
return;
}
var end = generator.CreateLabel();
scope = this.Scope;
ILLocalVariable scopeVariable = generator.CreateTemporaryVariable(typeof(Scope));
EmitHelpers.LoadScope(generator);
generator.StoreVariable(scopeVariable);
do
{
if (scope is DeclarativeScope)
{
if (scope.HasDeclaredVariable(this.Name))
{
// The variable exists but declarative scopes always produce undefined for
// the "this" value.
EmitHelpers.EmitUndefined(generator);
break;
}
}
else
{
var objectScope = (ObjectScope)scope;
// Check if the property exists by calling scope.ScopeObject.HasProperty(propertyName)
if (objectScope.ProvidesImplicitThisValue == false)
EmitHelpers.EmitUndefined(generator);
generator.LoadVariable(scopeVariable);
generator.CastClass(typeof(ObjectScope));
generator.Call(ReflectionHelpers.ObjectScope_ScopeObject);
if (objectScope.ProvidesImplicitThisValue == true)
generator.Duplicate();
generator.LoadString(this.Name);
generator.Call(ReflectionHelpers.ObjectInstance_HasProperty);
generator.BranchIfTrue(end);
generator.Pop();
// If the name is not defined, use undefined for the "this" value.
if (scope.ParentScope == null)
{
EmitHelpers.EmitUndefined(generator);
}
}
// Try the parent scope.
if (scope.ParentScope != null && scope.ExistsAtRuntime == true)
{
generator.LoadVariable(scopeVariable);
generator.Call(ReflectionHelpers.Scope_ParentScope);
generator.StoreVariable(scopeVariable);
}
scope = scope.ParentScope;
} while (scope != null);
// Release the temporary variable.
generator.ReleaseTemporaryVariable(scopeVariable);
// Define a label at the end.
generator.DefineLabelPosition(end);
}
示例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)
{
// 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)
{
//.........这里部分代码省略.........
示例10: 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;
}
}
}
示例11: 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));
}
}
示例12: GenerateTemplateArgumentsArray
/// <summary>
/// Generates an array containing the argument values for a tagged template literal.
/// </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="templateLiteral"> The template literal expression containing the parameter
/// values. </param>
internal void GenerateTemplateArgumentsArray(ILGenerator generator, OptimizationInfo optimizationInfo, TemplateLiteralExpression templateLiteral)
{
// Generate an array containing the value of each argument.
generator.LoadInt32(templateLiteral.Values.Count + 1);
generator.NewArray(typeof(object));
// Load the first parameter.
generator.Duplicate();
generator.LoadInt32(0);
// The first parameter to the tag function is an array of strings.
var stringsExpression = new List<Expression>(templateLiteral.Strings.Count);
foreach (var templateString in templateLiteral.Strings)
{
stringsExpression.Add(new LiteralExpression(templateString));
}
new LiteralExpression(stringsExpression).GenerateCode(generator, optimizationInfo);
generator.Duplicate();
// Now we need the name of the property.
generator.LoadString("raw");
// Now generate an array of raw strings.
var rawStringsExpression = new List<Expression>(templateLiteral.RawStrings.Count);
foreach (var rawString in templateLiteral.RawStrings)
{
rawStringsExpression.Add(new LiteralExpression(rawString));
}
new LiteralExpression(rawStringsExpression).GenerateCode(generator, optimizationInfo);
// Freeze array by calling ObjectInstance Freeze(ObjectInstance).
generator.CallStatic(ReflectionHelpers.ObjectConstructor_Freeze);
// Now store the raw strings as a property of the base strings array.
generator.LoadBoolean(optimizationInfo.StrictMode);
generator.Call(ReflectionHelpers.ObjectInstance_SetPropertyValue_Object);
// Freeze array by calling ObjectInstance Freeze(ObjectInstance).
generator.CallStatic(ReflectionHelpers.ObjectConstructor_Freeze);
// Store in the array.
generator.StoreArrayElement(typeof(object));
// Values are passed as subsequent parameters.
for (int i = 0; i < templateLiteral.Values.Count; i++)
{
generator.Duplicate();
generator.LoadInt32(i + 1);
templateLiteral.Values[i].GenerateCode(generator, optimizationInfo);
EmitConversion.ToAny(generator, templateLiteral.Values[i].ResultType);
generator.StoreArrayElement(typeof(object));
}
}
示例13: 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)
{
// This code is only used for untagged template literals.
// Tagged template literals are handled by FunctionCallExpression.
// Load the values array onto the stack.
generator.LoadInt32(this.Strings.Count + this.Values.Count);
generator.NewArray(typeof(string));
for (int i = 0; i < this.Strings.Count; i++)
{
// Operands for StoreArrayElement() are: an array (string[]), index (int), value (string).
// Store the string.
generator.Duplicate();
generator.LoadInt32(i * 2);
generator.LoadString(this.Strings[i]);
generator.StoreArrayElement(typeof(string));
if (i == this.Strings.Count - 1)
break;
// Store the value.
generator.Duplicate();
generator.LoadInt32(i * 2 + 1);
this.Values[i].GenerateCode(generator, optimizationInfo);
EmitConversion.ToString(generator, this.Values[i].ResultType);
generator.StoreArrayElement(typeof(string));
}
// Call String.Concat(string[])
generator.CallStatic(ReflectionHelpers.String_Concat);
}
示例14: 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);
}
}
示例15: 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);
}
}