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