de4ccc5a14f9b52d8857ec4c0fe840e7025523f8
[WebKit-https.git] / JavaScriptCore / VM / Machine.cpp
1 /*
2  * Copyright (C) 2008 Apple Inc. All rights reserved.
3  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "Machine.h"
32
33 #include "CodeBlock.h"
34 #include "DebuggerCallFrame.h"
35 #include "ExceptionHelpers.h"
36 #include "ExecState.h"
37 #include "GlobalEvalFunction.h"
38 #include "JSActivation.h"
39 #include "JSArray.h"
40 #include "JSFunction.h"
41 #include "JSNotAnObject.h"
42 #include "JSPropertyNameIterator.h"
43 #include "JSStaticScopeObject.h"
44 #include "JSString.h"
45 #include "ObjectPrototype.h"
46 #include "Parser.h"
47 #include "Profiler.h"
48 #include "RegExpObject.h"
49 #include "RegExpPrototype.h"
50 #include "Register.h"
51 #include "collector.h"
52 #include "debugger.h"
53 #include "operations.h"
54 #include "SamplingTool.h"
55 #include <stdio.h>
56
57 #if HAVE(SYS_TIME_H)
58 #include <sys/time.h>
59 #endif
60
61 #if PLATFORM(WIN_OS)
62 #include <windows.h>
63 #endif
64
65 #if PLATFORM(QT)
66 #include <QDateTime>
67 #endif
68
69 using namespace std;
70
71 namespace KJS {
72
73 // Default number of ticks before a timeout check should be done.
74 static const int initialTickCountThreshold = 255;
75
76 // Preferred number of milliseconds between each timeout check
77 static const int preferredScriptCheckTimeInterval = 1000;
78
79 #if HAVE(COMPUTED_GOTO)
80 static void* op_throw_end_indirect;
81 static void* op_call_indirect;
82 #endif
83
84 // Returns the depth of the scope chain within a given call frame.
85 static int depth(ScopeChain& sc)
86 {
87     int scopeDepth = 0;
88     ScopeChainIterator iter = sc.begin();
89     ScopeChainIterator end = sc.end();
90     while (!(*iter)->isActivationObject()) {
91         ++iter;
92         if (iter == end)
93             break;
94         ++scopeDepth;
95     }
96     return scopeDepth;
97 }
98
99 static inline bool jsLess(ExecState* exec, JSValue* v1, JSValue* v2)
100 {
101     if (JSImmediate::areBothImmediateNumbers(v1, v2))
102         return JSImmediate::getTruncatedInt32(v1) < JSImmediate::getTruncatedInt32(v2);
103
104     double n1;
105     double n2;
106     JSValue* p1;
107     JSValue* p2;
108     bool wasNotString1 = v1->getPrimitiveNumber(exec, n1, p1);
109     bool wasNotString2 = v2->getPrimitiveNumber(exec, n2, p2);
110
111     if (wasNotString1 | wasNotString2)
112         return n1 < n2;
113
114     return static_cast<const JSString*>(p1)->value() < static_cast<const JSString*>(p2)->value();
115 }
116
117 static inline bool jsLessEq(ExecState* exec, JSValue* v1, JSValue* v2)
118 {
119     if (JSImmediate::areBothImmediateNumbers(v1, v2))
120         return JSImmediate::getTruncatedInt32(v1) <= JSImmediate::getTruncatedInt32(v2);
121
122     double n1;
123     double n2;
124     JSValue* p1;
125     JSValue* p2;
126     bool wasNotString1 = v1->getPrimitiveNumber(exec, n1, p1);
127     bool wasNotString2 = v2->getPrimitiveNumber(exec, n2, p2);
128
129     if (wasNotString1 | wasNotString2)
130         return n1 <= n2;
131
132     return !(static_cast<const JSString*>(p2)->value() < static_cast<const JSString*>(p1)->value());
133 }
134
135 static JSValue* jsAddSlowCase(ExecState* exec, JSValue* v1, JSValue* v2)
136 {
137     // exception for the Date exception in defaultValue()
138     JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);
139     JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType);
140
141     if (p1->isString() || p2->isString()) {
142         UString value = p1->toString(exec) + p2->toString(exec);
143         if (value.isNull())
144             return throwOutOfMemoryError(exec);
145         return jsString(exec, value);
146     }
147
148     return jsNumber(exec, p1->toNumber(exec) + p2->toNumber(exec));
149 }
150
151 // Fast-path choices here are based on frequency data from SunSpider:
152 //    <times> Add case: <t1> <t2>
153 //    ---------------------------
154 //    5626160 Add case: 3 3 (of these, 3637690 are for immediate values)
155 //    247412  Add case: 5 5
156 //    20900   Add case: 5 6
157 //    13962   Add case: 5 3
158 //    4000    Add case: 3 5
159
160 static inline JSValue* jsAdd(ExecState* exec, JSValue* v1, JSValue* v2)
161 {
162     JSType t1 = v1->type();
163     JSType t2 = v2->type();
164     const unsigned bothTypes = (t1 << 3) | t2;
165
166     if (bothTypes == ((NumberType << 3) | NumberType))
167         return jsNumber(exec, v1->uncheckedGetNumber() + v2->uncheckedGetNumber());
168     if (bothTypes == ((StringType << 3) | StringType)) {
169         UString value = static_cast<JSString*>(v1)->value() + static_cast<JSString*>(v2)->value();
170         if (value.isNull())
171             return throwOutOfMemoryError(exec);
172         return jsString(exec, value);
173     }
174
175     // All other cases are pretty uncommon
176     return jsAddSlowCase(exec, v1, v2);
177 }
178
179 static JSValue* jsTypeStringForValue(ExecState* exec, JSValue* v)
180 {
181     switch (v->type()) {
182         case UndefinedType:
183             return jsString(exec, "undefined");
184         case NullType:
185             return jsString(exec, "object");
186         case BooleanType:
187             return jsString(exec, "boolean");
188         case NumberType:
189             return jsString(exec, "number");
190         case StringType:
191             return jsString(exec, "string");
192         default:
193             if (v->isObject()) {
194                 // Return "undefined" for objects that should be treated
195                 // as null when doing comparisons.
196                 if (static_cast<JSObject*>(v)->masqueradeAsUndefined())
197                     return jsString(exec, "undefined");
198                 CallData callData;
199                 if (static_cast<JSObject*>(v)->getCallData(callData) != CallTypeNone)
200                     return jsString(exec, "function");
201             }
202
203             return jsString(exec, "object");
204     }
205 }
206
207 static bool NEVER_INLINE resolve(ExecState* exec, Instruction* vPC, Register* r, ScopeChainNode* scopeChain, CodeBlock* codeBlock, JSValue*& exceptionValue)
208 {
209     int dst = (vPC + 1)->u.operand;
210     int property = (vPC + 2)->u.operand;
211
212     ScopeChainIterator iter = scopeChain->begin();
213     ScopeChainIterator end = scopeChain->end();
214     ASSERT(iter != end);
215
216     Identifier& ident = codeBlock->identifiers[property];
217     do {
218         JSObject* o = *iter;
219         PropertySlot slot(o);
220         if (o->getPropertySlot(exec, ident, slot)) {
221             JSValue* result = slot.getValue(exec, ident);
222             exceptionValue = exec->exception();
223             if (exceptionValue)
224                 return false;
225             r[dst] = result;
226             return true;
227         }
228     } while (++iter != end);
229     exceptionValue = createUndefinedVariableError(exec, ident, vPC, codeBlock);
230     return false;
231 }
232
233 static bool NEVER_INLINE resolve_skip(ExecState* exec, Instruction* vPC, Register* r, ScopeChainNode* scopeChain, CodeBlock* codeBlock, JSValue*& exceptionValue)
234 {
235     int dst = (vPC + 1)->u.operand;
236     int property = (vPC + 2)->u.operand;
237     int skip = (vPC + 3)->u.operand + codeBlock->needsFullScopeChain;
238
239     ScopeChainIterator iter = scopeChain->begin();
240     ScopeChainIterator end = scopeChain->end();
241     ASSERT(iter != end);
242     while (skip--) {
243         ++iter;
244         ASSERT(iter != end);
245     }
246     Identifier& ident = codeBlock->identifiers[property];
247     do {
248         JSObject* o = *iter;
249         PropertySlot slot(o);
250         if (o->getPropertySlot(exec, ident, slot)) {
251             JSValue* result = slot.getValue(exec, ident);
252             exceptionValue = exec->exception();
253             if (exceptionValue)
254                 return false;
255             r[dst] = result;
256             return true;
257         }
258     } while (++iter != end);
259     exceptionValue = createUndefinedVariableError(exec, ident, vPC, codeBlock);
260     return false;
261 }
262
263 static void NEVER_INLINE resolveBase(ExecState* exec, Instruction* vPC, Register* r, ScopeChainNode* scopeChain, CodeBlock* codeBlock)
264 {
265     int dst = (vPC + 1)->u.operand;
266     int property = (vPC + 2)->u.operand;
267
268     ScopeChainIterator iter = scopeChain->begin();
269     ScopeChainIterator next = iter;
270     ++next;
271     ScopeChainIterator end = scopeChain->end();
272     ASSERT(iter != end);
273
274     PropertySlot slot;
275     Identifier& ident = codeBlock->identifiers[property];
276     JSObject* base;
277     while (true) {
278         base = *iter;
279         if (next == end || base->getPropertySlot(exec, ident, slot)) {
280             r[dst] = base;
281             return;
282         }
283         iter = next;
284         ++next;
285     }
286 }
287
288 static bool NEVER_INLINE resolveBaseAndProperty(ExecState* exec, Instruction* vPC, Register* r, ScopeChainNode* scopeChain, CodeBlock* codeBlock, JSValue*& exceptionValue)
289 {
290     int baseDst = (vPC + 1)->u.operand;
291     int propDst = (vPC + 2)->u.operand;
292     int property = (vPC + 3)->u.operand;
293
294     ScopeChainIterator iter = scopeChain->begin();
295     ScopeChainIterator end = scopeChain->end();
296
297     // FIXME: add scopeDepthIsZero optimization
298
299     ASSERT(iter != end);
300
301     Identifier& ident = codeBlock->identifiers[property];
302     JSObject* base;
303     do {
304         base = *iter;
305         PropertySlot slot(base);
306         if (base->getPropertySlot(exec, ident, slot)) {
307             JSValue* result = slot.getValue(exec, ident);
308             exceptionValue = exec->exception();
309             if (exceptionValue)
310                 return false;
311             r[propDst] = result;
312             r[baseDst] = base;
313             return true;
314         }
315         ++iter;
316     } while (iter != end);
317
318     exceptionValue = createUndefinedVariableError(exec, ident, vPC, codeBlock);
319     return false;
320 }
321
322 static bool NEVER_INLINE resolveBaseAndFunc(ExecState* exec, Instruction* vPC, Register* r, ScopeChainNode* scopeChain, CodeBlock* codeBlock, JSValue*& exceptionValue)
323 {
324     int baseDst = (vPC + 1)->u.operand;
325     int funcDst = (vPC + 2)->u.operand;
326     int property = (vPC + 3)->u.operand;
327
328     ScopeChainIterator iter = scopeChain->begin();
329     ScopeChainIterator end = scopeChain->end();
330
331     // FIXME: add scopeDepthIsZero optimization
332
333     ASSERT(iter != end);
334
335     Identifier& ident = codeBlock->identifiers[property];
336     JSObject* base;
337     do {
338         base = *iter;
339         PropertySlot slot(base);
340         if (base->getPropertySlot(exec, ident, slot)) {            
341             // ECMA 11.2.3 says that if we hit an activation the this value should be null.
342             // However, section 10.2.3 says that in the case where the value provided
343             // by the caller is null, the global object should be used. It also says
344             // that the section does not apply to internal functions, but for simplicity
345             // of implementation we use the global object anyway here. This guarantees
346             // that in host objects you always get a valid object for this.
347             // We also handle wrapper substitution for the global object at the same time.
348             JSObject* thisObj = base->toThisObject(exec);
349             JSValue* result = slot.getValue(exec, ident);
350             exceptionValue = exec->exception();
351             if (exceptionValue)
352                 return false;
353
354             r[baseDst] = thisObj;
355             r[funcDst] = result;
356             return true;
357         }
358         ++iter;
359     } while (iter != end);
360
361     exceptionValue = createUndefinedVariableError(exec, ident, vPC, codeBlock);
362     return false;
363 }
364
365 ALWAYS_INLINE void Machine::initializeCallFrame(Register* callFrame, CodeBlock* codeBlock, Instruction* vPC, ScopeChainNode* scopeChain, Register* r, int returnValueRegister, int argv, int argc, int calledAsConstructor, JSValue* function)
366 {
367     callFrame[RegisterFile::CallerCodeBlock] = codeBlock;
368     callFrame[RegisterFile::ReturnVPC] = vPC + 1;
369     callFrame[RegisterFile::CallerScopeChain] = scopeChain;
370     callFrame[RegisterFile::CallerRegisters] = r;
371     callFrame[RegisterFile::ReturnValueRegister] = returnValueRegister;
372     callFrame[RegisterFile::ArgumentStartRegister] = argv; // original argument vector (for the sake of the "arguments" object)
373     callFrame[RegisterFile::ArgumentCount] = argc; // original argument count (for the sake of the "arguments" object)
374     callFrame[RegisterFile::CalledAsConstructor] = calledAsConstructor;
375     callFrame[RegisterFile::Callee] = function;
376     callFrame[RegisterFile::OptionalCalleeActivation] = nullJSValue;
377 }
378
379 ALWAYS_INLINE Register* slideRegisterWindowForCall(ExecState* exec, CodeBlock* newCodeBlock, RegisterFile* registerFile, Register* registerBase, Register* r, int argv, int argc, JSValue*& exceptionValue)
380 {
381     size_t registerOffset = argv + newCodeBlock->numLocals;
382     size_t size = r - registerBase + registerOffset + newCodeBlock->numTemporaries;
383
384     if (argc == newCodeBlock->numParameters) { // correct number of arguments
385         if (!registerFile->grow(size)) {
386             exceptionValue = createStackOverflowError(exec);
387             return r;
388         }
389         r += registerOffset;
390     } else if (argc < newCodeBlock->numParameters) { // too few arguments -- fill in the blanks
391         if (!registerFile->grow(size)) {
392             exceptionValue = createStackOverflowError(exec);
393             return r;
394         }
395         r += registerOffset;
396
397         int omittedArgCount = newCodeBlock->numParameters - argc;
398         Register* endOfParams = r - newCodeBlock->numVars;
399         for (Register* it = endOfParams - omittedArgCount; it != endOfParams; ++it)
400             (*it) = jsUndefined();
401     } else { // too many arguments -- copy return info and expected arguments, leaving the extra arguments behind
402         int shift = argc + RegisterFile::CallFrameHeaderSize;
403         registerOffset += shift;
404         size += shift;
405
406         if (!registerFile->grow(size)) {
407             exceptionValue = createStackOverflowError(exec);
408             return r;
409         }
410         r += registerOffset;
411
412         Register* it = r - newCodeBlock->numLocals - RegisterFile::CallFrameHeaderSize - shift;
413         Register* end = it + RegisterFile::CallFrameHeaderSize + newCodeBlock->numParameters;
414         for ( ; it != end; ++it)
415             *(it + shift) = *it;
416     }
417     
418     // initialize local variable slots
419     for (Register* it = r - newCodeBlock->numVars; it != r; ++it)
420         (*it) = jsUndefined();
421
422     return r;
423 }
424
425 ALWAYS_INLINE ScopeChainNode* scopeChainForCall(ExecState* exec, FunctionBodyNode* functionBodyNode, CodeBlock* newCodeBlock, ScopeChainNode* callDataScopeChain, Register* r)
426 {
427     if (newCodeBlock->needsFullScopeChain) {
428         JSActivation* activation = new (exec) JSActivation(functionBodyNode, r);
429         r[RegisterFile::OptionalCalleeActivation - RegisterFile::CallFrameHeaderSize - newCodeBlock->numLocals] = activation;
430
431         return callDataScopeChain->copy()->push(activation);
432     }
433
434     return callDataScopeChain;
435 }
436
437 static NEVER_INLINE bool isNotObject(ExecState* exec, bool forInstanceOf, CodeBlock* codeBlock, const Instruction* vPC, JSValue* value, JSValue*& exceptionData)
438 {
439     if (value->isObject())
440         return false;
441     exceptionData = createInvalidParamError(exec, forInstanceOf ? "instanceof" : "in" , value, vPC, codeBlock);
442     return true;
443 }
444
445 NEVER_INLINE JSValue* Machine::callEval(ExecState* exec, JSObject* thisObj, ScopeChainNode* scopeChain, RegisterFile* registerFile, Register* r, int argv, int argc, JSValue*& exceptionValue)
446 {
447     if (argc < 2)
448         return jsUndefined();
449
450     JSValue* program = r[argv + 1].jsValue(exec);
451
452     if (!program->isString())
453         return program;
454
455     Profiler** profiler = Profiler::enabledProfilerReference();
456     if (*profiler)
457         (*profiler)->willExecute(exec, scopeChain->globalObject()->evalFunction());
458
459     int sourceId;
460     int errLine;
461     UString errMsg;
462     RefPtr<EvalNode> evalNode = exec->parser()->parse<EvalNode>(exec, UString(), 1, UStringSourceProvider::create(static_cast<JSString*>(program)->value()), &sourceId, &errLine, &errMsg);
463
464     if (!evalNode) {
465         exceptionValue = Error::create(exec, SyntaxError, errMsg, errLine, sourceId, NULL);
466         if (*profiler)
467             (*profiler)->didExecute(exec, scopeChain->globalObject()->evalFunction());
468         return 0;
469     }
470
471     JSValue* result = exec->globalData().machine->execute(evalNode.get(), exec, thisObj, r - registerFile->base() + argv + argc, scopeChain, &exceptionValue);
472
473     if (*profiler)
474         (*profiler)->didExecute(exec, scopeChain->globalObject()->evalFunction());
475
476     return result;
477 }
478
479 Machine::Machine()
480     : m_sampler(0)
481     , m_reentryDepth(0)
482     , m_timeoutTime(0)
483     , m_timeAtLastCheckTimeout(0)
484     , m_timeExecuting(0)
485     , m_timeoutCheckCount(0)
486     , m_ticksUntilNextTimeoutCheck(initialTickCountThreshold)
487 {
488     privateExecute(InitializeAndReturn);
489     
490     // Bizarrely, calling fastMalloc here is faster than allocating space on the stack.
491     void* storage = fastMalloc(sizeof(CollectorBlock));
492
493     JSArray* jsArray = new (storage) JSArray(jsNull(), 0);
494     m_jsArrayVptr = jsArray->vptr();
495     static_cast<JSCell*>(jsArray)->~JSCell();
496
497     JSString* jsString = new (storage) JSString("");
498     m_jsStringVptr = jsString->vptr();
499     static_cast<JSCell*>(jsString)->~JSCell();
500     
501     fastFree(storage);
502 }
503
504 void Machine::dumpCallFrame(const CodeBlock* codeBlock, ScopeChainNode* scopeChain, RegisterFile* registerFile, const Register* r)
505 {
506     ScopeChain sc(scopeChain);
507     JSGlobalObject* globalObject = sc.globalObject();
508     codeBlock->dump(globalObject->globalExec());
509     dumpRegisters(codeBlock, registerFile, r);
510 }
511
512 void Machine::dumpRegisters(const CodeBlock* codeBlock, RegisterFile* registerFile, const Register* r)
513 {
514     printf("Register frame: \n\n");
515     printf("----------------------------------------------------\n");
516     printf("            use            |   address  |   value   \n");
517     printf("----------------------------------------------------\n");
518
519     const Register* it;
520     const Register* end;
521
522     if (codeBlock->codeType == GlobalCode) {
523         it = registerFile->lastGlobal();
524         end = it + registerFile->numGlobals();
525         while (it != end) {
526             printf("[global var]               | %10p | %10p \n", it, (*it).v());
527             ++it;
528         }
529         printf("----------------------------------------------------\n");
530     }
531     
532     it = r - codeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
533     printf("[CallerCodeBlock]          | %10p | %10p \n", it, (*it).v()); ++it;
534     printf("[ReturnVPC]                | %10p | %10p \n", it, (*it).v()); ++it;
535     printf("[CallerScopeChain]         | %10p | %10p \n", it, (*it).v()); ++it;
536     printf("[CallerRegisterOffset]     | %10p | %10p \n", it, (*it).v()); ++it;
537     printf("[ReturnValueRegister]      | %10p | %10p \n", it, (*it).v()); ++it;
538     printf("[ArgumentStartRegister]    | %10p | %10p \n", it, (*it).v()); ++it;
539     printf("[ArgumentCount]            | %10p | %10p \n", it, (*it).v()); ++it;
540     printf("[CalledAsConstructor]      | %10p | %10p \n", it, (*it).v()); ++it;
541     printf("[Callee]                   | %10p | %10p \n", it, (*it).v()); ++it;
542     printf("[OptionalCalleeActivation] | %10p | %10p \n", it, (*it).v()); ++it;
543     printf("----------------------------------------------------\n");
544
545     printf("[this]                     | %10p | %10p \n", it, (*it).v()); ++it;
546     end = it + max(codeBlock->numParameters - 1, 0); // - 1 to skip "this"
547     if (it != end) {
548         do {
549             printf("[param]                    | %10p | %10p \n", it, (*it).v());
550             ++it;
551         } while (it != end);
552     }
553     printf("----------------------------------------------------\n");
554
555     if (codeBlock->codeType != GlobalCode) {
556         end = it + codeBlock->numVars;
557         if (it != end) {
558             do {
559                 printf("[var]                      | %10p | %10p \n", it, (*it).v());
560                 ++it;
561             } while (it != end);
562         printf("----------------------------------------------------\n");
563         }
564     }
565
566     end = it + codeBlock->numTemporaries;
567     if (it != end) {
568         do {
569             printf("[temp]                     | %10p | %10p \n", it, (*it).v());
570             ++it;
571         } while (it != end);
572     }
573 }
574
575 bool Machine::isOpcode(Opcode opcode)
576 {
577 #if HAVE(COMPUTED_GOTO)
578     return opcode != HashTraits<Opcode>::emptyValue()
579         && !HashTraits<Opcode>::isDeletedValue(opcode)
580         && m_opcodeIDTable.contains(opcode);
581 #else
582     return opcode >= 0 && opcode <= op_end;
583 #endif
584 }
585
586 NEVER_INLINE bool Machine::unwindCallFrame(ExecState* exec, JSValue* exceptionValue, const Instruction*& vPC, CodeBlock*& codeBlock, Register*& k, ScopeChainNode*& scopeChain, Register*& r)
587 {
588     CodeBlock* oldCodeBlock = codeBlock;
589     Register* callFrame = r - oldCodeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
590
591     if (Debugger* debugger = exec->dynamicGlobalObject()->debugger()) {
592         DebuggerCallFrame debuggerCallFrame(exec->dynamicGlobalObject(), codeBlock, scopeChain, r, exceptionValue);
593         if (callFrame[RegisterFile::Callee].jsValue(exec))
594             debugger->returnEvent(debuggerCallFrame, codeBlock->ownerNode->sourceId(), codeBlock->ownerNode->lastLine());
595         else
596             debugger->didExecuteProgram(debuggerCallFrame, codeBlock->ownerNode->sourceId(), codeBlock->ownerNode->lastLine());
597     }
598
599     if (Profiler* profiler = *Profiler::enabledProfilerReference()) {
600         if (callFrame[RegisterFile::Callee].jsValue(exec))
601             profiler->didExecute(exec, static_cast<JSObject*>(callFrame[RegisterFile::Callee].jsValue(exec)));
602         else
603             profiler->didExecute(exec, codeBlock->ownerNode->sourceURL(), codeBlock->ownerNode->lineNo());
604     }
605
606     if (oldCodeBlock->needsFullScopeChain)
607         scopeChain->deref();
608
609     // If this call frame created an activation, tear it off.
610     if (JSActivation* activation = static_cast<JSActivation*>(callFrame[RegisterFile::OptionalCalleeActivation].jsValue(exec))) {
611         ASSERT(activation->isActivationObject());
612         activation->copyRegisters();
613     }
614     
615     codeBlock = callFrame[RegisterFile::CallerCodeBlock].codeBlock();
616     if (!codeBlock)
617         return false;
618
619     k = codeBlock->registers.data();
620     scopeChain = callFrame[RegisterFile::CallerScopeChain].scopeChain();
621     r = callFrame[RegisterFile::CallerRegisters].r();
622     exec->m_callFrame = r - oldCodeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
623     vPC = callFrame[RegisterFile::ReturnVPC].vPC();
624
625     return true;
626 }
627
628 NEVER_INLINE Instruction* Machine::throwException(ExecState* exec, JSValue*& exceptionValue, const Instruction* vPC, CodeBlock*& codeBlock, Register*& k, ScopeChainNode*& scopeChain, Register*& r, bool explicitThrow)
629 {
630     // Set up the exception object
631
632     if (exceptionValue->isObject()) {
633         JSObject* exception = static_cast<JSObject*>(exceptionValue);
634         if (exception->isNotAnObjectErrorStub()) {
635             exception = createNotAnObjectError(exec, static_cast<JSNotAnObjectErrorStub*>(exception), vPC, codeBlock);
636             exceptionValue = exception;
637         } else {
638             if (!exception->hasProperty(exec, Identifier(exec, "line")) && 
639                 !exception->hasProperty(exec, Identifier(exec, "sourceId")) && 
640                 !exception->hasProperty(exec, Identifier(exec, "sourceURL")) && 
641                 !exception->hasProperty(exec, Identifier(exec, expressionBeginOffsetPropertyName)) && 
642                 !exception->hasProperty(exec, Identifier(exec, expressionCaretOffsetPropertyName)) && 
643                 !exception->hasProperty(exec, Identifier(exec, expressionEndOffsetPropertyName))) {
644                 if (explicitThrow) {
645                     int startOffset = 0;
646                     int endOffset = 0;
647                     int divotPoint = 0;
648                     int line = codeBlock->expressionRangeForVPC(vPC, divotPoint, startOffset, endOffset);
649                     exception->putWithAttributes(exec, Identifier(exec, "line"), jsNumber(exec, line), ReadOnly | DontDelete);
650                     
651                     // We only hit this path for error messages and throw statements, which don't have a specific failure position
652                     // So we just give the full range of the error/throw statement.
653                     exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
654                     exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
655                 } else
656                     exception->putWithAttributes(exec, Identifier(exec, "line"), jsNumber(exec, codeBlock->lineNumberForVPC(vPC)), ReadOnly | DontDelete);
657                 exception->putWithAttributes(exec, Identifier(exec, "sourceId"), jsNumber(exec, codeBlock->ownerNode->sourceId()), ReadOnly | DontDelete);
658                 exception->putWithAttributes(exec, Identifier(exec, "sourceURL"), jsOwnedString(exec, codeBlock->ownerNode->sourceURL()), ReadOnly | DontDelete);
659             }
660             
661             if (exception->isWatchdogException()) {
662                 while (unwindCallFrame(exec, exceptionValue, vPC, codeBlock, k, scopeChain, r)) {
663                     // Don't need handler checks or anything, we just want to unroll all the JS callframes possible.
664                 }
665                 return 0;
666             }
667         }
668     }
669
670     if (Debugger* debugger = exec->dynamicGlobalObject()->debugger()) {
671         DebuggerCallFrame debuggerCallFrame(exec->dynamicGlobalObject(), codeBlock, scopeChain, r, exceptionValue);
672         debugger->exception(debuggerCallFrame, codeBlock->ownerNode->sourceId(), codeBlock->lineNumberForVPC(vPC));
673     }
674
675     // Calculate an exception handler vPC, unwinding call frames as necessary.
676
677     int scopeDepth;
678     Instruction* handlerVPC;
679
680     while (!codeBlock->getHandlerForVPC(vPC, handlerVPC, scopeDepth)) {
681         if (!unwindCallFrame(exec, exceptionValue, vPC, codeBlock, k, scopeChain, r))
682             return 0;
683     }
684
685     // Now unwind the scope chain within the exception handler's call frame.
686
687     ScopeChain sc(scopeChain);
688     int scopeDelta = depth(sc) - scopeDepth;
689     ASSERT(scopeDelta >= 0);
690     while (scopeDelta--)
691         sc.pop();
692     setScopeChain(exec, scopeChain, sc.node());
693
694     return handlerVPC;
695 }
696
697 JSValue* Machine::execute(ProgramNode* programNode, ExecState* exec, ScopeChainNode* scopeChain, JSObject* thisObj, JSValue** exception)
698 {
699     if (m_reentryDepth >= MaxReentryDepth) {
700         *exception = createStackOverflowError(exec);
701         return 0;
702     }
703
704     CodeBlock* codeBlock = &programNode->byteCode(scopeChain);
705
706     size_t oldSize = m_registerFile.size();
707     size_t newSize = oldSize + RegisterFile::CallFrameHeaderSize + codeBlock->numVars + codeBlock->numTemporaries;
708     if (!m_registerFile.grow(newSize)) {
709         *exception = createStackOverflowError(exec);
710         return 0;
711     }
712
713     JSGlobalObject* lastGlobalObject = m_registerFile.globalObject();
714     JSGlobalObject* globalObject = exec->dynamicGlobalObject();
715     globalObject->copyGlobalsTo(m_registerFile);
716
717     Register* callFrame = m_registerFile.base() + oldSize;
718
719     // a 0 codeBlock indicates a built-in caller
720     initializeCallFrame(callFrame, 0, 0, 0, 0, 0, 0, 0, 0, 0);
721
722     Register* r = callFrame + RegisterFile::CallFrameHeaderSize + codeBlock->numVars;
723     r[codeBlock->thisRegister] = thisObj;
724
725     if (codeBlock->needsFullScopeChain)
726         scopeChain = scopeChain->copy();
727
728     ExecState newExec(exec, &m_registerFile, scopeChain, 0);
729
730     Profiler** profiler = Profiler::enabledProfilerReference();
731     if (*profiler)
732         (*profiler)->willExecute(exec, programNode->sourceURL(), programNode->lineNo());
733
734     m_reentryDepth++;
735     JSValue* result = privateExecute(Normal, &newExec, &m_registerFile, r, scopeChain, codeBlock, exception);
736     m_reentryDepth--;
737
738     MACHINE_SAMPLING_privateExecuteReturned();
739
740     if (*profiler) {
741         (*profiler)->didExecute(exec, programNode->sourceURL(), programNode->lineNo());
742         if (!m_reentryDepth)
743             (*profiler)->didFinishAllExecution(exec);
744     }
745
746     if (m_reentryDepth && lastGlobalObject && globalObject != lastGlobalObject)
747         lastGlobalObject->copyGlobalsTo(m_registerFile);
748
749     m_registerFile.shrink(oldSize);
750     return result;
751 }
752
753 JSValue* Machine::execute(FunctionBodyNode* functionBodyNode, ExecState* exec, JSFunction* function, JSObject* thisObj, const ArgList& args, ScopeChainNode* scopeChain, JSValue** exception)
754 {
755     if (m_reentryDepth >= MaxReentryDepth) {
756         *exception = createStackOverflowError(exec);
757         return 0;
758     }
759
760     int argv = RegisterFile::CallFrameHeaderSize;
761     int argc = args.size() + 1; // implicit "this" parameter
762
763     size_t oldSize = m_registerFile.size();
764     if (!m_registerFile.grow(oldSize + RegisterFile::CallFrameHeaderSize + argc)) {
765         *exception = createStackOverflowError(exec);
766         return 0;
767     }
768
769     Register* callFrame = m_registerFile.base() + oldSize;
770
771     // put args in place, including "this"
772     Register* dst = callFrame + RegisterFile::CallFrameHeaderSize;
773     (*dst) = thisObj;
774
775     ArgList::const_iterator end = args.end();
776     for (ArgList::const_iterator it = args.begin(); it != end; ++it)
777         (*++dst) = *it;
778
779     // a 0 codeBlock indicates a built-in caller
780     initializeCallFrame(callFrame, 0, 0, 0, callFrame, 0, argv, argc, 0, function);
781
782     CodeBlock* newCodeBlock = &functionBodyNode->byteCode(scopeChain);
783     Register* r = slideRegisterWindowForCall(exec, newCodeBlock, &m_registerFile, m_registerFile.base(), callFrame, argv, argc, *exception);
784     if (*exception) {
785         m_registerFile.shrink(oldSize);
786         return 0;
787     }
788
789     scopeChain = scopeChainForCall(exec, functionBodyNode, newCodeBlock, scopeChain, r);
790
791     ExecState newExec(exec, &m_registerFile, scopeChain, callFrame);
792
793     Profiler** profiler = Profiler::enabledProfilerReference();
794     if (*profiler)
795         (*profiler)->willExecute(exec, function);
796
797     m_reentryDepth++;
798     JSValue* result = privateExecute(Normal, &newExec, &m_registerFile, r, scopeChain, newCodeBlock, exception);
799     m_reentryDepth--;
800
801     MACHINE_SAMPLING_privateExecuteReturned();
802
803     if (*profiler && !m_reentryDepth)
804         (*profiler)->didFinishAllExecution(exec);
805
806     m_registerFile.shrink(oldSize);
807     return result;
808 }
809
810 JSValue* Machine::execute(EvalNode* evalNode, ExecState* exec, JSObject* thisObj, int registerOffset, ScopeChainNode* scopeChain, JSValue** exception)
811 {
812     if (m_reentryDepth >= MaxReentryDepth) {
813         *exception = createStackOverflowError(exec);
814         return 0;
815     }
816
817     EvalCodeBlock* codeBlock = &evalNode->byteCode(scopeChain);
818
819     JSVariableObject* variableObject;
820     for (ScopeChainNode* node = scopeChain; ; node = node->next) {
821         ASSERT(node);
822         if (node->object->isVariableObject()) {
823             variableObject = static_cast<JSVariableObject*>(node->object);
824             break;
825         }
826     }
827
828     const Node::VarStack& varStack = codeBlock->ownerNode->varStack();
829     Node::VarStack::const_iterator varStackEnd = varStack.end();
830     for (Node::VarStack::const_iterator it = varStack.begin(); it != varStackEnd; ++it) {
831         const Identifier& ident = (*it).first;
832         if (!variableObject->hasProperty(exec, ident))
833             variableObject->put(exec, ident, jsUndefined());
834     }
835
836     const Node::FunctionStack& functionStack = codeBlock->ownerNode->functionStack();
837     Node::FunctionStack::const_iterator functionStackEnd = functionStack.end();
838     for (Node::FunctionStack::const_iterator it = functionStack.begin(); it != functionStackEnd; ++it)
839         variableObject->put(exec, (*it)->m_ident, (*it)->makeFunction(exec, scopeChain));
840
841     size_t oldSize = m_registerFile.size();
842     size_t newSize = registerOffset + codeBlock->numVars + codeBlock->numTemporaries + RegisterFile::CallFrameHeaderSize;
843     if (!m_registerFile.grow(newSize)) {
844         *exception = createStackOverflowError(exec);
845         return 0;
846     }
847
848     Register* callFrame = m_registerFile.base() + registerOffset;
849
850     // a 0 codeBlock indicates a built-in caller
851     initializeCallFrame(callFrame, 0, 0, 0, 0, 0, 0, 0, 0, 0);
852
853     Register* r = callFrame + RegisterFile::CallFrameHeaderSize + codeBlock->numVars;
854     r[codeBlock->thisRegister] = thisObj;
855
856     if (codeBlock->needsFullScopeChain)
857         scopeChain = scopeChain->copy();
858
859     ExecState newExec(exec, &m_registerFile, scopeChain, 0);
860
861     Profiler** profiler = Profiler::enabledProfilerReference();
862     if (*profiler)
863         (*profiler)->willExecute(exec, evalNode->sourceURL(), evalNode->lineNo());
864
865     m_reentryDepth++;
866     JSValue* result = privateExecute(Normal, &newExec, &m_registerFile, r, scopeChain, codeBlock, exception);
867     m_reentryDepth--;
868
869     MACHINE_SAMPLING_privateExecuteReturned();
870
871     if (*profiler) {
872         (*profiler)->didExecute(exec, evalNode->sourceURL(), evalNode->lineNo());
873         if (!m_reentryDepth)
874             (*profiler)->didFinishAllExecution(exec);
875     }
876
877     m_registerFile.shrink(oldSize);
878     return result;
879 }
880
881 ALWAYS_INLINE void Machine::setScopeChain(ExecState* exec, ScopeChainNode*& scopeChain, ScopeChainNode* newScopeChain)
882 {
883     scopeChain = newScopeChain;
884     exec->m_scopeChain = newScopeChain;
885 }
886
887 NEVER_INLINE void Machine::debug(ExecState* exec, const Instruction* vPC, const CodeBlock* codeBlock, ScopeChainNode* scopeChain, Register* r)
888 {
889     int debugHookID = (++vPC)->u.operand;
890     int firstLine = (++vPC)->u.operand;
891     int lastLine = (++vPC)->u.operand;
892
893     Debugger* debugger = exec->dynamicGlobalObject()->debugger();
894     if (!debugger)
895         return;
896
897     DebuggerCallFrame debuggerCallFrame(exec->dynamicGlobalObject(), codeBlock, scopeChain, r, 0);
898
899     switch((DebugHookID)debugHookID) {
900     case DidEnterCallFrame: {
901         debugger->callEvent(debuggerCallFrame, codeBlock->ownerNode->sourceId(), firstLine);
902         return;
903     }
904     case WillLeaveCallFrame: {
905         debugger->returnEvent(debuggerCallFrame, codeBlock->ownerNode->sourceId(), lastLine);
906         return;
907     }
908     case WillExecuteStatement: {
909         debugger->atStatement(debuggerCallFrame, codeBlock->ownerNode->sourceId(), firstLine);
910         return;
911     }
912     case WillExecuteProgram: {
913         debugger->willExecuteProgram(debuggerCallFrame, codeBlock->ownerNode->sourceId(), firstLine);
914         return;
915     }
916     case DidExecuteProgram: {
917         debugger->didExecuteProgram(debuggerCallFrame, codeBlock->ownerNode->sourceId(), lastLine);
918         return;
919     }
920     case DidReachBreakpoint: {
921         debugger->didReachBreakpoint(debuggerCallFrame, codeBlock->ownerNode->sourceId(), lastLine);
922         return;
923     }
924     }
925 }
926
927 void Machine::resetTimeoutCheck()
928 {
929     m_ticksUntilNextTimeoutCheck = initialTickCountThreshold;
930     m_timeAtLastCheckTimeout = 0;
931     m_timeExecuting = 0;
932 }
933
934 // Returns the current time in milliseconds
935 // It doesn't matter what "current time" is here, just as long as
936 // it's possible to measure the time difference correctly.
937 // In an ideal world this would just be getCurrentUTCTimeWithMicroseconds
938 // from DateMath.h, but unfortunately there's a slowdown if we use tha.
939 static inline unsigned getCurrentTime()
940 {
941 #if HAVE(SYS_TIME_H)
942     struct timeval tv;
943     gettimeofday(&tv, 0);
944     return tv.tv_sec * 1000 + tv.tv_usec / 1000;
945 #elif PLATFORM(QT)
946     QDateTime t = QDateTime::currentDateTime();
947     return t.toTime_t() * 1000 + t.time().msec();
948 #elif PLATFORM(WIN_OS)
949     return timeGetTime();
950 #else
951 #error Platform does not have getCurrentTime function
952 #endif
953 }
954
955 // We have to return a JSValue here, gcc seems to produce worse code if 
956 // we attempt to return a bool
957 ALWAYS_INLINE JSValue* Machine::checkTimeout(JSGlobalObject* globalObject)
958 {
959     unsigned currentTime = getCurrentTime();
960     
961     if (!m_timeAtLastCheckTimeout) {
962         // Suspicious amount of looping in a script -- start timing it
963         m_timeAtLastCheckTimeout = currentTime;
964         return 0;
965     }
966     
967     unsigned timeDiff = currentTime - m_timeAtLastCheckTimeout;
968     
969     if (timeDiff == 0)
970         timeDiff = 1;
971     
972     m_timeExecuting += timeDiff;
973     m_timeAtLastCheckTimeout = currentTime;
974     
975     // Adjust the tick threshold so we get the next checkTimeout call in the interval specified in 
976     // preferredScriptCheckTimeInterval
977     m_ticksUntilNextTimeoutCheck = static_cast<unsigned>((static_cast<float>(preferredScriptCheckTimeInterval) / timeDiff) * m_ticksUntilNextTimeoutCheck);
978     // If the new threshold is 0 reset it to the default threshold. This can happen if the timeDiff is higher than the
979     // preferred script check time interval.
980     if (m_ticksUntilNextTimeoutCheck == 0)
981         m_ticksUntilNextTimeoutCheck = initialTickCountThreshold;
982     
983     if (m_timeoutTime && m_timeExecuting > m_timeoutTime) {
984         if (globalObject->shouldInterruptScript())
985             return jsNull(); // Appeasing GCC, all we need is a non-null js value.
986         
987         resetTimeoutCheck();
988     }
989     
990     return 0;
991 }
992
993 static int32_t offsetForStringSwitch(StringJumpTable& jumpTable, JSValue* scrutinee, int32_t defaultOffset) {
994     StringJumpTable::const_iterator end = jumpTable.end();
995     UString::Rep* value = static_cast<JSString*>(scrutinee)->value().rep();
996     StringJumpTable::const_iterator loc = jumpTable.find(value);
997     if (loc == end)
998         return defaultOffset;
999     return loc->second;
1000 }
1001
1002 static NEVER_INLINE ScopeChainNode* createExceptionScope(ExecState* exec, CodeBlock* codeBlock, const Instruction* vPC, Register* r, ScopeChainNode* scopeChain)
1003 {
1004     int dst = (++vPC)->u.operand;
1005     Identifier& property = codeBlock->identifiers[(++vPC)->u.operand];
1006     JSValue* value = r[(++vPC)->u.operand].jsValue(exec);
1007     JSObject* scope = new (exec) JSStaticScopeObject(property, value, DontDelete);
1008     r[dst] = scope;
1009     return scopeChain->push(scope);
1010 }
1011
1012 JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFile* registerFile, Register* r, ScopeChainNode* scopeChain, CodeBlock* codeBlock, JSValue** exception)
1013 {
1014     // One-time initialization of our address tables. We have to put this code
1015     // here because our labels are only in scope inside this function.
1016     if (flag == InitializeAndReturn) {
1017         #if HAVE(COMPUTED_GOTO)
1018             #define ADD_OPCODE(id) m_opcodeTable[id] = &&id;
1019                 FOR_EACH_OPCODE_ID(ADD_OPCODE);
1020             #undef ADD_OPCODE
1021
1022             #define ADD_OPCODE_ID(id) m_opcodeIDTable.add(&&id, id);
1023                 FOR_EACH_OPCODE_ID(ADD_OPCODE_ID);
1024             #undef ADD_OPCODE
1025             ASSERT(m_opcodeIDTable.size() == numOpcodeIDs);
1026             op_throw_end_indirect = &&op_throw_end;
1027             op_call_indirect = &&op_call;
1028         #endif // HAVE(COMPUTED_GOTO)
1029         return 0;
1030     }
1031
1032     JSValue* exceptionValue = 0;
1033     Instruction* handlerVPC = 0;
1034
1035     Register* registerBase = registerFile->base();
1036     Instruction* vPC = codeBlock->instructions.begin();
1037     Register* k = codeBlock->registers.data();
1038     Profiler** enabledProfilerReference = Profiler::enabledProfilerReference();
1039     unsigned tickCount = m_ticksUntilNextTimeoutCheck + 1;
1040
1041 #define VM_CHECK_EXCEPTION() \
1042      do { \
1043         if (UNLIKELY(exec->hadException())) { \
1044             exceptionValue = exec->exception(); \
1045             goto vm_throw; \
1046         } \
1047     } while (0)
1048
1049 #if DUMP_OPCODE_STATS
1050     OpcodeStats::resetLastInstruction();
1051 #endif
1052
1053 #define CHECK_FOR_TIMEOUT() \
1054     if (!--tickCount) { \
1055         if ((exceptionValue = checkTimeout(exec->dynamicGlobalObject()))) \
1056             goto vm_throw; \
1057         tickCount = m_ticksUntilNextTimeoutCheck; \
1058     }
1059     
1060 #if HAVE(COMPUTED_GOTO)
1061     #define NEXT_OPCODE MACHINE_SAMPLING_sample(codeBlock, vPC); goto *vPC->u.opcode
1062 #if DUMP_OPCODE_STATS
1063     #define BEGIN_OPCODE(opcode) opcode: OpcodeStats::recordInstruction(opcode);
1064 #else
1065     #define BEGIN_OPCODE(opcode) opcode:
1066 #endif
1067     NEXT_OPCODE;
1068 #else
1069     #define NEXT_OPCODE MACHINE_SAMPLING_sample(codeBlock, vPC); continue
1070 #if DUMP_OPCODE_STATS
1071     #define BEGIN_OPCODE(opcode) case opcode: OpcodeStats::recordInstruction(opcode);
1072 #else
1073     #define BEGIN_OPCODE(opcode) case opcode:
1074 #endif
1075     while (1) // iterator loop begins
1076     switch (vPC->u.opcode)
1077 #endif
1078     {
1079     BEGIN_OPCODE(op_load) {
1080         /* load dst(r) src(k)
1081
1082            Copies constant src to register dst.
1083         */
1084         int dst = (++vPC)->u.operand;
1085         int src = (++vPC)->u.operand;
1086         r[dst] = k[src];
1087
1088         ++vPC;
1089         NEXT_OPCODE;
1090     }
1091     BEGIN_OPCODE(op_new_object) {
1092         /* new_object dst(r)
1093
1094            Constructs a new empty Object instance using the original
1095            constructor, and puts the result in register dst.
1096         */
1097         int dst = (++vPC)->u.operand;
1098         r[dst] = constructEmptyObject(exec);
1099
1100         ++vPC;
1101         NEXT_OPCODE;
1102     }
1103     BEGIN_OPCODE(op_new_array) {
1104         /* new_array dst(r) firstArg(r) argCount(n)
1105
1106            Constructs a new Array instance using the original
1107            constructor, and puts the result in register dst.
1108            The array will contain argCount elements with values
1109            taken from registers starting at register firstArg.
1110         */
1111         int dst = (++vPC)->u.operand;
1112         int firstArg = (++vPC)->u.operand;
1113         int argCount = (++vPC)->u.operand;
1114         ArgList args(r + firstArg, argCount);
1115         r[dst] = constructArray(exec, args);
1116
1117         ++vPC;
1118         NEXT_OPCODE;
1119     }
1120     BEGIN_OPCODE(op_new_regexp) {
1121         /* new_regexp dst(r) regExp(re)
1122
1123            Constructs a new RegExp instance using the original
1124            constructor from regexp regExp, and puts the result in
1125            register dst.
1126         */
1127         int dst = (++vPC)->u.operand;
1128         int regExp = (++vPC)->u.operand;
1129         r[dst] = new (exec) RegExpObject(scopeChain->globalObject()->regExpPrototype(), codeBlock->regexps[regExp]);
1130
1131         ++vPC;
1132         NEXT_OPCODE;
1133     }
1134     BEGIN_OPCODE(op_mov) {
1135         /* mov dst(r) src(r)
1136
1137            Copies register src to register dst.
1138         */
1139         int dst = (++vPC)->u.operand;
1140         int src = (++vPC)->u.operand;
1141         r[dst] = r[src];
1142
1143         ++vPC;
1144         NEXT_OPCODE;
1145     }
1146     BEGIN_OPCODE(op_eq) {
1147         /* eq dst(r) src1(r) src2(r)
1148
1149            Checks whether register src1 and register src2 are equal,
1150            as with the ECMAScript '==' operator, and puts the result
1151            as a boolean in register dst.
1152         */
1153         int dst = (++vPC)->u.operand;
1154         JSValue* src1 = r[(++vPC)->u.operand].jsValue(exec);
1155         JSValue* src2 = r[(++vPC)->u.operand].jsValue(exec);
1156         if (JSImmediate::areBothImmediateNumbers(src1, src2))
1157             r[dst] = jsBoolean(reinterpret_cast<intptr_t>(src1) == reinterpret_cast<intptr_t>(src2));
1158         else {
1159             JSValue* result = jsBoolean(equal(exec, src1, src2));
1160             VM_CHECK_EXCEPTION();
1161             r[dst] = result;
1162         }
1163
1164         ++vPC;
1165         NEXT_OPCODE;
1166     }
1167     BEGIN_OPCODE(op_neq) {
1168         /* neq dst(r) src1(r) src2(r)
1169
1170            Checks whether register src1 and register src2 are not
1171            equal, as with the ECMAScript '!=' operator, and puts the
1172            result as a boolean in register dst.
1173         */
1174         int dst = (++vPC)->u.operand;
1175         JSValue* src1 = r[(++vPC)->u.operand].jsValue(exec);
1176         JSValue* src2 = r[(++vPC)->u.operand].jsValue(exec);
1177         if (JSImmediate::areBothImmediateNumbers(src1, src2))
1178             r[dst] = jsBoolean(reinterpret_cast<intptr_t>(src1) != reinterpret_cast<intptr_t>(src2));
1179         else {
1180             JSValue* result = jsBoolean(!equal(exec, src1, src2));
1181             VM_CHECK_EXCEPTION();
1182             r[dst] = result;
1183         }
1184
1185         ++vPC;
1186         NEXT_OPCODE;
1187     }
1188     BEGIN_OPCODE(op_stricteq) {
1189         /* stricteq dst(r) src1(r) src2(r)
1190
1191            Checks whether register src1 and register src2 are strictly
1192            equal, as with the ECMAScript '===' operator, and puts the
1193            result as a boolean in register dst.
1194         */
1195         int dst = (++vPC)->u.operand;
1196         JSValue* src1 = r[(++vPC)->u.operand].jsValue(exec);
1197         JSValue* src2 = r[(++vPC)->u.operand].jsValue(exec);
1198         if (JSImmediate::areBothImmediateNumbers(src1, src2))
1199             r[dst] = jsBoolean(reinterpret_cast<intptr_t>(src1) == reinterpret_cast<intptr_t>(src2));
1200         else
1201             r[dst] = jsBoolean(strictEqual(src1, src2));
1202
1203         ++vPC;
1204         NEXT_OPCODE;
1205     }
1206     BEGIN_OPCODE(op_nstricteq) {
1207         /* nstricteq dst(r) src1(r) src2(r)
1208
1209            Checks whether register src1 and register src2 are not
1210            strictly equal, as with the ECMAScript '!==' operator, and
1211            puts the result as a boolean in register dst.
1212         */
1213         int dst = (++vPC)->u.operand;
1214         JSValue* src1 = r[(++vPC)->u.operand].jsValue(exec);
1215         JSValue* src2 = r[(++vPC)->u.operand].jsValue(exec);
1216         if (JSImmediate::areBothImmediateNumbers(src1, src2))
1217             r[dst] = jsBoolean(reinterpret_cast<intptr_t>(src1) != reinterpret_cast<intptr_t>(src2));
1218         else
1219             r[dst] = jsBoolean(!strictEqual(src1, src2));
1220
1221         ++vPC;
1222         NEXT_OPCODE;
1223     }
1224     BEGIN_OPCODE(op_less) {
1225         /* less dst(r) src1(r) src2(r)
1226
1227            Checks whether register src1 is less than register src2, as
1228            with the ECMAScript '<' operator, and puts the result as
1229            a boolean in register dst.
1230         */
1231         int dst = (++vPC)->u.operand;
1232         JSValue* src1 = r[(++vPC)->u.operand].jsValue(exec);
1233         JSValue* src2 = r[(++vPC)->u.operand].jsValue(exec);
1234         JSValue* result = jsBoolean(jsLess(exec, src1, src2));
1235         VM_CHECK_EXCEPTION();
1236         r[dst] = result;
1237
1238         ++vPC;
1239         NEXT_OPCODE;
1240     }
1241     BEGIN_OPCODE(op_lesseq) {
1242         /* lesseq dst(r) src1(r) src2(r)
1243
1244            Checks whether register src1 is less than or equal to
1245            register src2, as with the ECMAScript '<=' operator, and
1246            puts the result as a boolean in register dst.
1247         */
1248         int dst = (++vPC)->u.operand;
1249         JSValue* src1 = r[(++vPC)->u.operand].jsValue(exec);
1250         JSValue* src2 = r[(++vPC)->u.operand].jsValue(exec);
1251         JSValue* result = jsBoolean(jsLessEq(exec, src1, src2));
1252         VM_CHECK_EXCEPTION();
1253         r[dst] = result;
1254
1255         ++vPC;
1256         NEXT_OPCODE;
1257     }
1258     BEGIN_OPCODE(op_pre_inc) {
1259         /* pre_inc srcDst(r)
1260
1261            Converts register srcDst to number, adds one, and puts the result
1262            back in register srcDst.
1263         */
1264         int srcDst = (++vPC)->u.operand;
1265         JSValue* v = r[srcDst].jsValue(exec);
1266         if (JSImmediate::canDoFastAdditiveOperations(v))
1267             r[srcDst] = JSImmediate::incImmediateNumber(v);
1268         else {
1269             JSValue* result = jsNumber(exec, v->toNumber(exec) + 1);
1270             VM_CHECK_EXCEPTION();
1271             r[srcDst] = result;
1272         }
1273
1274         ++vPC;
1275         NEXT_OPCODE;
1276     }
1277     BEGIN_OPCODE(op_pre_dec) {
1278         /* pre_dec srcDst(r)
1279
1280            Converts register srcDst to number, subtracts one, and puts the result
1281            back in register srcDst.
1282         */
1283         int srcDst = (++vPC)->u.operand;
1284         JSValue* v = r[srcDst].jsValue(exec);
1285         if (JSImmediate::canDoFastAdditiveOperations(v))
1286             r[srcDst] = JSImmediate::decImmediateNumber(v);
1287         else {
1288             JSValue* result = jsNumber(exec, v->toNumber(exec) - 1);
1289             VM_CHECK_EXCEPTION();
1290             r[srcDst] = result;
1291         }
1292
1293         ++vPC;
1294         NEXT_OPCODE;
1295     }
1296     BEGIN_OPCODE(op_post_inc) {
1297         /* post_inc dst(r) srcDst(r)
1298
1299            Converts register srcDst to number. The number itself is
1300            written to register dst, and the number plus one is written
1301            back to register srcDst.
1302         */
1303         int dst = (++vPC)->u.operand;
1304         int srcDst = (++vPC)->u.operand;
1305         JSValue* v = r[srcDst].jsValue(exec);
1306         if (JSImmediate::canDoFastAdditiveOperations(v)) {
1307             r[dst] = v;
1308             r[srcDst] = JSImmediate::incImmediateNumber(v);
1309         } else {
1310             JSValue* number = r[srcDst].jsValue(exec)->toJSNumber(exec);
1311             VM_CHECK_EXCEPTION();
1312             r[dst] = number;
1313             r[srcDst] = jsNumber(exec, number->uncheckedGetNumber() + 1);
1314         }
1315
1316         ++vPC;
1317         NEXT_OPCODE;
1318     }
1319     BEGIN_OPCODE(op_post_dec) {
1320         /* post_dec dst(r) srcDst(r)
1321
1322            Converts register srcDst to number. The number itself is
1323            written to register dst, and the number minus one is written
1324            back to register srcDst.
1325         */
1326         int dst = (++vPC)->u.operand;
1327         int srcDst = (++vPC)->u.operand;
1328         JSValue* v = r[srcDst].jsValue(exec);
1329         if (JSImmediate::canDoFastAdditiveOperations(v)) {
1330             r[dst] = v;
1331             r[srcDst] = JSImmediate::decImmediateNumber(v);
1332         } else {
1333             JSValue* number = r[srcDst].jsValue(exec)->toJSNumber(exec);
1334             VM_CHECK_EXCEPTION();
1335             r[dst] = number;
1336             r[srcDst] = jsNumber(exec, number->uncheckedGetNumber() - 1);
1337         }
1338
1339         ++vPC;
1340         NEXT_OPCODE;
1341     }
1342     BEGIN_OPCODE(op_to_jsnumber) {
1343         /* to_jsnumber dst(r) src(r)
1344
1345            Converts register src to number, and puts the result
1346            in register dst.
1347         */
1348         int dst = (++vPC)->u.operand;
1349         int src = (++vPC)->u.operand;
1350         JSValue* result = r[src].jsValue(exec)->toJSNumber(exec);
1351         VM_CHECK_EXCEPTION();
1352
1353         r[dst] = result;
1354
1355         ++vPC;
1356         NEXT_OPCODE;
1357     }
1358     BEGIN_OPCODE(op_negate) {
1359         /* negate dst(r) src(r)
1360
1361            Converts register src to number, negates it, and puts the
1362            result in register dst.
1363         */
1364         int dst = (++vPC)->u.operand;
1365         int src = (++vPC)->u.operand;
1366         JSValue* result = jsNumber(exec, -r[src].jsValue(exec)->toNumber(exec));
1367         VM_CHECK_EXCEPTION();
1368         r[dst] = result;
1369
1370         ++vPC;
1371         NEXT_OPCODE;
1372     }
1373     BEGIN_OPCODE(op_add) {
1374         /* add dst(r) src1(r) src2(r)
1375
1376            Adds register src1 and register src2, and puts the result
1377            in register dst. (JS add may be string concatenation or
1378            numeric add, depending on the types of the operands.)
1379         */
1380         int dst = (++vPC)->u.operand;
1381         JSValue* src1 = r[(++vPC)->u.operand].jsValue(exec);
1382         JSValue* src2 = r[(++vPC)->u.operand].jsValue(exec);
1383         if (JSImmediate::canDoFastAdditiveOperations(src1) && JSImmediate::canDoFastAdditiveOperations(src2))
1384             r[dst] = JSImmediate::addImmediateNumbers(src1, src2);
1385         else {
1386             JSValue* result = jsAdd(exec, src1, src2);
1387             VM_CHECK_EXCEPTION();
1388             r[dst] = result;
1389         }
1390         ++vPC;
1391         NEXT_OPCODE;
1392     }
1393     BEGIN_OPCODE(op_mul) {
1394         /* mul dst(r) src1(r) src2(r)
1395
1396            Multiplies register src1 and register src2 (converted to
1397            numbers), and puts the product in register dst.
1398         */
1399         int dst = (++vPC)->u.operand;
1400         JSValue* src1 = r[(++vPC)->u.operand].jsValue(exec);
1401         JSValue* src2 = r[(++vPC)->u.operand].jsValue(exec);
1402         JSValue* result = jsNumber(exec, src1->toNumber(exec) * src2->toNumber(exec));
1403         VM_CHECK_EXCEPTION();
1404         r[dst] = result;
1405
1406         ++vPC;
1407         NEXT_OPCODE;
1408     }
1409     BEGIN_OPCODE(op_div) {
1410         /* div dst(r) dividend(r) divisor(r)
1411
1412            Divides register dividend (converted to number) by the
1413            register divisor (converted to number), and puts the
1414            quotient in register dst.
1415         */
1416         int dst = (++vPC)->u.operand;
1417         int dividend = (++vPC)->u.operand;
1418         int divisor = (++vPC)->u.operand;
1419         JSValue* result = jsNumber(exec, r[dividend].jsValue(exec)->toNumber(exec) / r[divisor].jsValue(exec)->toNumber(exec));
1420         VM_CHECK_EXCEPTION();
1421         r[dst] = result;
1422         ++vPC;
1423         NEXT_OPCODE;
1424     }
1425     BEGIN_OPCODE(op_mod) {
1426         /* mod dst(r) dividend(r) divisor(r)
1427
1428            Divides register dividend (converted to number) by
1429            register divisor (converted to number), and puts the
1430            remainder in register dst.
1431         */
1432         int dst = (++vPC)->u.operand;
1433         int dividend = (++vPC)->u.operand;
1434         int divisor = (++vPC)->u.operand;
1435
1436         JSValue* dividendValue = r[dividend].jsValue(exec);
1437         JSValue* divisorValue = r[divisor].jsValue(exec);
1438
1439         if (JSImmediate::areBothImmediateNumbers(dividendValue, divisorValue) && divisorValue != JSImmediate::from(0)) {
1440             r[dst] = JSImmediate::from(JSImmediate::getTruncatedInt32(dividendValue) % JSImmediate::getTruncatedInt32(divisorValue));
1441             ++vPC;
1442             NEXT_OPCODE;
1443         }
1444
1445         double d = dividendValue->toNumber(exec);
1446         JSValue* result = jsNumber(exec, fmod(d, divisorValue->toNumber(exec)));
1447         VM_CHECK_EXCEPTION();
1448         r[dst] = result;
1449         ++vPC;
1450         NEXT_OPCODE;
1451     }
1452     BEGIN_OPCODE(op_sub) {
1453         /* sub dst(r) src1(r) src2(r)
1454
1455            Subtracts register src2 (converted to number) from register
1456            src1 (converted to number), and puts the difference in
1457            register dst.
1458         */
1459         int dst = (++vPC)->u.operand;
1460         JSValue* src1 = r[(++vPC)->u.operand].jsValue(exec);
1461         JSValue* src2 = r[(++vPC)->u.operand].jsValue(exec);
1462         if (JSImmediate::canDoFastAdditiveOperations(src1) && JSImmediate::canDoFastAdditiveOperations(src2))
1463             r[dst] = JSImmediate::subImmediateNumbers(src1, src2);
1464         else {
1465             JSValue* result = jsNumber(exec, src1->toNumber(exec) - src2->toNumber(exec));
1466             VM_CHECK_EXCEPTION();
1467             r[dst] = result;
1468         }
1469         ++vPC;
1470         NEXT_OPCODE;
1471     }
1472     BEGIN_OPCODE(op_lshift) {
1473         /* lshift dst(r) val(r) shift(r)
1474
1475            Performs left shift of register val (converted to int32) by
1476            register shift (converted to uint32), and puts the result
1477            in register dst.
1478         */
1479         int dst = (++vPC)->u.operand;
1480         JSValue* val = r[(++vPC)->u.operand].jsValue(exec);
1481         JSValue* shift = r[(++vPC)->u.operand].jsValue(exec);
1482         if (JSImmediate::areBothImmediateNumbers(val, shift))
1483             r[dst] = jsNumber(exec, JSImmediate::getTruncatedInt32(val) << (JSImmediate::toTruncatedUInt32(shift) & 0x1f));
1484         else {
1485             JSValue* result = jsNumber(exec, (val->toInt32(exec)) << (shift->toUInt32(exec) & 0x1f));
1486             VM_CHECK_EXCEPTION();
1487             r[dst] = result;
1488         }
1489
1490         ++vPC;
1491         NEXT_OPCODE;
1492     }
1493     BEGIN_OPCODE(op_rshift) {
1494         /* rshift dst(r) val(r) shift(r)
1495
1496            Performs arithmetic right shift of register val (converted
1497            to int32) by register shift (converted to
1498            uint32), and puts the result in register dst.
1499         */
1500         int dst = (++vPC)->u.operand;
1501         JSValue* val = r[(++vPC)->u.operand].jsValue(exec);
1502         JSValue* shift = r[(++vPC)->u.operand].jsValue(exec);
1503         if (JSImmediate::areBothImmediateNumbers(val, shift))
1504             r[dst] = JSImmediate::rightShiftImmediateNumbers(val, shift);
1505         else {
1506             JSValue* result = jsNumber(exec, (val->toInt32(exec)) >> (shift->toUInt32(exec) & 0x1f));
1507             VM_CHECK_EXCEPTION();
1508             r[dst] = result;
1509         }
1510
1511         ++vPC;
1512         NEXT_OPCODE;
1513     }
1514     BEGIN_OPCODE(op_urshift) {
1515         /* rshift dst(r) val(r) shift(r)
1516
1517            Performs logical right shift of register val (converted
1518            to uint32) by register shift (converted to
1519            uint32), and puts the result in register dst.
1520         */
1521         int dst = (++vPC)->u.operand;
1522         JSValue* val = r[(++vPC)->u.operand].jsValue(exec);
1523         JSValue* shift = r[(++vPC)->u.operand].jsValue(exec);
1524         if (JSImmediate::areBothImmediateNumbers(val, shift) && !JSImmediate::isNegative(val))
1525             r[dst] = JSImmediate::rightShiftImmediateNumbers(val, shift);
1526         else {
1527             JSValue* result = jsNumber(exec, (val->toUInt32(exec)) >> (shift->toUInt32(exec) & 0x1f));
1528             VM_CHECK_EXCEPTION();
1529             r[dst] = result;
1530         }
1531
1532         ++vPC;
1533         NEXT_OPCODE;
1534     }
1535     BEGIN_OPCODE(op_bitand) {
1536         /* bitand dst(r) src1(r) src2(r)
1537
1538            Computes bitwise AND of register src1 (converted to int32)
1539            and register src2 (converted to int32), and puts the result
1540            in register dst.
1541         */
1542         int dst = (++vPC)->u.operand;
1543         JSValue* src1 = r[(++vPC)->u.operand].jsValue(exec);
1544         JSValue* src2 = r[(++vPC)->u.operand].jsValue(exec);
1545         if (JSImmediate::areBothImmediateNumbers(src1, src2))
1546             r[dst] = JSImmediate::andImmediateNumbers(src1, src2);
1547         else {
1548             JSValue* result = jsNumber(exec, src1->toInt32(exec) & src2->toInt32(exec));
1549             VM_CHECK_EXCEPTION();
1550             r[dst] = result;
1551         }
1552
1553         ++vPC;
1554         NEXT_OPCODE;
1555     }
1556     BEGIN_OPCODE(op_bitxor) {
1557         /* bitxor dst(r) src1(r) src2(r)
1558
1559            Computes bitwise XOR of register src1 (converted to int32)
1560            and register src2 (converted to int32), and puts the result
1561            in register dst.
1562         */
1563         int dst = (++vPC)->u.operand;
1564         JSValue* src1 = r[(++vPC)->u.operand].jsValue(exec);
1565         JSValue* src2 = r[(++vPC)->u.operand].jsValue(exec);
1566         if (JSImmediate::areBothImmediateNumbers(src1, src2))
1567             r[dst] = JSImmediate::xorImmediateNumbers(src1, src2);
1568         else {
1569             JSValue* result = jsNumber(exec, src1->toInt32(exec) ^ src2->toInt32(exec));
1570             VM_CHECK_EXCEPTION();
1571             r[dst] = result;
1572         }
1573
1574         ++vPC;
1575         NEXT_OPCODE;
1576     }
1577     BEGIN_OPCODE(op_bitor) {
1578         /* bitor dst(r) src1(r) src2(r)
1579
1580            Computes bitwise OR of register src1 (converted to int32)
1581            and register src2 (converted to int32), and puts the
1582            result in register dst.
1583         */
1584         int dst = (++vPC)->u.operand;
1585         JSValue* src1 = r[(++vPC)->u.operand].jsValue(exec);
1586         JSValue* src2 = r[(++vPC)->u.operand].jsValue(exec);
1587         if (JSImmediate::areBothImmediateNumbers(src1, src2))
1588             r[dst] = JSImmediate::orImmediateNumbers(src1, src2);
1589         else {
1590             JSValue* result = jsNumber(exec, src1->toInt32(exec) | src2->toInt32(exec));
1591             VM_CHECK_EXCEPTION();
1592             r[dst] = result;
1593         }
1594
1595         ++vPC;
1596         NEXT_OPCODE;
1597     }
1598     BEGIN_OPCODE(op_bitnot) {
1599         /* bitnot dst(r) src(r)
1600
1601            Computes bitwise NOT of register src1 (converted to int32),
1602            and puts the result in register dst.
1603         */
1604         int dst = (++vPC)->u.operand;
1605         int src = (++vPC)->u.operand;
1606         JSValue* result = jsNumber(exec, ~r[src].jsValue(exec)->toInt32(exec));
1607         VM_CHECK_EXCEPTION();
1608         r[dst] = result;
1609
1610         ++vPC;
1611         NEXT_OPCODE;
1612     }
1613     BEGIN_OPCODE(op_not) {
1614         /* not dst(r) src1(r) src2(r)
1615
1616            Computes logical NOT of register src1 (converted to
1617            boolean), and puts the result in register dst.
1618         */
1619         int dst = (++vPC)->u.operand;
1620         int src = (++vPC)->u.operand;
1621         JSValue* result = jsBoolean(!r[src].jsValue(exec)->toBoolean(exec));
1622         VM_CHECK_EXCEPTION();
1623         r[dst] = result;
1624
1625         ++vPC;
1626         NEXT_OPCODE;
1627     }
1628     BEGIN_OPCODE(op_instanceof) {
1629         /* instanceof dst(r) value(r) constructor(r)
1630
1631            Tests whether register value is an instance of register
1632            constructor, and puts the boolean result in register dst.
1633
1634            Raises an exception if register constructor is not an
1635            object.
1636         */
1637         int dst = (++vPC)->u.operand;
1638         int value = (++vPC)->u.operand;
1639         int base = (++vPC)->u.operand;
1640
1641         JSValue* baseVal = r[base].jsValue(exec);
1642
1643         if (isNotObject(exec, true, codeBlock, vPC, baseVal, exceptionValue))
1644             goto vm_throw;
1645
1646         JSObject* baseObj = static_cast<JSObject*>(baseVal);
1647         r[dst] = jsBoolean(baseObj->implementsHasInstance() ? baseObj->hasInstance(exec, r[value].jsValue(exec)) : false);
1648
1649         ++vPC;
1650         NEXT_OPCODE;
1651     }
1652     BEGIN_OPCODE(op_typeof) {
1653         /* typeof dst(r) src(r)
1654
1655            Determines the type string for src according to ECMAScript
1656            rules, and puts the result in register dst.
1657         */
1658         int dst = (++vPC)->u.operand;
1659         int src = (++vPC)->u.operand;
1660         r[dst] = jsTypeStringForValue(exec, r[src].jsValue(exec));
1661
1662         ++vPC;
1663         NEXT_OPCODE;
1664     }
1665     BEGIN_OPCODE(op_in) {
1666         /* in dst(r) property(r) base(r)
1667
1668            Tests whether register base has a property named register
1669            property, and puts the boolean result in register dst.
1670
1671            Raises an exception if register constructor is not an
1672            object.
1673         */
1674         int dst = (++vPC)->u.operand;
1675         int property = (++vPC)->u.operand;
1676         int base = (++vPC)->u.operand;
1677
1678         JSValue* baseVal = r[base].jsValue(exec);
1679         if (isNotObject(exec, false, codeBlock, vPC, baseVal, exceptionValue))
1680             goto vm_throw;
1681
1682         JSObject* baseObj = static_cast<JSObject*>(baseVal);
1683
1684         JSValue* propName = r[property].jsValue(exec);
1685
1686         uint32_t i;
1687         if (propName->getUInt32(i))
1688             r[dst] = jsBoolean(baseObj->hasProperty(exec, i));
1689         else {
1690             Identifier property(exec, propName->toString(exec));
1691             VM_CHECK_EXCEPTION();
1692             r[dst] = jsBoolean(baseObj->hasProperty(exec, property));
1693         }
1694
1695         ++vPC;
1696         NEXT_OPCODE;
1697     }
1698     BEGIN_OPCODE(op_resolve) {
1699         /* resolve dst(r) property(id)
1700
1701            Looks up the property named by identifier property in the
1702            scope chain, and writes the resulting value to register
1703            dst. If the property is not found, raises an exception.
1704         */
1705         if (UNLIKELY(!resolve(exec, vPC, r, scopeChain, codeBlock, exceptionValue)))
1706             goto vm_throw;
1707
1708         vPC += 3;
1709         NEXT_OPCODE;
1710     }
1711     BEGIN_OPCODE(op_resolve_skip) {
1712         /* resolve_skip dst(r) property(id) skip(n)
1713
1714          Looks up the property named by identifier property in the
1715          scope chain skipping the top 'skip' levels, and writes the resulting
1716          value to register dst. If the property is not found, raises an exception.
1717          */
1718         if (UNLIKELY(!resolve_skip(exec, vPC, r, scopeChain, codeBlock, exceptionValue)))
1719             goto vm_throw;
1720
1721         vPC += 4;
1722
1723         NEXT_OPCODE;
1724     }
1725     BEGIN_OPCODE(op_get_scoped_var) {
1726         /* get_scoped_var dst(r) index(n) skip(n)
1727
1728          Loads the contents of the index-th local from the scope skip nodes from
1729          the top of the scope chain, and places it in register dst
1730          */
1731         int dst = (++vPC)->u.operand;
1732         int index = (++vPC)->u.operand;
1733         int skip = (++vPC)->u.operand + codeBlock->needsFullScopeChain;
1734
1735         ScopeChainIterator iter = scopeChain->begin();
1736         ScopeChainIterator end = scopeChain->end();
1737         ASSERT(iter != end);
1738         while (skip--) {
1739             ++iter;
1740             ASSERT(iter != end);
1741         }
1742
1743         ASSERT((*iter)->isVariableObject());
1744         JSVariableObject* scope = static_cast<JSVariableObject*>(*iter);
1745         r[dst] = scope->registerAt(index);
1746         ++vPC;
1747         NEXT_OPCODE;
1748     }
1749     BEGIN_OPCODE(op_put_scoped_var) {
1750         /* put_scoped_var index(n) skip(n) value(r)
1751
1752          */
1753         int index = (++vPC)->u.operand;
1754         int skip = (++vPC)->u.operand + codeBlock->needsFullScopeChain;
1755         int value = (++vPC)->u.operand;
1756
1757         ScopeChainIterator iter = scopeChain->begin();
1758         ScopeChainIterator end = scopeChain->end();
1759         ASSERT(iter != end);
1760         while (skip--) {
1761             ++iter;
1762             ASSERT(iter != end);
1763         }
1764
1765         ASSERT((*iter)->isVariableObject());
1766         JSVariableObject* scope = static_cast<JSVariableObject*>(*iter);
1767         scope->registerAt(index) = r[value].jsValue(exec);
1768         ++vPC;
1769         NEXT_OPCODE;
1770     }
1771     BEGIN_OPCODE(op_resolve_base) {
1772         /* resolve_base dst(r) property(id)
1773
1774            Searches the scope chain for an object containing
1775            identifier property, and if one is found, writes it to
1776            register dst. If none is found, the outermost scope (which
1777            will be the global object) is stored in register dst.
1778         */
1779         resolveBase(exec, vPC, r, scopeChain, codeBlock);
1780
1781         vPC += 3;
1782         NEXT_OPCODE;
1783     }
1784     BEGIN_OPCODE(op_resolve_with_base) {
1785         /* resolve_with_base baseDst(r) propDst(r) property(id)
1786
1787            Searches the scope chain for an object containing
1788            identifier property, and if one is found, writes it to
1789            register srcDst, and the retrieved property value to register
1790            propDst. If the property is not found, raises an exception.
1791
1792            This is more efficient than doing resolve_base followed by
1793            resolve, or resolve_base followed by get_by_id, as it
1794            avoids duplicate hash lookups.
1795         */
1796         if (UNLIKELY(!resolveBaseAndProperty(exec, vPC, r, scopeChain, codeBlock, exceptionValue)))
1797             goto vm_throw;
1798
1799         vPC += 4;
1800         NEXT_OPCODE;
1801     }
1802     BEGIN_OPCODE(op_resolve_func) {
1803         /* resolve_func baseDst(r) funcDst(r) property(id)
1804
1805            Searches the scope chain for an object containing
1806            identifier property, and if one is found, writes the
1807            appropriate object to use as "this" when calling its
1808            properties to register baseDst; and the retrieved property
1809            value to register propDst. If the property is not found,
1810            raises an exception.
1811
1812            This differs from resolve_with_base, because the
1813            global this value will be substituted for activations or
1814            the global object, which is the right behavior for function
1815            calls but not for other property lookup.
1816         */
1817         if (UNLIKELY(!resolveBaseAndFunc(exec, vPC, r, scopeChain, codeBlock, exceptionValue)))
1818             goto vm_throw;
1819
1820         vPC += 4;
1821         NEXT_OPCODE;
1822     }
1823     BEGIN_OPCODE(op_get_by_id) {
1824         /* get_by_id dst(r) base(r) property(id)
1825
1826            Converts register base to Object, gets the property
1827            named by identifier property from the object, and puts the
1828            result in register dst.
1829         */
1830         int dst = (++vPC)->u.operand;
1831         int base = (++vPC)->u.operand;
1832         int property = (++vPC)->u.operand;
1833
1834         Identifier& ident = codeBlock->identifiers[property];
1835         JSValue *result = r[base].jsValue(exec)->get(exec, ident);
1836         VM_CHECK_EXCEPTION();
1837         r[dst] = result;
1838         ++vPC;
1839         NEXT_OPCODE;
1840     }
1841     BEGIN_OPCODE(op_put_by_id) {
1842         /* put_by_id base(r) property(id) value(r)
1843
1844            Sets register value on register base as the property named
1845            by identifier property. Base is converted to object first.
1846
1847            Unlike many opcodes, this one does not write any output to
1848            the register file.
1849         */
1850         int base = (++vPC)->u.operand;
1851         int property = (++vPC)->u.operand;
1852         int value = (++vPC)->u.operand;
1853
1854         Identifier& ident = codeBlock->identifiers[property];
1855         r[base].jsValue(exec)->put(exec, ident, r[value].jsValue(exec));
1856
1857         VM_CHECK_EXCEPTION();
1858         ++vPC;
1859         NEXT_OPCODE;
1860     }
1861     BEGIN_OPCODE(op_del_by_id) {
1862         /* del_by_id dst(r) base(r) property(id)
1863
1864            Converts register base to Object, deletes the property
1865            named by identifier property from the object, and writes a
1866            boolean indicating success (if true) or failure (if false)
1867            to register dst.
1868         */
1869         int dst = (++vPC)->u.operand;
1870         int base = (++vPC)->u.operand;
1871         int property = (++vPC)->u.operand;
1872
1873         JSObject* baseObj = r[base].jsValue(exec)->toObject(exec);
1874
1875         Identifier& ident = codeBlock->identifiers[property];
1876         JSValue* result = jsBoolean(baseObj->deleteProperty(exec, ident));
1877         VM_CHECK_EXCEPTION();
1878         r[dst] = result;
1879         ++vPC;
1880         NEXT_OPCODE;
1881     }
1882     BEGIN_OPCODE(op_get_by_val) {
1883         /* get_by_val dst(r) base(r) property(r)
1884
1885            Converts register base to Object, gets the property named
1886            by register property from the object, and puts the result
1887            in register dst. property is nominally converted to string
1888            but numbers are treated more efficiently.
1889         */
1890         int dst = (++vPC)->u.operand;
1891         int base = (++vPC)->u.operand;
1892         int property = (++vPC)->u.operand;
1893
1894         JSValue* baseValue = r[base].jsValue(exec);
1895         JSValue* subscript = r[property].jsValue(exec);
1896
1897         JSValue* result;
1898         unsigned i;
1899
1900         bool isUInt32 = JSImmediate::getUInt32(subscript, i);
1901         if (LIKELY(isUInt32)) {
1902             if (isJSArray(baseValue)) {
1903                 JSArray* jsArray = static_cast<JSArray*>(baseValue);
1904                 if (jsArray->canGetIndex(i))
1905                     result = jsArray->getIndex(i);
1906                 else
1907                     result = jsArray->JSArray::get(exec, i);
1908             } else if (isJSString(baseValue) && static_cast<JSString*>(baseValue)->canGetIndex(i))
1909                 result = static_cast<JSString*>(baseValue)->getIndex(exec, i);
1910             else
1911                 result = baseValue->get(exec, i);
1912         } else {
1913             Identifier property(exec, subscript->toString(exec));
1914             result = baseValue->get(exec, property);
1915         }
1916
1917         VM_CHECK_EXCEPTION();
1918         r[dst] = result;
1919         ++vPC;
1920         NEXT_OPCODE;
1921     }
1922     BEGIN_OPCODE(op_put_by_val) {
1923         /* put_by_val base(r) property(r) value(r)
1924
1925            Sets register value on register base as the property named
1926            by register property. Base is converted to object
1927            first. register property is nominally converted to string
1928            but numbers are treated more efficiently.
1929
1930            Unlike many opcodes, this one does not write any output to
1931            the register file.
1932         */
1933         int base = (++vPC)->u.operand;
1934         int property = (++vPC)->u.operand;
1935         int value = (++vPC)->u.operand;
1936
1937         JSValue* baseValue = r[base].jsValue(exec);
1938         JSValue* subscript = r[property].jsValue(exec);
1939
1940         unsigned i;
1941
1942         bool isUInt32 = JSImmediate::getUInt32(subscript, i);
1943         if (LIKELY(isUInt32)) {
1944             if (isJSArray(baseValue)) {
1945                 JSArray* jsArray = static_cast<JSArray*>(baseValue);
1946                 if (jsArray->canSetIndex(i))
1947                     jsArray->setIndex(i, r[value].jsValue(exec));
1948                 else
1949                     jsArray->JSArray::put(exec, i, r[value].jsValue(exec));
1950             } else
1951                 baseValue->put(exec, i, r[value].jsValue(exec));
1952         } else {
1953             Identifier property(exec, subscript->toString(exec));
1954             if (!exec->hadException()) // Don't put to an object if toString threw an exception.
1955                 baseValue->put(exec, property, r[value].jsValue(exec));
1956         }
1957
1958         VM_CHECK_EXCEPTION();
1959         ++vPC;
1960         NEXT_OPCODE;
1961     }
1962     BEGIN_OPCODE(op_del_by_val) {
1963         /* del_by_val dst(r) base(r) property(r)
1964
1965            Converts register base to Object, deletes the property
1966            named by register property from the object, and writes a
1967            boolean indicating success (if true) or failure (if false)
1968            to register dst.
1969         */
1970         int dst = (++vPC)->u.operand;
1971         int base = (++vPC)->u.operand;
1972         int property = (++vPC)->u.operand;
1973
1974         JSObject* baseObj = r[base].jsValue(exec)->toObject(exec); // may throw
1975
1976         JSValue* subscript = r[property].jsValue(exec);
1977         JSValue* result;
1978         uint32_t i;
1979         if (subscript->getUInt32(i))
1980             result = jsBoolean(baseObj->deleteProperty(exec, i));
1981         else {
1982             VM_CHECK_EXCEPTION();
1983             Identifier property(exec, subscript->toString(exec));
1984             VM_CHECK_EXCEPTION();
1985             result = jsBoolean(baseObj->deleteProperty(exec, property));
1986         }
1987
1988         VM_CHECK_EXCEPTION();
1989         r[dst] = result;
1990         ++vPC;
1991         NEXT_OPCODE;
1992     }
1993     BEGIN_OPCODE(op_put_by_index) {
1994         /* put_by_index base(r) property(n) value(r)
1995
1996            Sets register value on register base as the property named
1997            by the immediate number property. Base is converted to
1998            object first.
1999
2000            Unlike many opcodes, this one does not write any output to
2001            the register file.
2002
2003            This opcode is mainly used to initialize array literals.
2004         */
2005         int base = (++vPC)->u.operand;
2006         unsigned property = (++vPC)->u.operand;
2007         int value = (++vPC)->u.operand;
2008
2009         r[base].jsValue(exec)->put(exec, property, r[value].jsValue(exec));
2010
2011         ++vPC;
2012         NEXT_OPCODE;
2013     }
2014     BEGIN_OPCODE(op_loop) {
2015         /* loop target(offset)
2016          
2017            Jumps unconditionally to offset target from the current
2018            instruction.
2019
2020            Additionally this loop instruction may terminate JS execution is
2021            the JS timeout is reached.
2022          */
2023 #if DUMP_OPCODE_STATS
2024         OpcodeStats::resetLastInstruction();
2025 #endif
2026         int target = (++vPC)->u.operand;
2027         CHECK_FOR_TIMEOUT();
2028         vPC += target;
2029         NEXT_OPCODE;
2030     }
2031     BEGIN_OPCODE(op_jmp) {
2032         /* jmp target(offset)
2033
2034            Jumps unconditionally to offset target from the current
2035            instruction.
2036         */
2037 #if DUMP_OPCODE_STATS
2038         OpcodeStats::resetLastInstruction();
2039 #endif
2040         int target = (++vPC)->u.operand;
2041
2042         vPC += target;
2043         NEXT_OPCODE;
2044     }
2045     BEGIN_OPCODE(op_loop_if_true) {
2046         /* loop_if_true cond(r) target(offset)
2047          
2048            Jumps to offset target from the current instruction, if and
2049            only if register cond converts to boolean as true.
2050
2051            Additionally this loop instruction may terminate JS execution is
2052            the JS timeout is reached.
2053          */
2054         int cond = (++vPC)->u.operand;
2055         int target = (++vPC)->u.operand;
2056         if (r[cond].jsValue(exec)->toBoolean(exec)) {
2057             vPC += target;
2058             CHECK_FOR_TIMEOUT();
2059             NEXT_OPCODE;
2060         }
2061         
2062         ++vPC;
2063         NEXT_OPCODE;
2064     }
2065     BEGIN_OPCODE(op_jtrue) {
2066         /* jtrue cond(r) target(offset)
2067
2068            Jumps to offset target from the current instruction, if and
2069            only if register cond converts to boolean as true.
2070         */
2071         int cond = (++vPC)->u.operand;
2072         int target = (++vPC)->u.operand;
2073         if (r[cond].jsValue(exec)->toBoolean(exec)) {
2074             vPC += target;
2075             NEXT_OPCODE;
2076         }
2077
2078         ++vPC;
2079         NEXT_OPCODE;
2080     }
2081     BEGIN_OPCODE(op_jfalse) {
2082         /* jfalse cond(r) target(offset)
2083
2084            Jumps to offset target from the current instruction, if and
2085            only if register cond converts to boolean as false.
2086         */
2087         int cond = (++vPC)->u.operand;
2088         int target = (++vPC)->u.operand;
2089         if (!r[cond].jsValue(exec)->toBoolean(exec)) {
2090             vPC += target;
2091             NEXT_OPCODE;
2092         }
2093
2094         ++vPC;
2095         NEXT_OPCODE;
2096     }
2097     BEGIN_OPCODE(op_loop_if_less) {
2098         /* loop_if_less src1(r) src2(r) target(offset)
2099
2100            Checks whether register src1 is less than register src2, as
2101            with the ECMAScript '<' operator, and then jumps to offset
2102            target from the current instruction, if and only if the 
2103            result of the comparison is true.
2104
2105            Additionally this loop instruction may terminate JS execution is
2106            the JS timeout is reached.
2107          */
2108         JSValue* src1 = r[(++vPC)->u.operand].jsValue(exec);
2109         JSValue* src2 = r[(++vPC)->u.operand].jsValue(exec);
2110         int target = (++vPC)->u.operand;
2111         
2112         bool result = jsLess(exec, src1, src2);
2113         VM_CHECK_EXCEPTION();
2114         
2115         if (result) {
2116             vPC += target;
2117             CHECK_FOR_TIMEOUT();
2118             NEXT_OPCODE;
2119         }
2120         
2121         ++vPC;
2122         NEXT_OPCODE;
2123     }
2124     BEGIN_OPCODE(op_jless) {
2125         /* jless src1(r) src2(r) target(offset)
2126
2127            Checks whether register src1 is less than register src2, as
2128            with the ECMAScript '<' operator, and then jumps to offset
2129            target from the current instruction, if and only if the 
2130            result of the comparison is true.
2131         */
2132         JSValue* src1 = r[(++vPC)->u.operand].jsValue(exec);
2133         JSValue* src2 = r[(++vPC)->u.operand].jsValue(exec);
2134         int target = (++vPC)->u.operand;
2135
2136         bool result = jsLess(exec, src1, src2);
2137         VM_CHECK_EXCEPTION();
2138         
2139         if (result) {
2140             vPC += target;
2141             NEXT_OPCODE;
2142         }
2143
2144         ++vPC;
2145         NEXT_OPCODE;
2146     }
2147     BEGIN_OPCODE(op_jnless) {
2148         /* jnless src1(r) src2(r) target(offset)
2149
2150            Checks whether register src1 is less than register src2, as
2151            with the ECMAScript '<' operator, and then jumps to offset
2152            target from the current instruction, if and only if the 
2153            result of the comparison is false.
2154         */
2155         JSValue* src1 = r[(++vPC)->u.operand].jsValue(exec);
2156         JSValue* src2 = r[(++vPC)->u.operand].jsValue(exec);
2157         int target = (++vPC)->u.operand;
2158
2159         bool result = jsLess(exec, src1, src2);
2160         VM_CHECK_EXCEPTION();
2161         
2162         if (!result) {
2163             vPC += target;
2164             NEXT_OPCODE;
2165         }
2166
2167         ++vPC;
2168         NEXT_OPCODE;
2169     }
2170     BEGIN_OPCODE(op_switch_imm) {
2171         /* switch_imm tableIndex(n) defaultOffset(offset) scrutinee(r)
2172
2173            Performs a range checked switch on the scrutinee value, using
2174            the tableIndex-th immediate switch jump table.  If the scrutinee value
2175            is an immediate number in the range covered by the referenced jump
2176            table, and the value at jumpTable[scrutinee value] is non-zero, then
2177            that value is used as the jump offset, otherwise defaultOffset is used.
2178          */
2179         int tableIndex = (++vPC)->u.operand;
2180         int defaultOffset = (++vPC)->u.operand;
2181         JSValue* scrutinee = r[(++vPC)->u.operand].jsValue(exec);
2182         if (!JSImmediate::isNumber(scrutinee))
2183             vPC += defaultOffset;
2184         else {
2185             int32_t value = JSImmediate::getTruncatedInt32(scrutinee);
2186             vPC += codeBlock->immediateSwitchJumpTables[tableIndex].offsetForValue(value, defaultOffset);
2187         }
2188         NEXT_OPCODE;
2189     }
2190     BEGIN_OPCODE(op_switch_char) {
2191         /* switch_char tableIndex(n) defaultOffset(offset) scrutinee(r)
2192
2193            Performs a range checked switch on the scrutinee value, using
2194            the tableIndex-th character switch jump table.  If the scrutinee value
2195            is a single character string in the range covered by the referenced jump
2196            table, and the value at jumpTable[scrutinee value] is non-zero, then
2197            that value is used as the jump offset, otherwise defaultOffset is used.
2198          */
2199         int tableIndex = (++vPC)->u.operand;
2200         int defaultOffset = (++vPC)->u.operand;
2201         JSValue* scrutinee = r[(++vPC)->u.operand].jsValue(exec);
2202         if (scrutinee->type() != StringType)
2203             vPC += defaultOffset;
2204         else {
2205             UString::Rep* value = static_cast<JSString*>(scrutinee)->value().rep();
2206             if (value->size() != 1)
2207                 vPC += defaultOffset;
2208             else
2209                 vPC += codeBlock->characterSwitchJumpTables[tableIndex].offsetForValue(value->data()[0], defaultOffset);
2210         }
2211         NEXT_OPCODE;
2212     }
2213     BEGIN_OPCODE(op_switch_string) {
2214         /* switch_string tableIndex(n) defaultOffset(offset) scrutinee(r)
2215
2216            Performs a sparse hashmap based switch on the value in the scrutinee
2217            register, using the tableIndex-th string switch jump table.  If the 
2218            scrutinee value is a string that exists as a key in the referenced 
2219            jump table, then the value associated with the string is used as the 
2220            jump offset, otherwise defaultOffset is used.
2221          */
2222         int tableIndex = (++vPC)->u.operand;
2223         int defaultOffset = (++vPC)->u.operand;
2224         JSValue* scrutinee = r[(++vPC)->u.operand].jsValue(exec);
2225         if (scrutinee->type() != StringType)
2226             vPC += defaultOffset;
2227         else 
2228             vPC += offsetForStringSwitch(codeBlock->stringSwitchJumpTables[tableIndex], scrutinee, defaultOffset);
2229         NEXT_OPCODE;
2230     }
2231     BEGIN_OPCODE(op_new_func) {
2232         /* new_func dst(r) func(f)
2233
2234            Constructs a new Function instance from function func and
2235            the current scope chain using the original Function
2236            constructor, using the rules for function declarations, and
2237            puts the result in register dst.
2238         */
2239         int dst = (++vPC)->u.operand;
2240         int func = (++vPC)->u.operand;
2241
2242         r[dst] = codeBlock->functions[func]->makeFunction(exec, scopeChain);
2243
2244         ++vPC;
2245         NEXT_OPCODE;
2246     }
2247     BEGIN_OPCODE(op_new_func_exp) {
2248         /* new_func_exp dst(r) func(f)
2249
2250            Constructs a new Function instance from function func and
2251            the current scope chain using the original Function
2252            constructor, using the rules for function expressions, and
2253            puts the result in register dst.
2254         */
2255         int dst = (++vPC)->u.operand;
2256         int func = (++vPC)->u.operand;
2257
2258         r[dst] = codeBlock->functionExpressions[func]->makeFunction(exec, scopeChain);
2259
2260         ++vPC;
2261         NEXT_OPCODE;
2262     }
2263     BEGIN_OPCODE(op_call_eval) {
2264         /* call_eval dst(r) func(r) thisVal(r) firstArg(r) argCount(n)
2265
2266            Call a function named "eval" with no explicit "this" value
2267            (which may therefore be the eval operator). If register
2268            thisVal is the global object, and register func contains
2269            that global object's original global eval function, then
2270            perform the eval operator in local scope (interpreting
2271            the argument registers as for the "call"
2272            opcode). Otherwise, act exactly as the "call" opcode would.
2273          */
2274
2275         int dst = (++vPC)->u.operand;
2276         int func = (++vPC)->u.operand;
2277         int thisVal = (++vPC)->u.operand;
2278         int firstArg = (++vPC)->u.operand;
2279         int argCount = (++vPC)->u.operand;
2280
2281         JSValue* funcVal = r[func].jsValue(exec);
2282         JSValue* baseVal = r[thisVal].jsValue(exec);
2283
2284         if (baseVal == scopeChain->globalObject() && funcVal == scopeChain->globalObject()->evalFunction()) {
2285             JSObject* thisObject = static_cast<JSObject*>(r[codeBlock->thisRegister].jsValue(exec));
2286             JSValue* result = callEval(exec, thisObject, scopeChain, registerFile, r, firstArg, argCount, exceptionValue);
2287             if (exceptionValue)
2288                 goto vm_throw;
2289
2290             r[dst] = result;
2291
2292             ++vPC;
2293             NEXT_OPCODE;
2294         }
2295
2296         // We didn't find the blessed version of eval, so reset vPC and process
2297         // this instruction as a normal function call, supplying the proper 'this'
2298         // value.
2299         vPC -= 5;
2300         r[thisVal] = baseVal->toThisObject(exec);
2301
2302 #if HAVE(COMPUTED_GOTO)
2303         // Hack around gcc performance quirk by performing an indirect goto
2304         // in order to set the vPC -- attempting to do so directly results in a
2305         // significant regression.
2306         goto *op_call_indirect; // indirect goto -> op_call
2307 #endif
2308         // fall through to op_call
2309     }
2310     BEGIN_OPCODE(op_call) {
2311         /* call dst(r) func(r) thisVal(r) firstArg(r) argCount(n)
2312
2313            Perform a function call. Specifically, call register func
2314            with a "this" value of register thisVal, and put the result
2315            in register dst.
2316
2317            The arguments start at register firstArg and go up to
2318            argCount, but the "this" value is considered an implicit
2319            first argument, so the argCount should be one greater than
2320            the number of explicit arguments passed, and the register
2321            after firstArg should contain the actual first
2322            argument. This opcode will copy from the thisVal register
2323            to the firstArg register, unless the register index of
2324            thisVal is the special missing this object marker, which is
2325            2^31-1; in that case, the global object will be used as the
2326            "this" value.
2327
2328            If func is a native code function, then this opcode calls
2329            it and returns the value immediately. 
2330
2331            But if it is a JS function, then the current scope chain
2332            and code block is set to the function's, and we slide the
2333            register window so that the arguments would form the first
2334            few local registers of the called function's register
2335            window. In addition, a call frame header is written
2336            immediately before the arguments; see the call frame
2337            documentation for an explanation of how many registers a
2338            call frame takes and what they contain. That many registers
2339            before the firstArg register will be overwritten by the
2340            call. In addition, any registers higher than firstArg +
2341            argCount may be overwritten. Once this setup is complete,
2342            execution continues from the called function's first
2343            argument, and does not return until a "ret" opcode is
2344            encountered.
2345          */
2346
2347         int dst = (++vPC)->u.operand;
2348         int func = (++vPC)->u.operand;
2349         int thisVal = (++vPC)->u.operand;
2350         int firstArg = (++vPC)->u.operand;
2351         int argCount = (++vPC)->u.operand;
2352
2353         JSValue* v = r[func].jsValue(exec);
2354
2355         CallData callData;
2356         CallType callType = v->getCallData(callData);
2357
2358         if (callType == CallTypeJS) {
2359             if (*enabledProfilerReference)
2360                 (*enabledProfilerReference)->willExecute(exec, static_cast<JSObject*>(v));
2361
2362             ScopeChainNode* callDataScopeChain = callData.js.scopeChain;
2363             FunctionBodyNode* functionBodyNode = callData.js.functionBody;
2364             CodeBlock* newCodeBlock = &functionBodyNode->byteCode(callDataScopeChain);
2365
2366             r[firstArg] = thisVal == missingThisObjectMarker() ? exec->globalThisValue() : r[thisVal].jsValue(exec);
2367
2368             Register* callFrame = r + firstArg - RegisterFile::CallFrameHeaderSize;
2369             initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, r, dst, firstArg, argCount, 0, v);
2370             exec->m_callFrame = callFrame;
2371
2372             r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, r, firstArg, argCount, exceptionValue);
2373             if (UNLIKELY(exceptionValue != 0))
2374                 goto vm_throw;
2375
2376             codeBlock = newCodeBlock;
2377             setScopeChain(exec, scopeChain, scopeChainForCall(exec, functionBodyNode, codeBlock, callDataScopeChain, r));
2378             k = codeBlock->registers.data();
2379             vPC = codeBlock->instructions.begin();
2380
2381 #if DUMP_OPCODE_STATS
2382             OpcodeStats::resetLastInstruction();
2383 #endif
2384             
2385             NEXT_OPCODE;
2386         }
2387
2388         if (callType == CallTypeHost) {
2389             if (*enabledProfilerReference)
2390                 (*enabledProfilerReference)->willExecute(exec, static_cast<JSObject*>(v));
2391
2392             JSValue* thisValue = thisVal == missingThisObjectMarker() ? exec->globalThisValue() : r[thisVal].jsValue(exec);
2393             ArgList args(r + firstArg + 1, argCount - 1);
2394
2395             MACHINE_SAMPLING_callingHostFunction();
2396
2397             JSValue* returnValue = callData.native.function(exec, static_cast<JSObject*>(v), thisValue, args);
2398             VM_CHECK_EXCEPTION();
2399
2400             r[dst] = returnValue;
2401
2402             if (*enabledProfilerReference)
2403                 (*enabledProfilerReference)->didExecute(exec, static_cast<JSObject*>(v));
2404
2405             ++vPC;
2406             NEXT_OPCODE;
2407         }
2408
2409         ASSERT(callType == CallTypeNone);
2410
2411         exceptionValue = createNotAFunctionError(exec, v, vPC, codeBlock);
2412         goto vm_throw;
2413     }
2414     BEGIN_OPCODE(op_ret) {
2415         /* ret result(r)
2416            
2417            Return register result as the return value of the current
2418            function call, writing it into the caller's expected return
2419            value register. In addition, unwind one call frame and
2420            restore the scope chain, code block instruction pointer and
2421            register base to those of the calling function.
2422         */
2423            
2424         int result = (++vPC)->u.operand;
2425
2426         Register* callFrame = r - codeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
2427         if (JSActivation* activation = static_cast<JSActivation*>(callFrame[RegisterFile::OptionalCalleeActivation].jsValue(exec))) {
2428             ASSERT(!codeBlock->needsFullScopeChain || scopeChain->object == activation);
2429             ASSERT(activation->isActivationObject());
2430             activation->copyRegisters();
2431         }
2432
2433         if (*enabledProfilerReference)
2434             (*enabledProfilerReference)->didExecute(exec, static_cast<JSObject*>(callFrame[RegisterFile::Callee].jsValue(exec)));
2435
2436         if (codeBlock->needsFullScopeChain)
2437             scopeChain->deref();
2438
2439         JSValue* returnValue = r[result].jsValue(exec);
2440         if (callFrame[RegisterFile::CalledAsConstructor].i() && !returnValue->isObject()) {
2441             JSValue* thisObject = callFrame[RegisterFile::CallFrameHeaderSize].jsValue(exec);
2442             returnValue = thisObject;
2443         }
2444
2445         codeBlock = callFrame[RegisterFile::CallerCodeBlock].codeBlock();
2446         if (!codeBlock)
2447             return returnValue;
2448
2449         k = codeBlock->registers.data();
2450         vPC = callFrame[RegisterFile::ReturnVPC].vPC();
2451         setScopeChain(exec, scopeChain, callFrame[RegisterFile::CallerScopeChain].scopeChain());
2452         r = callFrame[RegisterFile::CallerRegisters].r();
2453         exec->m_callFrame = r - codeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
2454         int dst = callFrame[RegisterFile::ReturnValueRegister].i();
2455         r[dst] = returnValue;
2456
2457         NEXT_OPCODE;
2458     }
2459     BEGIN_OPCODE(op_construct) {
2460         /* construct dst(r) constr(r) firstArg(r) argCount(n)
2461
2462            Invoke register "constr" as a constructor. For JS
2463            functions, the calling convention is exactly as for the
2464            "call" opcode, except that the "this" value is a newly
2465            created Object. For native constructors, a null "this"
2466            value is passed. In either case, the firstArg and argCount
2467            registers are interpreted as for the "call" opcode.
2468         */
2469
2470         int dst = (++vPC)->u.operand;
2471         int constr = (++vPC)->u.operand;
2472         int firstArg = (++vPC)->u.operand;
2473         int argCount = (++vPC)->u.operand;
2474
2475         JSValue* constrVal = r[constr].jsValue(exec);
2476
2477         ConstructData constructData;
2478         ConstructType constructType = constrVal->getConstructData(constructData);
2479
2480         // Removing this line of code causes a measurable regression on squirrelfish.
2481         JSObject* constructor = static_cast<JSObject*>(constrVal);
2482
2483         if (constructType == ConstructTypeJS) {
2484             if (*enabledProfilerReference)
2485                 (*enabledProfilerReference)->willExecute(exec, constructor);
2486
2487             JSObject* prototype;
2488             JSValue* p = constructor->get(exec, exec->propertyNames().prototype);
2489             if (p->isObject())
2490                 prototype = static_cast<JSObject*>(p);
2491             else
2492                 prototype = scopeChain->globalObject()->objectPrototype();
2493             JSObject* newObject = new (exec) JSObject(prototype);
2494
2495             ScopeChainNode* callDataScopeChain = constructData.js.scopeChain;
2496             FunctionBodyNode* functionBodyNode = constructData.js.functionBody;
2497             CodeBlock* newCodeBlock = &functionBodyNode->byteCode(callDataScopeChain);
2498
2499             r[firstArg] = newObject; // "this" value
2500
2501             Register* callFrame = r + firstArg - RegisterFile::CallFrameHeaderSize;
2502             initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, r, dst, firstArg, argCount, 1, constructor);
2503             exec->m_callFrame = callFrame;
2504
2505             r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, r, firstArg, argCount, exceptionValue);
2506             if (exceptionValue)
2507                 goto vm_throw;
2508
2509             codeBlock = newCodeBlock;
2510             setScopeChain(exec, scopeChain, scopeChainForCall(exec, functionBodyNode, codeBlock, callDataScopeChain, r));
2511             k = codeBlock->registers.data();
2512             vPC = codeBlock->instructions.begin();
2513
2514             NEXT_OPCODE;
2515         }
2516
2517         if (constructType == ConstructTypeHost) {
2518             if (*enabledProfilerReference)
2519                 (*enabledProfilerReference)->willExecute(exec, constructor);
2520
2521             ArgList args(r + firstArg + 1, argCount - 1);
2522
2523             MACHINE_SAMPLING_callingHostFunction();
2524
2525             JSValue* returnValue = constructData.native.function(exec, constructor, args);
2526
2527             VM_CHECK_EXCEPTION();
2528             r[dst] = returnValue;
2529
2530             if (*enabledProfilerReference)
2531                 (*enabledProfilerReference)->didExecute(exec, constructor);
2532
2533             ++vPC;
2534             NEXT_OPCODE;
2535         }
2536
2537         ASSERT(constructType == ConstructTypeNone);
2538
2539         exceptionValue = createNotAConstructorError(exec, constrVal, vPC, codeBlock);
2540         goto vm_throw;
2541     }
2542     BEGIN_OPCODE(op_push_scope) {
2543         /* push_scope scope(r)
2544
2545            Converts register scope to object, and pushes it onto the top
2546            of the current scope chain.
2547         */
2548         int scope = (++vPC)->u.operand;
2549         JSValue* v = r[scope].jsValue(exec);
2550         JSObject* o = v->toObject(exec);
2551         VM_CHECK_EXCEPTION();
2552
2553         setScopeChain(exec, scopeChain, scopeChain->push(o));
2554
2555         ++vPC;
2556         NEXT_OPCODE;
2557     }
2558     BEGIN_OPCODE(op_pop_scope) {
2559         /* pop_scope
2560
2561            Removes the top item from the current scope chain.
2562         */
2563         setScopeChain(exec, scopeChain, scopeChain->pop());
2564
2565         ++vPC;
2566         NEXT_OPCODE;
2567     }
2568     BEGIN_OPCODE(op_get_pnames) {
2569         /* get_pnames dst(r) base(r)
2570
2571            Creates a property name list for register base and puts it
2572            in register dst. This is not a true JavaScript value, just
2573            a synthetic value used to keep the iteration state in a
2574            register.
2575         */
2576         int dst = (++vPC)->u.operand;
2577         int base = (++vPC)->u.operand;
2578
2579         r[dst] = JSPropertyNameIterator::create(exec, r[base].jsValue(exec));
2580         ++vPC;
2581         NEXT_OPCODE;
2582     }
2583     BEGIN_OPCODE(op_next_pname) {
2584         /* next_pname dst(r) iter(r) target(offset)
2585
2586            Tries to copies the next name from property name list in
2587            register iter. If there are names left, then copies one to
2588            register dst, and jumps to offset target. If there are none
2589            left, invalidates the iterator and continues to the next
2590            instruction.
2591         */
2592         int dst = (++vPC)->u.operand;
2593         int iter = (++vPC)->u.operand;
2594         int target = (++vPC)->u.operand;
2595
2596         JSPropertyNameIterator* it = r[iter].jsPropertyNameIterator();
2597         if (JSValue* temp = it->next(exec)) {
2598             CHECK_FOR_TIMEOUT();
2599             r[dst] = temp;
2600             vPC += target;
2601             NEXT_OPCODE;
2602         }
2603         it->invalidate();
2604
2605         ++vPC;
2606         NEXT_OPCODE;
2607     }
2608     BEGIN_OPCODE(op_jmp_scopes) {
2609         /* jmp_scopes count(n) target(offset)
2610
2611            Removes the a number of items from the current scope chain
2612            specified by immediate number count, then jumps to offset
2613            target.
2614         */
2615         int count = (++vPC)->u.operand;
2616         int target = (++vPC)->u.operand;
2617
2618         ScopeChainNode* tmp = scopeChain;
2619         while (count--)
2620             tmp = tmp->pop();
2621         setScopeChain(exec, scopeChain, tmp);
2622
2623         vPC += target;
2624         NEXT_OPCODE;
2625     }
2626 #if HAVE(COMPUTED_GOTO)
2627     // Appease GCC
2628     goto *(&&skip_new_scope);
2629 #endif
2630     BEGIN_OPCODE(op_push_new_scope) {
2631         /* new_scope dst(r) property(id) value(r)
2632          
2633            Constructs a new StaticScopeObject with property set to value.  That scope
2634            object is then pushed onto the ScopeChain.  The scope object is then stored
2635            in dst for GC.
2636          */
2637         setScopeChain(exec, scopeChain, createExceptionScope(exec, codeBlock, vPC, r, scopeChain));
2638         vPC += 4;
2639         NEXT_OPCODE;
2640     }
2641 #if HAVE(COMPUTED_GOTO)
2642     skip_new_scope:
2643 #endif
2644     BEGIN_OPCODE(op_catch) {
2645         /* catch ex(r)
2646
2647            Retrieves the VMs current exception and puts it in register
2648            ex. This is only valid after an exception has been raised,
2649            and usually forms the beginning of an exception handler.
2650         */
2651         ASSERT(exceptionValue);
2652         ASSERT(!exec->hadException());
2653         int ex = (++vPC)->u.operand;
2654         r[ex] = exceptionValue;
2655         exceptionValue = 0;
2656
2657         ++vPC;
2658         NEXT_OPCODE;
2659     }
2660     BEGIN_OPCODE(op_throw) {
2661         /* throw ex(r)
2662
2663            Throws register ex as an exception. This involves three
2664            steps: first, it is set as the current exception in the
2665            VM's internal state, then the stack is unwound until an
2666            exception handler or a native code boundary is found, and
2667            then control resumes at the exception handler if any or
2668            else the script returns control to the nearest native caller.
2669         */
2670
2671         int ex = (++vPC)->u.operand;
2672         exceptionValue = r[ex].jsValue(exec);
2673
2674         handlerVPC = throwException(exec, exceptionValue, vPC, codeBlock, k, scopeChain, r, true);
2675         if (!handlerVPC) {
2676             *exception = exceptionValue;
2677             return jsNull();
2678         }
2679
2680 #if HAVE(COMPUTED_GOTO)
2681         // Hack around gcc performance quirk by performing an indirect goto
2682         // in order to set the vPC -- attempting to do so directly results in a
2683         // significant regression.
2684         goto *op_throw_end_indirect; // indirect goto -> op_throw_end
2685     }
2686     op_throw_end: {
2687 #endif
2688
2689         vPC = handlerVPC;
2690         NEXT_OPCODE;
2691     }
2692     BEGIN_OPCODE(op_new_error) {
2693         /* new_error dst(r) type(n) message(k)
2694
2695            Constructs a new Error instance using the original
2696            constructor, using immediate number n as the type and
2697            constant message as the message string. The result is
2698            written to register dst.
2699         */
2700         int dst = (++vPC)->u.operand;
2701         int type = (++vPC)->u.operand;
2702         int message = (++vPC)->u.operand;
2703
2704         r[dst] = Error::create(exec, (ErrorType)type, k[message].jsValue(exec)->toString(exec), codeBlock->lineNumberForVPC(vPC), codeBlock->ownerNode->sourceId(), codeBlock->ownerNode->sourceURL());
2705
2706         ++vPC;
2707         NEXT_OPCODE;
2708     }
2709     BEGIN_OPCODE(op_end) {
2710         /* end result(r)
2711            
2712            Return register result as the value of a global or eval
2713            program. Return control to the calling native code.
2714         */
2715
2716         if (codeBlock->needsFullScopeChain) {
2717             ASSERT(scopeChain->refCount > 1);
2718             scopeChain->deref();
2719         }
2720         int result = (++vPC)->u.operand;
2721         return r[result].jsValue(exec);
2722     }
2723     BEGIN_OPCODE(op_put_getter) {
2724         /* put_getter base(r) property(id) function(r)
2725
2726            Sets register function on register base as the getter named
2727            by identifier property. Base and function are assumed to be
2728            objects as this op should only be used for getters defined
2729            in object literal form.
2730
2731            Unlike many opcodes, this one does not write any output to
2732            the register file.
2733         */
2734         int base = (++vPC)->u.operand;
2735         int property = (++vPC)->u.operand;
2736         int function = (++vPC)->u.operand;
2737
2738         ASSERT(r[base].jsValue(exec)->isObject());
2739         JSObject* baseObj = static_cast<JSObject*>(r[base].jsValue(exec));
2740         Identifier& ident = codeBlock->identifiers[property];
2741         ASSERT(r[function].jsValue(exec)->isObject());
2742         baseObj->defineGetter(exec, ident, static_cast<JSObject*>(r[function].jsValue(exec)));
2743
2744         ++vPC;
2745         NEXT_OPCODE;
2746     }
2747     BEGIN_OPCODE(op_put_setter) {
2748         /* put_setter base(r) property(id) function(r)
2749
2750            Sets register function on register base as the setter named
2751            by identifier property. Base and function are assumed to be
2752            objects as this op should only be used for setters defined
2753            in object literal form.
2754
2755            Unlike many opcodes, this one does not write any output to
2756            the register file.
2757         */
2758         int base = (++vPC)->u.operand;
2759         int property = (++vPC)->u.operand;
2760         int function = (++vPC)->u.operand;
2761
2762         ASSERT(r[base].jsValue(exec)->isObject());
2763         JSObject* baseObj = static_cast<JSObject*>(r[base].jsValue(exec));
2764         Identifier& ident = codeBlock->identifiers[property];
2765         ASSERT(r[function].jsValue(exec)->isObject());
2766         baseObj->defineSetter(exec, ident, static_cast<JSObject*>(r[function].jsValue(exec)));
2767
2768         ++vPC;
2769         NEXT_OPCODE;
2770     }
2771     BEGIN_OPCODE(op_jsr) {
2772         /* jsr retAddrDst(r) target(offset)
2773
2774            Places the address of the next instruction into the retAddrDst
2775            register and jumps to offset target from the current instruction.
2776         */
2777         int retAddrDst = (++vPC)->u.operand;
2778         int target = (++vPC)->u.operand;
2779         r[retAddrDst] = vPC + 1;
2780
2781         vPC += target;
2782         NEXT_OPCODE;
2783     }
2784     BEGIN_OPCODE(op_sret) {
2785         /* sret retAddrSrc(r)
2786
2787          Jumps to the address stored in the retAddrSrc register. This
2788          differs from op_jmp because the target address is stored in a
2789          register, not as an immediate.
2790         */
2791         int retAddrSrc = (++vPC)->u.operand;
2792         vPC = r[retAddrSrc].vPC();
2793         NEXT_OPCODE;
2794     }
2795     BEGIN_OPCODE(op_debug) {
2796         /* debug debugHookID(n) firstLine(n) lastLine(n)
2797
2798          Notifies the debugger of the current state of execution. This opcode
2799          is only generated while the debugger is attached.
2800         */
2801
2802         debug(exec, vPC, codeBlock, scopeChain, r);
2803
2804         vPC += 4;
2805         NEXT_OPCODE;
2806     }
2807     vm_throw: {
2808         exec->clearException();
2809         if (!tickCount) {
2810             // The exceptionValue is a lie! (GCC produces bad code for reasons I 
2811             // cannot fathom if we don't assign to the exceptionValue before branching)
2812             exceptionValue = createInterruptedExecutionException(exec);
2813         }
2814         handlerVPC = throwException(exec, exceptionValue, vPC, codeBlock, k, scopeChain, r, false);
2815         if (!handlerVPC) {
2816             *exception = exceptionValue;
2817             return jsNull();
2818         }
2819         vPC = handlerVPC;
2820         NEXT_OPCODE;
2821     }
2822     }
2823     #undef NEXT_OPCODE
2824     #undef BEGIN_OPCODE
2825     #undef VM_CHECK_EXCEPTION
2826 }
2827
2828 JSValue* Machine::retrieveArguments(ExecState* exec, JSFunction* function) const
2829 {
2830     Register* callFrame = this->callFrame(exec, function);
2831     if (!callFrame)
2832         return jsNull();
2833
2834     JSActivation* activation = static_cast<JSActivation*>(callFrame[RegisterFile::OptionalCalleeActivation].jsValue(exec));
2835     if (!activation) {
2836         CodeBlock* codeBlock = &function->m_body->generatedByteCode();
2837         activation = new (exec) JSActivation(function->m_body, callFrame + RegisterFile::CallFrameHeaderSize + codeBlock->numLocals);
2838         callFrame[RegisterFile::OptionalCalleeActivation] = activation;
2839     }
2840
2841     return activation->get(exec, exec->propertyNames().arguments);
2842 }
2843
2844 JSValue* Machine::retrieveCaller(ExecState* exec, JSFunction* function) const
2845 {
2846     Register* callFrame = this->callFrame(exec, function);
2847     if (!callFrame)
2848         return jsNull();
2849
2850     CodeBlock* callerCodeBlock = callFrame[RegisterFile::CallerCodeBlock].codeBlock();
2851     if (!callerCodeBlock)
2852         return jsNull();
2853
2854     Register* callerCallFrame = callFrame[RegisterFile::CallerRegisters].r() - callerCodeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
2855     if (JSValue* caller = callerCallFrame[RegisterFile::Callee].jsValue(exec))
2856         return caller;
2857
2858     return jsNull();
2859 }
2860
2861 Register* Machine::callFrame(ExecState* exec, JSFunction* function) const
2862 {
2863     Register* callFrame = exec->m_callFrame;
2864
2865     while (1) {
2866         while (!callFrame) {
2867             exec = exec->m_prev;
2868             if (!exec)
2869                 return 0;
2870             callFrame = exec->m_callFrame;
2871         }
2872
2873         if (callFrame[RegisterFile::Callee].jsValue(exec) == function)
2874             return callFrame;
2875
2876         CodeBlock* callerCodeBlock = callFrame[RegisterFile::CallerCodeBlock].codeBlock();
2877         if (!callerCodeBlock) {
2878             callFrame = 0;
2879             continue;
2880         }
2881         
2882         callFrame = callFrame[RegisterFile::CallerRegisters].r() - callerCodeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
2883     }
2884 }
2885
2886 void Machine::getArgumentsData(Register* callFrame, JSFunction*& function, Register*& argv, int& argc)
2887 {
2888     function = static_cast<JSFunction*>(callFrame[RegisterFile::Callee].getJSValue());
2889     ASSERT(function->inherits(&JSFunction::info));
2890
2891     argv = callFrame[RegisterFile::CallerRegisters].r() + callFrame[RegisterFile::ArgumentStartRegister].i() + 1; //  + 1 to skip "this"
2892     argc = callFrame[RegisterFile::ArgumentCount].i() - 1; // - 1 to skip "this"
2893 }
2894
2895 } // namespace KJS