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