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