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