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