Ejemplo n.º 1
0
        /// <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)
        {
            if (optimizationInfo.RootExpression == this)
            {
                // Return isn't in use. Do nothing.
                Left.GenerateCode(generator, optimizationInfo);
                Right.GenerateCode(generator, optimizationInfo);
                generator.Pop();
                generator.Pop();
                return;
            }

            // Dynamic resolve required (The 'Evaluate' method above diverts away otherwise).

            // Engine required:
            EmitHelpers.LoadEngine(generator);

            // Emit the object:
            Right.GenerateCode(generator, optimizationInfo);

            // Emit the left-hand side expression and convert it to a string.
            Left.GenerateCode(generator, optimizationInfo);
            EmitConversion.ToString(generator, Left.GetResultType(optimizationInfo));

            // Property name is now on the stack too.

            // Emit the property test:
            generator.Call(ReflectionHelpers.Object_HasProperty);
        }
Ejemplo n.º 2
0
        /// <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)
        {
            // Setup the method info.
            // this.context.SetupMethod(optimizationInfo);

            // Add the generated method to the nested function list.
            if (optimizationInfo.NestedFunctions == null)
            {
                optimizationInfo.NestedFunctions = new List <FunctionMethodGenerator>();
            }
            optimizationInfo.NestedFunctions.Add(context);

            // Add all the nested methods to the parent list.
            // Note: it's used to compute which variables are being hoisted.
            if (this.context.Dependencies != null)
            {
                foreach (var nestedFunctionExpression in this.context.Dependencies)
                {
                    optimizationInfo.NestedFunctions.Add(nestedFunctionExpression);
                }
            }

            if (HoistValues != null)
            {
                // Script engine:
                EmitHelpers.LoadEngine(generator);

                // Method ID:
                generator.LoadInt64(context.MethodID);

                generator.LoadInt32(HoistValues.Count);

                // Hoist vars array:
                generator.NewArray(typeof(object));

                // Load each one:
                for (int i = 0; i < HoistValues.Count; i++)
                {
                    generator.Duplicate();
                    generator.LoadInt32(i);

                    // Load the variable value:
                    Type type = HoistValues[i].Get(generator);

                    // Box if necessary:
                    EmitConversion.ToAny(generator, type);

                    generator.StoreArrayElement(typeof(object));
                }

                generator.NewObject(ReflectionHelpers.HoistFunctionReference_Constructor);
            }
            else
            {
                // body
                generator.LoadInt64(context.MethodID);
                generator.Call(ReflectionHelpers.MethodLookup_Load);
            }
        }
Ejemplo n.º 3
0
 /// <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.LoadEngine(generator);
     generator.LoadString(name);
     generator.LoadString(message);
     generator.LoadInt32(line);
     generator.LoadStringOrNull(path);
     generator.LoadStringOrNull(function);
     generator.NewObject(ReflectionHelpers.JavaScriptException_Constructor_Error);
     generator.Throw();
 }
Ejemplo n.º 4
0
 /// <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)
 {
     // Emit code to throw the given value.
     EmitHelpers.LoadEngine(generator);
     this.Value.GenerateCode(generator, optimizationInfo);
     EmitConversion.ToAny(generator, this.Value.GetResultType(optimizationInfo));
     generator.LoadInt32(1);
     generator.LoadStringOrNull(optimizationInfo.Source.Path);
     generator.LoadStringOrNull(optimizationInfo.FunctionName);
     generator.NewObject(ReflectionHelpers.JavaScriptException_Constructor_Object);
     generator.Throw();
 }
Ejemplo n.º 5
0
 /// <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>
 public static void ToPrototype(ILGenerator generator, Type fromType, string path, string function)
 {
     if (fromType == typeof(Nitrassic.Undefined))
     {
         // Converting from undefined always throws an exception.
         EmitHelpers.EmitThrow(generator, "TypeError", "Undefined cannot be converted to an object", path, function, 1);
     }
     else if (fromType == typeof(Nitrassic.Null))
     {
         // Converting from null always throws an exception.
         EmitHelpers.EmitThrow(generator, "TypeError", "Null cannot be converted to an object", path, function, 1);
     }
     else
     {
         // Otherwise, fall back to calling TypeConverter.ToPrototype()
         ToAny(generator, fromType);
         EmitHelpers.LoadEngine(generator);
         generator.Call(ReflectionHelpers.TypeConverter_ToPrototype);
     }
 }
Ejemplo n.º 6
0
        /// <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)
        {
            // Get the previous root - we'll be changing it:
            Expression prevRoot = optimizationInfo.RootExpression;

            List <string> labels = optimizationInfo.Labels;

            optimizationInfo.Labels = null;

            // Construct a loop expression.
            // var enumerator = TypeUtilities.EnumeratePropertyNames(rhs).GetEnumerator();
            // while (true) {
            //   continue-target:
            //   if (enumerator.MoveNext() == false)
            //	 goto break-target;
            //   lhs = enumerator.Current;
            //
            //   <body statements>
            // }
            // break-target:

            // Call IEnumerable<string> EnumeratePropertyNames(ScriptEngine engine, object obj)
            // optimizationInfo.MarkSequencePoint(generator, this.TargetObjectSourceSpan);
            EmitHelpers.LoadEngine(generator);
            this.TargetObject.GenerateCode(generator, optimizationInfo);
            EmitConversion.ToAny(generator, this.TargetObject.GetResultType(optimizationInfo));
            generator.Call(ReflectionHelpers.TypeUtilities_EnumeratePropertyNames);

            // Store the enumerator in a temporary variable.
            var enumerator = generator.CreateTemporaryVariable(typeof(IEnumerator <string>));

            generator.StoreVariable(enumerator);

            var breakTarget    = generator.CreateLabel();
            var continueTarget = generator.DefineLabelPosition();

            // Emit debugging information.
            // if (optimizationInfo.DebugDocument != null)
            //  generator.MarkSequencePoint(optimizationInfo.DebugDocument, this.VariableSourceSpan);

            //   if (enumerator.MoveNext() == false)
            //	 goto break-target;
            generator.LoadVariable(enumerator);
            generator.Call(ReflectionHelpers.IEnumerator_MoveNext);
            generator.BranchIfFalse(breakTarget);

            // lhs = enumerator.Current;
            this.Variable.GenerateSet(generator, optimizationInfo, false, typeof(string), delegate(bool two){
                generator.LoadVariable(enumerator);
                generator.Call(ReflectionHelpers.IEnumerator_Current);

                if (two)
                {
                    generator.Duplicate();
                }
            }, false);



            // Emit the body statement(s).
            optimizationInfo.PushBreakOrContinueInfo(labels, breakTarget, continueTarget, false);

            // Mark the body as root:
            Body.SetRoot(optimizationInfo);

            Body.GenerateCode(generator, optimizationInfo);
            optimizationInfo.PopBreakOrContinueInfo();

            generator.Branch(continueTarget);
            generator.DefineLabelPosition(breakTarget);

            // Restore root:
            optimizationInfo.RootExpression = prevRoot;
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Generates CIL for the instanceof 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 GenerateInstanceOf(ILGenerator generator, OptimizationInfo optimizationInfo)
        {
            if (optimizationInfo.RootExpression == this)
            {
                Left.GenerateCode(generator, optimizationInfo);
                Right.GenerateCode(generator, optimizationInfo);
                generator.Pop();
                generator.Pop();
                return;
            }

            // Emit the left-hand side expression and convert it to an object.
            this.Left.GenerateCode(generator, optimizationInfo);
            EmitConversion.ToAny(generator, this.Left.GetResultType(optimizationInfo));

            // Store the left-hand side expression in a temporary variable.
            var temp = generator.CreateTemporaryVariable(typeof(object));

            generator.StoreVariable(temp);

            // Emit the right-hand side expression.
            this.Right.GenerateCode(generator, optimizationInfo);
            EmitConversion.ToAny(generator, this.Right.GetResultType(optimizationInfo));

            // Check the right-hand side 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 rightValue = generator.CreateTemporaryVariable(typeof(object));

            generator.StoreVariable(rightValue);
            EmitHelpers.LoadEngine(generator);
            generator.LoadString("TypeError");
            generator.LoadString("The instanceof operator expected a function, 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(1);
            generator.LoadStringOrNull(optimizationInfo.Source.Path);
            generator.LoadStringOrNull(optimizationInfo.FunctionName);
            generator.NewObject(ReflectionHelpers.JavaScriptException_Constructor_Error);
            generator.Throw();
            generator.DefineLabelPosition(endOfTypeCheck);
            generator.ReleaseTemporaryVariable(rightValue);

            // Emit the engine for FunctionInstance_HasInstance:
            EmitHelpers.LoadEngine(generator);

            // Load the left-hand side expression from the temporary variable.
            generator.LoadVariable(temp);

            // Call FunctionInstance.HasInstance(object)
            generator.Call(ReflectionHelpers.FunctionInstance_HasInstance);

            // Allow the temporary variable to be reused.
            generator.ReleaseTemporaryVariable(temp);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Emits the arguments set.
        /// </summary>
        private void EmitArguments(ILGenerator generator, OptimizationInfo optimizationInfo)
        {
            // Get the args:
            IList <Expression> arguments        = null;
            Expression         argumentsOperand = null;

            if (OperandCount > 1)
            {
                argumentsOperand = this.GetRawOperand(1);
                ListExpression argList = argumentsOperand as ListExpression;

                if (argList != null)
                {
                    // Multiple parameters were recieved.
                    arguments = argList.Items;

                    // Set the operand to null so it doesn't try to emit it as a single arg:
                    argumentsOperand = null;
                }
            }

            int  paraCount       = 0;
            int  parameterOffset = 0;
            bool staticMethod    = false;

            System.Reflection.ParameterInfo[] paraSet = null;
            IList <ArgVariable> argsSet = null;


            if (UserDefined == null)
            {
                // - Is the first arg ScriptEngine?
                // - Does it have thisObj / does it want an instance object?
                paraSet = ResolvedMethod.GetParameters();

                paraCount = paraSet.Length;

                staticMethod = ResolvedMethod.IsStatic || ResolvedMethod.IsConstructor;

                if (paraSet.Length > 0)
                {
                    if (paraSet[0].ParameterType == typeof(ScriptEngine))
                    {
                        // Emit an engine reference now:
                        EmitHelpers.LoadEngine(generator);

                        parameterOffset++;
                    }

                    if (paraSet.Length > parameterOffset && paraSet[parameterOffset].Name == "thisObj")
                    {
                        // It's acting like an instance method.
                        parameterOffset++;
                        staticMethod = false;
                    }
                }

                if (!staticMethod)
                {
                    // Generate the 'this' ref:
                    var baseExpression = ((MemberAccessExpression)this.Target).Base;
                    baseExpression.GenerateCode(generator, optimizationInfo);
                }
            }
            else
            {
                // These are always static.
                paraCount = UserDefined.Arguments.Count;

                argsSet = UserDefined.Arguments;

                // Skip 'this' - it's emitted separately:
                parameterOffset = 1;
            }

            // Next, we're matching params starting from parameterOffset with the args,
            // type casting if needed.
            for (int i = parameterOffset; i < paraCount; i++)
            {
                Expression expression   = null;
                object     defaultValue = null;
                Type       paramType    = null;

                if (paraSet == null)
                {
                    // Get the type:
                    paramType = argsSet[i].Type;
                }
                else
                {
                    // Get the parameter info:
                    var param = paraSet[i];

                    // Get the parameters type:
                    paramType = param.ParameterType;

                    // Get the default value:
                    defaultValue = param.RawDefaultValue;

                    // Is it a params array?
                    if (Attribute.IsDefined(param, typeof(ParamArrayAttribute)))
                    {
                        // It's always an array - get the element type:
                        paramType = paramType.GetElementType();

                        // For each of the remaining args..
                        int offset = i - parameterOffset;

                        int argCount = 0;

                        if (arguments != null)
                        {
                            // Get the full count:
                            argCount = arguments.Count;
                        }
                        else if (argumentsOperand != null)
                        {
                            // Just one arg and it's still hanging around.
                            argCount = offset + 1;
                        }

                        // Define an array:
                        generator.LoadInt32(argCount);
                        generator.NewArray(paramType);

                        for (int a = offset; a < argCount; a++)
                        {
                            if (arguments != null)
                            {
                                // One of many args:
                                expression = arguments[a];
                            }
                            else
                            {
                                // Just one arg:
                                expression = argumentsOperand;
                            }

                            generator.Duplicate();
                            generator.LoadInt32(a - offset);
                            expression.GenerateCode(generator, optimizationInfo);
                            Type res = expression.GetResultType(optimizationInfo);

                            EmitConversion.Convert(generator, res, paramType);
                            generator.StoreArrayElement(paramType);
                        }

                        // All done - can't be anymore.
                        break;
                    }
                }

                if (arguments != null && (i - parameterOffset) <= arguments.Count)
                {
                    // Get one of many args:
                    expression = arguments[i - parameterOffset];
                }
                else if (argumentsOperand != null)
                {
                    // Just the one argument.
                    expression = argumentsOperand;

                    // By setting it to null after, it can't get emitted again
                    // (in the event that this method actually accepts >1 args)
                    argumentsOperand = null;
                }

                if (expression == null)
                {
                    // Emit whatever the default is for the parameters type:
                    if (defaultValue != null)
                    {
                        // Emit the default value:
                        EmitHelpers.EmitValue(generator, defaultValue);
                    }
                    else if (paramType.IsValueType)
                    {
                        // E.g. an integer 0
                        EmitHelpers.EmitValue(generator, Activator.CreateInstance(paramType));
                    }
                    else
                    {
                        // Just a null (a real one):
                        generator.LoadNull();
                    }
                }
                else if (expression is TemplateLiteralExpression)
                {
                    // Tagged template literal.
                    TemplateLiteralExpression templateLiteral = (TemplateLiteralExpression)expression;
                    GenerateTemplateArgumentsArray(generator, optimizationInfo, templateLiteral);
                    return;
                }
                else
                {
                    // Output the arg:
                    expression.GenerateCode(generator, optimizationInfo);

                    // Convert:
                    EmitConversion.Convert(generator, expression.GetResultType(optimizationInfo), paramType);
                }
            }
        }
Ejemplo n.º 9
0
        /// <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, bool rIU, Type valueType, SetValueMethod value, bool throwIfUnresolvable)
        {
            if (ResolvedProperty == null)
            {
                // Dynamic property access
                // -----------------------
                // xxx = object.Set(x)

                // Load the left-hand side:
                var lhs = this.GetOperand(0);

                // -- Begin args for Prototype.SetPropertyValue --

                // Script engine (engine):
                EmitHelpers.LoadEngine(generator);

                // Put LHS object onto stack now (thisObj):
                lhs.GenerateCode(generator, optimizationInfo);

                // What type have we now got on the stack? Typically expected to be 'object'.
                Type lhsType = lhs.GetResultType(optimizationInfo);

                // Ensure it's boxed (still thisObj):
                EmitConversion.ToAny(generator, lhsType);

                // Load the property name and convert to a string.
                var rhs = this.GetOperand(1);
                rhs.GenerateCode(generator, optimizationInfo);
                EmitConversion.ToString(generator, rhs.GetResultType(optimizationInfo));

                if (rIU)
                {
                    // Output the value now (twice):
                    value(true);

                    // We now have [obj][value][value] on the stack.
                    // Calling the set method would fail (as it'll operate on the duplicated value).
                    // So, we have to pop one off and re-add it after.

                    // In order for SetValue to work, we need to shove the 2nd copy into a temp variable.
                    ILLocalVariable localVar = generator.DeclareVariable(valueType);

                    // Store into the local:
                    generator.StoreVariable(localVar);

                    // Set the value:
                    generator.Call(ReflectionHelpers.Object_SetPropertyValue);

                    // Load from the local:
                    generator.LoadVariable(localVar);
                }
                else
                {
                    // Output the value now:
                    value(false);

                    // Set the value:
                    generator.Call(ReflectionHelpers.Object_SetPropertyValue);
                }
            }
            else if (isArrayIndex)
            {
                // Array indexer
                // -------------
                // object[index] = x

                // Load the left-hand side and convert to an object instance.
                var lhs = this.GetOperand(0);
                lhs.GenerateCode(generator, optimizationInfo);

                // Load the right-hand side and convert to int32/uint32/whatever the indexer function wants.
                var rhs = this.GetOperand(1);
                rhs.GenerateCode(generator, optimizationInfo);

                // Convert the index:
                EmitConversion.Convert(generator, rhs.GetResultType(optimizationInfo), ResolvedProperty.FirstIndexType);

                // Call set:
                ResolvedProperty.Set(generator, optimizationInfo, rIU, valueType, value);
            }
            else
            {
                // Named property modification (e.g. x.property = y)
                // -------------------------------------------------

                if (ResolvedProperty.HasEngine)
                {
                    // Emit the engine ref:
                    EmitHelpers.LoadEngine(generator);
                }

                if (ResolvedProperty.HasAccessor)
                {
                    // Load the left-hand side:
                    var lhs = GetOperand(0);
                    lhs.GenerateCode(generator, optimizationInfo);
                }

                // Target object is now on the stack.

                // Set it:
                ResolvedProperty.Set(generator, optimizationInfo, rIU, valueType, value);
            }
        }
Ejemplo n.º 10
0
        /// <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)
        {
            if (ResolvedProperty == null)
            {
                // Dynamic access.

                // optimizationInfo.TypeError("Attempted to get a property dynamically. Currently unsupported.");

                // Load the left-hand side:
                var lhs = this.GetOperand(0);

                // -- Begin args for Prototype.GetPropertyValue --

                // Script engine (engine):
                EmitHelpers.LoadEngine(generator);

                // Emit LHS to the stack (thisObj):
                lhs.GenerateCode(generator, optimizationInfo);

                // What type have we now got on the stack? Expected to be just 'object'.
                Type lhsType = lhs.GetResultType(optimizationInfo);

                // Ensure it's boxed (still thisObj):
                EmitConversion.ToAny(generator, lhsType);

                // Load the property name and convert to a string (property).
                var rhs = this.GetOperand(1);
                rhs.GenerateCode(generator, optimizationInfo);
                EmitConversion.ToString(generator, rhs.GetResultType(optimizationInfo));

                // Get the value:
                generator.Call(ReflectionHelpers.Object_GetPropertyValue);

                // Either it's now on the stack, or we threw a null ref.
            }
            else if (isArrayIndex)
            {
                // Array indexer
                // -------------
                // xxx = object[index]

                // Load the left-hand side
                var lhs = this.GetOperand(0);
                lhs.GenerateCode(generator, optimizationInfo);

                // Load the right-hand side and convert to [theTypeHere] (typically int32).
                var rhs = this.GetOperand(1);
                rhs.GenerateCode(generator, optimizationInfo);

                // Convert the index:
                EmitConversion.Convert(generator, rhs.GetResultType(optimizationInfo), ResolvedProperty.FirstIndexType);

                // Emit a get for the indexer:
                ResolvedProperty.Get(generator);
            }
            else
            {
                // Load the left-hand side and convert to an object instance.
                var lhs = this.GetOperand(0);

                if (ResolvedProperty != null)
                {
                    if (ResolvedProperty.HasEngine)
                    {
                        // Emit the engine ref:
                        EmitHelpers.LoadEngine(generator);
                    }

                    if (ResolvedProperty.HasAccessor)
                    {
                        // Emit the 'this' obj:
                        lhs.GenerateCode(generator, optimizationInfo);
                    }

                    // Emit a get:
                    ResolvedProperty.Get(generator);
                }
            }
        }
Ejemplo n.º 11
0
        /// <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.RootExpression == this)
            {
                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.OnConstruct(source, flags)
                EmitHelpers.LoadPrototypes(generator);
                generator.LoadField(ReflectionHelpers.PrototypeLookup_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.OnConstruct(sharedRegExp, flags)
                EmitHelpers.LoadPrototypes(generator);
                generator.LoadField(ReflectionHelpers.PrototypeLookup_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.LoadEngine(generator);

                // 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.GetResultType(optimizationInfo));
                    }

                    // Store the element value.
                    generator.StoreArrayElement(typeof(object));
                }

                // ArrayConstructor.New(object[])
                generator.Call(ReflectionHelpers.Array_New);
            }
            else if (this.Value is List <KeyValuePair <Expression, Expression> > )
            {
                // This is an object literal.
                var properties = (List <KeyValuePair <Expression, Expression> >) this.Value;

                // We'll generate a prototype and a custom object type for it:
                Library.Prototype proto = CreatedPrototype;

                // Create a new object.
                generator.NewObject(proto.TypeConstructor);

                foreach (var keyValuePair in properties)
                {
                    string     propertyName  = keyValuePair.Key.ToString();
                    Expression propertyValue = keyValuePair.Value;

                    // Duplicate the object ref:
                    generator.Duplicate();

                    // Add a new property to the object.

                    Type valueType = propertyValue.GetResultType(optimizationInfo);

                    // Get the property:
                    Library.PropertyVariable pv = proto.GetProperty(propertyName);

                    // Set it:
                    pv.Set(generator, optimizationInfo, false, valueType, delegate(bool two){
                        if (pv.IsConstant)
                        {
                            // Emit the constant:
                            EmitHelpers.EmitValue(generator, pv.ConstantValue);
                        }
                        else
                        {
                            // Write the value to set now:
                            propertyValue.GenerateCode(generator, optimizationInfo);
                        }

                        // Note: This one always ignores 'two'
                    });
                }
            }
            else
            {
                throw new NotImplementedException("Unknown literal type.");
            }
        }