dccb30f25c666810f6e0eb9d75c4b236d3b9be4f
[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         ++vPC;
1877         NEXT_INSTRUCTION();
1878     }
1879     DEFINE_OPCODE(op_add) {
1880         /* add dst(r) src1(r) src2(r)
1881
1882            Adds register src1 and register src2, and puts the result
1883            in register dst. (JS add may be string concatenation or
1884            numeric add, depending on the types of the operands.)
1885         */
1886         int dst = (++vPC)->u.operand;
1887         JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1888         JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1889         if (JSImmediate::canDoFastAdditiveOperations(src1) && JSImmediate::canDoFastAdditiveOperations(src2))
1890             callFrame[dst] = JSImmediate::addImmediateNumbers(src1, src2);
1891         else {
1892             JSValue* result = jsAdd(callFrame, src1, src2);
1893             CHECK_FOR_EXCEPTION();
1894             callFrame[dst] = result;
1895         }
1896         vPC += 2;
1897         NEXT_INSTRUCTION();
1898     }
1899     DEFINE_OPCODE(op_mul) {
1900         /* mul dst(r) src1(r) src2(r)
1901
1902            Multiplies register src1 and register src2 (converted to
1903            numbers), and puts the product in register dst.
1904         */
1905         int dst = (++vPC)->u.operand;
1906         JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1907         JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1908         double left;
1909         double right;
1910         if (JSImmediate::areBothImmediateNumbers(src1, src2)) {
1911             int32_t left = JSImmediate::getTruncatedInt32(src1);
1912             int32_t right = JSImmediate::getTruncatedInt32(src2);
1913             if ((left | right) >> 15 == 0)
1914                 callFrame[dst] = jsNumber(callFrame, left * right);
1915             else
1916                 callFrame[dst] = jsNumber(callFrame, static_cast<double>(left) * static_cast<double>(right));
1917         } else if (fastIsNumber(src1, left) && fastIsNumber(src2, right))
1918             callFrame[dst] = jsNumber(callFrame, left * right);
1919         else {
1920             JSValue* result = jsNumber(callFrame, src1->toNumber(callFrame) * src2->toNumber(callFrame));
1921             CHECK_FOR_EXCEPTION();
1922             callFrame[dst] = result;
1923         }
1924
1925         vPC += 2;
1926         NEXT_INSTRUCTION();
1927     }
1928     DEFINE_OPCODE(op_div) {
1929         /* div dst(r) dividend(r) divisor(r)
1930
1931            Divides register dividend (converted to number) by the
1932            register divisor (converted to number), and puts the
1933            quotient in register dst.
1934         */
1935         int dst = (++vPC)->u.operand;
1936         JSValue* dividend = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1937         JSValue* divisor = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1938         double left;
1939         double right;
1940         if (fastIsNumber(dividend, left) && fastIsNumber(divisor, right))
1941             callFrame[dst] = jsNumber(callFrame, left / right);
1942         else {
1943             JSValue* result = jsNumber(callFrame, dividend->toNumber(callFrame) / divisor->toNumber(callFrame));
1944             CHECK_FOR_EXCEPTION();
1945             callFrame[dst] = result;
1946         }
1947         ++vPC;
1948         NEXT_INSTRUCTION();
1949     }
1950     DEFINE_OPCODE(op_mod) {
1951         /* mod dst(r) dividend(r) divisor(r)
1952
1953            Divides register dividend (converted to number) by
1954            register divisor (converted to number), and puts the
1955            remainder in register dst.
1956         */
1957         int dst = (++vPC)->u.operand;
1958         int dividend = (++vPC)->u.operand;
1959         int divisor = (++vPC)->u.operand;
1960
1961         JSValue* dividendValue = callFrame[dividend].jsValue(callFrame);
1962         JSValue* divisorValue = callFrame[divisor].jsValue(callFrame);
1963
1964         if (JSImmediate::areBothImmediateNumbers(dividendValue, divisorValue) && divisorValue != JSImmediate::from(0)) {
1965             callFrame[dst] = JSImmediate::from(JSImmediate::getTruncatedInt32(dividendValue) % JSImmediate::getTruncatedInt32(divisorValue));
1966             ++vPC;
1967             NEXT_INSTRUCTION();
1968         }
1969
1970         double d = dividendValue->toNumber(callFrame);
1971         JSValue* result = jsNumber(callFrame, fmod(d, divisorValue->toNumber(callFrame)));
1972         CHECK_FOR_EXCEPTION();
1973         callFrame[dst] = result;
1974         ++vPC;
1975         NEXT_INSTRUCTION();
1976     }
1977     DEFINE_OPCODE(op_sub) {
1978         /* sub dst(r) src1(r) src2(r)
1979
1980            Subtracts register src2 (converted to number) from register
1981            src1 (converted to number), and puts the difference in
1982            register dst.
1983         */
1984         int dst = (++vPC)->u.operand;
1985         JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1986         JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1987         double left;
1988         double right;
1989         if (JSImmediate::canDoFastAdditiveOperations(src1) && JSImmediate::canDoFastAdditiveOperations(src2))
1990             callFrame[dst] = JSImmediate::subImmediateNumbers(src1, src2);
1991         else if (fastIsNumber(src1, left) && fastIsNumber(src2, right))
1992             callFrame[dst] = jsNumber(callFrame, left - right);
1993         else {
1994             JSValue* result = jsNumber(callFrame, src1->toNumber(callFrame) - src2->toNumber(callFrame));
1995             CHECK_FOR_EXCEPTION();
1996             callFrame[dst] = result;
1997         }
1998         vPC += 2;
1999         NEXT_INSTRUCTION();
2000     }
2001     DEFINE_OPCODE(op_lshift) {
2002         /* lshift dst(r) val(r) shift(r)
2003
2004            Performs left shift of register val (converted to int32) by
2005            register shift (converted to uint32), and puts the result
2006            in register dst.
2007         */
2008         int dst = (++vPC)->u.operand;
2009         JSValue* val = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2010         JSValue* shift = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2011         int32_t left;
2012         uint32_t right;
2013         if (JSImmediate::areBothImmediateNumbers(val, shift))
2014             callFrame[dst] = jsNumber(callFrame, JSImmediate::getTruncatedInt32(val) << (JSImmediate::getTruncatedUInt32(shift) & 0x1f));
2015         else if (fastToInt32(val, left) && fastToUInt32(shift, right))
2016             callFrame[dst] = jsNumber(callFrame, left << (right & 0x1f));
2017         else {
2018             JSValue* result = jsNumber(callFrame, (val->toInt32(callFrame)) << (shift->toUInt32(callFrame) & 0x1f));
2019             CHECK_FOR_EXCEPTION();
2020             callFrame[dst] = result;
2021         }
2022
2023         ++vPC;
2024         NEXT_INSTRUCTION();
2025     }
2026     DEFINE_OPCODE(op_rshift) {
2027         /* rshift dst(r) val(r) shift(r)
2028
2029            Performs arithmetic right shift of register val (converted
2030            to int32) by register shift (converted to
2031            uint32), and puts the result in register dst.
2032         */
2033         int dst = (++vPC)->u.operand;
2034         JSValue* val = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2035         JSValue* shift = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2036         int32_t left;
2037         uint32_t right;
2038         if (JSImmediate::areBothImmediateNumbers(val, shift))
2039             callFrame[dst] = JSImmediate::rightShiftImmediateNumbers(val, shift);
2040         else if (fastToInt32(val, left) && fastToUInt32(shift, right))
2041             callFrame[dst] = jsNumber(callFrame, left >> (right & 0x1f));
2042         else {
2043             JSValue* result = jsNumber(callFrame, (val->toInt32(callFrame)) >> (shift->toUInt32(callFrame) & 0x1f));
2044             CHECK_FOR_EXCEPTION();
2045             callFrame[dst] = result;
2046         }
2047
2048         ++vPC;
2049         NEXT_INSTRUCTION();
2050     }
2051     DEFINE_OPCODE(op_urshift) {
2052         /* rshift dst(r) val(r) shift(r)
2053
2054            Performs logical right shift of register val (converted
2055            to uint32) by register shift (converted to
2056            uint32), and puts the result in register dst.
2057         */
2058         int dst = (++vPC)->u.operand;
2059         JSValue* val = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2060         JSValue* shift = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2061         if (JSImmediate::areBothImmediateNumbers(val, shift) && !JSImmediate::isNegative(val))
2062             callFrame[dst] = JSImmediate::rightShiftImmediateNumbers(val, shift);
2063         else {
2064             JSValue* result = jsNumber(callFrame, (val->toUInt32(callFrame)) >> (shift->toUInt32(callFrame) & 0x1f));
2065             CHECK_FOR_EXCEPTION();
2066             callFrame[dst] = result;
2067         }
2068
2069         ++vPC;
2070         NEXT_INSTRUCTION();
2071     }
2072     DEFINE_OPCODE(op_bitand) {
2073         /* bitand dst(r) src1(r) src2(r)
2074
2075            Computes bitwise AND of register src1 (converted to int32)
2076            and register src2 (converted to int32), and puts the result
2077            in register dst.
2078         */
2079         int dst = (++vPC)->u.operand;
2080         JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2081         JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2082         int32_t left;
2083         int32_t right;
2084         if (JSImmediate::areBothImmediateNumbers(src1, src2))
2085             callFrame[dst] = JSImmediate::andImmediateNumbers(src1, src2);
2086         else if (fastToInt32(src1, left) && fastToInt32(src2, right))
2087             callFrame[dst] = jsNumber(callFrame, left & right);
2088         else {
2089             JSValue* result = jsNumber(callFrame, src1->toInt32(callFrame) & src2->toInt32(callFrame));
2090             CHECK_FOR_EXCEPTION();
2091             callFrame[dst] = result;
2092         }
2093
2094         vPC += 2;
2095         NEXT_INSTRUCTION();
2096     }
2097     DEFINE_OPCODE(op_bitxor) {
2098         /* bitxor dst(r) src1(r) src2(r)
2099
2100            Computes bitwise XOR of register src1 (converted to int32)
2101            and register src2 (converted to int32), and puts the result
2102            in register dst.
2103         */
2104         int dst = (++vPC)->u.operand;
2105         JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2106         JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2107         int32_t left;
2108         int32_t right;
2109         if (JSImmediate::areBothImmediateNumbers(src1, src2))
2110             callFrame[dst] = JSImmediate::xorImmediateNumbers(src1, src2);
2111         else if (fastToInt32(src1, left) && fastToInt32(src2, right))
2112             callFrame[dst] = jsNumber(callFrame, left ^ right);
2113         else {
2114             JSValue* result = jsNumber(callFrame, src1->toInt32(callFrame) ^ src2->toInt32(callFrame));
2115             CHECK_FOR_EXCEPTION();
2116             callFrame[dst] = result;
2117         }
2118
2119         vPC += 2;
2120         NEXT_INSTRUCTION();
2121     }
2122     DEFINE_OPCODE(op_bitor) {
2123         /* bitor dst(r) src1(r) src2(r)
2124
2125            Computes bitwise OR of register src1 (converted to int32)
2126            and register src2 (converted to int32), and puts the
2127            result in register dst.
2128         */
2129         int dst = (++vPC)->u.operand;
2130         JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2131         JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2132         int32_t left;
2133         int32_t right;
2134         if (JSImmediate::areBothImmediateNumbers(src1, src2))
2135             callFrame[dst] = JSImmediate::orImmediateNumbers(src1, src2);
2136         else if (fastToInt32(src1, left) && fastToInt32(src2, right))
2137             callFrame[dst] = jsNumber(callFrame, left | right);
2138         else {
2139             JSValue* result = jsNumber(callFrame, src1->toInt32(callFrame) | src2->toInt32(callFrame));
2140             CHECK_FOR_EXCEPTION();
2141             callFrame[dst] = result;
2142         }
2143
2144         vPC += 2;
2145         NEXT_INSTRUCTION();
2146     }
2147     DEFINE_OPCODE(op_bitnot) {
2148         /* bitnot dst(r) src(r)
2149
2150            Computes bitwise NOT of register src1 (converted to int32),
2151            and puts the result in register dst.
2152         */
2153         int dst = (++vPC)->u.operand;
2154         JSValue* src = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2155         int32_t value;
2156         if (fastToInt32(src, value))
2157             callFrame[dst] = jsNumber(callFrame, ~value);
2158         else {
2159             JSValue* result = jsNumber(callFrame, ~src->toInt32(callFrame));
2160             CHECK_FOR_EXCEPTION();
2161             callFrame[dst] = result;
2162         }
2163         ++vPC;
2164         NEXT_INSTRUCTION();
2165     }
2166     DEFINE_OPCODE(op_not) {
2167         /* not dst(r) src(r)
2168
2169            Computes logical NOT of register src (converted to
2170            boolean), and puts the result in register dst.
2171         */
2172         int dst = (++vPC)->u.operand;
2173         int src = (++vPC)->u.operand;
2174         JSValue* result = jsBoolean(!callFrame[src].jsValue(callFrame)->toBoolean(callFrame));
2175         CHECK_FOR_EXCEPTION();
2176         callFrame[dst] = result;
2177
2178         ++vPC;
2179         NEXT_INSTRUCTION();
2180     }
2181     DEFINE_OPCODE(op_instanceof) {
2182         /* instanceof dst(r) value(r) constructor(r) constructorProto(r)
2183
2184            Tests whether register value is an instance of register
2185            constructor, and puts the boolean result in register
2186            dst. Register constructorProto must contain the "prototype"
2187            property (not the actual prototype) of the object in
2188            register constructor. This lookup is separated so that
2189            polymorphic inline caching can apply.
2190
2191            Raises an exception if register constructor is not an
2192            object.
2193         */
2194         int dst = vPC[1].u.operand;
2195         int value = vPC[2].u.operand;
2196         int base = vPC[3].u.operand;
2197         int baseProto = vPC[4].u.operand;
2198
2199         JSValue* baseVal = callFrame[base].jsValue(callFrame);
2200
2201         if (isNotObject(callFrame, true, callFrame->codeBlock(), vPC, baseVal, exceptionValue))
2202             goto vm_throw;
2203
2204         JSObject* baseObj = asObject(baseVal);
2205         callFrame[dst] = jsBoolean(baseObj->structure()->typeInfo().implementsHasInstance() ? baseObj->hasInstance(callFrame, callFrame[value].jsValue(callFrame), callFrame[baseProto].jsValue(callFrame)) : false);
2206
2207         vPC += 5;
2208         NEXT_INSTRUCTION();
2209     }
2210     DEFINE_OPCODE(op_typeof) {
2211         /* typeof dst(r) src(r)
2212
2213            Determines the type string for src according to ECMAScript
2214            rules, and puts the result in register dst.
2215         */
2216         int dst = (++vPC)->u.operand;
2217         int src = (++vPC)->u.operand;
2218         callFrame[dst] = jsTypeStringForValue(callFrame, callFrame[src].jsValue(callFrame));
2219
2220         ++vPC;
2221         NEXT_INSTRUCTION();
2222     }
2223     DEFINE_OPCODE(op_is_undefined) {
2224         /* is_undefined dst(r) src(r)
2225
2226            Determines whether the type string for src according to
2227            the ECMAScript rules is "undefined", and puts the result
2228            in register dst.
2229         */
2230         int dst = (++vPC)->u.operand;
2231         int src = (++vPC)->u.operand;
2232         JSValue* v = callFrame[src].jsValue(callFrame);
2233         callFrame[dst] = jsBoolean(JSImmediate::isImmediate(v) ? v->isUndefined() : v->asCell()->structure()->typeInfo().masqueradesAsUndefined());
2234
2235         ++vPC;
2236         NEXT_INSTRUCTION();
2237     }
2238     DEFINE_OPCODE(op_is_boolean) {
2239         /* is_boolean dst(r) src(r)
2240
2241            Determines whether the type string for src according to
2242            the ECMAScript rules is "boolean", and puts the result
2243            in register dst.
2244         */
2245         int dst = (++vPC)->u.operand;
2246         int src = (++vPC)->u.operand;
2247         callFrame[dst] = jsBoolean(callFrame[src].jsValue(callFrame)->isBoolean());
2248
2249         ++vPC;
2250         NEXT_INSTRUCTION();
2251     }
2252     DEFINE_OPCODE(op_is_number) {
2253         /* is_number dst(r) src(r)
2254
2255            Determines whether the type string for src according to
2256            the ECMAScript rules is "number", and puts the result
2257            in register dst.
2258         */
2259         int dst = (++vPC)->u.operand;
2260         int src = (++vPC)->u.operand;
2261         callFrame[dst] = jsBoolean(callFrame[src].jsValue(callFrame)->isNumber());
2262
2263         ++vPC;
2264         NEXT_INSTRUCTION();
2265     }
2266     DEFINE_OPCODE(op_is_string) {
2267         /* is_string dst(r) src(r)
2268
2269            Determines whether the type string for src according to
2270            the ECMAScript rules is "string", and puts the result
2271            in register dst.
2272         */
2273         int dst = (++vPC)->u.operand;
2274         int src = (++vPC)->u.operand;
2275         callFrame[dst] = jsBoolean(callFrame[src].jsValue(callFrame)->isString());
2276
2277         ++vPC;
2278         NEXT_INSTRUCTION();
2279     }
2280     DEFINE_OPCODE(op_is_object) {
2281         /* is_object dst(r) src(r)
2282
2283            Determines whether the type string for src according to
2284            the ECMAScript rules is "object", and puts the result
2285            in register dst.
2286         */
2287         int dst = (++vPC)->u.operand;
2288         int src = (++vPC)->u.operand;
2289         callFrame[dst] = jsBoolean(jsIsObjectType(callFrame[src].jsValue(callFrame)));
2290
2291         ++vPC;
2292         NEXT_INSTRUCTION();
2293     }
2294     DEFINE_OPCODE(op_is_function) {
2295         /* is_function dst(r) src(r)
2296
2297            Determines whether the type string for src according to
2298            the ECMAScript rules is "function", and puts the result
2299            in register dst.
2300         */
2301         int dst = (++vPC)->u.operand;
2302         int src = (++vPC)->u.operand;
2303         callFrame[dst] = jsBoolean(jsIsFunctionType(callFrame[src].jsValue(callFrame)));
2304
2305         ++vPC;
2306         NEXT_INSTRUCTION();
2307     }
2308     DEFINE_OPCODE(op_in) {
2309         /* in dst(r) property(r) base(r)
2310
2311            Tests whether register base has a property named register
2312            property, and puts the boolean result in register dst.
2313
2314            Raises an exception if register constructor is not an
2315            object.
2316         */
2317         int dst = (++vPC)->u.operand;
2318         int property = (++vPC)->u.operand;
2319         int base = (++vPC)->u.operand;
2320
2321         JSValue* baseVal = callFrame[base].jsValue(callFrame);
2322         if (isNotObject(callFrame, false, callFrame->codeBlock(), vPC, baseVal, exceptionValue))
2323             goto vm_throw;
2324
2325         JSObject* baseObj = asObject(baseVal);
2326
2327         JSValue* propName = callFrame[property].jsValue(callFrame);
2328
2329         uint32_t i;
2330         if (propName->getUInt32(i))
2331             callFrame[dst] = jsBoolean(baseObj->hasProperty(callFrame, i));
2332         else {
2333             Identifier property(callFrame, propName->toString(callFrame));
2334             CHECK_FOR_EXCEPTION();
2335             callFrame[dst] = jsBoolean(baseObj->hasProperty(callFrame, property));
2336         }
2337
2338         ++vPC;
2339         NEXT_INSTRUCTION();
2340     }
2341     DEFINE_OPCODE(op_resolve) {
2342         /* resolve dst(r) property(id)
2343
2344            Looks up the property named by identifier property in the
2345            scope chain, and writes the resulting value to register
2346            dst. If the property is not found, raises an exception.
2347         */
2348         if (UNLIKELY(!resolve(callFrame, vPC, exceptionValue)))
2349             goto vm_throw;
2350
2351         vPC += 3;
2352         NEXT_INSTRUCTION();
2353     }
2354     DEFINE_OPCODE(op_resolve_skip) {
2355         /* resolve_skip dst(r) property(id) skip(n)
2356
2357          Looks up the property named by identifier property in the
2358          scope chain skipping the top 'skip' levels, and writes the resulting
2359          value to register dst. If the property is not found, raises an exception.
2360          */
2361         if (UNLIKELY(!resolveSkip(callFrame, vPC, exceptionValue)))
2362             goto vm_throw;
2363
2364         vPC += 4;
2365
2366         NEXT_INSTRUCTION();
2367     }
2368     DEFINE_OPCODE(op_resolve_global) {
2369         /* resolve_skip dst(r) globalObject(c) property(id) structure(sID) offset(n)
2370          
2371            Performs a dynamic property lookup for the given property, on the provided
2372            global object.  If structure matches the Structure of the global then perform
2373            a fast lookup using the case offset, otherwise fall back to a full resolve and
2374            cache the new structure and offset
2375          */
2376         if (UNLIKELY(!resolveGlobal(callFrame, vPC, exceptionValue)))
2377             goto vm_throw;
2378         
2379         vPC += 6;
2380         
2381         NEXT_INSTRUCTION();
2382     }
2383     DEFINE_OPCODE(op_get_global_var) {
2384         /* get_global_var dst(r) globalObject(c) index(n)
2385
2386            Gets the global var at global slot index and places it in register dst.
2387          */
2388         int dst = (++vPC)->u.operand;
2389         JSGlobalObject* scope = static_cast<JSGlobalObject*>((++vPC)->u.jsCell);
2390         ASSERT(scope->isGlobalObject());
2391         int index = (++vPC)->u.operand;
2392
2393         callFrame[dst] = scope->registerAt(index);
2394         ++vPC;
2395         NEXT_INSTRUCTION();
2396     }
2397     DEFINE_OPCODE(op_put_global_var) {
2398         /* put_global_var globalObject(c) index(n) value(r)
2399          
2400            Puts value into global slot index.
2401          */
2402         JSGlobalObject* scope = static_cast<JSGlobalObject*>((++vPC)->u.jsCell);
2403         ASSERT(scope->isGlobalObject());
2404         int index = (++vPC)->u.operand;
2405         int value = (++vPC)->u.operand;
2406         
2407         scope->registerAt(index) = callFrame[value].jsValue(callFrame);
2408         ++vPC;
2409         NEXT_INSTRUCTION();
2410     }            
2411     DEFINE_OPCODE(op_get_scoped_var) {
2412         /* get_scoped_var dst(r) index(n) skip(n)
2413
2414          Loads the contents of the index-th local from the scope skip nodes from
2415          the top of the scope chain, and places it in register dst
2416          */
2417         int dst = (++vPC)->u.operand;
2418         int index = (++vPC)->u.operand;
2419         int skip = (++vPC)->u.operand + callFrame->codeBlock()->needsFullScopeChain;
2420
2421         ScopeChainNode* scopeChain = callFrame->scopeChain();
2422         ScopeChainIterator iter = scopeChain->begin();
2423         ScopeChainIterator end = scopeChain->end();
2424         ASSERT(iter != end);
2425         while (skip--) {
2426             ++iter;
2427             ASSERT(iter != end);
2428         }
2429
2430         ASSERT((*iter)->isVariableObject());
2431         JSVariableObject* scope = static_cast<JSVariableObject*>(*iter);
2432         callFrame[dst] = scope->registerAt(index);
2433         ++vPC;
2434         NEXT_INSTRUCTION();
2435     }
2436     DEFINE_OPCODE(op_put_scoped_var) {
2437         /* put_scoped_var index(n) skip(n) value(r)
2438
2439          */
2440         int index = (++vPC)->u.operand;
2441         int skip = (++vPC)->u.operand + callFrame->codeBlock()->needsFullScopeChain;
2442         int value = (++vPC)->u.operand;
2443
2444         ScopeChainNode* scopeChain = callFrame->scopeChain();
2445         ScopeChainIterator iter = scopeChain->begin();
2446         ScopeChainIterator end = scopeChain->end();
2447         ASSERT(iter != end);
2448         while (skip--) {
2449             ++iter;
2450             ASSERT(iter != end);
2451         }
2452
2453         ASSERT((*iter)->isVariableObject());
2454         JSVariableObject* scope = static_cast<JSVariableObject*>(*iter);
2455         scope->registerAt(index) = callFrame[value].jsValue(callFrame);
2456         ++vPC;
2457         NEXT_INSTRUCTION();
2458     }
2459     DEFINE_OPCODE(op_resolve_base) {
2460         /* resolve_base dst(r) property(id)
2461
2462            Searches the scope chain for an object containing
2463            identifier property, and if one is found, writes it to
2464            register dst. If none is found, the outermost scope (which
2465            will be the global object) is stored in register dst.
2466         */
2467         resolveBase(callFrame, vPC);
2468
2469         vPC += 3;
2470         NEXT_INSTRUCTION();
2471     }
2472     DEFINE_OPCODE(op_resolve_with_base) {
2473         /* resolve_with_base baseDst(r) propDst(r) property(id)
2474
2475            Searches the scope chain for an object containing
2476            identifier property, and if one is found, writes it to
2477            register srcDst, and the retrieved property value to register
2478            propDst. If the property is not found, raises an exception.
2479
2480            This is more efficient than doing resolve_base followed by
2481            resolve, or resolve_base followed by get_by_id, as it
2482            avoids duplicate hash lookups.
2483         */
2484         if (UNLIKELY(!resolveBaseAndProperty(callFrame, vPC, exceptionValue)))
2485             goto vm_throw;
2486
2487         vPC += 4;
2488         NEXT_INSTRUCTION();
2489     }
2490     DEFINE_OPCODE(op_resolve_func) {
2491         /* resolve_func baseDst(r) funcDst(r) property(id)
2492
2493            Searches the scope chain for an object containing
2494            identifier property, and if one is found, writes the
2495            appropriate object to use as "this" when calling its
2496            properties to register baseDst; and the retrieved property
2497            value to register propDst. If the property is not found,
2498            raises an exception.
2499
2500            This differs from resolve_with_base, because the
2501            global this value will be substituted for activations or
2502            the global object, which is the right behavior for function
2503            calls but not for other property lookup.
2504         */
2505         if (UNLIKELY(!resolveBaseAndFunc(callFrame, vPC, exceptionValue)))
2506             goto vm_throw;
2507
2508         vPC += 4;
2509         NEXT_INSTRUCTION();
2510     }
2511     DEFINE_OPCODE(op_get_by_id) {
2512         /* get_by_id dst(r) base(r) property(id) structure(sID) nop(n) nop(n) nop(n)
2513
2514            Generic property access: Gets the property named by identifier
2515            property from the value base, and puts the result in register dst.
2516         */
2517         int dst = vPC[1].u.operand;
2518         int base = vPC[2].u.operand;
2519         int property = vPC[3].u.operand;
2520
2521         CodeBlock* codeBlock = callFrame->codeBlock();
2522         Identifier& ident = codeBlock->identifiers[property];
2523         JSValue* baseValue = callFrame[base].jsValue(callFrame);
2524         PropertySlot slot(baseValue);
2525         JSValue* result = baseValue->get(callFrame, ident, slot);
2526         CHECK_FOR_EXCEPTION();
2527
2528         tryCacheGetByID(callFrame, codeBlock, vPC, baseValue, ident, slot);
2529
2530         callFrame[dst] = result;
2531         vPC += 8;
2532         NEXT_INSTRUCTION();
2533     }
2534     DEFINE_OPCODE(op_get_by_id_self) {
2535         /* op_get_by_id_self dst(r) base(r) property(id) structure(sID) offset(n) nop(n) nop(n)
2536
2537            Cached property access: Attempts to get a cached property from the
2538            value base. If the cache misses, op_get_by_id_self reverts to
2539            op_get_by_id.
2540         */
2541         int base = vPC[2].u.operand;
2542         JSValue* baseValue = callFrame[base].jsValue(callFrame);
2543
2544         if (LIKELY(!JSImmediate::isImmediate(baseValue))) {
2545             JSCell* baseCell = asCell(baseValue);
2546             Structure* structure = vPC[4].u.structure;
2547
2548             if (LIKELY(baseCell->structure() == structure)) {
2549                 ASSERT(baseCell->isObject());
2550                 JSObject* baseObject = asObject(baseCell);
2551                 int dst = vPC[1].u.operand;
2552                 int offset = vPC[5].u.operand;
2553
2554                 ASSERT(baseObject->get(callFrame, callFrame->codeBlock()->identifiers[vPC[3].u.operand]) == baseObject->getDirectOffset(offset));
2555                 callFrame[dst] = baseObject->getDirectOffset(offset);
2556
2557                 vPC += 8;
2558                 NEXT_INSTRUCTION();
2559             }
2560         }
2561
2562         uncacheGetByID(callFrame->codeBlock(), vPC);
2563         NEXT_INSTRUCTION();
2564     }
2565     DEFINE_OPCODE(op_get_by_id_proto) {
2566         /* op_get_by_id_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n)
2567
2568            Cached property access: Attempts to get a cached property from the
2569            value base's prototype. If the cache misses, op_get_by_id_proto
2570            reverts to op_get_by_id.
2571         */
2572         int base = vPC[2].u.operand;
2573         JSValue* baseValue = callFrame[base].jsValue(callFrame);
2574
2575         if (LIKELY(!JSImmediate::isImmediate(baseValue))) {
2576             JSCell* baseCell = asCell(baseValue);
2577             Structure* structure = vPC[4].u.structure;
2578
2579             if (LIKELY(baseCell->structure() == structure)) {
2580                 ASSERT(structure->prototypeForLookup(callFrame)->isObject());
2581                 JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
2582                 Structure* prototypeStructure = vPC[5].u.structure;
2583
2584                 if (LIKELY(protoObject->structure() == prototypeStructure)) {
2585                     int dst = vPC[1].u.operand;
2586                     int offset = vPC[6].u.operand;
2587
2588                     ASSERT(protoObject->get(callFrame, callFrame->codeBlock()->identifiers[vPC[3].u.operand]) == protoObject->getDirectOffset(offset));
2589                     callFrame[dst] = protoObject->getDirectOffset(offset);
2590
2591                     vPC += 8;
2592                     NEXT_INSTRUCTION();
2593                 }
2594             }
2595         }
2596
2597         uncacheGetByID(callFrame->codeBlock(), vPC);
2598         NEXT_INSTRUCTION();
2599     }
2600     DEFINE_OPCODE(op_get_by_id_self_list) {
2601         // Polymorphic self access caching currently only supported when JITting.
2602         ASSERT_NOT_REACHED();
2603         // This case of the switch must not be empty, else (op_get_by_id_self_list == op_get_by_id_chain)!
2604         vPC += 8;
2605         NEXT_INSTRUCTION();
2606     }
2607     DEFINE_OPCODE(op_get_by_id_proto_list) {
2608         // Polymorphic prototype access caching currently only supported when JITting.
2609         ASSERT_NOT_REACHED();
2610         // This case of the switch must not be empty, else (op_get_by_id_proto_list == op_get_by_id_chain)!
2611         vPC += 8;
2612         NEXT_INSTRUCTION();
2613     }
2614     DEFINE_OPCODE(op_get_by_id_chain) {
2615         /* op_get_by_id_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n)
2616
2617            Cached property access: Attempts to get a cached property from the
2618            value base's prototype chain. If the cache misses, op_get_by_id_chain
2619            reverts to op_get_by_id.
2620         */
2621         int base = vPC[2].u.operand;
2622         JSValue* baseValue = callFrame[base].jsValue(callFrame);
2623
2624         if (LIKELY(!JSImmediate::isImmediate(baseValue))) {
2625             JSCell* baseCell = asCell(baseValue);
2626             Structure* structure = vPC[4].u.structure;
2627
2628             if (LIKELY(baseCell->structure() == structure)) {
2629                 RefPtr<Structure>* it = vPC[5].u.structureChain->head();
2630                 size_t count = vPC[6].u.operand;
2631                 RefPtr<Structure>* end = it + count;
2632
2633                 JSObject* baseObject = asObject(baseCell);
2634                 while (1) {
2635                     baseObject = asObject(baseObject->structure()->prototypeForLookup(callFrame));
2636                     if (UNLIKELY(baseObject->structure() != (*it).get()))
2637                         break;
2638
2639                     if (++it == end) {
2640                         int dst = vPC[1].u.operand;
2641                         int offset = vPC[7].u.operand;
2642
2643                         ASSERT(baseObject->get(callFrame, callFrame->codeBlock()->identifiers[vPC[3].u.operand]) == baseObject->getDirectOffset(offset));
2644                         callFrame[dst] = baseObject->getDirectOffset(offset);
2645
2646                         vPC += 8;
2647                         NEXT_INSTRUCTION();
2648                     }
2649                 }
2650             }
2651         }
2652
2653         uncacheGetByID(callFrame->codeBlock(), vPC);
2654         NEXT_INSTRUCTION();
2655     }
2656     DEFINE_OPCODE(op_get_by_id_generic) {
2657         /* op_get_by_id_generic dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)
2658
2659            Generic property access: Gets the property named by identifier
2660            property from the value base, and puts the result in register dst.
2661         */
2662         int dst = vPC[1].u.operand;
2663         int base = vPC[2].u.operand;
2664         int property = vPC[3].u.operand;
2665
2666         Identifier& ident = callFrame->codeBlock()->identifiers[property];
2667         JSValue* baseValue = callFrame[base].jsValue(callFrame);
2668         PropertySlot slot(baseValue);
2669         JSValue* result = baseValue->get(callFrame, ident, slot);
2670         CHECK_FOR_EXCEPTION();
2671
2672         callFrame[dst] = result;
2673         vPC += 8;
2674         NEXT_INSTRUCTION();
2675     }
2676     DEFINE_OPCODE(op_get_array_length) {
2677         /* op_get_array_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)
2678
2679            Cached property access: Gets the length of the array in register base,
2680            and puts the result in register dst. If register base does not hold
2681            an array, op_get_array_length reverts to op_get_by_id.
2682         */
2683
2684         int base = vPC[2].u.operand;
2685         JSValue* baseValue = callFrame[base].jsValue(callFrame);
2686         if (LIKELY(isJSArray(baseValue))) {
2687             int dst = vPC[1].u.operand;
2688             callFrame[dst] = jsNumber(callFrame, asArray(baseValue)->length());
2689             vPC += 8;
2690             NEXT_INSTRUCTION();
2691         }
2692
2693         uncacheGetByID(callFrame->codeBlock(), vPC);
2694         NEXT_INSTRUCTION();
2695     }
2696     DEFINE_OPCODE(op_get_string_length) {
2697         /* op_get_string_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)
2698
2699            Cached property access: Gets the length of the string in register base,
2700            and puts the result in register dst. If register base does not hold
2701            a string, op_get_string_length reverts to op_get_by_id.
2702         */
2703
2704         int base = vPC[2].u.operand;
2705         JSValue* baseValue = callFrame[base].jsValue(callFrame);
2706         if (LIKELY(isJSString(baseValue))) {
2707             int dst = vPC[1].u.operand;
2708             callFrame[dst] = jsNumber(callFrame, asString(baseValue)->value().size());
2709             vPC += 8;
2710             NEXT_INSTRUCTION();
2711         }
2712
2713         uncacheGetByID(callFrame->codeBlock(), vPC);
2714         NEXT_INSTRUCTION();
2715     }
2716     DEFINE_OPCODE(op_put_by_id) {
2717         /* put_by_id base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n)
2718
2719            Generic property access: Sets the property named by identifier
2720            property, belonging to register base, to register value.
2721
2722            Unlike many opcodes, this one does not write any output to
2723            the register file.
2724         */
2725
2726         int base = vPC[1].u.operand;
2727         int property = vPC[2].u.operand;
2728         int value = vPC[3].u.operand;
2729
2730         CodeBlock* codeBlock = callFrame->codeBlock();
2731         JSValue* baseValue = callFrame[base].jsValue(callFrame);
2732         Identifier& ident = codeBlock->identifiers[property];
2733         PutPropertySlot slot;
2734         baseValue->put(callFrame, ident, callFrame[value].jsValue(callFrame), slot);
2735         CHECK_FOR_EXCEPTION();
2736
2737         tryCachePutByID(callFrame, codeBlock, vPC, baseValue, slot);
2738
2739         vPC += 8;
2740         NEXT_INSTRUCTION();
2741     }
2742     DEFINE_OPCODE(op_put_by_id_transition) {
2743         /* op_put_by_id_transition base(r) property(id) value(r) oldStructure(sID) newStructure(sID) structureChain(chain) offset(n)
2744          
2745            Cached property access: Attempts to set a new property with a cached transition
2746            property named by identifier property, belonging to register base,
2747            to register value. If the cache misses, op_put_by_id_transition
2748            reverts to op_put_by_id_generic.
2749          
2750            Unlike many opcodes, this one does not write any output to
2751            the register file.
2752          */
2753         int base = vPC[1].u.operand;
2754         JSValue* baseValue = callFrame[base].jsValue(callFrame);
2755         
2756         if (LIKELY(!JSImmediate::isImmediate(baseValue))) {
2757             JSCell* baseCell = asCell(baseValue);
2758             Structure* oldStructure = vPC[4].u.structure;
2759             Structure* newStructure = vPC[5].u.structure;
2760             
2761             if (LIKELY(baseCell->structure() == oldStructure)) {
2762                 ASSERT(baseCell->isObject());
2763                 JSObject* baseObject = asObject(baseCell);
2764
2765                 RefPtr<Structure>* it = vPC[6].u.structureChain->head();
2766
2767                 JSValue* proto = baseObject->structure()->prototypeForLookup(callFrame);
2768                 while (!proto->isNull()) {
2769                     if (UNLIKELY(asObject(proto)->structure() != (*it).get())) {
2770                         uncachePutByID(callFrame->codeBlock(), vPC);
2771                         NEXT_INSTRUCTION();
2772                     }
2773                     ++it;
2774                     proto = asObject(proto)->structure()->prototypeForLookup(callFrame);
2775                 }
2776
2777                 baseObject->transitionTo(newStructure);
2778
2779                 int value = vPC[3].u.operand;
2780                 unsigned offset = vPC[7].u.operand;
2781                 ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(callFrame->codeBlock()->identifiers[vPC[2].u.operand])) == offset);
2782                 baseObject->putDirectOffset(offset, callFrame[value].jsValue(callFrame));
2783
2784                 vPC += 8;
2785                 NEXT_INSTRUCTION();
2786             }
2787         }
2788         
2789         uncachePutByID(callFrame->codeBlock(), vPC);
2790         NEXT_INSTRUCTION();
2791     }
2792     DEFINE_OPCODE(op_put_by_id_replace) {
2793         /* op_put_by_id_replace base(r) property(id) value(r) structure(sID) offset(n) nop(n) nop(n)
2794
2795            Cached property access: Attempts to set a pre-existing, cached
2796            property named by identifier property, belonging to register base,
2797            to register value. If the cache misses, op_put_by_id_replace
2798            reverts to op_put_by_id.
2799
2800            Unlike many opcodes, this one does not write any output to
2801            the register file.
2802         */
2803         int base = vPC[1].u.operand;
2804         JSValue* baseValue = callFrame[base].jsValue(callFrame);
2805
2806         if (LIKELY(!JSImmediate::isImmediate(baseValue))) {
2807             JSCell* baseCell = asCell(baseValue);
2808             Structure* structure = vPC[4].u.structure;
2809
2810             if (LIKELY(baseCell->structure() == structure)) {
2811                 ASSERT(baseCell->isObject());
2812                 JSObject* baseObject = asObject(baseCell);
2813                 int value = vPC[3].u.operand;
2814                 unsigned offset = vPC[5].u.operand;
2815                 
2816                 ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(callFrame->codeBlock()->identifiers[vPC[2].u.operand])) == offset);
2817                 baseObject->putDirectOffset(offset, callFrame[value].jsValue(callFrame));
2818
2819                 vPC += 8;
2820                 NEXT_INSTRUCTION();
2821             }
2822         }
2823
2824         uncachePutByID(callFrame->codeBlock(), vPC);
2825         NEXT_INSTRUCTION();
2826     }
2827     DEFINE_OPCODE(op_put_by_id_generic) {
2828         /* op_put_by_id_generic base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n)
2829
2830            Generic property access: Sets the property named by identifier
2831            property, belonging to register base, to register value.
2832
2833            Unlike many opcodes, this one does not write any output to
2834            the register file.
2835         */
2836         int base = vPC[1].u.operand;
2837         int property = vPC[2].u.operand;
2838         int value = vPC[3].u.operand;
2839
2840         JSValue* baseValue = callFrame[base].jsValue(callFrame);
2841         Identifier& ident = callFrame->codeBlock()->identifiers[property];
2842         PutPropertySlot slot;
2843         baseValue->put(callFrame, ident, callFrame[value].jsValue(callFrame), slot);
2844         CHECK_FOR_EXCEPTION();
2845
2846         vPC += 8;
2847         NEXT_INSTRUCTION();
2848     }
2849     DEFINE_OPCODE(op_del_by_id) {
2850         /* del_by_id dst(r) base(r) property(id)
2851
2852            Converts register base to Object, deletes the property
2853            named by identifier property from the object, and writes a
2854            boolean indicating success (if true) or failure (if false)
2855            to register dst.
2856         */
2857         int dst = (++vPC)->u.operand;
2858         int base = (++vPC)->u.operand;
2859         int property = (++vPC)->u.operand;
2860
2861         JSObject* baseObj = callFrame[base].jsValue(callFrame)->toObject(callFrame);
2862         Identifier& ident = callFrame->codeBlock()->identifiers[property];
2863         JSValue* result = jsBoolean(baseObj->deleteProperty(callFrame, ident));
2864         CHECK_FOR_EXCEPTION();
2865         callFrame[dst] = result;
2866         ++vPC;
2867         NEXT_INSTRUCTION();
2868     }
2869     DEFINE_OPCODE(op_get_by_val) {
2870         /* get_by_val dst(r) base(r) property(r)
2871
2872            Converts register base to Object, gets the property named
2873            by register property from the object, and puts the result
2874            in register dst. property is nominally converted to string
2875            but numbers are treated more efficiently.
2876         */
2877         int dst = (++vPC)->u.operand;
2878         int base = (++vPC)->u.operand;
2879         int property = (++vPC)->u.operand;
2880         
2881         JSValue* baseValue = callFrame[base].jsValue(callFrame);
2882         JSValue* subscript = callFrame[property].jsValue(callFrame);
2883
2884         JSValue* result;
2885         unsigned i;
2886
2887         bool isUInt32 = JSImmediate::getUInt32(subscript, i);
2888         if (LIKELY(isUInt32)) {
2889             if (isJSArray(baseValue)) {
2890                 JSArray* jsArray = asArray(baseValue);
2891                 if (jsArray->canGetIndex(i))
2892                     result = jsArray->getIndex(i);
2893                 else
2894                     result = jsArray->JSArray::get(callFrame, i);
2895             } else if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
2896                 result = asString(baseValue)->getIndex(&callFrame->globalData(), i);
2897             else
2898                 result = baseValue->get(callFrame, i);
2899         } else {
2900             Identifier property(callFrame, subscript->toString(callFrame));
2901             result = baseValue->get(callFrame, property);
2902         }
2903
2904         CHECK_FOR_EXCEPTION();
2905         callFrame[dst] = result;
2906         ++vPC;
2907         NEXT_INSTRUCTION();
2908     }
2909     DEFINE_OPCODE(op_put_by_val) {
2910         /* put_by_val base(r) property(r) value(r)
2911
2912            Sets register value on register base as the property named
2913            by register property. Base is converted to object
2914            first. register property is nominally converted to string
2915            but numbers are treated more efficiently.
2916
2917            Unlike many opcodes, this one does not write any output to
2918            the register file.
2919         */
2920         int base = (++vPC)->u.operand;
2921         int property = (++vPC)->u.operand;
2922         int value = (++vPC)->u.operand;
2923
2924         JSValue* baseValue = callFrame[base].jsValue(callFrame);
2925         JSValue* subscript = callFrame[property].jsValue(callFrame);
2926
2927         unsigned i;
2928
2929         bool isUInt32 = JSImmediate::getUInt32(subscript, i);
2930         if (LIKELY(isUInt32)) {
2931             if (isJSArray(baseValue)) {
2932                 JSArray* jsArray = asArray(baseValue);
2933                 if (jsArray->canSetIndex(i))
2934                     jsArray->setIndex(i, callFrame[value].jsValue(callFrame));
2935                 else
2936                     jsArray->JSArray::put(callFrame, i, callFrame[value].jsValue(callFrame));
2937             } else
2938                 baseValue->put(callFrame, i, callFrame[value].jsValue(callFrame));
2939         } else {
2940             Identifier property(callFrame, subscript->toString(callFrame));
2941             if (!globalData->exception) { // Don't put to an object if toString threw an exception.
2942                 PutPropertySlot slot;
2943                 baseValue->put(callFrame, property, callFrame[value].jsValue(callFrame), slot);
2944             }
2945         }
2946
2947         CHECK_FOR_EXCEPTION();
2948         ++vPC;
2949         NEXT_INSTRUCTION();
2950     }
2951     DEFINE_OPCODE(op_del_by_val) {
2952         /* del_by_val dst(r) base(r) property(r)
2953
2954            Converts register base to Object, deletes the property
2955            named by register property from the object, and writes a
2956            boolean indicating success (if true) or failure (if false)
2957            to register dst.
2958         */
2959         int dst = (++vPC)->u.operand;
2960         int base = (++vPC)->u.operand;
2961         int property = (++vPC)->u.operand;
2962
2963         JSObject* baseObj = callFrame[base].jsValue(callFrame)->toObject(callFrame); // may throw
2964
2965         JSValue* subscript = callFrame[property].jsValue(callFrame);
2966         JSValue* result;
2967         uint32_t i;
2968         if (subscript->getUInt32(i))
2969             result = jsBoolean(baseObj->deleteProperty(callFrame, i));
2970         else {
2971             CHECK_FOR_EXCEPTION();
2972             Identifier property(callFrame, subscript->toString(callFrame));
2973             CHECK_FOR_EXCEPTION();
2974             result = jsBoolean(baseObj->deleteProperty(callFrame, property));
2975         }
2976
2977         CHECK_FOR_EXCEPTION();
2978         callFrame[dst] = result;
2979         ++vPC;
2980         NEXT_INSTRUCTION();
2981     }
2982     DEFINE_OPCODE(op_put_by_index) {
2983         /* put_by_index base(r) property(n) value(r)
2984
2985            Sets register value on register base as the property named
2986            by the immediate number property. Base is converted to
2987            object first.
2988
2989            Unlike many opcodes, this one does not write any output to
2990            the register file.
2991
2992            This opcode is mainly used to initialize array literals.
2993         */
2994         int base = (++vPC)->u.operand;
2995         unsigned property = (++vPC)->u.operand;
2996         int value = (++vPC)->u.operand;
2997
2998         callFrame[base].jsValue(callFrame)->put(callFrame, property, callFrame[value].jsValue(callFrame));
2999
3000         ++vPC;
3001         NEXT_INSTRUCTION();
3002     }
3003     DEFINE_OPCODE(op_loop) {
3004         /* loop target(offset)
3005          
3006            Jumps unconditionally to offset target from the current
3007            instruction.
3008
3009            Additionally this loop instruction may terminate JS execution is
3010            the JS timeout is reached.
3011          */
3012 #if ENABLE(OPCODE_STATS)
3013         OpcodeStats::resetLastInstruction();
3014 #endif
3015         int target = (++vPC)->u.operand;
3016         CHECK_FOR_TIMEOUT();
3017         vPC += target;
3018         NEXT_INSTRUCTION();
3019     }
3020     DEFINE_OPCODE(op_jmp) {
3021         /* jmp target(offset)
3022
3023            Jumps unconditionally to offset target from the current
3024            instruction.
3025         */
3026 #if ENABLE(OPCODE_STATS)
3027         OpcodeStats::resetLastInstruction();
3028 #endif
3029         int target = (++vPC)->u.operand;
3030
3031         vPC += target;
3032         NEXT_INSTRUCTION();
3033     }
3034     DEFINE_OPCODE(op_loop_if_true) {
3035         /* loop_if_true cond(r) target(offset)
3036          
3037            Jumps to offset target from the current instruction, if and
3038            only if register cond converts to boolean as true.
3039
3040            Additionally this loop instruction may terminate JS execution is
3041            the JS timeout is reached.
3042          */
3043         int cond = (++vPC)->u.operand;
3044         int target = (++vPC)->u.operand;
3045         if (callFrame[cond].jsValue(callFrame)->toBoolean(callFrame)) {
3046             vPC += target;
3047             CHECK_FOR_TIMEOUT();
3048             NEXT_INSTRUCTION();
3049         }
3050         
3051         ++vPC;
3052         NEXT_INSTRUCTION();
3053     }
3054     DEFINE_OPCODE(op_jtrue) {
3055         /* jtrue cond(r) target(offset)
3056
3057            Jumps to offset target from the current instruction, if and
3058            only if register cond converts to boolean as true.
3059         */
3060         int cond = (++vPC)->u.operand;
3061         int target = (++vPC)->u.operand;
3062         if (callFrame[cond].jsValue(callFrame)->toBoolean(callFrame)) {
3063             vPC += target;
3064             NEXT_INSTRUCTION();
3065         }
3066
3067         ++vPC;
3068         NEXT_INSTRUCTION();
3069     }
3070     DEFINE_OPCODE(op_jfalse) {
3071         /* jfalse cond(r) target(offset)
3072
3073            Jumps to offset target from the current instruction, if and
3074            only if register cond converts to boolean as false.
3075         */
3076         int cond = (++vPC)->u.operand;
3077         int target = (++vPC)->u.operand;
3078         if (!callFrame[cond].jsValue(callFrame)->toBoolean(callFrame)) {
3079             vPC += target;
3080             NEXT_INSTRUCTION();
3081         }
3082
3083         ++vPC;
3084         NEXT_INSTRUCTION();
3085     }
3086     DEFINE_OPCODE(op_jeq_null) {
3087         /* jeq_null src(r) target(offset)
3088
3089            Jumps to offset target from the current instruction, if and
3090            only if register src is null.
3091         */
3092         int src = (++vPC)->u.operand;
3093         int target = (++vPC)->u.operand;
3094         JSValue* srcValue = callFrame[src].jsValue(callFrame);
3095
3096         if (srcValue->isUndefinedOrNull() || (!JSImmediate::isImmediate(srcValue) && srcValue->asCell()->structure()->typeInfo().masqueradesAsUndefined())) {
3097             vPC += target;
3098             NEXT_INSTRUCTION();
3099         }
3100
3101         ++vPC;
3102         NEXT_INSTRUCTION();
3103     }
3104     DEFINE_OPCODE(op_jneq_null) {
3105         /* jneq_null src(r) target(offset)
3106
3107            Jumps to offset target from the current instruction, if and
3108            only if register src is not null.
3109         */
3110         int src = (++vPC)->u.operand;
3111         int target = (++vPC)->u.operand;
3112         JSValue* srcValue = callFrame[src].jsValue(callFrame);
3113
3114         if (!srcValue->isUndefinedOrNull() || (!JSImmediate::isImmediate(srcValue) && !srcValue->asCell()->structure()->typeInfo().masqueradesAsUndefined())) {
3115             vPC += target;
3116             NEXT_INSTRUCTION();
3117         }
3118
3119         ++vPC;
3120         NEXT_INSTRUCTION();
3121     }
3122     DEFINE_OPCODE(op_loop_if_less) {
3123         /* loop_if_less src1(r) src2(r) target(offset)
3124
3125            Checks whether register src1 is less than register src2, as
3126            with the ECMAScript '<' operator, and then jumps to offset
3127            target from the current instruction, if and only if the 
3128            result of the comparison is true.
3129
3130            Additionally this loop instruction may terminate JS execution is
3131            the JS timeout is reached.
3132          */
3133         JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
3134         JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
3135         int target = (++vPC)->u.operand;
3136         
3137         bool result = jsLess(callFrame, src1, src2);
3138         CHECK_FOR_EXCEPTION();
3139         
3140         if (result) {
3141             vPC += target;
3142             CHECK_FOR_TIMEOUT();
3143             NEXT_INSTRUCTION();
3144         }
3145         
3146         ++vPC;
3147         NEXT_INSTRUCTION();
3148     }
3149     DEFINE_OPCODE(op_loop_if_lesseq) {
3150         /* loop_if_lesseq src1(r) src2(r) target(offset)
3151
3152            Checks whether register src1 is less than or equal to register
3153            src2, as with the ECMAScript '<=' operator, and then jumps to
3154            offset target from the current instruction, if and only if the 
3155            result of the comparison is true.
3156
3157            Additionally this loop instruction may terminate JS execution is
3158            the JS timeout is reached.
3159         */
3160         JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
3161         JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
3162         int target = (++vPC)->u.operand;
3163         
3164         bool result = jsLessEq(callFrame, src1, src2);
3165         CHECK_FOR_EXCEPTION();
3166         
3167         if (result) {
3168             vPC += target;
3169             CHECK_FOR_TIMEOUT();
3170             NEXT_INSTRUCTION();
3171         }
3172         
3173         ++vPC;
3174         NEXT_INSTRUCTION();
3175     }
3176     DEFINE_OPCODE(op_jnless) {
3177         /* jnless src1(r) src2(r) target(offset)
3178
3179            Checks whether register src1 is less than register src2, as
3180            with the ECMAScript '<' operator, and then jumps to offset
3181            target from the current instruction, if and only if the 
3182            result of the comparison is false.
3183         */
3184         JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
3185         JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
3186         int target = (++vPC)->u.operand;
3187
3188         bool result = jsLess(callFrame, src1, src2);
3189         CHECK_FOR_EXCEPTION();
3190         
3191         if (!result) {
3192             vPC += target;
3193             NEXT_INSTRUCTION();
3194         }
3195
3196         ++vPC;
3197         NEXT_INSTRUCTION();
3198     }
3199     DEFINE_OPCODE(op_switch_imm) {
3200         /* switch_imm tableIndex(n) defaultOffset(offset) scrutinee(r)
3201
3202            Performs a range checked switch on the scrutinee value, using
3203            the tableIndex-th immediate switch jump table.  If the scrutinee value
3204            is an immediate number in the range covered by the referenced jump
3205            table, and the value at jumpTable[scrutinee value] is non-zero, then
3206            that value is used as the jump offset, otherwise defaultOffset is used.
3207          */
3208         int tableIndex = (++vPC)->u.operand;
3209         int defaultOffset = (++vPC)->u.operand;
3210         JSValue* scrutinee = callFrame[(++vPC)->u.operand].jsValue(callFrame);
3211         if (!JSImmediate::isNumber(scrutinee))
3212             vPC += defaultOffset;
3213         else {
3214             int32_t value = JSImmediate::getTruncatedInt32(scrutinee);
3215             vPC += callFrame->codeBlock()->immediateSwitchJumpTables[tableIndex].offsetForValue(value, defaultOffset);
3216         }
3217         NEXT_INSTRUCTION();
3218     }
3219     DEFINE_OPCODE(op_switch_char) {
3220         /* switch_char tableIndex(n) defaultOffset(offset) scrutinee(r)
3221
3222            Performs a range checked switch on the scrutinee value, using
3223            the tableIndex-th character switch jump table.  If the scrutinee value
3224            is a single character string in the range covered by the referenced jump
3225            table, and the value at jumpTable[scrutinee value] is non-zero, then
3226            that value is used as the jump offset, otherwise defaultOffset is used.
3227          */
3228         int tableIndex = (++vPC)->u.operand;
3229         int defaultOffset = (++vPC)->u.operand;
3230         JSValue* scrutinee = callFrame[(++vPC)->u.operand].jsValue(callFrame);
3231         if (!scrutinee->isString())
3232             vPC += defaultOffset;
3233         else {
3234             UString::Rep* value = asString(scrutinee)->value().rep();
3235             if (value->size() != 1)
3236                 vPC += defaultOffset;
3237             else
3238                 vPC += callFrame->codeBlock()->characterSwitchJumpTables[tableIndex].offsetForValue(value->data()[0], defaultOffset);
3239         }
3240         NEXT_INSTRUCTION();
3241     }
3242     DEFINE_OPCODE(op_switch_string) {
3243         /* switch_string tableIndex(n) defaultOffset(offset) scrutinee(r)
3244
3245            Performs a sparse hashmap based switch on the value in the scrutinee
3246            register, using the tableIndex-th string switch jump table.  If the 
3247            scrutinee value is a string that exists as a key in the referenced 
3248            jump table, then the value associated with the string is used as the 
3249            jump offset, otherwise defaultOffset is used.
3250          */
3251         int tableIndex = (++vPC)->u.operand;
3252         int defaultOffset = (++vPC)->u.operand;
3253         JSValue* scrutinee = callFrame[(++vPC)->u.operand].jsValue(callFrame);
3254         if (!scrutinee->isString())
3255             vPC += defaultOffset;
3256         else 
3257             vPC += callFrame->codeBlock()->stringSwitchJumpTables[tableIndex].offsetForValue(asString(scrutinee)->value().rep(), defaultOffset);
3258         NEXT_INSTRUCTION();
3259     }
3260     DEFINE_OPCODE(op_new_func) {
3261         /* new_func dst(r) func(f)
3262
3263            Constructs a new Function instance from function func and
3264            the current scope chain using the original Function
3265            constructor, using the rules for function declarations, and
3266            puts the result in register dst.
3267         */
3268         int dst = (++vPC)->u.operand;
3269         int func = (++vPC)->u.operand;
3270
3271         callFrame[dst] = callFrame->codeBlock()->functions[func]->makeFunction(callFrame, callFrame->scopeChain());
3272
3273         ++vPC;
3274         NEXT_INSTRUCTION();
3275     }
3276     DEFINE_OPCODE(op_new_func_exp) {
3277         /* new_func_exp dst(r) func(f)
3278
3279            Constructs a new Function instance from function func and
3280            the current scope chain using the original Function
3281            constructor, using the rules for function expressions, and
3282            puts the result in register dst.
3283         */
3284         int dst = (++vPC)->u.operand;
3285         int func = (++vPC)->u.operand;
3286
3287         callFrame[dst] = callFrame->codeBlock()->functionExpressions[func]->makeFunction(callFrame, callFrame->scopeChain());
3288
3289         ++vPC;
3290         NEXT_INSTRUCTION();
3291     }
3292     DEFINE_OPCODE(op_call_eval) {
3293         /* call_eval dst(r) func(r) argCount(n) registerOffset(n)
3294
3295            Call a function named "eval" with no explicit "this" value
3296            (which may therefore be the eval operator). If register
3297            thisVal is the global object, and register func contains
3298            that global object's original global eval function, then
3299            perform the eval operator in local scope (interpreting
3300            the argument registers as for the "call"
3301            opcode). Otherwise, act exactly as the "call" opcode would.
3302          */
3303
3304         int dst = vPC[1].u.operand;
3305         int func = vPC[2].u.operand;
3306         int argCount = vPC[3].u.operand;
3307         int registerOffset = vPC[4].u.operand;
3308
3309         JSValue* funcVal = callFrame[func].jsValue(callFrame);
3310
3311         Register* newCallFrame = callFrame->registers() + registerOffset;
3312         Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount;
3313         JSValue* thisValue = argv[0].jsValue(callFrame);
3314         JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject();
3315
3316         if (thisValue == globalObject && funcVal == globalObject->evalFunction()) {
3317             JSValue* result = callEval(callFrame, registerFile, argv, argCount, registerOffset, exceptionValue);
3318             if (exceptionValue)
3319                 goto vm_throw;
3320             callFrame[dst] = result;
3321
3322             vPC += 5;
3323             NEXT_INSTRUCTION();
3324         }
3325
3326         // We didn't find the blessed version of eval, so process this
3327         // instruction as a normal function call.
3328         // fall through to op_call
3329     }
3330     DEFINE_OPCODE(op_call) {
3331         /* call dst(r) func(r) argCount(n) registerOffset(n)
3332
3333            Perform a function call.
3334            
3335            registerOffset is the distance the callFrame pointer should move
3336            before the VM initializes the new call frame's header.
3337            
3338            dst is where op_ret should store its result.
3339          */
3340
3341         int dst = vPC[1].u.operand;
3342         int func = vPC[2].u.operand;
3343         int argCount = vPC[3].u.operand;
3344         int registerOffset = vPC[4].u.operand;
3345
3346         JSValue* v = callFrame[func].jsValue(callFrame);
3347
3348         CallData callData;
3349         CallType callType = v->getCallData(callData);
3350
3351         if (callType == CallTypeJS) {
3352             ScopeChainNode* callDataScopeChain = callData.js.scopeChain;
3353             FunctionBodyNode* functionBodyNode = callData.js.functionBody;
3354             CodeBlock* newCodeBlock = &functionBodyNode->bytecode(callDataScopeChain);
3355
3356             CallFrame* previousCallFrame = callFrame;
3357
3358             callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount);
3359             if (UNLIKELY(!callFrame)) {
3360                 callFrame = previousCallFrame;
3361                 exceptionValue = createStackOverflowError(callFrame);
3362                 goto vm_throw;
3363             }
3364
3365             callFrame->init(newCodeBlock, vPC + 5, callDataScopeChain, previousCallFrame, dst, argCount, asFunction(v));
3366             vPC = newCodeBlock->instructions.begin();
3367
3368 #if ENABLE(OPCODE_STATS)
3369             OpcodeStats::resetLastInstruction();
3370 #endif
3371
3372             NEXT_INSTRUCTION();
3373         }
3374
3375         if (callType == CallTypeHost) {
3376             ScopeChainNode* scopeChain = callFrame->scopeChain();
3377             CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
3378             newCallFrame->init(0, vPC + 5, scopeChain, callFrame, dst, argCount, 0);
3379
3380             Register* thisRegister = newCallFrame->registers() - RegisterFile::CallFrameHeaderSize - argCount;
3381             ArgList args(thisRegister + 1, argCount - 1);
3382
3383             // FIXME: All host methods should be calling toThisObject, but this is not presently the case.
3384             JSValue* thisValue = thisRegister->jsValue(callFrame);
3385             if (thisValue == jsNull())
3386                 thisValue = callFrame->globalThisValue();
3387
3388             JSValue* returnValue;
3389             {
3390                 SamplingTool::HostCallRecord callRecord(m_sampler);
3391                 returnValue = callData.native.function(newCallFrame, asObject(v), thisValue, args);
3392             }
3393             CHECK_FOR_EXCEPTION();
3394
3395             callFrame[dst] = returnValue;
3396
3397             vPC += 5;
3398             NEXT_INSTRUCTION();
3399         }
3400
3401         ASSERT(callType == CallTypeNone);
3402
3403         exceptionValue = createNotAFunctionError(callFrame, v, vPC, callFrame->codeBlock());
3404         goto vm_throw;
3405     }
3406     DEFINE_OPCODE(op_tear_off_activation) {
3407         /* tear_off_activation activation(r)
3408
3409            Copy all locals and parameters to new memory allocated on
3410            the heap, and make the passed activation use this memory
3411            in the future when looking up entries in the symbol table.
3412            If there is an 'arguments' object, then it will also use
3413            this memory for storing the named parameters, but not any
3414            extra arguments.
3415
3416            This opcode should only be used immediately before op_ret.
3417         */
3418
3419         int src = (++vPC)->u.operand;
3420         ASSERT(callFrame->codeBlock()->needsFullScopeChain);
3421
3422         asActivation(callFrame[src].getJSValue())->copyRegisters(callFrame->optionalCalleeArguments());
3423
3424         ++vPC;
3425         NEXT_INSTRUCTION();
3426     }
3427     DEFINE_OPCODE(op_tear_off_arguments) {
3428         /* tear_off_arguments
3429
3430            Copy all arguments to new memory allocated on the heap,
3431            and make the 'arguments' object use this memory in the
3432            future when looking up named parameters, but not any
3433            extra arguments. If an activation object exists for the
3434            current function context, then the tear_off_activation
3435            opcode should be used instead.
3436
3437            This opcode should only be used immediately before op_ret.
3438         */
3439
3440         ASSERT(callFrame->codeBlock()->usesArguments && !callFrame->codeBlock()->needsFullScopeChain);
3441
3442         callFrame->optionalCalleeArguments()->copyRegisters();
3443
3444         ++vPC;
3445         NEXT_INSTRUCTION();
3446     }
3447     DEFINE_OPCODE(op_ret) {
3448         /* ret result(r)
3449            
3450            Return register result as the return value of the current
3451            function call, writing it into the caller's expected return
3452            value register. In addition, unwind one call frame and
3453            restore the scope chain, code block instruction pointer and
3454            register base to those of the calling function.
3455         */
3456
3457         int result = (++vPC)->u.operand;
3458
3459         if (callFrame->codeBlock()->needsFullScopeChain)
3460             callFrame->scopeChain()->deref();
3461
3462         JSValue* returnValue = callFrame[result].jsValue(callFrame);
3463
3464         vPC = callFrame->returnPC();
3465         int dst = callFrame->returnValueRegister();
3466         callFrame = callFrame->callerFrame();
3467         
3468         if (callFrame->hasHostCallFrameFlag())
3469             return returnValue;
3470
3471         callFrame[dst] = returnValue;
3472
3473         NEXT_INSTRUCTION();
3474     }
3475     DEFINE_OPCODE(op_enter) {
3476         /* enter
3477
3478            Initializes local variables to undefined and fills constant
3479            registers with their values. If the code block requires an
3480            activation, enter_with_activation should be used instead.
3481
3482            This opcode should only be used at the beginning of a code
3483            block.
3484         */
3485
3486         size_t i = 0;
3487         CodeBlock* codeBlock = callFrame->codeBlock();
3488         
3489         for (size_t count = codeBlock->numVars; i < count; ++i)
3490             callFrame[i] = jsUndefined();
3491
3492         for (size_t count = codeBlock->constantRegisters.size(), j = 0; j < count; ++i, ++j)
3493             callFrame[i] = codeBlock->constantRegisters[j];
3494
3495         ++vPC;
3496         NEXT_INSTRUCTION();
3497     }
3498     DEFINE_OPCODE(op_enter_with_activation) {
3499         /* enter_with_activation dst(r)
3500
3501            Initializes local variables to undefined, fills constant
3502            registers with their values, creates an activation object,
3503            and places the new activation both in dst and at the top
3504            of the scope chain. If the code block does not require an
3505            activation, enter should be used instead.
3506
3507            This opcode should only be used at the beginning of a code
3508            block.
3509         */
3510
3511         size_t i = 0;
3512         CodeBlock* codeBlock = callFrame->codeBlock();
3513
3514         for (size_t count = codeBlock->numVars; i < count; ++i)
3515             callFrame[i] = jsUndefined();
3516
3517         for (size_t count = codeBlock->constantRegisters.size(), j = 0; j < count; ++i, ++j)
3518             callFrame[i] = codeBlock->constantRegisters[j];
3519
3520         int dst = (++vPC)->u.operand;
3521         JSActivation* activation = new (globalData) JSActivation(callFrame, static_cast<FunctionBodyNode*>(codeBlock->ownerNode));
3522         callFrame[dst] = activation;
3523         callFrame->setScopeChain(callFrame->scopeChain()->copy()->push(activation));
3524
3525         ++vPC;
3526         NEXT_INSTRUCTION();
3527     }
3528     DEFINE_OPCODE(op_convert_this) {
3529         /* convert_this this(r)
3530
3531            Takes the value in the 'this' register, converts it to a
3532            value that is suitable for use as the 'this' value, and
3533            stores it in the 'this' register. This opcode is emitted
3534            to avoid doing the conversion in the caller unnecessarily.
3535
3536            This opcode should only be used at the beginning of a code
3537            block.
3538         */
3539
3540         int thisRegister = (++vPC)->u.operand;
3541         JSValue* thisVal = callFrame[thisRegister].getJSValue();
3542         if (thisVal->needsThisConversion())
3543             callFrame[thisRegister] = thisVal->toThisObject(callFrame);
3544
3545         ++vPC;
3546         NEXT_INSTRUCTION();
3547     }
3548     DEFINE_OPCODE(op_create_arguments) {
3549         /* create_arguments
3550
3551            Creates the 'arguments' object and places it in both the
3552            'arguments' call frame slot and the local 'arguments'
3553            register.
3554
3555            This opcode should only be used at the beginning of a code
3556            block.
3557         */
3558
3559         Arguments* arguments = new (globalData) Arguments(callFrame);
3560         callFrame->setCalleeArguments(arguments);
3561         callFrame[RegisterFile::ArgumentsRegister] = arguments;
3562         
3563         ++vPC;
3564         NEXT_INSTRUCTION();
3565     }
3566     DEFINE_OPCODE(op_construct) {
3567         /* construct dst(r) func(r) argCount(n) registerOffset(n) proto(r) thisRegister(r)
3568
3569            Invoke register "func" as a constructor. For JS
3570            functions, the calling convention is exactly as for the
3571            "call" opcode, except that the "this" value is a newly
3572            created Object. For native constructors, no "this"
3573            value is passed. In either case, the argCount and registerOffset
3574            registers are interpreted as for the "call" opcode.
3575
3576            Register proto must contain the prototype property of
3577            register func. This is to enable polymorphic inline
3578            caching of this lookup.
3579         */
3580
3581         int dst = vPC[1].u.operand;
3582         int func = vPC[2].u.operand;
3583         int argCount = vPC[3].u.operand;
3584         int registerOffset = vPC[4].u.operand;
3585         int proto = vPC[5].u.operand;
3586         int thisRegister = vPC[6].u.operand;
3587
3588         JSValue* v = callFrame[func].jsValue(callFrame);
3589
3590         ConstructData constructData;
3591         ConstructType constructType = v->getConstructData(constructData);
3592
3593         if (constructType == ConstructTypeJS) {
3594             ScopeChainNode* callDataScopeChain = constructData.js.scopeChain;
3595             FunctionBodyNode* functionBodyNode = constructData.js.functionBody;
3596             CodeBlock* newCodeBlock = &functionBodyNode->bytecode(callDataScopeChain);
3597
3598             Structure* structure;
3599             JSValue* prototype = callFrame[proto].jsValue(callFrame);
3600             if (prototype->isObject())
3601                 structure = asObject(prototype)->inheritorID();
3602             else
3603                 structure = callDataScopeChain->globalObject()->emptyObjectStructure();
3604             JSObject* newObject = new (globalData) JSObject(structure);
3605
3606             callFrame[thisRegister] = newObject; // "this" value
3607
3608             CallFrame* previousCallFrame = callFrame;
3609
3610             callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount);
3611             if (UNLIKELY(!callFrame)) {
3612                 callFrame = previousCallFrame;
3613                 exceptionValue = createStackOverflowError(callFrame);
3614                 goto vm_throw;
3615             }
3616
3617             callFrame->init(newCodeBlock, vPC + 7, callDataScopeChain, previousCallFrame, dst, argCount, asFunction(v));
3618             vPC = newCodeBlock->instructions.begin();
3619
3620 #if ENABLE(OPCODE_STATS)
3621             OpcodeStats::resetLastInstruction();
3622 #endif
3623
3624             NEXT_INSTRUCTION();
3625         }
3626
3627         if (constructType == ConstructTypeHost) {
3628             ArgList args(callFrame->registers() + thisRegister + 1, argCount - 1);
3629
3630             ScopeChainNode* scopeChain = callFrame->scopeChain();
3631             CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
3632             newCallFrame->init(0, vPC + 7, scopeChain, callFrame, dst, argCount, 0);
3633
3634             JSValue* returnValue;
3635             {
3636                 SamplingTool::HostCallRecord callRecord(m_sampler);
3637                 returnValue = constructData.native.function(newCallFrame, asObject(v), args);
3638             }
3639             CHECK_FOR_EXCEPTION();
3640             callFrame[dst] = returnValue;
3641
3642             vPC += 7;
3643             NEXT_INSTRUCTION();
3644         }
3645
3646         ASSERT(constructType == ConstructTypeNone);
3647
3648         exceptionValue = createNotAConstructorError(callFrame, v, vPC, callFrame->codeBlock());
3649         goto vm_throw;
3650     }
3651     DEFINE_OPCODE(op_construct_verify) {
3652         /* construct_verify dst(r) override(r)
3653
3654            Verifies that register dst holds an object. If not, moves
3655            the object in register override to register dst.
3656         */
3657
3658         int dst = vPC[1].u.operand;;
3659         if (LIKELY(callFrame[dst].jsValue(callFrame)->isObject())) {
3660             vPC += 3;
3661             NEXT_INSTRUCTION();
3662         }
3663
3664         int override = vPC[2].u.operand;
3665         callFrame[dst] = callFrame[override];
3666
3667         vPC += 3;
3668         NEXT_INSTRUCTION();
3669     }
3670     DEFINE_OPCODE(op_push_scope) {
3671         /* push_scope scope(r)
3672
3673            Converts register scope to object, and pushes it onto the top
3674            of the current scope chain.
3675         */
3676         int scope = (++vPC)->u.operand;
3677         JSValue* v = callFrame[scope].jsValue(callFrame);
3678         JSObject* o = v->toObject(callFrame);
3679         CHECK_FOR_EXCEPTION();
3680
3681         callFrame->setScopeChain(callFrame->scopeChain()->push(o));
3682
3683         ++vPC;
3684         NEXT_INSTRUCTION();
3685     }
3686     DEFINE_OPCODE(op_pop_scope) {
3687         /* pop_scope
3688
3689            Removes the top item from the current scope chain.
3690         */
3691         callFrame->setScopeChain(callFrame->scopeChain()->pop());
3692
3693         ++vPC;
3694         NEXT_INSTRUCTION();
3695     }
3696     DEFINE_OPCODE(op_get_pnames) {
3697         /* get_pnames dst(r) base(r)
3698
3699            Creates a property name list for register base and puts it
3700            in register dst. This is not a true JavaScript value, just
3701            a synthetic value used to keep the iteration state in a
3702            register.
3703         */
3704         int dst = (++vPC)->u.operand;
3705         int base = (++vPC)->u.operand;
3706
3707         callFrame[dst] = JSPropertyNameIterator::create(callFrame, callFrame[base].jsValue(callFrame));
3708         ++vPC;
3709         NEXT_INSTRUCTION();
3710     }
3711     DEFINE_OPCODE(op_next_pname) {
3712         /* next_pname dst(r) iter(r) target(offset)
3713
3714            Tries to copies the next name from property name list in
3715            register iter. If there are names left, then copies one to
3716            register dst, and jumps to offset target. If there are none
3717            left, invalidates the iterator and continues to the next
3718            instruction.
3719         */
3720         int dst = (++vPC)->u.operand;
3721         int iter = (++vPC)->u.operand;
3722         int target = (++vPC)->u.operand;
3723
3724         JSPropertyNameIterator* it = callFrame[iter].propertyNameIterator();
3725         if (JSValue* temp = it->next(callFrame)) {
3726             CHECK_FOR_TIMEOUT();
3727             callFrame[dst] = temp;
3728             vPC += target;
3729             NEXT_INSTRUCTION();
3730         }
3731         it->invalidate();
3732
3733         ++vPC;
3734         NEXT_INSTRUCTION();
3735     }
3736     DEFINE_OPCODE(op_jmp_scopes) {
3737         /* jmp_scopes count(n) target(offset)
3738
3739            Removes the a number of items from the current scope chain
3740            specified by immediate number count, then jumps to offset
3741            target.
3742         */
3743         int count = (++vPC)->u.operand;
3744         int target = (++vPC)->u.operand;
3745
3746         ScopeChainNode* tmp = callFrame->scopeChain();
3747         while (count--)
3748             tmp = tmp->pop();
3749         callFrame->setScopeChain(tmp);
3750
3751         vPC += target;
3752         NEXT_INSTRUCTION();
3753     }
3754 #if HAVE(COMPUTED_GOTO)
3755     // Appease GCC
3756     goto *(&&skip_new_scope);
3757 #endif
3758     DEFINE_OPCODE(op_push_new_scope) {
3759         /* new_scope dst(r) property(id) value(r)
3760          
3761            Constructs a new StaticScopeObject with property set to value.  That scope
3762            object is then pushed onto the ScopeChain.  The scope object is then stored
3763            in dst for GC.
3764          */
3765         callFrame->setScopeChain(createExceptionScope(callFrame, vPC));
3766
3767         vPC += 4;
3768         NEXT_INSTRUCTION();
3769     }
3770 #if HAVE(COMPUTED_GOTO)
3771     skip_new_scope:
3772 #endif
3773     DEFINE_OPCODE(op_catch) {
3774         /* catch ex(r)
3775
3776            Retrieves the VMs current exception and puts it in register
3777            ex. This is only valid after an exception has been raised,
3778            and usually forms the beginning of an exception handler.
3779         */
3780         ASSERT(exceptionValue);
3781         ASSERT(!globalData->exception);
3782         int ex = (++vPC)->u.operand;
3783         callFrame[ex] = exceptionValue;
3784         exceptionValue = noValue();
3785
3786         ++vPC;
3787         NEXT_INSTRUCTION();
3788     }
3789     DEFINE_OPCODE(op_throw) {
3790         /* throw ex(r)
3791
3792            Throws register ex as an exception. This involves three
3793            steps: first, it is set as the current exception in the
3794            VM's internal state, then the stack is unwound until an
3795            exception handler or a native code boundary is found, and
3796            then control resumes at the exception handler if any or
3797            else the script returns control to the nearest native caller.
3798         */
3799
3800         int ex = (++vPC)->u.operand;
3801         exceptionValue = callFrame[ex].jsValue(callFrame);
3802
3803         handlerVPC = throwException(callFrame, exceptionValue, vPC, true);
3804         if (!handlerVPC) {
3805             *exception = exceptionValue;
3806             return jsNull();
3807         }
3808
3809         vPC = handlerVPC;
3810         NEXT_INSTRUCTION();
3811     }
3812     DEFINE_OPCODE(op_unexpected_load) {
3813         /* unexpected_load load dst(r) src(k)
3814
3815            Copies constant src to register dst.
3816         */
3817         int dst = (++vPC)->u.operand;
3818         int src = (++vPC)->u.operand;
3819         callFrame[dst] = callFrame->codeBlock()->unexpectedConstants[src];
3820
3821         ++vPC;
3822         NEXT_INSTRUCTION();
3823     }
3824     DEFINE_OPCODE(op_new_error) {
3825         /* new_error dst(r) type(n) message(k)
3826
3827            Constructs a new Error instance using the original
3828            constructor, using immediate number n as the type and
3829            constant message as the message string. The result is
3830            written to register dst.
3831         */
3832         int dst = (++vPC)->u.operand;
3833         int type = (++vPC)->u.operand;
3834         int message = (++vPC)->u.operand;
3835
3836         CodeBlock* codeBlock = callFrame->codeBlock();
3837         callFrame[dst] = Error::create(callFrame, (ErrorType)type, codeBlock->unexpectedConstants[message]->toString(callFrame), codeBlock->lineNumberForVPC(vPC), codeBlock->ownerNode->sourceID(), codeBlock->ownerNode->sourceURL());
3838
3839         ++vPC;
3840         NEXT_INSTRUCTION();
3841     }