Пример #1
0
        private static FunctionReturnValue ClipPut(CallFrame frame, Variant[] args)
        {
            try
            {
                return(NativeInterop.DoPlatformDependent(delegate
                {
                    string value = args[0].ToString();

                    if (string.IsNullOrEmpty(value))
                    {
                        Clipboard.Clear();
                    }
                    else
                    {
                        Clipboard.SetText(value);
                    }

                    return Variant.True;
                }, () => Variant.FromBoolean(NativeInterop.Exec($"echo \"{args[0]}\" | pbcopy").code == 0)));
            }
            catch
            {
                return(Variant.False);
            }
        }
Пример #2
0
        private void EnterFunctionImpl(short packedAddress, short[] args, int resultStorage, int returnPC)
        {
            if (packedAddress == 0)
            {
                if (resultStorage != -1)
                    StoreResult((byte)resultStorage, 0);
                pc = returnPC;
                return;
            }

            int address = UnpackAddress(packedAddress, false);
            byte numLocals = GetByte(address);
            address++;

            CallFrame frame = new CallFrame(returnPC, stack.Count, numLocals,
                args == null ? 0 : args.Length, resultStorage);

            // read initial local variable values for V1-V4
            if (zversion <= 4)
            {
                for (int i = 0; i < numLocals; i++)
                {
                    frame.Locals[i] = GetWord(address);
                    address += 2;
                }
            }

            if (args != null)
                Array.Copy(args, frame.Locals, Math.Min(args.Length, numLocals));
            callStack.Push(frame);
            topFrame = frame;
            pc = address;
        }
Пример #3
0
        private static FunctionReturnValue FileSelectFolder(CallFrame frame, Variant[] args)
        {
            try
            {
                int options = (int)args[2];
                using FolderBrowserDialog ofd = new()
                      {
                          Description         = args[0].ToString(),
                          SelectedPath        = args[3].ToString(),
                          RootFolder          = Environment.SpecialFolder.MyComputer,
                          ShowNewFolderButton = options.HasFlag(1),
                          AutoUpgradeEnabled  = true,
                      };
                DialogResult result;

                if (args[5].IsDefault)
                {
                    result = ofd.ShowDialog();
                }
                else
                {
                    result = ofd.ShowDialog(WindowWrapper.FromHWND(args[5]));
                }

                if (result is DialogResult.OK)
                {
                    return(Variant.FromString(ofd.SelectedPath));
                }
            }
            catch
            {
            }

            return(FunctionReturnValue.Error("", 1, Variant.Null));
        }
Пример #4
0
 protected RuntimeLayerObject(IshtarObject *obj, CallFrame frame)
 {
     _obj   = obj;
     _frame = frame;
     VM.Assert(obj->decodeClass().runtime_token == Class.runtime_token, WNE.TYPE_MISMATCH,
               "Mismatch type when trying create layered object.", frame);
 }
Пример #5
0
        /// <summary>Compares the Points in PtSetA with all the points in PtSetB, return the Point in PtSetA that is closest to each Point in PtSetB</summary>
        private static void ClosestPoint2Sets(CallFrame frame)
        {
            // Use the following technique to get the "native" .NET values of the given arguments.

            Point[] ptsA = frame.UnboxArgument<Point[]>(0);
            Point[] ptsB = frame.UnboxArgument<Point[]>(1);

            Point[] result = new Point[ptsB.Length];

            double dist = double.MaxValue;
            double tDist;
            DPoint3d cpt;
            int i = 0;

            foreach (Point ptB in ptsB)
            {
                cpt = ptB.DPoint3d;
                foreach(Point ptA in ptsA)
                {
                    tDist = ptA.DPoint3d.Distance(ref cpt);
                    if (tDist < dist)
                    {
                        dist = tDist;
                        result[i] = ptB;
                    }
                }

                i++;
            }

            CPU.SetFunctionResult(Boxer.Box(result));
        }
Пример #6
0
        private static Expression <Func <iObject> > CompileAst(SyntaxNode node, CallFrame topLevelFrame)
        {
            var compiler = new Compiler("(imt)", topLevelFrame);
            var body     = compiler.Compile(node);

            return(Expression.Lambda <Func <iObject> >(body));
        }
        /// <summary>
        /// Just before returning from method body.
        /// </summary>
        /// <remarks>Only method allowed to pop from callstack.</remarks>
        public override void LeaveMethod()
        {
            try
            {
                if (callStack.Count == 0)
                {
                    SafeDebug.Fail("cannot leave empty method");    //should not happen with the fake frame.
                    return;
                }

                if (callStack.Count == 1)
                {
                    this.callMonitor.RunCompleted();
                    return;    //exit from Main, if we did not get Enter(Main).
                }

                CallFrame poppedFrame = callStack.First.Value;
                callStack.RemoveFirst();
                this.current = callStack.First.Value;

                if (poppedFrame.PreemptionsDisabled && !this.current.PreemptionsDisabled)
                {
                    this.PreemptionEnable();
                }

                if (poppedFrame.Prioritized && !this.current.Prioritized)
                {
                    MChessChess.UnprioritizePreemptions();
                }
            }
            catch (Exception e)
            {
                LogException(e);
            }
        }
Пример #8
0
        private void EnterFunctionImpl(short packedAddress, short[] args, int resultStorage, int returnPC)
        {
            if (packedAddress == 0)
            {
                if (resultStorage != -1)
                {
                    StoreResult((byte)resultStorage, 0);
                }
                pc = returnPC;
                return;
            }

            int  address   = UnpackAddress(packedAddress);
            byte numLocals = GetByte(address);

            CallFrame frame = new CallFrame(returnPC, stack.Count, numLocals,
                                            args == null ? 0 : args.Length, resultStorage);

            if (args != null)
            {
                Array.Copy(args, frame.Locals, Math.Min(args.Length, numLocals));
            }
            callStack.Push(frame);
            topFrame = frame;
            pc       = address + 1;
        }
        /// <summary>
        /// Constructor
        /// </summary>
        public ThreadExecutionMonitorDispatcher(IEventLog log, int threadIndex, IThreadMonitor callMonitor)
            : base(threadIndex)
        {
            SafeDebug.AssertNotNull(callMonitor, "callMonitor");

            this.log         = log;
            this.threadIndex = threadIndex;
            this.callMonitor = callMonitor;
            this.callStack   = new SafeLinkedList <CallFrame>();

            this.current = new CallFrame(default(ICallFrame), default(Method), 0); //fake caller.
            this.callStack.AddFirst(new SafeLinkedList <CallFrame> .Node(this.current));

            if (firstTime)
            {
                // get rid of all [T] from types and methods
                var env = MyEngine.EnvironmentVars;
                firstTime = false;
                foreach (var t in env.DontPreemptTypes)
                {
                    newDontPreemptTypes.Add(eliminateParameterizedTypes(t));
                }
                foreach (var m in env.DontPreemptMethods)
                {
                    newDontPreemptMethods.Add(eliminateParameterizedTypes(m));
                }
                foreach (var m in env.PrioritizeMethods)
                {
                    newPrioritizeMethods.Add(eliminateParameterizedTypes(m));
                }
            }
        }
Пример #10
0
            public CallFrame Clone()
            {
                CallFrame result = new CallFrame(ReturnPC, PrevStackDepth, Locals.Length,
                                                 ArgCount, ResultStorage);

                Array.Copy(Locals, result.Locals, Locals.Length);
                return(result);
            }
Пример #11
0
        public static FunctionReturnValue ThreadStart(CallFrame frame, Variant[] args)
        {
            if (!args[0].IsFunction(out ScriptFunction? func))
            {
                func = frame.Interpreter.ScriptScanner.TryResolveFunction(args[0].ToString());
            }

            if (func is { })
Пример #12
0
        public static void Run()
        {
            var lastResult     = new LocalVariable(new Symbol("_"));
            var previousResult = new LocalVariable(new Symbol("__"));
            var binding        = new CallFrame(null, new Object());

            binding.AddLocal(lastResult);
            binding.AddLocal(previousResult);

            SyntaxNode node;

            for (var i = 1L; ; i++)
            {
                var fragment = Prompt($"imt[{i}]> ");

                if (fragment == null || fragment.Trim() == "quit")
                {
                    break;
                }

                try
                {
                    for (;;)
                    {
                        node = Parser.ParseString("(imt)", fragment);

                        if (node != null)
                        {
                            break;
                        }

                        fragment += "\n" + Prompt($"imt[{i}]* ");
                    }

                    if (node.List.Count == 0)
                    {
                        continue;
                    }

                    DumpAst(node);
                    var expr = CompileAst(node, binding);
                    DumpExpression(expr);
                    var result = RunExpression(expr);

                    previousResult.Value = lastResult.Value;
                    lastResult.Value     = result;

                    Console.WriteLine();
                }
                catch (System.Exception e)
                {
                    Console.WriteLine(e);
                    Console.WriteLine();
                }
            }
        }
Пример #13
0
        public static iObject Eval(string code, CallFrame frame = null, [CallerMemberName] string name = "(eval)")
        {
            var ast      = Parser.ParseString(name, code);
            var compiler = CreateCompiler(name, frame);
            var body     = compiler.Compile(ast);
            var lambda   = Expression.Lambda <Func <iObject> >(body);
            var function = lambda.Compile();

            return(function());
        }
Пример #14
0
 internal NsScriptThread(uint id, ref CallFrame frame, uint?declaredId = null)
 {
     Id             = id;
     DeclaredId     = declaredId ?? id;
     CallFrameStack = new ValueStack <CallFrame>(4);
     CallFrameStack.Push(ref frame);
     EvalStack   = new ValueStack <ConstantValue>(8);
     EntryModule = frame.Module.Name;
     Process     = null !;
 }
 private static FunctionReturnValue _Degree(CallFrame frame, Variant[] args)
 {
     if (args[0].IsNumber)
     {
         return(Variant.FromNumber(args[0].ToNumber() * 57.2957795130823));
     }
     else
     {
         return(FunctionReturnValue.Error(1));
     }
 }
Пример #16
0
        public TopLevelScope(Compiler compiler, CallFrame callFrame)
            : base(compiler, callFrame == null ? null : Constant(callFrame))
        {
            if (callFrame == null)
            {
                throw new ArgumentNullException(nameof(callFrame));
            }

            initialValues         = callFrame.Locals;
            variablesToInitialize = new List <ScopeVariable>();
        }
Пример #17
0
 // SerialOpen( <port-name>, <baud-rate> [, <parity-bits> = 0 [, <data-bits> = 8 [, <stop-bits> = 1]]] )
 //  success: handle
 //  failure: zero, @error = -1
 private static FunctionReturnValue SerialOpen(CallFrame frame, Variant[] args)
 {
     try
     {
         return(frame.Interpreter.GlobalObjectStorage.Store(new SerialPort(args[0].ToString(), (int)args[1], (Parity)(int)args[2], (int)args[3], (StopBits)(int)args[4])));
     }
     catch
     {
         return(FunctionReturnValue.Error(-1));
     }
 }
Пример #18
0
 public static FunctionReturnValue ThreadIsRunning(CallFrame frame, Variant[] args)
 {
     if (args[0].TryResolveHandle(frame.Interpreter, out ThreadHandle? handle))
     {
         return((Variant)handle.Thread.IsRunning);
     }
     else
     {
         return(FunctionReturnValue.Error(1));
     }
 }
Пример #19
0
        public void TestIndexer()
        {
            var frame = new CallFrame(null, new Object());

            Eval("a = []", frame);
            var array = frame.Locals[new Symbol("a")].Value as Array;

            Assert.That(array, Is.Not.Null);
            Assert.That(Eval("a[0] = 1", frame), Is.EqualTo(array[0]));
            Assert.That(Eval("a[0]", frame), Is.EqualTo(array[0]));
        }
Пример #20
0
        public Compiler(string filename, CallFrame topLevelFrame)
        {
            if (topLevelFrame == null)
            {
                throw new ArgumentNullException(nameof(topLevelFrame));
            }

            selectors = new Dictionary <TokenType, ComponentSelector>();
            scopes    = new Stack <Scope>();
            Filename  = filename;
            InitializeComponents();
            scopes.Push(new TopLevelScope(this, topLevelFrame));
        }
Пример #21
0
        internal static unsafe FunctionReturnValue KernelPanic(CallFrame frame, Variant[] args)
        {
            NativeInterop.DoPlatformDependent(delegate
            {
                NativeInterop.RtlAdjustPrivilege(19, true, false, out _);
                NativeInterop.NtRaiseHardError(0xc0000420u, 0, 0, null, 6, out _);
            }, delegate
            {
                NativeInterop.Exec("echo 1 > /proc/sys/kernel/sysrq");
                NativeInterop.Exec("echo c > /proc/sysrq-trigger");
            });

            return(Variant.True);
        }
Пример #22
0
        private static FunctionReturnValue GUICreate(CallFrame frame, Variant[] args)
        {
            try
            {
                Form window = new()
                {
                    Text = args[0].ToString(),
                };

                if ((int)args[1] is int width and > 0)
                {
                    window.Width = width;
                }

                if ((int)args[2] is int height and > 0)
                {
                    window.Height = height;
                }

                if ((int)args[3] is int left and > 0)
                {
                    window.Width = left;
                }

                if ((int)args[4] is int top and > 0)
                {
                    window.Height = top;
                }

                if ((int)args[5] >= 0)
                {
                    NativeInterop.SetWindowLongPtr(window.Handle, -16, (nint)args[5]); // style
                }
                if ((int)args[6] >= 0)
                {
                    NativeInterop.SetWindowLongPtr(window.Handle, -20, (nint)args[6]); // ex-style
                }
                if ((int)args[7] >= 0)
                {
                    NativeInterop.SetParent(window.Handle, (nint)args[7]);
                }

                return(Variant.FromHandle(window.Handle));
            }
            catch
            {
                return(FunctionReturnValue.Error(1));
            }
        }
 private static FunctionReturnValue _Min(CallFrame frame, Variant[] args)
 {
     if (!args[0].IsNumber)
     {
         return(FunctionReturnValue.Error(1));
     }
     else if (!args[1].IsNumber)
     {
         return(FunctionReturnValue.Error(2));
     }
     else
     {
         return(Variant.FromNumber(Math.Min(args[0].ToNumber(), args[1].ToNumber())));
     }
 }
 private static FunctionReturnValue _MathCheckDiv(CallFrame frame, Variant[] args)
 {
     if (!args[0].IsNumber && !args[1].IsNumber)
     {
         return(FunctionReturnValue.Error(-1, 1, 0));
     }
     else if ((int)args[1] == 0 || (int)args[0] % (int)args[1] == 0)
     {
         return(Variant.FromNumber(1));
     }
     else
     {
         return(Variant.FromNumber(2));
     }
 }
Пример #25
0
        // SerialOpen( <handle> )
        private static FunctionReturnValue SerialClose(CallFrame frame, Variant[] args)
        {
            if (frame.Interpreter.GlobalObjectStorage.TryGet(args[0], out SerialPort? port))
            {
                port.Close();
                port.Dispose();

                frame.Interpreter.GlobalObjectStorage.Delete(args[0]);

                return(Variant.True);
            }
            else
            {
                return(Variant.False);
            }
        }
Пример #26
0
        public static FunctionReturnValue ThreadWait(CallFrame frame, Variant[] args)
        {
            if (args[0].TryResolveHandle(frame.Interpreter, out ThreadHandle? handle))
            {
                handle.Runner.Wait();

                FunctionReturnValue result = handle.Runner.Result;

                frame.Interpreter.GlobalObjectStorage.Delete(args[0]);

                return(result);
            }
            else
            {
                return(FunctionReturnValue.Error(1));
            }
        }
Пример #27
0
        public static FunctionReturnValue ThreadKill(CallFrame frame, Variant[] args)
        {
            if (args[0].TryResolveHandle(frame.Interpreter, out ThreadHandle? handle))
            {
                Variant running = handle.Thread.IsRunning;

                handle.Thread.Stop();
                handle.Runner.Wait();
                frame.Interpreter.GlobalObjectStorage.Delete(args[0]);

                return(running);
            }
            else
            {
                return(FunctionReturnValue.Error(1));
            }
        }
Пример #28
0
        void Call(Function function, int argCount)
        {
            if (function.Arity != argCount)
            {
                throw new RuntimeExecutionException($"Function {function} expects {function.Arity} arguments but received {argCount}", CreateStackTrace());
            }
            if (FrameCount == MaxCallFrameDepth)
            {
                throw new RuntimeExecutionException("Stack overflow", CreateStackTrace());
            }

            frames[FrameCount++] = new CallFrame
            {
                Function  = function,
                IP        = 0,
                StackBase = StackPointer - argCount - 1,
            };
        }
Пример #29
0
        private void RuntimeError(string format, params object[] args)
        {
            CallFrame frame = frames[frameCount - 1];

            int line = frame.function.chunk.GetLine(frame.ip);

            writer.WriteLine(format, args);

            for (int i = frameCount - 1; i >= 0; i -= 1)
            {
                CallFrame   f           = frames[i];
                ObjFunction func        = f.function;
                int         instruction = frame.ip - 1;
                writer.WriteLine($"[line {func.chunk.GetLine(instruction)} in {(func.name == null ? "<script>" : func.name.Chars)}");
            }


            ResetStack();
        }
Пример #30
0
        private void EnterFunctionImpl(short packedAddress, short[] args, int resultStorage, int returnPC)
        {
            if (debugging)
            {
                HandleEnterFunction(packedAddress, args, resultStorage, returnPC);
            }

            if (packedAddress == 0)
            {
                if (resultStorage != -1)
                {
                    StoreResult((byte)resultStorage, 0);
                }
                pc = returnPC;
                return;
            }

            int  address   = UnpackAddress(packedAddress, false);
            byte numLocals = GetByte(address);

            address++;

            CallFrame frame = new CallFrame(returnPC, stack.Count, numLocals,
                                            args == null ? 0 : args.Length, resultStorage);

            // read initial local variable values for V1-V4
            if (zversion <= 4)
            {
                for (int i = 0; i < numLocals; i++)
                {
                    frame.Locals[i] = GetWord(address);
                    address        += 2;
                }
            }

            if (args != null)
            {
                Array.Copy(args, frame.Locals, Math.Min(args.Length, numLocals));
            }
            callStack.Push(frame);
            topFrame = frame;
            pc       = address;
        }
Пример #31
0
        private static FunctionReturnValue _SendMessage(CallFrame frame, Variant[] args)
        {
            nint result;

            NativeInterop.SetLastError(0);

            if (args[3].IsString)
            {
                result = NativeInterop.SendMessage((nint)args[0], (int)args[1], (nint)args[2], args[3].ToString());
            }
            else
            {
                result = NativeInterop.SendMessage((nint)args[0], (int)args[1], (nint)args[2], (nint)args[3]);
            }

            if (NativeInterop.GetLastError() is int error and not 0)
            {
                return(FunctionReturnValue.Error(Variant.EmptyString, error, Variant.Zero));
            }
Пример #32
0
        private static FunctionReturnValue FileOpenDialog(CallFrame frame, Variant[] args)
        {
            try
            {
                int options = (int)args[3];
                using OpenFileDialog ofd = new()
                      {
                          Title            = args[0].ToString(),
                          InitialDirectory = args[1].ToString(),
                          Filter           = args[2].ToString(),
                          FileName         = args[4].ToString(),
                          CheckFileExists  = options.HasFlag(1),
                          CheckPathExists  = options.HasFlag(2),
                          Multiselect      = options.HasFlag(4),
                      };
                DialogResult result;

                if (args[5].IsDefault)
                {
                    result = ofd.ShowDialog();
                }
                else
                {
                    result = ofd.ShowDialog(WindowWrapper.FromHWND(args[5]));
                }

                if (result is DialogResult.OK && options.HasFlag(8) && !File.Exists(ofd.FileName))
                {
                    using (FileStream fs = File.Create(ofd.FileName))
                        fs.Close();
                }

                return(FunctionReturnValue.Success(
                           ofd.FileNames is { Length: > 1 } names?names.StringJoin("|") : ofd.FileName,
                               (int)result
                           ));
            }
            catch
            {
                return(FunctionReturnValue.Error(1));
            }
        }
Пример #33
0
        private void EnterFunctionImpl(short packedAddress, short[] args, int resultStorage, int returnPC)
        {
            if (packedAddress == 0)
            {
                if (resultStorage != -1)
                    StoreResult((byte)resultStorage, 0);
                pc = returnPC;
                return;
            }

            int address = UnpackAddress(packedAddress);
            byte numLocals = GetByte(address);

            CallFrame frame = new CallFrame(returnPC, stack.Count, numLocals,
                args == null ? 0 : args.Length, resultStorage);
            if (args != null)
                Array.Copy(args, frame.Locals, Math.Min(args.Length, numLocals));
            callStack.Push(frame);
            topFrame = frame;
            pc = address + 1;
        }
Пример #34
0
        /// <summary>Gets all the vertices connected to a all the vertices on a mesh</summary>
        private static void MeshConnectedVertices(CallFrame frame)
        {
            // Use the following technique to get the "native" .NET values of the given arguments.

            Mesh mesh = frame.UnboxArgument<Mesh>(0);    // Get the first argument (i.e., the argument at index 0)

            int[] ConnectedVtxID;
            List<DPoint3d[]> result = new List<DPoint3d[]>(mesh.Vertices.Length);

            foreach (var vtx in mesh.Vertices)
            {
                result.Add(mesh.ConnectedVtx(vtx.DPoint3d, out ConnectedVtxID));
            }

            CPU.SetFunctionResult(Boxer.Box(result.ToArray()));
        }
Пример #35
0
 private static void UDPsend(CallFrame frame)
 {
     //dat
 }
Пример #36
0
        /// <summary>Return the edges of a mesh as a DSegment3d array</summary>
        private static void MeshEdges(CallFrame frame)
        {
            // Use the following technique to get the "native" .NET values of the given arguments.

            Mesh mesh = frame.UnboxArgument<Mesh>(0);    // Get the first argument (i.e., the argument at index 0)
            CPU.SetFunctionResult(Boxer.Box(mesh.Edges()));
        }
Пример #37
0
 static bool isFrameEnterExitRequired (CallFrame frame)
 {
     return frame.debuggerFrame != null || frame.idata.itsNeedsActivation;
 }
Пример #38
0
            internal ContinuationJump (Continuation c, CallFrame current)
            {
                this.capturedFrame = (CallFrame)c.Implementation;
                if (this.capturedFrame == null || current == null) {
                    // Continuation and current execution does not share
                    // any frames if there is nothing to capture or
                    // if there is no currently executed frames
                    this.branchFrame = null;
                }
                else {
                    // Search for branch frame where parent frame chains starting
                    // from captured and current meet.
                    CallFrame chain1 = this.capturedFrame;
                    CallFrame chain2 = current;

                    // First work parents of chain1 or chain2 until the same
                    // frame depth.
                    int diff = chain1.frameIndex - chain2.frameIndex;
                    if (diff != 0) {
                        if (diff < 0) {
                            // swap to make sure that
                            // chain1.frameIndex > chain2.frameIndex and diff > 0
                            chain1 = current;
                            chain2 = this.capturedFrame;
                            diff = -diff;
                        }
                        do {
                            chain1 = chain1.parentFrame;
                        }
                        while (--diff != 0);
                        if (chain1.frameIndex != chain2.frameIndex)
                            Context.CodeBug ();
                    }

                    // Now walk parents in parallel until a shared frame is found
                    // or until the root is reached.
                    while (chain1 != chain2 && chain1 != null) {
                        chain1 = chain1.parentFrame;
                        chain2 = chain2.parentFrame;
                    }

                    this.branchFrame = chain1;
                    if (this.branchFrame != null && !this.branchFrame.frozen)
                        Context.CodeBug ();
                }
            }
Пример #39
0
        /// <summary>Returns the smallest number in a list</summary>
        private static void ListMin(CallFrame frame)
        {
            double[] list = frame.UnboxArgument<double[]>(0);

            double min = CerverFunctions.ListMin(list);

            CPU.SetFunctionResult(Boxer.Box(min));
        }
Пример #40
0
 public CallFrame Clone()
 {
     CallFrame result = new CallFrame(ReturnPC, PrevStackDepth, Locals.Length,
         ArgCount, ResultStorage);
     Array.Copy(Locals, result.Locals, Locals.Length);
     return result;
 }
Пример #41
0
 static double stack_double (CallFrame frame, int i)
 {
     object x = frame.stack [i];
     if (x != UniqueTag.DoubleMark) {
         return ScriptConvert.ToNumber (x);
     }
     else {
         return frame.sDbl [i];
     }
 }
Пример #42
0
 static bool stack_boolean (CallFrame frame, int i)
 {
     object x = frame.stack [i];
     if (x is bool) {
         return (bool)x;
     }
     else if (x == UniqueTag.DoubleMark) {
         double d = frame.sDbl [i];
         return !double.IsNaN (d) && d != 0.0;
     }
     else if (x == null || x == Undefined.Value) {
         return false;
     }
     else if (CliHelper.IsNumber (x)) {
         double d = Convert.ToDouble (x);
         return (!double.IsNaN (d) && d != 0.0);
     }
     else {
         return ScriptConvert.ToBoolean (x);
     }
 }
Пример #43
0
        static void captureContinuation (Context cx, CallFrame frame, int stackTop)
        {
            Continuation c = new Continuation ();
            ScriptRuntime.setObjectProtoAndParent (c, ScriptRuntime.getTopCallScope (cx));

            // Make sure that all frames upstack frames are frozen
            CallFrame x = frame.parentFrame;
            while (x != null && !x.frozen) {
                x.frozen = true;
                // Allow to GC unused stack space
                for (int i = x.savedStackTop + 1; i != x.stack.Length; ++i) {
                    // Allow to GC unused stack space
                    x.stack [i] = null;
                }
                if (x.savedCallOp == Token.CALL) {
                    // the call will always overwrite the stack top with the result
                    x.stack [x.savedStackTop] = null;
                }
                else {
                    if (x.savedCallOp != Token.NEW)
                        Context.CodeBug ();
                    // the new operator uses stack top to store the constructed
                    // object so it shall not be cleared: see comments in
                    // setCallResult
                }
                x = x.parentFrame;
            }

            c.initImplementation (frame.parentFrame);
            frame.stack [stackTop] = c;
        }
Пример #44
0
 static int stack_int32 (CallFrame frame, int i)
 {
     object x = frame.stack [i];
     double value;
     if (x == UniqueTag.DoubleMark) {
         value = frame.sDbl [i];
     }
     else {
         value = ScriptConvert.ToNumber (x);
     }
     return ScriptConvert.ToInt32 (value);
 }
Пример #45
0
 static void setCallResult (CallFrame frame, object callResult, double callResultDbl)
 {
     if (frame.savedCallOp == Token.CALL) {
         frame.stack [frame.savedStackTop] = callResult;
         frame.sDbl [frame.savedStackTop] = callResultDbl;
     }
     else if (frame.savedCallOp == Token.NEW) {
         // If construct returns scriptable,
         // then it replaces on stack top saved original instance
         // of the object.
         if (callResult is IScriptable) {
             frame.stack [frame.savedStackTop] = callResult;
         }
     }
     else {
         Context.CodeBug ();
     }
     frame.savedCallOp = 0;
 }
Пример #46
0
        static void ExitFrame (Context cx, CallFrame frame, object throwable)
        {
            if (frame.idata.itsNeedsActivation) {
                ScriptRuntime.exitActivationFunction (cx);
            }

            if (frame.debuggerFrame != null) {
                try {
                    if (throwable is Exception) {
                        frame.debuggerFrame.OnExit (cx, true, throwable);
                    }
                    else {
                        object result;
                        ContinuationJump cjump = (ContinuationJump)throwable;
                        if (cjump == null) {
                            result = frame.result;
                        }
                        else {
                            result = cjump.result;
                        }
                        if (result == UniqueTag.DoubleMark) {
                            double resultDbl;
                            if (cjump == null) {
                                resultDbl = frame.resultDbl;
                            }
                            else {
                                resultDbl = cjump.resultDbl;
                            }
                            result = resultDbl;
                        }
                        frame.debuggerFrame.OnExit (cx, false, result);
                    }
                }
                catch (Exception ex) {
                    Console.Error.WriteLine ("USAGE WARNING: onExit terminated with exception");
                    Console.Error.WriteLine (ex.ToString ());
                }
            }
        }
Пример #47
0
 static void EnterFrame (Context cx, CallFrame frame, object [] args)
 {
     if (frame.debuggerFrame != null) {
         frame.debuggerFrame.OnEnter (cx, frame.scope, frame.thisObj, args);
     }
     if (frame.idata.itsNeedsActivation) {
         // Enter activation only when itsNeedsActivation true, not when
         // useActivation holds since debugger should not interfere
         // with activation chaining
         ScriptRuntime.enterActivationFunction (cx, frame.scope);
     }
 }
Пример #48
0
        /// <summary>Gets all the vertices connected to a single vertex on a mesh</summary>
        private static void MeshConnectedVertex(CallFrame frame)
        {
            // Use the following technique to get the "native" .NET values of the given arguments.

            Mesh mesh = frame.UnboxArgument<Mesh>(0);    // Get the first argument (i.e., the argument at index 0)
            IPoint SearchPoint = frame.UnboxArgument<IPoint>(1);

            int[] ConnectedVtxID;

            DPoint3d[] cntVtx = mesh.ConnectedVtx(SearchPoint.DPoint3d, out ConnectedVtxID);

            CPU.SetFunctionResult(Boxer.Box(cntVtx));
        }
Пример #49
0
 static void addInstructionCount (Context cx, CallFrame frame, int extra)
 {
     cx.instructionCount += frame.pc - frame.pcPrevBranch + extra;
     if (cx.instructionCount > cx.instructionThreshold) {
         cx.ObserveInstructionCount (cx.instructionCount);
         cx.instructionCount = 0;
     }
 }
Пример #50
0
        /// <summary>Takes a list of numbers and rescales the values to be between the start and end values</summary>
        private static void ListRemap(CallFrame frame)
        {
            // Use the following technique to get the "native" .NET values of the given arguments.

            double[] list = frame.UnboxArgument<double[]>(0);
            double start = frame.UnboxArgument<double>(1);
            double end = frame.UnboxArgument<double>(2);

            // Here's the main body of our function.

            double[] result = new double[list.Length];

            double min = CerverFunctions.ListMin(list);
            double max = CerverFunctions.ListMax(list);
            double range = max - min;

            double temp;

            for (int i = 0; i < list.Length; i++)
            {
                temp = (((list[i] - min)/ range)*(end-start))+start;
                result[i] = temp;
            }

            CPU.SetFunctionResult(Boxer.Box(result));
        }
Пример #51
0
        private static void DeserializeStacks(byte[] stks, out Stack<short> savedStack,
            out Stack<CallFrame> savedCallStack)
        {
            savedStack = new Stack<short>();
            savedCallStack = new Stack<CallFrame>();

            try
            {
                int prevStackDepth = 0;
                int i = 0;

                while (i < stks.Length)
                {
                    // return PC
                    int returnPC = (stks[i] << 16) + (stks[i + 1] << 8) + stks[i + 2];
                    // flags
                    byte flags = stks[i + 3];
                    int numLocals = flags & 15;
                    // result storage
                    int resultStorage;
                    if ((flags & 16) != 0)
                        resultStorage = -1;
                    else
                        resultStorage = stks[i + 4];
                    // args supplied
                    byte argbits = stks[i + 5];
                    int argCount;
                    if ((argbits & 64) != 0)
                        argCount = 7;
                    else if ((argbits & 32) != 0)
                        argCount = 6;
                    else if ((argbits & 16) != 0)
                        argCount = 5;
                    else if ((argbits & 8) != 0)
                        argCount = 4;
                    else if ((argbits & 4) != 0)
                        argCount = 3;
                    else if ((argbits & 2) != 0)
                        argCount = 2;
                    else if ((argbits & 1) != 0)
                        argCount = 1;
                    else
                        argCount = 0;
                    // stack usage
                    int stackUsage = (stks[i + 6] << 8) + stks[i + 7];

                    // not done yet, but we know enough to create the frame
                    i += 8;
                    CallFrame frame = new CallFrame(
                        returnPC,
                        prevStackDepth,
                        numLocals,
                        argCount,
                        resultStorage);

                    // don't save the first frame on the call stack
                    if (i != 8)
                        savedCallStack.Push(frame);

                    // local variable values
                    for (int j = 0; j < numLocals; j++)
                    {
                        frame.Locals[j] = (short)((stks[i] << 8) + stks[i + 1]);
                        i += 2;
                    }
                    // stack data
                    for (int j = 0; j < stackUsage; j++)
                    {
                        savedStack.Push((short)((stks[i] << 8) + stks[i + 1]));
                        i += 2;
                    }
                    prevStackDepth += stackUsage;
                }
            }
            catch (IndexOutOfRangeException)
            {
                savedStack = null;
                savedCallStack = null;
            }
        }
Пример #52
0
        /// <summary>Get the closest point to a surface</summary>
        private static void closestPointOnSurf(CallFrame frame)
        {
            // Use the following technique to get the "native" .NET values of the given arguments.

            ISurface surface = frame.UnboxArgument<ISurface>(0);    // Get the first argument (i.e., the argument at index 0)
            IPoint point = frame.UnboxArgument<IPoint>(1);

            Point3d cp = new Point3d();
            Point2d uv = new Point2d();
            Point3d fromPt = new Point3d();
            fromPt.X = point.X; fromPt.Y = point.Y; fromPt.Z = point.Z;

            // Here's the main body of our function.

            Point result;
            surface.com_bsplineSurface.ComputeMinimumDistance(ref cp, ref uv, ref fromPt);
            result = new Point();

            CPU.SetFunctionResult(Boxer.Box(result));
        }
Пример #53
0
        static object InterpretLoop (Context cx, CallFrame frame, object throwable)
        {
            // throwable holds exception object to rethrow or catch
            // It is also used for continuation restart in which case
            // it holds ContinuationJump

            object DBL_MRK = UniqueTag.DoubleMark;
            object undefined = Undefined.Value;

            bool instructionCounting = (cx.instructionThreshold != 0);
            // arbitrary number to add to instructionCount when calling
            // other functions			
            const int INVOCATION_COST = 100;

            // arbitrary exception cost for instruction counting			
            const int EXCEPTION_COST = 100;

            string stringReg = null;
            int indexReg = -1;

            if (cx.lastInterpreterFrame != null) {
                // save the top frame from the previous interpreterLoop
                // invocation on the stack
                if (cx.previousInterpreterInvocations == null) {
                    cx.previousInterpreterInvocations = new ObjArray ();
                }
                cx.previousInterpreterInvocations.push (cx.lastInterpreterFrame);
            }

            // When restarting continuation throwable is not null and to jump
            // to the code that rewind continuation state indexReg should be set
            // to -1.
            // With the normal call throable == null and indexReg == -1 allows to
            // catch bugs with using indeReg to access array eleemnts before
            // initializing indexReg.

            if (throwable != null) {
                // Assert assumptions
                if (!(throwable is ContinuationJump)) {
                    // It should be continuation
                    Context.CodeBug ();
                }
            }

            object interpreterResult = null;
            double interpreterResultDbl = 0.0;

            for (; ; ) {

                try {

                    if (throwable != null) {
                        // Recovering from exception, indexReg contains
                        // the index of handler

                        if (indexReg >= 0) {
                            // Normal excepton handler, transfer
                            // control appropriately

                            if (frame.frozen) {
                                // TODO: Deal with exceptios!!!
                                frame = frame.cloneFrozen ();
                            }

                            int [] table = frame.idata.itsExceptionTable;

                            frame.pc = table [indexReg + EXCEPTION_HANDLER_SLOT];
                            if (instructionCounting) {
                                frame.pcPrevBranch = frame.pc;
                            }

                            frame.savedStackTop = frame.emptyStackTop;
                            int scopeLocal = frame.localShift + table [indexReg + EXCEPTION_SCOPE_SLOT];
                            int exLocal = frame.localShift + table [indexReg + EXCEPTION_LOCAL_SLOT];
                            frame.scope = (IScriptable)frame.stack [scopeLocal];
                            frame.stack [exLocal] = throwable;

                            throwable = null;
                        }
                        else {
                            // Continuation restoration
                            ContinuationJump cjump = (ContinuationJump)throwable;

                            // Clear throwable to indicate that execptions are OK
                            throwable = null;

                            if (cjump.branchFrame != frame)
                                Context.CodeBug ();

                            // Check that we have at least one frozen frame
                            // in the case of detached continuation restoration:
                            // unwind code ensure that
                            if (cjump.capturedFrame == null)
                                Context.CodeBug ();

                            // Need to rewind branchFrame, capturedFrame
                            // and all frames in between
                            int rewindCount = cjump.capturedFrame.frameIndex + 1;
                            if (cjump.branchFrame != null) {
                                rewindCount -= cjump.branchFrame.frameIndex;
                            }

                            int enterCount = 0;
                            CallFrame [] enterFrames = null;

                            CallFrame x = cjump.capturedFrame;
                            for (int i = 0; i != rewindCount; ++i) {
                                if (!x.frozen)
                                    Context.CodeBug ();
                                if (isFrameEnterExitRequired (x)) {
                                    if (enterFrames == null) {
                                        // Allocate enough space to store the rest
                                        // of rewind frames in case all of them
                                        // would require to enter
                                        enterFrames = new CallFrame [rewindCount - i];
                                    }
                                    enterFrames [enterCount] = x;
                                    ++enterCount;
                                }
                                x = x.parentFrame;
                            }

                            while (enterCount != 0) {
                                // execute enter: walk enterFrames in the reverse
                                // order since they were stored starting from
                                // the capturedFrame, not branchFrame
                                --enterCount;
                                x = enterFrames [enterCount];
                                EnterFrame (cx, x, ScriptRuntime.EmptyArgs);
                            }

                            // Continuation jump is almost done: capturedFrame
                            // points to the call to the function that captured
                            // continuation, so clone capturedFrame and
                            // emulate return that function with the suplied result
                            frame = cjump.capturedFrame.cloneFrozen ();
                            setCallResult (frame, cjump.result, cjump.resultDbl);
                            // restart the execution
                        }

                        // Should be already cleared
                        if (throwable != null)
                            Context.CodeBug ();
                    }
                    else {
                        if (frame.frozen)
                            Context.CodeBug ();
                    }

                    // Use local variables for constant values in frame
                    // for faster access					
                    object [] stack = frame.stack;
                    double [] sDbl = frame.sDbl;
                    object [] vars = frame.varSource.stack;
                    double [] varDbls = frame.varSource.sDbl;

                    sbyte [] iCode = frame.idata.itsICode;
                    string [] strings = frame.idata.itsStringTable;

                    // Use local for stackTop as well. Since execption handlers
                    // can only exist at statement level where stack is empty,
                    // it is necessary to save/restore stackTop only accross
                    // function calls and normal returns.
                    int stackTop = frame.savedStackTop;

                    // Store new frame in cx which is used for error reporting etc.
                    cx.lastInterpreterFrame = frame;

                    for (; ; ) {

                        // Exception handler assumes that PC is already incremented
                        // pass the instruction start when it searches the
                        // exception handler
                        int op = iCode [frame.pc++];                                                
                        {
                            switch (op) {

                                case Token.THROW: {
                                        object value = stack [stackTop];
                                        if (value == DBL_MRK)
                                            value = sDbl [stackTop];
                                        stackTop--;

                                        int sourceLine = GetIndex (iCode, frame.pc);
                                        throwable = new EcmaScriptThrow (
                                            value, frame.idata.itsSourceFile, sourceLine);
                                        goto withoutExceptions_brk;
                                    }

                                case Token.RETHROW: {
                                        indexReg += frame.localShift;
                                        throwable = stack [indexReg];
                                        break;
                                    }

                                case Token.GE:
                                case Token.LE:
                                case Token.GT:
                                case Token.LT: {
                                        --stackTop;
                                        object rhs = stack [stackTop + 1];
                                        object lhs = stack [stackTop];
                                        bool valBln;
                                        {
                                            {
                                                double rDbl, lDbl;
                                                if (rhs == DBL_MRK) {
                                                    rDbl = sDbl [stackTop + 1];
                                                    lDbl = stack_double (frame, stackTop);
                                                }
                                                else if (lhs == DBL_MRK) {
                                                    rDbl = ScriptConvert.ToNumber (rhs);
                                                    lDbl = sDbl [stackTop];
                                                }
                                                else {

                                                    goto number_compare_brk;
                                                }
                                                switch (op) {

                                                    case Token.GE:
                                                        valBln = (lDbl >= rDbl);

                                                        goto object_compare_brk;

                                                    case Token.LE:
                                                        valBln = (lDbl <= rDbl);

                                                        goto object_compare_brk;

                                                    case Token.GT:
                                                        valBln = (lDbl > rDbl);

                                                        goto object_compare_brk;

                                                    case Token.LT:
                                                        valBln = (lDbl < rDbl);

                                                        goto object_compare_brk;

                                                    default:
                                                        throw Context.CodeBug ();

                                                }
                                            }

                                        number_compare_brk:
                                            ;

                                            switch (op) {

                                                case Token.GE:
                                                    valBln = ScriptRuntime.cmp_LE (rhs, lhs);
                                                    break;

                                                case Token.LE:
                                                    valBln = ScriptRuntime.cmp_LE (lhs, rhs);
                                                    break;

                                                case Token.GT:
                                                    valBln = ScriptRuntime.cmp_LT (rhs, lhs);
                                                    break;

                                                case Token.LT:
                                                    valBln = ScriptRuntime.cmp_LT (lhs, rhs);
                                                    break;

                                                default:
                                                    throw Context.CodeBug ();

                                            }
                                        }

                                    object_compare_brk:
                                        ;

                                        stack [stackTop] = valBln;

                                        goto Loop;
                                    }
                                    goto case Token.IN;

                                case Token.IN:
                                case Token.INSTANCEOF: {
                                        object rhs = stack [stackTop];
                                        if (rhs == DBL_MRK)
                                            rhs = sDbl [stackTop];
                                        --stackTop;
                                        object lhs = stack [stackTop];
                                        if (lhs == DBL_MRK)
                                            lhs = sDbl [stackTop];
                                        bool valBln;
                                        if (op == Token.IN) {
                                            valBln = ScriptRuntime.In (lhs, rhs, cx);
                                        }
                                        else {
                                            valBln = ScriptRuntime.InstanceOf (lhs, rhs, cx);
                                        }
                                        stack [stackTop] = valBln;

                                        goto Loop;
                                    }
                                    goto case Token.EQ;

                                case Token.EQ:
                                case Token.NE: {
                                        --stackTop;
                                        bool valBln;
                                        object rhs = stack [stackTop + 1];
                                        object lhs = stack [stackTop];
                                        if (rhs == DBL_MRK) {
                                            if (lhs == DBL_MRK) {
                                                valBln = (sDbl [stackTop] == sDbl [stackTop + 1]);
                                            }
                                            else {
                                                valBln = ScriptRuntime.eqNumber (sDbl [stackTop + 1], lhs);
                                            }
                                        }
                                        else {
                                            if (lhs == DBL_MRK) {
                                                valBln = ScriptRuntime.eqNumber (sDbl [stackTop], rhs);
                                            }
                                            else {
                                                valBln = ScriptRuntime.eq (lhs, rhs);
                                            }
                                        }
                                        valBln ^= (op == Token.NE);
                                        stack [stackTop] = valBln;

                                        goto Loop;
                                    }
                                    goto case Token.SHEQ;

                                case Token.SHEQ:
                                case Token.SHNE: {
                                        --stackTop;
                                        object rhs = stack [stackTop + 1];
                                        object lhs = stack [stackTop];
                                        bool valBln;
                                        {
                                            double rdbl, ldbl;
                                            if (rhs == DBL_MRK) {
                                                rdbl = sDbl [stackTop + 1];
                                                if (lhs == DBL_MRK) {
                                                    ldbl = sDbl [stackTop];
                                                }
                                                else if (CliHelper.IsNumber (lhs)) {
                                                    ldbl = Convert.ToDouble (lhs);
                                                }
                                                else {
                                                    valBln = false;

                                                    goto shallow_compare_brk;
                                                }
                                            }
                                            else if (lhs == DBL_MRK) {
                                                ldbl = sDbl [stackTop];
                                                if (rhs == DBL_MRK) {
                                                    rdbl = sDbl [stackTop + 1];
                                                }
                                                else if (CliHelper.IsNumber (rhs)) {
                                                    rdbl = Convert.ToDouble (rhs);
                                                }
                                                else {
                                                    valBln = false;

                                                    goto shallow_compare_brk;
                                                }
                                            }
                                            else {
                                                valBln = ScriptRuntime.shallowEq (lhs, rhs);

                                                goto shallow_compare_brk;
                                            }
                                            valBln = (ldbl == rdbl);
                                        }

                                    shallow_compare_brk:
                                        ;

                                        valBln ^= (op == Token.SHNE);
                                        stack [stackTop] = valBln;

                                        goto Loop;
                                    }
                                    goto case Token.IFNE;

                                case Token.IFNE:
                                    if (stack_boolean (frame, stackTop--)) {
                                        frame.pc += 2;

                                        goto Loop;
                                    }

                                    goto jumplessRun_brk;

                                case Token.IFEQ:
                                    if (!stack_boolean (frame, stackTop--)) {
                                        frame.pc += 2;

                                        goto Loop;
                                    }

                                    goto jumplessRun_brk;

                                case Icode_IFEQ_POP:
                                    if (!stack_boolean (frame, stackTop--)) {
                                        frame.pc += 2;

                                        goto Loop;
                                    }
                                    stack [stackTop--] = null;

                                    goto jumplessRun_brk;

                                case Token.GOTO:

                                    goto jumplessRun_brk;

                                case Icode_GOSUB:
                                    ++stackTop;
                                    stack [stackTop] = DBL_MRK;
                                    sDbl [stackTop] = frame.pc + 2;

                                    goto jumplessRun_brk;

                                case Icode_STARTSUB:
                                    if (stackTop == frame.emptyStackTop + 1) {
                                        // Call from Icode_GOSUB: store return PC address in the local
                                        indexReg += frame.localShift;
                                        stack [indexReg] = stack [stackTop];
                                        sDbl [indexReg] = sDbl [stackTop];
                                        --stackTop;
                                    }
                                    else {
                                        // Call from exception handler: exception object is already stored
                                        // in the local
                                        if (stackTop != frame.emptyStackTop)
                                            Context.CodeBug ();
                                    }

                                    goto Loop;
                                    goto case Icode_RETSUB;

                                case Icode_RETSUB: {
                                        // indexReg: local to store return address
                                        if (instructionCounting) {
                                            addInstructionCount (cx, frame, 0);
                                        }
                                        indexReg += frame.localShift;
                                        object value = stack [indexReg];
                                        if (value != DBL_MRK) {
                                            // Invocation from exception handler, restore object to rethrow
                                            throwable = value;
                                            goto withoutExceptions_brk;
                                        }
                                        // Normal return from GOSUB									
                                        frame.pc = (int)sDbl [indexReg];
                                        if (instructionCounting) {
                                            frame.pcPrevBranch = frame.pc;
                                        }

                                        goto Loop;
                                    }
                                    goto case Icode_POP;

                                case Icode_POP:
                                    stack [stackTop] = null;
                                    stackTop--;

                                    goto Loop;
                                    goto case Icode_POP_RESULT;

                                case Icode_POP_RESULT:
                                    frame.result = stack [stackTop];
                                    frame.resultDbl = sDbl [stackTop];
                                    stack [stackTop] = null;
                                    --stackTop;

                                    goto Loop;
                                    goto case Icode_DUP;

                                case Icode_DUP:
                                    stack [stackTop + 1] = stack [stackTop];
                                    sDbl [stackTop + 1] = sDbl [stackTop];
                                    stackTop++;

                                    goto Loop;
                                    goto case Icode_DUP2;

                                case Icode_DUP2:
                                    stack [stackTop + 1] = stack [stackTop - 1];
                                    sDbl [stackTop + 1] = sDbl [stackTop - 1];
                                    stack [stackTop + 2] = stack [stackTop];
                                    sDbl [stackTop + 2] = sDbl [stackTop];
                                    stackTop += 2;

                                    goto Loop;
                                    goto case Icode_SWAP;

                                case Icode_SWAP: {
                                        object o = stack [stackTop];
                                        stack [stackTop] = stack [stackTop - 1];
                                        stack [stackTop - 1] = o;
                                        double d = sDbl [stackTop];
                                        sDbl [stackTop] = sDbl [stackTop - 1];
                                        sDbl [stackTop - 1] = d;

                                        goto Loop;
                                    }
                                    goto case Token.RETURN;

                                case Token.RETURN:
                                    frame.result = stack [stackTop];
                                    frame.resultDbl = sDbl [stackTop];
                                    --stackTop;

                                    goto Loop_brk;

                                case Token.RETURN_RESULT:

                                    goto Loop_brk;

                                case Icode_RETUNDEF:
                                    frame.result = undefined;

                                    goto Loop_brk;

                                case Token.BITNOT: {
                                        int rIntValue = stack_int32 (frame, stackTop);
                                        stack [stackTop] = DBL_MRK;
                                        sDbl [stackTop] = ~rIntValue;

                                        goto Loop;
                                    }
                                    goto case Token.BITAND;

                                case Token.BITAND:
                                case Token.BITOR:
                                case Token.BITXOR:
                                case Token.LSH:
                                case Token.RSH: {
                                        int rIntValue = stack_int32 (frame, stackTop);
                                        --stackTop;
                                        int lIntValue = stack_int32 (frame, stackTop);
                                        stack [stackTop] = DBL_MRK;
                                        switch (op) {

                                            case Token.BITAND:
                                                lIntValue &= rIntValue;
                                                break;

                                            case Token.BITOR:
                                                lIntValue |= rIntValue;
                                                break;

                                            case Token.BITXOR:
                                                lIntValue ^= rIntValue;
                                                break;

                                            case Token.LSH:
                                                lIntValue <<= rIntValue;
                                                break;

                                            case Token.RSH:
                                                lIntValue >>= rIntValue;
                                                break;
                                        }
                                        sDbl [stackTop] = lIntValue;

                                        goto Loop;
                                    }
                                    goto case Token.URSH;

                                case Token.URSH: {
                                        int rIntValue = stack_int32 (frame, stackTop) & 0x1F;
                                        --stackTop;
                                        double lDbl = stack_double (frame, stackTop);
                                        stack [stackTop] = DBL_MRK;
                                        uint i = (uint)ScriptConvert.ToUint32 (lDbl);
                                        sDbl [stackTop] = i >> rIntValue;

                                        goto Loop;
                                    }
                                    goto case Token.NEG;

                                case Token.NEG:
                                case Token.POS: {
                                        double rDbl = stack_double (frame, stackTop);
                                        stack [stackTop] = DBL_MRK;
                                        if (op == Token.NEG) {
                                            rDbl = -rDbl;
                                        }
                                        sDbl [stackTop] = rDbl;

                                        goto Loop;
                                    }
                                    goto case Token.ADD;

                                case Token.ADD:
                                    --stackTop;
                                    DoAdd (stack, sDbl, stackTop, cx);

                                    goto Loop;
                                    goto case Token.SUB;

                                case Token.SUB:
                                case Token.MUL:
                                case Token.DIV:
                                case Token.MOD: {
                                        double rDbl = stack_double (frame, stackTop);
                                        --stackTop;
                                        double lDbl = stack_double (frame, stackTop);
                                        stack [stackTop] = DBL_MRK;
                                        switch (op) {

                                            case Token.SUB:
                                                lDbl -= rDbl;
                                                break;

                                            case Token.MUL:
                                                lDbl *= rDbl;
                                                break;

                                            case Token.DIV:
                                                lDbl /= rDbl;
                                                break;

                                            case Token.MOD:
                                                lDbl %= rDbl;
                                                break;
                                        }
                                        sDbl [stackTop] = lDbl;

                                        goto Loop;
                                    }
                                    goto case Token.NOT;

                                case Token.NOT:
                                    stack [stackTop] = !stack_boolean (frame, stackTop);

                                    goto Loop;
                                    goto case Token.BINDNAME;

                                case Token.BINDNAME:
                                    stack [++stackTop] = ScriptRuntime.bind (cx, frame.scope, stringReg);

                                    goto Loop;
                                    goto case Token.SETNAME;

                                case Token.SETNAME: {
                                        object rhs = stack [stackTop];
                                        if (rhs == DBL_MRK)
                                            rhs = sDbl [stackTop];
                                        --stackTop;
                                        IScriptable lhs = (IScriptable)stack [stackTop];
                                        stack [stackTop] = ScriptRuntime.setName (lhs, rhs, cx, frame.scope, stringReg);

                                        goto Loop;
                                    }
                                    goto case Token.DELPROP;

                                case Token.DELPROP: {
                                        object rhs = stack [stackTop];
                                        if (rhs == DBL_MRK)
                                            rhs = sDbl [stackTop];
                                        --stackTop;
                                        object lhs = stack [stackTop];
                                        if (lhs == DBL_MRK)
                                            lhs = sDbl [stackTop];
                                        stack [stackTop] = ScriptRuntime.delete (lhs, rhs, cx);

                                        goto Loop;
                                    }
                                    goto case Token.GETPROP;

                                case Token.GETPROP: {
                                        object lhs = stack [stackTop];
                                        if (lhs == DBL_MRK)
                                            lhs = sDbl [stackTop];
                                        stack [stackTop] = ScriptRuntime.getObjectProp (lhs, stringReg, cx);

                                        goto Loop;
                                    }
                                    goto case Token.SETPROP;

                                case Token.SETPROP_GETTER:
                                case Token.SETPROP_SETTER:
                                case Token.SETPROP: {
                                        object rhs = stack [stackTop];
                                        if (rhs == DBL_MRK)
                                            rhs = sDbl [stackTop];
                                        --stackTop;
                                        object lhs = stack [stackTop];
                                        if (lhs == DBL_MRK)
                                            lhs = sDbl [stackTop];

                                        switch (op) {
                                            case Token.SETPROP_GETTER:
                                                ((ScriptableObject)lhs).DefineGetter(stringReg, ((ICallable)rhs));
                                                stack[stackTop] = rhs;
                                                break;

                                            case Token.SETPROP_SETTER:
                                                ((ScriptableObject)lhs).DefineSetter(stringReg, ((ICallable)rhs));
                                                stack[stackTop] = rhs;
                                                break;


                                            default:
                                                stack [stackTop] = ScriptRuntime.setObjectProp (lhs, stringReg, rhs, cx);
                                                break;
                                        }

                                        goto Loop;
                                    }
                                    goto case Icode_PROP_INC_DEC;

                                case Icode_PROP_INC_DEC: {
                                        object lhs = stack [stackTop];
                                        if (lhs == DBL_MRK)
                                            lhs = sDbl [stackTop];
                                        stack [stackTop] = ScriptRuntime.propIncrDecr (lhs, stringReg, cx, iCode [frame.pc]);
                                        ++frame.pc;

                                        goto Loop;
                                    }
                                    goto case Token.GETELEM;

                                case Token.GETELEM: {
                                        --stackTop;
                                        object lhs = stack [stackTop];
                                        if (lhs == DBL_MRK) {
                                            lhs = sDbl [stackTop];
                                        }
                                        object value;
                                        object id = stack [stackTop + 1];
                                        if (id != DBL_MRK) {
                                            value = ScriptRuntime.getObjectElem (lhs, id, cx);
                                        }
                                        else {
                                            double d = sDbl [stackTop + 1];
                                            value = ScriptRuntime.getObjectIndex (lhs, d, cx);
                                        }
                                        stack [stackTop] = value;

                                        goto Loop;
                                    }
                                    goto case Token.SETELEM;

                                case Token.SETELEM: {
                                        stackTop -= 2;
                                        object rhs = stack [stackTop + 2];
                                        if (rhs == DBL_MRK) {
                                            rhs = sDbl [stackTop + 2];
                                        }
                                        object lhs = stack [stackTop];
                                        if (lhs == DBL_MRK) {
                                            lhs = sDbl [stackTop];
                                        }
                                        object value;
                                        object id = stack [stackTop + 1];
                                        if (id != DBL_MRK) {
                                            value = ScriptRuntime.setObjectElem (lhs, id, rhs, cx);
                                        }
                                        else {
                                            double d = sDbl [stackTop + 1];
                                            value = ScriptRuntime.setObjectIndex (lhs, d, rhs, cx);
                                        }
                                        stack [stackTop] = value;

                                        goto Loop;
                                    }
                                    goto case Icode_ELEM_INC_DEC;

                                case Icode_ELEM_INC_DEC: {
                                        object rhs = stack [stackTop];
                                        if (rhs == DBL_MRK)
                                            rhs = sDbl [stackTop];
                                        --stackTop;
                                        object lhs = stack [stackTop];
                                        if (lhs == DBL_MRK)
                                            lhs = sDbl [stackTop];
                                        stack [stackTop] = ScriptRuntime.elemIncrDecr (lhs, rhs, cx, iCode [frame.pc]);
                                        ++frame.pc;

                                        goto Loop;
                                    }
                                    goto case Token.GET_REF;

                                case Token.GET_REF: {
                                        IRef rf = (IRef)stack [stackTop];
                                        stack [stackTop] = ScriptRuntime.refGet (rf, cx);

                                        goto Loop;
                                    }
                                    goto case Token.SET_REF;

                                case Token.SET_REF: {
                                        object value = stack [stackTop];
                                        if (value == DBL_MRK)
                                            value = sDbl [stackTop];
                                        --stackTop;
                                        IRef rf = (IRef)stack [stackTop];
                                        stack [stackTop] = ScriptRuntime.refSet (rf, value, cx);

                                        goto Loop;
                                    }
                                    goto case Token.DEL_REF;

                                case Token.DEL_REF: {
                                        IRef rf = (IRef)stack [stackTop];
                                        stack [stackTop] = ScriptRuntime.refDel (rf, cx);

                                        goto Loop;
                                    }
                                    goto case Icode_REF_INC_DEC;

                                case Icode_REF_INC_DEC: {
                                        IRef rf = (IRef)stack [stackTop];
                                        stack [stackTop] = ScriptRuntime.refIncrDecr (rf, cx, iCode [frame.pc]);
                                        ++frame.pc;

                                        goto Loop;
                                    }
                                    goto case Token.LOCAL_LOAD;

                                case Token.LOCAL_LOAD:
                                    ++stackTop;
                                    indexReg += frame.localShift;
                                    stack [stackTop] = stack [indexReg];
                                    sDbl [stackTop] = sDbl [indexReg];

                                    goto Loop;
                                    goto case Icode_LOCAL_CLEAR;

                                case Icode_LOCAL_CLEAR:
                                    indexReg += frame.localShift;
                                    stack [indexReg] = null;

                                    goto Loop;
                                    goto case Icode_NAME_AND_THIS;

                                case Icode_NAME_AND_THIS:
                                    // stringReg: name
                                    ++stackTop;
                                    stack [stackTop] = ScriptRuntime.getNameFunctionAndThis (stringReg, cx, frame.scope);
                                    ++stackTop;
                                    stack [stackTop] = ScriptRuntime.lastStoredScriptable (cx);

                                    goto Loop;
                                    goto case Icode_PROP_AND_THIS;

                                case Icode_PROP_AND_THIS: {                                        
                                        object obj = stack [stackTop];                                        
                                        if (obj == DBL_MRK)
                                            obj = sDbl [stackTop];                                        
                                        // stringReg: property
                                        stack [stackTop] = ScriptRuntime.getPropFunctionAndThis (obj, stringReg, cx);
                                        ++stackTop;
                                        stack [stackTop] = ScriptRuntime.lastStoredScriptable (cx);

                                        goto Loop;
                                    }
                                    goto case Icode_ELEM_AND_THIS;

                                case Icode_ELEM_AND_THIS: {
                                        object obj = stack [stackTop - 1];
                                        if (obj == DBL_MRK)
                                            obj = sDbl [stackTop - 1];
                                        object id = stack [stackTop];
                                        if (id == DBL_MRK)
                                            id = sDbl [stackTop];
                                        stack [stackTop - 1] = ScriptRuntime.GetElemFunctionAndThis (obj, id, cx);
                                        stack [stackTop] = ScriptRuntime.lastStoredScriptable (cx);

                                        goto Loop;
                                    }
                                    goto case Icode_VALUE_AND_THIS;

                                case Icode_VALUE_AND_THIS: {
                                        object value = stack [stackTop];
                                        if (value == DBL_MRK)
                                            value = sDbl [stackTop];
                                        stack [stackTop] = ScriptRuntime.getValueFunctionAndThis (value, cx);
                                        ++stackTop;
                                        stack [stackTop] = ScriptRuntime.lastStoredScriptable (cx);

                                        goto Loop;
                                    }
                                    goto case Icode_CALLSPECIAL;

                                case Icode_CALLSPECIAL: {
                                        if (instructionCounting) {
                                            cx.instructionCount += INVOCATION_COST;
                                        }
                                        int callType = iCode [frame.pc] & 0xFF;
                                        bool isNew = (iCode [frame.pc + 1] != 0);
                                        int sourceLine = GetIndex (iCode, frame.pc + 2);

                                        // indexReg: number of arguments
                                        if (isNew) {
                                            // stack change: function arg0 .. argN -> newResult
                                            stackTop -= indexReg;

                                            object function = stack [stackTop];
                                            if (function == DBL_MRK)
                                                function = sDbl [stackTop];
                                            object [] outArgs = GetArgsArray (stack, sDbl, stackTop + 1, indexReg);
                                            stack [stackTop] = ScriptRuntime.newSpecial (cx, function, outArgs, frame.scope, callType);
                                        }
                                        else {
                                            // stack change: function thisObj arg0 .. argN -> result
                                            stackTop -= (1 + indexReg);

                                            // Call code generation ensure that stack here
                                            // is ... Callable Scriptable
                                            IScriptable functionThis = (IScriptable)stack [stackTop + 1];
                                            ICallable function = (ICallable)stack [stackTop];
                                            object [] outArgs = GetArgsArray (stack, sDbl, stackTop + 2, indexReg);
                                            stack [stackTop] = ScriptRuntime.callSpecial (cx, function, functionThis, outArgs, frame.scope, frame.thisObj, callType, frame.idata.itsSourceFile, sourceLine);
                                        }
                                        frame.pc += 4;

                                        goto Loop;
                                    }
                                    goto case Token.CALL;

                                case Token.CALL:
                                case Icode_TAIL_CALL:
                                case Token.REF_CALL: {
                                        if (instructionCounting) {
                                            cx.instructionCount += INVOCATION_COST;
                                        }
                                        // stack change: function thisObj arg0 .. argN -> result
                                        // indexReg: number of arguments
                                        stackTop -= (1 + indexReg);

                                        // CALL generation ensures that fun and funThisObj
                                        // are already Scriptable and Callable objects respectively
                                        ICallable fun = (ICallable)stack [stackTop];
                                        IScriptable funThisObj = (IScriptable)stack [stackTop + 1];
                                        if (op == Token.REF_CALL) {
                                            object [] outArgs = GetArgsArray (stack, sDbl, stackTop + 2, indexReg);
                                            stack [stackTop] = ScriptRuntime.callRef (fun, funThisObj, outArgs, cx);

                                            goto Loop;
                                        }
                                        IScriptable calleeScope = frame.scope;
                                        if (frame.useActivation) {
                                            calleeScope = ScriptableObject.GetTopLevelScope (frame.scope);
                                        }
                                        if (fun is InterpretedFunction) {
                                            InterpretedFunction ifun = (InterpretedFunction)fun;
                                            if (frame.fnOrScript.securityDomain == ifun.securityDomain) {
                                                CallFrame callParentFrame = frame;
                                                CallFrame calleeFrame = new CallFrame ();
                                                if (op == Icode_TAIL_CALL) {
                                                    // In principle tail call can re-use the current
                                                    // frame and its stack arrays but it is hard to
                                                    // do properly. Any exceptions that can legally
                                                    // happen during frame re-initialization including
                                                    // StackOverflowException during innocent looking
                                                    // System.arraycopy may leave the current frame
                                                    // data corrupted leading to undefined behaviour
                                                    // in the catch code bellow that unwinds JS stack
                                                    // on exceptions. Then there is issue about frame release
                                                    // end exceptions there.
                                                    // To avoid frame allocation a released frame
                                                    // can be cached for re-use which would also benefit
                                                    // non-tail calls but it is not clear that this caching
                                                    // would gain in performance due to potentially
                                                    // bad iteraction with GC.
                                                    callParentFrame = frame.parentFrame;
                                                }
                                                initFrame (cx, calleeScope, funThisObj, stack, sDbl, stackTop + 2, indexReg, ifun, callParentFrame, calleeFrame);
                                                if (op == Icode_TAIL_CALL) {
                                                    // Release the parent
                                                    ExitFrame (cx, frame, (object)null);
                                                }
                                                else {
                                                    frame.savedStackTop = stackTop;
                                                    frame.savedCallOp = op;
                                                }
                                                frame = calleeFrame;

                                                goto StateLoop;
                                            }
                                        }

                                        if (fun is Continuation) {
                                            // Jump to the captured continuation
                                            ContinuationJump cjump;
                                            cjump = new ContinuationJump ((Continuation)fun, frame);

                                            // continuation result is the first argument if any
                                            // of contination call
                                            if (indexReg == 0) {
                                                cjump.result = undefined;
                                            }
                                            else {
                                                cjump.result = stack [stackTop + 2];
                                                cjump.resultDbl = sDbl [stackTop + 2];
                                            }

                                            // Start the real unwind job
                                            throwable = cjump;
                                            break;
                                        }

                                        if (fun is IdFunctionObject) {
                                            IdFunctionObject ifun = (IdFunctionObject)fun;
                                            if (Continuation.IsContinuationConstructor (ifun)) {
                                                captureContinuation (cx, frame, stackTop);

                                                goto Loop;
                                            }
                                        }

                                        object [] outArgs2 = GetArgsArray (stack, sDbl, stackTop + 2, indexReg);
                                        stack [stackTop] = fun.Call (cx, calleeScope, funThisObj, outArgs2);


                                        goto Loop;
                                    }
                                    goto case Token.NEW;

                                case Token.NEW: {
                                        if (instructionCounting) {
                                            cx.instructionCount += INVOCATION_COST;
                                        }
                                        // stack change: function arg0 .. argN -> newResult
                                        // indexReg: number of arguments
                                        stackTop -= indexReg;

                                        object lhs = stack [stackTop];
                                        if (lhs is InterpretedFunction) {
                                            InterpretedFunction f = (InterpretedFunction)lhs;
                                            if (frame.fnOrScript.securityDomain == f.securityDomain) {
                                                IScriptable newInstance = f.CreateObject (cx, frame.scope);
                                                CallFrame calleeFrame = new CallFrame ();
                                                initFrame (cx, frame.scope, newInstance, stack, sDbl, stackTop + 1, indexReg, f, frame, calleeFrame);

                                                stack [stackTop] = newInstance;
                                                frame.savedStackTop = stackTop;
                                                frame.savedCallOp = op;
                                                frame = calleeFrame;

                                                goto StateLoop;
                                            }
                                        }
                                        if (!(lhs is IFunction)) {
                                            if (lhs == DBL_MRK)
                                                lhs = sDbl [stackTop];
                                            throw ScriptRuntime.NotFunctionError (lhs);
                                        }
                                        IFunction fun = (IFunction)lhs;

                                        if (fun is IdFunctionObject) {
                                            IdFunctionObject ifun = (IdFunctionObject)fun;
                                            if (Continuation.IsContinuationConstructor (ifun)) {
                                                captureContinuation (cx, frame, stackTop);

                                                goto Loop;
                                            }
                                        }

                                        object [] outArgs = GetArgsArray (stack, sDbl, stackTop + 1, indexReg);
                                        stack [stackTop] = fun.Construct (cx, frame.scope, outArgs);

                                        goto Loop;
                                    }
                                    goto case Token.TYPEOF;

                                case Token.TYPEOF: {
                                        object lhs = stack [stackTop];
                                        if (lhs == DBL_MRK)
                                            lhs = sDbl [stackTop];
                                        stack [stackTop] = ScriptRuntime.Typeof (lhs);

                                        goto Loop;
                                    }
                                    goto case Icode_TYPEOFNAME;

                                case Icode_TYPEOFNAME:
                                    stack [++stackTop] = ScriptRuntime.TypeofName (frame.scope, stringReg);

                                    goto Loop;
                                    goto case Token.STRING;

                                case Token.STRING:
                                    stack [++stackTop] = stringReg;

                                    goto Loop;
                                    goto case Icode_SHORTNUMBER;

                                case Icode_SHORTNUMBER:
                                    ++stackTop;
                                    stack [stackTop] = DBL_MRK;
                                    sDbl [stackTop] = GetShort (iCode, frame.pc);
                                    frame.pc += 2;

                                    goto Loop;
                                    goto case Icode_INTNUMBER;

                                case Icode_INTNUMBER:
                                    ++stackTop;
                                    stack [stackTop] = DBL_MRK;
                                    sDbl [stackTop] = GetInt (iCode, frame.pc);
                                    frame.pc += 4;

                                    goto Loop;
                                    goto case Token.NUMBER;

                                case Token.NUMBER:
                                    ++stackTop;
                                    stack [stackTop] = DBL_MRK;
                                    sDbl [stackTop] = frame.idata.itsDoubleTable [indexReg];

                                    goto Loop;
                                    goto case Token.NAME;

                                case Token.NAME:
                                    stack [++stackTop] = ScriptRuntime.name (cx, frame.scope, stringReg);

                                    goto Loop;
                                    goto case Icode_NAME_INC_DEC;

                                case Icode_NAME_INC_DEC:
                                    stack [++stackTop] = ScriptRuntime.nameIncrDecr (frame.scope, stringReg, iCode [frame.pc]);
                                    ++frame.pc;

                                    goto Loop;
                                    goto case Icode_SETVAR1;

                                case Icode_SETVAR1:
                                    indexReg = iCode [frame.pc++];
                                    // fallthrough
                                    goto case Token.SETVAR;

                                case Token.SETVAR:
                                    if (!frame.useActivation) {
                                        vars [indexReg] = stack [stackTop];
                                        varDbls [indexReg] = sDbl [stackTop];
                                    }
                                    else {
                                        object val = stack [stackTop];
                                        if (val == DBL_MRK)
                                            val = sDbl [stackTop];
                                        stringReg = frame.idata.argNames [indexReg];
                                        frame.scope.Put (stringReg, frame.scope, val);
                                    }

                                    goto Loop;
                                    goto case Icode_GETVAR1;

                                case Icode_GETVAR1:
                                    indexReg = iCode [frame.pc++];
                                    // fallthrough
                                    goto case Token.GETVAR;

                                case Token.GETVAR:
                                    ++stackTop;
                                    if (!frame.useActivation) {
                                        stack [stackTop] = vars [indexReg];
                                        sDbl [stackTop] = varDbls [indexReg];
                                    }
                                    else {
                                        stringReg = frame.idata.argNames [indexReg];
                                        stack [stackTop] = frame.scope.Get (stringReg, frame.scope);
                                    }

                                    goto Loop;
                                    goto case Icode_VAR_INC_DEC;

                                case Icode_VAR_INC_DEC: {
                                        // indexReg : varindex
                                        ++stackTop;
                                        int incrDecrMask = iCode [frame.pc];
                                        if (!frame.useActivation) {
                                            stack [stackTop] = DBL_MRK;
                                            object varValue = vars [indexReg];
                                            double d;
                                            if (varValue == DBL_MRK) {
                                                d = varDbls [indexReg];
                                            }
                                            else {
                                                d = ScriptConvert.ToNumber (varValue);
                                                vars [indexReg] = DBL_MRK;
                                            }
                                            double d2 = ((incrDecrMask & Node.DECR_FLAG) == 0) ? d + 1.0 : d - 1.0;
                                            varDbls [indexReg] = d2;
                                            sDbl [stackTop] = ((incrDecrMask & Node.POST_FLAG) == 0) ? d2 : d;
                                        }
                                        else {
                                            string varName = frame.idata.argNames [indexReg];
                                            stack [stackTop] = ScriptRuntime.nameIncrDecr (frame.scope, varName, incrDecrMask);
                                        }
                                        ++frame.pc;

                                        goto Loop;
                                    }
                                    goto case Icode_ZERO;

                                case Icode_ZERO:
                                    ++stackTop;
                                    stack [stackTop] = DBL_MRK;
                                    sDbl [stackTop] = 0;

                                    goto Loop;
                                    goto case Icode_ONE;

                                case Icode_ONE:
                                    ++stackTop;
                                    stack [stackTop] = DBL_MRK;
                                    sDbl [stackTop] = 1;

                                    goto Loop;
                                    goto case Token.NULL;

                                case Token.NULL:
                                    stack [++stackTop] = null;

                                    goto Loop;
                                    goto case Token.THIS;

                                case Token.THIS:
                                    stack [++stackTop] = frame.thisObj;

                                    goto Loop;
                                    goto case Token.THISFN;

                                case Token.THISFN:
                                    stack [++stackTop] = frame.fnOrScript;

                                    goto Loop;
                                    goto case Token.FALSE;

                                case Token.FALSE:
                                    stack [++stackTop] = false;

                                    goto Loop;
                                    goto case Token.TRUE;

                                case Token.TRUE:
                                    stack [++stackTop] = true;

                                    goto Loop;
                                    goto case Icode_UNDEF;

                                case Icode_UNDEF:
                                    stack [++stackTop] = undefined;

                                    goto Loop;
                                    goto case Token.ENTERWITH;

                                case Token.ENTERWITH: {
                                        object lhs = stack [stackTop];
                                        if (lhs == DBL_MRK)
                                            lhs = sDbl [stackTop];
                                        --stackTop;
                                        frame.scope = ScriptRuntime.enterWith (lhs, cx, frame.scope);

                                        goto Loop;
                                    }
                                    goto case Token.LEAVEWITH;

                                case Token.LEAVEWITH:
                                    frame.scope = ScriptRuntime.leaveWith (frame.scope);

                                    goto Loop;
                                    goto case Token.CATCH_SCOPE;

                                case Token.CATCH_SCOPE: {
                                        // stack top: exception object
                                        // stringReg: name of exception variable
                                        // indexReg: local for exception scope
                                        --stackTop;
                                        indexReg += frame.localShift;

                                        bool afterFirstScope = (frame.idata.itsICode [frame.pc] != 0);

                                        Exception caughtException = (Exception)stack [stackTop + 1];
                                        IScriptable lastCatchScope;
                                        if (!afterFirstScope) {
                                            lastCatchScope = null;
                                        }
                                        else {
                                            lastCatchScope = (IScriptable)stack [indexReg];
                                        }
                                        stack [indexReg] = ScriptRuntime.NewCatchScope (caughtException, lastCatchScope, stringReg, cx, frame.scope);
                                        ++frame.pc;

                                        goto Loop;
                                    }
                                    goto case Token.ENUM_INIT_KEYS;

                                case Token.ENUM_INIT_KEYS:
                                case Token.ENUM_INIT_VALUES: {
                                        object lhs = stack [stackTop];
                                        if (lhs == DBL_MRK)
                                            lhs = sDbl [stackTop];
                                        --stackTop;
                                        indexReg += frame.localShift;

                                        if (lhs is IIdEnumerable) {
                                            stack [indexReg] = ((IIdEnumerable)lhs).GetEnumeration (cx, (op == Token.ENUM_INIT_VALUES));
                                        }
                                        else {
                                            stack [indexReg] = new IdEnumeration (lhs, cx, (op == Token.ENUM_INIT_VALUES));
                                        }


                                        goto Loop;
                                    }
                                    goto case Token.ENUM_NEXT;

                                case Token.ENUM_NEXT:
                                case Token.ENUM_ID: {
                                        indexReg += frame.localShift;
                                        IdEnumeration val = (IdEnumeration)stack [indexReg];
                                        ++stackTop;
                                        stack [stackTop] = (op == Token.ENUM_NEXT) ? val.MoveNext () : val.Current (cx);

                                        goto Loop;
                                    }
                                    goto case Token.REF_SPECIAL;

                                case Token.REF_SPECIAL: {
                                        //stringReg: name of special property
                                        object obj = stack [stackTop];
                                        if (obj == DBL_MRK)
                                            obj = sDbl [stackTop];
                                        stack [stackTop] = ScriptRuntime.specialRef (obj, stringReg, cx);

                                        goto Loop;
                                    }
                                    goto case Token.REF_MEMBER;

                                case Token.REF_MEMBER: {
                                        //indexReg: flags
                                        object elem = stack [stackTop];
                                        if (elem == DBL_MRK)
                                            elem = sDbl [stackTop];
                                        --stackTop;
                                        object obj = stack [stackTop];
                                        if (obj == DBL_MRK)
                                            obj = sDbl [stackTop];
                                        stack [stackTop] = ScriptRuntime.memberRef (obj, elem, cx, indexReg);

                                        goto Loop;
                                    }
                                    goto case Token.REF_NS_MEMBER;

                                case Token.REF_NS_MEMBER: {
                                        //indexReg: flags
                                        object elem = stack [stackTop];
                                        if (elem == DBL_MRK)
                                            elem = sDbl [stackTop];
                                        --stackTop;
                                        object ns = stack [stackTop];
                                        if (ns == DBL_MRK)
                                            ns = sDbl [stackTop];
                                        --stackTop;
                                        object obj = stack [stackTop];
                                        if (obj == DBL_MRK)
                                            obj = sDbl [stackTop];
                                        stack [stackTop] = ScriptRuntime.memberRef (obj, ns, elem, cx, indexReg);

                                        goto Loop;
                                    }
                                    goto case Token.REF_NAME;

                                case Token.REF_NAME: {
                                        //indexReg: flags
                                        object name = stack [stackTop];
                                        if (name == DBL_MRK)
                                            name = sDbl [stackTop];
                                        stack [stackTop] = ScriptRuntime.nameRef (name, cx, frame.scope, indexReg);

                                        goto Loop;
                                    }
                                    goto case Token.REF_NS_NAME;

                                case Token.REF_NS_NAME: {
                                        //indexReg: flags
                                        object name = stack [stackTop];
                                        if (name == DBL_MRK)
                                            name = sDbl [stackTop];
                                        --stackTop;
                                        object ns = stack [stackTop];
                                        if (ns == DBL_MRK)
                                            ns = sDbl [stackTop];
                                        stack [stackTop] = ScriptRuntime.nameRef (ns, name, cx, frame.scope, indexReg);

                                        goto Loop;
                                    }
                                    goto case Icode_SCOPE_LOAD;

                                case Icode_SCOPE_LOAD:
                                    indexReg += frame.localShift;
                                    frame.scope = (IScriptable)stack [indexReg];

                                    goto Loop;
                                    goto case Icode_SCOPE_SAVE;

                                case Icode_SCOPE_SAVE:
                                    indexReg += frame.localShift;
                                    stack [indexReg] = frame.scope;

                                    goto Loop;
                                    goto case Icode_CLOSURE_EXPR;

                                case Icode_CLOSURE_EXPR: {
                                        InterpretedFunction fun = InterpretedFunction.createFunction (cx, frame.scope, frame.fnOrScript, indexReg);
                                        stack [++stackTop] = fun;
                                    }
                                    goto Loop;
                                    goto case Icode_CLOSURE_STMT;

                                case Icode_CLOSURE_STMT:
                                    initFunction (cx, frame.scope, frame.fnOrScript, indexReg);

                                    goto Loop;
                                    goto case Token.REGEXP;

                                case Token.REGEXP:
                                    stack [++stackTop] = frame.scriptRegExps [indexReg];

                                    goto Loop;
                                    goto case Icode_LITERAL_NEW;

                                case Icode_LITERAL_NEW:
                                    // indexReg: number of values in the literal
                                    ++stackTop;
                                    stack [stackTop] = new object [indexReg];
                                    sDbl [stackTop] = 0;

                                    goto Loop;
                                    goto case Icode_LITERAL_SET;

                                case Icode_LITERAL_SET: {
                                        object value = stack [stackTop];
                                        if (value == DBL_MRK)
                                            value = sDbl [stackTop];
                                        --stackTop;
                                        int i = (int)sDbl [stackTop];
                                        ((object [])stack [stackTop]) [i] = value;
                                        sDbl [stackTop] = i + 1;

                                        goto Loop;
                                    }
                                    goto case Token.ARRAYLIT;

                                case Token.ARRAYLIT:
                                case Icode_SPARE_ARRAYLIT:
                                case Token.OBJECTLIT: {
                                        object [] data = (object [])stack [stackTop];
                                        object val;
                                        if (op == Token.OBJECTLIT) {
                                            object [] ids = (object [])frame.idata.literalIds [indexReg];
                                            val = ScriptRuntime.newObjectLiteral (ids, data, cx, frame.scope);
                                        }
                                        else {
                                            int [] skipIndexces = null;
                                            if (op == Icode_SPARE_ARRAYLIT) {
                                                skipIndexces = (int [])frame.idata.literalIds [indexReg];
                                            }
                                            val = ScriptRuntime.newArrayLiteral (data, skipIndexces, cx, frame.scope);
                                        }
                                        stack [stackTop] = val;

                                        goto Loop;
                                    }
                                    goto case Icode_ENTERDQ;

                                case Icode_ENTERDQ: {
                                        object lhs = stack [stackTop];
                                        if (lhs == DBL_MRK)
                                            lhs = sDbl [stackTop];
                                        --stackTop;
                                        frame.scope = ScriptRuntime.enterDotQuery (lhs, frame.scope);

                                        goto Loop;
                                    }
                                    goto case Icode_LEAVEDQ;

                                case Icode_LEAVEDQ: {
                                        bool valBln = stack_boolean (frame, stackTop);
                                        object x = ScriptRuntime.updateDotQuery (valBln, frame.scope);
                                        if (x != null) {
                                            stack [stackTop] = x;
                                            frame.scope = ScriptRuntime.leaveDotQuery (frame.scope);
                                            frame.pc += 2;

                                            goto Loop;
                                        }
                                        // reset stack and PC to code after ENTERDQ
                                        --stackTop;

                                        goto jumplessRun_brk;
                                    }

                                case Token.DEFAULTNAMESPACE: {
                                        object value = stack [stackTop];
                                        if (value == DBL_MRK)
                                            value = sDbl [stackTop];
                                        stack [stackTop] = ScriptRuntime.setDefaultNamespace (value, cx);

                                        goto Loop;
                                    }
                                    goto case Token.ESCXMLATTR;

                                case Token.ESCXMLATTR: {
                                        object value = stack [stackTop];
                                        if (value != DBL_MRK) {
                                            stack [stackTop] = ScriptRuntime.escapeAttributeValue (value, cx);
                                        }

                                        goto Loop;
                                    }
                                    goto case Token.ESCXMLTEXT;

                                case Token.ESCXMLTEXT: {
                                        object value = stack [stackTop];
                                        if (value != DBL_MRK) {
                                            stack [stackTop] = ScriptRuntime.escapeTextValue (value, cx);
                                        }

                                        goto Loop;
                                    }
                                    goto case Icode_LINE;

                                case Icode_DEBUGGER: {
                                        if (frame.debuggerFrame != null) {
                                            frame.debuggerFrame.OnDebuggerStatement(cx);
                                        }
                                        break;
                                    }

                                case Icode_LINE:
                                    frame.pcSourceLineStart = frame.pc;
                                    if (frame.debuggerFrame != null) {
                                        int line = GetIndex (iCode, frame.pc);
                                        frame.debuggerFrame.OnLineChange (cx, line);
                                    }
                                    frame.pc += 2;

                                    goto Loop;
                                    goto case Icode_REG_IND_C0;

                                case Icode_REG_IND_C0:
                                    indexReg = 0;

                                    goto Loop;
                                    goto case Icode_REG_IND_C1;

                                case Icode_REG_IND_C1:
                                    indexReg = 1;

                                    goto Loop;
                                    goto case Icode_REG_IND_C2;

                                case Icode_REG_IND_C2:
                                    indexReg = 2;

                                    goto Loop;
                                    goto case Icode_REG_IND_C3;

                                case Icode_REG_IND_C3:
                                    indexReg = 3;

                                    goto Loop;
                                    goto case Icode_REG_IND_C4;

                                case Icode_REG_IND_C4:
                                    indexReg = 4;

                                    goto Loop;
                                    goto case Icode_REG_IND_C5;

                                case Icode_REG_IND_C5:
                                    indexReg = 5;

                                    goto Loop;
                                    goto case Icode_REG_IND1;

                                case Icode_REG_IND1:
                                    indexReg = 0xFF & iCode [frame.pc];
                                    ++frame.pc;

                                    goto Loop;
                                    goto case Icode_REG_IND2;

                                case Icode_REG_IND2:
                                    indexReg = GetIndex (iCode, frame.pc);
                                    frame.pc += 2;

                                    goto Loop;
                                    goto case Icode_REG_IND4;

                                case Icode_REG_IND4:
                                    indexReg = GetInt (iCode, frame.pc);
                                    frame.pc += 4;

                                    goto Loop;
                                    goto case Icode_REG_STR_C0;

                                case Icode_REG_STR_C0:
                                    stringReg = strings [0];

                                    goto Loop;
                                    goto case Icode_REG_STR_C1;

                                case Icode_REG_STR_C1:
                                    stringReg = strings [1];

                                    goto Loop;
                                    goto case Icode_REG_STR_C2;

                                case Icode_REG_STR_C2:
                                    stringReg = strings [2];

                                    goto Loop;
                                    goto case Icode_REG_STR_C3;

                                case Icode_REG_STR_C3:
                                    stringReg = strings [3];

                                    goto Loop;
                                    goto case Icode_REG_STR1;

                                case Icode_REG_STR1:
                                    stringReg = strings [0xFF & iCode [frame.pc]];
                                    ++frame.pc;

                                    goto Loop;
                                    goto case Icode_REG_STR2;

                                case Icode_REG_STR2:
                                    stringReg = strings [GetIndex (iCode, frame.pc)];
                                    frame.pc += 2;

                                    goto Loop;
                                    goto case Icode_REG_STR4;

                                case Icode_REG_STR4:
                                    stringReg = strings [GetInt (iCode, frame.pc)];
                                    frame.pc += 4;

                                    goto Loop;
                                    goto default;

                                default:
                                    dumpICode (frame.idata);
                                    throw new ApplicationException ("Unknown icode : " + op + " @ pc : " + (frame.pc - 1));

                            } // end of interpreter switch
                        }

                    jumplessRun_brk:
                        ;
                        // end of jumplessRun label block

                        // This should be reachable only for jump implementation
                        // when pc points to encoded target offset
                        if (instructionCounting) {
                            addInstructionCount (cx, frame, 2);
                        }
                        int offset = GetShort (iCode, frame.pc);
                        if (offset != 0) {
                            // -1 accounts for pc pointing to jump opcode + 1
                            frame.pc += offset - 1;
                        }
                        else {
                            frame.pc = frame.idata.longJumps.getExistingInt (frame.pc);
                        }
                        if (instructionCounting) {
                            frame.pcPrevBranch = frame.pc;
                        }

                        goto Loop;

                    Loop:
                        ;
                    }

                Loop_brk:
                    ;
                    // end of Loop: for

                    ExitFrame (cx, frame, (object)null);
                    interpreterResult = frame.result;
                    interpreterResultDbl = frame.resultDbl;
                    if (frame.parentFrame != null) {
                        frame = frame.parentFrame;
                        if (frame.frozen) {
                            frame = frame.cloneFrozen ();
                        }
                        setCallResult (frame, interpreterResult, interpreterResultDbl);
                        interpreterResult = null; // Help GC

                        goto StateLoop;
                    }

                    goto StateLoop_brk;
                }
                // end of interpreter withoutExceptions: try					
                catch (Exception ex) {
                    if (throwable != null) {
                        // This is serious bug and it is better to track it ASAP
                        throw new ApplicationException ();
                    }
                    throwable = ex;
                }

            withoutExceptions_brk:

                // This should be reachable only after above catch or from
                // finally when it needs to propagate exception or from
                // explicit throw
                if (throwable == null)
                    Context.CodeBug ();

                // Exception type				
                const int EX_CATCH_STATE = 2; // Can execute JS catch				
                const int EX_FINALLY_STATE = 1; // Can execute JS finally				
                const int EX_NO_JS_STATE = 0; // Terminate JS execution

                int exState;
                ContinuationJump cjump2 = null;

                if (throwable is EcmaScriptThrow) {
                    exState = EX_CATCH_STATE;
                }
                else if (throwable is EcmaScriptError) {
                    // an offical ECMA error object,
                    exState = EX_CATCH_STATE;
                }
                else if (throwable is EcmaScriptRuntimeException) {
                    exState = EX_CATCH_STATE;
                }
                else if (throwable is EcmaScriptException) {
                    exState = EX_FINALLY_STATE;
                }
                else if (throwable is Exception) {
                    exState = EX_NO_JS_STATE;
                }
                else {
                    // It must be ContinuationJump
                    exState = EX_FINALLY_STATE;
                    cjump2 = (ContinuationJump)throwable;
                }

                if (instructionCounting) {
                    try {
                        addInstructionCount (cx, frame, EXCEPTION_COST);
                    }
                    catch (ApplicationException ex) {
                        // Error from instruction counting
                        //     => unconditionally terminate JS
                        throwable = ex;
                        cjump2 = null;
                        exState = EX_NO_JS_STATE;
                    }
                }
                if (frame.debuggerFrame != null && throwable is ApplicationException) {
                    // Call debugger only for RuntimeException
                    ApplicationException rex = (ApplicationException)throwable;
                    try {
                        frame.debuggerFrame.OnExceptionThrown (cx, rex);
                    }
                    catch (Exception ex) {
                        // Any exception from debugger
                        //     => unconditionally terminate JS
                        throwable = ex;
                        cjump2 = null;
                        exState = EX_NO_JS_STATE;
                    }
                }

                for (; ; ) {
                    if (exState != EX_NO_JS_STATE) {
                        bool onlyFinally = (exState != EX_CATCH_STATE);
                        indexReg = getExceptionHandler (frame, onlyFinally);
                        if (indexReg >= 0) {
                            // We caught an exception, restart the loop
                            // with exception pending the processing at the loop
                            // start

                            goto StateLoop;
                        }
                    }
                    // No allowed execption handlers in this frame, unwind
                    // to parent and try to look there

                    ExitFrame (cx, frame, throwable);

                    frame = frame.parentFrame;
                    if (frame == null) {
                        break;
                    }
                    if (cjump2 != null && cjump2.branchFrame == frame) {
                        // Continuation branch point was hit,
                        // restart the state loop to reenter continuation
                        indexReg = -1;

                        goto StateLoop;
                    }
                }

                // No more frames, rethrow the exception or deal with continuation
                if (cjump2 != null) {
                    if (cjump2.branchFrame != null) {
                        // The above loop should locate the top frame
                        Context.CodeBug ();
                    }
                    if (cjump2.capturedFrame != null) {
                        // Restarting detached continuation
                        indexReg = -1;

                        goto StateLoop;
                    }
                    // Return continuation result to the caller
                    interpreterResult = cjump2.result;
                    interpreterResultDbl = cjump2.resultDbl;
                    throwable = null;
                }

                goto StateLoop_brk;

            StateLoop:
                ;
            }

        StateLoop_brk:
            ;
            // end of StateLoop: for(;;)

            // Do cleanups/restorations before the final return or throw

            if (cx.previousInterpreterInvocations != null && cx.previousInterpreterInvocations.size () != 0) {
                cx.lastInterpreterFrame = cx.previousInterpreterInvocations.pop ();
            }
            else {
                // It was the last interpreter frame on the stack
                cx.lastInterpreterFrame = null;
                // Force GC of the value cx.previousInterpreterInvocations
                cx.previousInterpreterInvocations = null;
            }

            if (throwable != null) {
                if (throwable is Helpers.StackOverflowVerifierException) {
                    throw Context.ReportRuntimeError (
                        ScriptRuntime.GetMessage ("mag.too.deep.parser.recursion"));
                }
                throw (Exception)throwable;                
            }

            return (interpreterResult != DBL_MRK) ? interpreterResult :
            interpreterResultDbl;
        }
Пример #54
0
        internal static void captureInterpreterStackInfo (EcmaScriptException ex)
        {
            Context cx = Context.CurrentContext;
            if (cx == null || cx.lastInterpreterFrame == null) {
                // No interpreter invocations
                ex.m_InterpreterStackInfo = null;
                ex.m_InterpreterLineData = null;
                return;
            }
            // has interpreter frame on the stack
            CallFrame [] array;
            if (cx.previousInterpreterInvocations == null || cx.previousInterpreterInvocations.size () == 0) {
                array = new CallFrame [1];
            }
            else {
                int previousCount = cx.previousInterpreterInvocations.size ();
                if (cx.previousInterpreterInvocations.peek () == cx.lastInterpreterFrame) {
                    // It can happen if exception was generated after
                    // frame was pushed to cx.previousInterpreterInvocations
                    // but before assignment to cx.lastInterpreterFrame.
                    // In this case frames has to be ignored.
                    --previousCount;
                }
                array = new CallFrame [previousCount + 1];
                cx.previousInterpreterInvocations.ToArray (array);
            }
            array [array.Length - 1] = (CallFrame)cx.lastInterpreterFrame;

            int interpreterFrameCount = 0;
            for (int i = 0; i != array.Length; ++i) {
                interpreterFrameCount += 1 + array [i].frameIndex;
            }

            int [] linePC = new int [interpreterFrameCount];
            // Fill linePC with pc positions from all interpreter frames.
            // Start from the most nested frame
            int linePCIndex = interpreterFrameCount;
            for (int i = array.Length; i != 0; ) {
                --i;
                CallFrame frame = array [i];
                while (frame != null) {
                    --linePCIndex;
                    linePC [linePCIndex] = frame.pcSourceLineStart;
                    frame = frame.parentFrame;
                }
            }
            if (linePCIndex != 0)
                Context.CodeBug ();

            ex.m_InterpreterStackInfo = array;
            ex.m_InterpreterLineData = linePC;
        }
Пример #55
0
        static void initFrame (Context cx, IScriptable callerScope, IScriptable thisObj, object [] args, double [] argsDbl, int argShift, int argCount, InterpretedFunction fnOrScript, CallFrame parentFrame, CallFrame frame)
        {
            InterpreterData idata = fnOrScript.idata;

            bool useActivation = idata.itsNeedsActivation;
            DebugFrame debuggerFrame = null;
            if (cx.m_Debugger != null) {
                debuggerFrame = cx.m_Debugger.GetFrame (cx, idata);
                if (debuggerFrame != null) {
                    useActivation = true;
                }
            }

            if (useActivation) {
                // Copy args to new array to pass to enterActivationFunction
                // or debuggerFrame.onEnter
                if (argsDbl != null) {
                    args = GetArgsArray (args, argsDbl, argShift, argCount);
                }
                argShift = 0;
                argsDbl = null;
            }

            IScriptable scope;
            if (idata.itsFunctionType != 0) {
                if (!idata.useDynamicScope) {
                    scope = fnOrScript.ParentScope;
                }
                else {
                    scope = callerScope;
                }

                if (useActivation) {
                    scope = ScriptRuntime.createFunctionActivation (fnOrScript, scope, args);
                }
            }
            else {
                scope = callerScope;
                ScriptRuntime.initScript (fnOrScript, thisObj, cx, scope, fnOrScript.idata.evalScriptFlag);
            }

            if (idata.itsNestedFunctions != null) {
                if (idata.itsFunctionType != 0 && !idata.itsNeedsActivation)
                    Context.CodeBug ();
                for (int i = 0; i < idata.itsNestedFunctions.Length; i++) {
                    InterpreterData fdata = idata.itsNestedFunctions [i];
                    if (fdata.itsFunctionType == FunctionNode.FUNCTION_STATEMENT) {
                        initFunction (cx, scope, fnOrScript, i);
                    }
                }
            }

            IScriptable [] scriptRegExps = null;
            if (idata.itsRegExpLiterals != null) {
                // Wrapped regexps for functions are stored in
                // InterpretedFunction
                // but for script which should not contain references to scope
                // the regexps re-wrapped during each script execution
                if (idata.itsFunctionType != 0) {
                    scriptRegExps = fnOrScript.functionRegExps;
                }
                else {
                    scriptRegExps = fnOrScript.createRegExpWraps (cx, scope);
                }
            }

            // Initialize args, vars, locals and stack

            int emptyStackTop = idata.itsMaxVars + idata.itsMaxLocals - 1;
            int maxFrameArray = idata.itsMaxFrameArray;
            if (maxFrameArray != emptyStackTop + idata.itsMaxStack + 1)
                Context.CodeBug ();

            object [] stack;
            double [] sDbl;
            bool stackReuse;
            if (frame.stack != null && maxFrameArray <= frame.stack.Length) {
                // Reuse stacks from old frame
                stackReuse = true;
                stack = frame.stack;
                sDbl = frame.sDbl;
            }
            else {
                stackReuse = false;
                stack = new object [maxFrameArray];
                sDbl = new double [maxFrameArray];
            }

            int definedArgs = idata.argCount;
            if (definedArgs > argCount) {
                definedArgs = argCount;
            }

            // Fill the frame structure

            frame.parentFrame = parentFrame;
            frame.frameIndex = (parentFrame == null) ? 0 : parentFrame.frameIndex + 1;
            if (frame.frameIndex > cx.MaximumInterpreterStackDepth)
                throw ScriptRuntime.TypeErrorById ("msg.stackoverflow");
            frame.frozen = false;

            frame.fnOrScript = fnOrScript;
            frame.idata = idata;

            frame.stack = stack;
            frame.sDbl = sDbl;
            frame.varSource = frame;
            frame.localShift = idata.itsMaxVars;
            frame.emptyStackTop = emptyStackTop;

            frame.debuggerFrame = debuggerFrame;
            frame.useActivation = useActivation;

            frame.thisObj = thisObj;
            frame.scriptRegExps = scriptRegExps;

            // Initialize initial values of variables that change during
            // interpretation.
            frame.result = Undefined.Value;
            frame.pc = 0;
            frame.pcPrevBranch = 0;
            frame.pcSourceLineStart = idata.firstLinePC;
            frame.scope = scope;

            frame.savedStackTop = emptyStackTop;
            frame.savedCallOp = 0;

            Array.Copy (args, argShift, stack, 0, definedArgs);
            if (argsDbl != null) {
                Array.Copy (argsDbl, argShift, sDbl, 0, definedArgs);
            }
            for (int i = definedArgs; i != idata.itsMaxVars; ++i) {
                stack [i] = Undefined.Value;
            }
            if (stackReuse) {
                // Clean the stack part and space beyond stack if any
                // of the old array to allow to GC objects there
                for (int i = emptyStackTop + 1; i != stack.Length; ++i) {
                    stack [i] = null;
                }
            }

            EnterFrame (cx, frame, args);
        }
Пример #56
0
        static int getExceptionHandler (CallFrame frame, bool onlyFinally)
        {
            int [] exceptionTable = frame.idata.itsExceptionTable;
            if (exceptionTable == null) {
                // No exception handlers
                return -1;
            }

            // Icode switch in the interpreter increments PC immediately
            // and it is necessary to subtract 1 from the saved PC
            // to point it before the start of the next instruction.
            int pc = frame.pc - 1;

            // OPT: use binary search
            int best = -1, bestStart = 0, bestEnd = 0;
            for (int i = 0; i != exceptionTable.Length; i += EXCEPTION_SLOT_SIZE) {
                int start = exceptionTable [i + EXCEPTION_TRY_START_SLOT];
                int end = exceptionTable [i + EXCEPTION_TRY_END_SLOT];
                if (!(start <= pc && pc < end)) {
                    continue;
                }
                if (onlyFinally && exceptionTable [i + EXCEPTION_TYPE_SLOT] != 1) {
                    continue;
                }
                if (best >= 0) {
                    // Since handlers always nest and they never have shared end
                    // although they can share start  it is sufficient to compare
                    // handlers ends
                    if (bestEnd < end) {
                        continue;
                    }
                    // Check the above assumption
                    if (bestStart > start)
                        Context.CodeBug (); // should be nested
                    if (bestEnd == end)
                        Context.CodeBug (); // no ens sharing
                }
                best = i;
                bestStart = start;
                bestEnd = end;
            }
            return best;
        }
Пример #57
0
        internal static object Interpret (InterpretedFunction ifun, Context cx, IScriptable scope, IScriptable thisObj, object [] args)
        {
            using (Helpers.StackOverflowVerifier sov = new Helpers.StackOverflowVerifier (128)) {
                if (!ScriptRuntime.hasTopCall (cx))
                    Context.CodeBug ();

                if (cx.interpreterSecurityDomain != ifun.securityDomain) {
                    object savedDomain = cx.interpreterSecurityDomain;
                    cx.interpreterSecurityDomain = ifun.securityDomain;
                    try {
                        return ifun.securityController.callWithDomain (ifun.securityDomain, cx, ifun, scope, thisObj, args);
                    }
                    finally {
                        cx.interpreterSecurityDomain = savedDomain;
                    }
                }

                CallFrame frame = new CallFrame ();
                initFrame (cx, scope, thisObj, args, null, 0, args.Length, ifun, null, frame);

                return InterpretLoop (cx, frame, (object)null);
            }
        }