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