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