blob: ba195b86746379c629a7dd5316da6fdae6494314 [file] [log] [blame]
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +00001/*
2 * Copyright (C) 2008 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
weinig@apple.coma963b962008-06-05 05:36:55 +000028
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000029#ifndef Machine_h
30#define Machine_h
31
32#include "Opcode.h"
ggaren@apple.com82a62d02008-06-27 22:35:33 +000033#include "RegisterFile.h"
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000034#include <kjs/list.h>
weinig@apple.coma963b962008-06-05 05:36:55 +000035#include <wtf/HashMap.h>
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000036
37namespace KJS {
38
39 class CodeBlock;
40 class EvalNode;
41 class ExecState;
42 class FunctionBodyNode;
ggaren@apple.com82a62d02008-06-27 22:35:33 +000043 class Instruction;
44 class JSFunction;
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000045 class ProgramNode;
46 class Register;
47 class RegisterFile;
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000048 class ScopeChainNode;
weinig@apple.coma963b962008-06-05 05:36:55 +000049
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000050 enum DebugHookID {
ggaren@apple.comd0740c82008-05-28 20:47:13 +000051 WillExecuteProgram,
52 DidExecuteProgram,
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000053 DidEnterCallFrame,
oliver@apple.com139b5292008-06-03 22:48:52 +000054 DidReachBreakpoint,
ggaren@apple.comd0740c82008-05-28 20:47:13 +000055 WillLeaveCallFrame,
56 WillExecuteStatement
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000057 };
58
ggaren@apple.com4668b2f2008-06-02 16:36:01 +000059 enum { MaxReentryDepth = 128 };
60
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000061 class Machine {
62 public:
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000063 Machine();
ggaren@apple.com82a62d02008-06-27 22:35:33 +000064
65 RegisterFile& registerFile() { return m_registerFile; }
66
weinig@apple.coma963b962008-06-05 05:36:55 +000067 Opcode getOpcode(OpcodeID id)
68 {
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000069 #if HAVE(COMPUTED_GOTO)
weinig@apple.coma963b962008-06-05 05:36:55 +000070 return m_opcodeTable[id];
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000071 #else
72 return id;
73 #endif
74 }
75
weinig@apple.coma963b962008-06-05 05:36:55 +000076 OpcodeID getOpcodeID(Opcode opcode)
77 {
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000078 #if HAVE(COMPUTED_GOTO)
79 ASSERT(isOpcode(opcode));
80 return m_opcodeIDTable.get(opcode);
81 #else
82 return opcode;
83 #endif
84 }
85
86 bool isOpcode(Opcode opcode);
ggaren@apple.com82a62d02008-06-27 22:35:33 +000087
88 JSValue* execute(ProgramNode*, ExecState*, ScopeChainNode*, JSObject* thisObj, JSValue** exception);
89 JSValue* execute(FunctionBodyNode*, ExecState*, JSFunction*, JSObject* thisObj, const ArgList& args, ScopeChainNode*, JSValue** exception);
90 JSValue* execute(EvalNode* evalNode, ExecState* exec, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue** exception)
91 {
92 return execute(evalNode, exec, thisObj, m_registerFile.size(), scopeChain, exception);
93 }
weinig@apple.coma963b962008-06-05 05:36:55 +000094
darin@apple.com980c6142008-06-16 02:19:08 +000095 JSValue* retrieveArguments(ExecState*, JSFunction*) const;
96 JSValue* retrieveCaller(ExecState*, JSFunction*) const;
weinig@apple.coma963b962008-06-05 05:36:55 +000097
darin@apple.com980c6142008-06-16 02:19:08 +000098 void getFunctionAndArguments(Register** registerBase, Register* callFrame, JSFunction*&, Register*& argv, int& argc);
weinig@apple.coma963b962008-06-05 05:36:55 +000099
ggaren@apple.com82a62d02008-06-27 22:35:33 +0000100 void mark(Heap* heap) { m_registerFile.mark(heap); }
101
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000102 private:
weinig@apple.coma963b962008-06-05 05:36:55 +0000103 enum ExecutionFlag { Normal, InitializeAndReturn };
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000104
ggaren@apple.com82a62d02008-06-27 22:35:33 +0000105 friend NEVER_INLINE JSValue* callEval(ExecState* exec, JSObject* thisObj, ScopeChainNode* scopeChain, RegisterFile*, Register* r, int argv, int argc, JSValue*& exceptionValue);
106 JSValue* execute(EvalNode*, ExecState*, JSObject* thisObj, int registerOffset, ScopeChainNode*, JSValue** exception);
107
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000108 ALWAYS_INLINE void setScopeChain(ExecState* exec, ScopeChainNode*&, ScopeChainNode*);
109 NEVER_INLINE void debug(ExecState*, const Instruction*, const CodeBlock*, ScopeChainNode*, Register**, Register*);
110
111 NEVER_INLINE bool unwindCallFrame(ExecState*, JSValue*, Register**, const Instruction*&, CodeBlock*&, JSValue**&, ScopeChainNode*&, Register*&);
112 NEVER_INLINE Instruction* throwException(ExecState*, JSValue*, Register**, const Instruction*, CodeBlock*&, JSValue**&, ScopeChainNode*&, Register*&);
weinig@apple.coma963b962008-06-05 05:36:55 +0000113
darin@apple.com980c6142008-06-16 02:19:08 +0000114 bool getCallFrame(ExecState*, JSFunction*, Register**& registerBase, int& callFrameOffset) const;
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000115
116 JSValue* privateExecute(ExecutionFlag, ExecState* = 0, RegisterFile* = 0, Register* = 0, ScopeChainNode* = 0, CodeBlock* = 0, JSValue** exception = 0);
117
118 void dumpCallFrame(const CodeBlock*, ScopeChainNode*, RegisterFile*, const Register*);
119 void dumpRegisters(const CodeBlock*, RegisterFile*, const Register*);
weinig@apple.coma963b962008-06-05 05:36:55 +0000120
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000121 int m_reentryDepth;
ggaren@apple.com82a62d02008-06-27 22:35:33 +0000122 RegisterFile m_registerFile;
123
weinig@apple.coma963b962008-06-05 05:36:55 +0000124#if HAVE(COMPUTED_GOTO)
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000125 Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
126 HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
127#endif
128 };
weinig@apple.coma963b962008-06-05 05:36:55 +0000129
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000130} // namespace KJS
131
132#endif // Machine_h