Roll out r108309, r108323, and r108326
[WebKit-https.git] / Source / JavaScriptCore / interpreter / Interpreter.cpp
1 /*
2  * Copyright (C) 2008, 2009, 2010 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 "CallFrame.h"
36 #include "CallFrameClosure.h"
37 #include "CodeBlock.h"
38 #include "Heap.h"
39 #include "Debugger.h"
40 #include "DebuggerCallFrame.h"
41 #include "ErrorInstance.h"
42 #include "EvalCodeCache.h"
43 #include "ExceptionHelpers.h"
44 #include "GetterSetter.h"
45 #include "JSActivation.h"
46 #include "JSArray.h"
47 #include "JSByteArray.h"
48 #include "JSNotAnObject.h"
49 #include "JSPropertyNameIterator.h"
50 #include "LiteralParser.h"
51 #include "JSStaticScopeObject.h"
52 #include "JSString.h"
53 #include "ObjectPrototype.h"
54 #include "Operations.h"
55 #include "Parser.h"
56 #include "Profiler.h"
57 #include "RegExpObject.h"
58 #include "RegExpPrototype.h"
59 #include "Register.h"
60 #include "SamplingTool.h"
61 #include "StrictEvalActivation.h"
62 #include "StrongInlines.h"
63 #include "UStringConcatenate.h"
64 #include <limits.h>
65 #include <stdio.h>
66 #include <wtf/Threading.h>
67
68 #if ENABLE(JIT)
69 #include "JIT.h"
70 #endif
71
72 #define WTF_USE_GCC_COMPUTED_GOTO_WORKAROUND (ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER) && !defined(__llvm__))
73
74 using namespace std;
75
76 namespace JSC {
77
78 // Returns the depth of the scope chain within a given call frame.
79 static int depth(CodeBlock* codeBlock, ScopeChainNode* sc)
80 {
81     if (!codeBlock->needsFullScopeChain())
82         return 0;
83     return sc->localDepth();
84 }
85
86 #if ENABLE(CLASSIC_INTERPRETER) 
87 static NEVER_INLINE JSValue concatenateStrings(ExecState* exec, Register* strings, unsigned count)
88 {
89     return jsString(exec, strings, count);
90 }
91
92 NEVER_INLINE bool Interpreter::resolve(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
93 {
94     int dst = vPC[1].u.operand;
95     int property = vPC[2].u.operand;
96
97     ScopeChainNode* scopeChain = callFrame->scopeChain();
98     ScopeChainIterator iter = scopeChain->begin();
99     ScopeChainIterator end = scopeChain->end();
100     ASSERT(iter != end);
101
102     CodeBlock* codeBlock = callFrame->codeBlock();
103     Identifier& ident = codeBlock->identifier(property);
104     do {
105         JSObject* o = iter->get();
106         PropertySlot slot(o);
107         if (o->getPropertySlot(callFrame, ident, slot)) {
108             JSValue result = slot.getValue(callFrame, ident);
109             exceptionValue = callFrame->globalData().exception;
110             if (exceptionValue)
111                 return false;
112             callFrame->uncheckedR(dst) = JSValue(result);
113             return true;
114         }
115     } while (++iter != end);
116     exceptionValue = createUndefinedVariableError(callFrame, ident);
117     return false;
118 }
119
120 NEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
121 {
122     CodeBlock* codeBlock = callFrame->codeBlock();
123
124     int dst = vPC[1].u.operand;
125     int property = vPC[2].u.operand;
126     int skip = vPC[3].u.operand;
127
128     ScopeChainNode* scopeChain = callFrame->scopeChain();
129     ScopeChainIterator iter = scopeChain->begin();
130     ScopeChainIterator end = scopeChain->end();
131     ASSERT(iter != end);
132     bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain();
133     ASSERT(skip || !checkTopLevel);
134     if (checkTopLevel && skip--) {
135         if (callFrame->uncheckedR(codeBlock->activationRegister()).jsValue())
136             ++iter;
137     }
138     while (skip--) {
139         ++iter;
140         ASSERT(iter != end);
141     }
142     Identifier& ident = codeBlock->identifier(property);
143     do {
144         JSObject* o = iter->get();
145         PropertySlot slot(o);
146         if (o->getPropertySlot(callFrame, ident, slot)) {
147             JSValue result = slot.getValue(callFrame, ident);
148             exceptionValue = callFrame->globalData().exception;
149             if (exceptionValue)
150                 return false;
151             ASSERT(result);
152             callFrame->uncheckedR(dst) = JSValue(result);
153             return true;
154         }
155     } while (++iter != end);
156     exceptionValue = createUndefinedVariableError(callFrame, ident);
157     return false;
158 }
159
160 NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
161 {
162     int dst = vPC[1].u.operand;
163     CodeBlock* codeBlock = callFrame->codeBlock();
164     JSGlobalObject* globalObject = codeBlock->globalObject();
165     ASSERT(globalObject->isGlobalObject());
166     int property = vPC[2].u.operand;
167     Structure* structure = vPC[3].u.structure.get();
168     int offset = vPC[4].u.operand;
169
170     if (structure == globalObject->structure()) {
171         callFrame->uncheckedR(dst) = JSValue(globalObject->getDirectOffset(offset));
172         return true;
173     }
174
175     Identifier& ident = codeBlock->identifier(property);
176     PropertySlot slot(globalObject);
177     if (globalObject->getPropertySlot(callFrame, ident, slot)) {
178         JSValue result = slot.getValue(callFrame, ident);
179         if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
180             vPC[3].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), globalObject->structure());
181             vPC[4] = slot.cachedOffset();
182             callFrame->uncheckedR(dst) = JSValue(result);
183             return true;
184         }
185
186         exceptionValue = callFrame->globalData().exception;
187         if (exceptionValue)
188             return false;
189         callFrame->uncheckedR(dst) = JSValue(result);
190         return true;
191     }
192
193     exceptionValue = createUndefinedVariableError(callFrame, ident);
194     return false;
195 }
196
197 NEVER_INLINE bool Interpreter::resolveGlobalDynamic(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
198 {
199     int dst = vPC[1].u.operand;
200     CodeBlock* codeBlock = callFrame->codeBlock();
201     JSGlobalObject* globalObject = codeBlock->globalObject();
202     ASSERT(globalObject->isGlobalObject());
203     int property = vPC[2].u.operand;
204     Structure* structure = vPC[3].u.structure.get();
205     int offset = vPC[4].u.operand;
206     int skip = vPC[5].u.operand;
207     
208     ScopeChainNode* scopeChain = callFrame->scopeChain();
209     ScopeChainIterator iter = scopeChain->begin();
210     ScopeChainIterator end = scopeChain->end();
211     ASSERT(iter != end);
212     bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain();
213     ASSERT(skip || !checkTopLevel);
214     if (checkTopLevel && skip--) {
215         if (callFrame->uncheckedR(codeBlock->activationRegister()).jsValue())
216             ++iter;
217     }
218     while (skip--) {
219         JSObject* o = iter->get();
220         if (o->hasCustomProperties()) {
221             Identifier& ident = codeBlock->identifier(property);
222             do {
223                 PropertySlot slot(o);
224                 if (o->getPropertySlot(callFrame, ident, slot)) {
225                     JSValue result = slot.getValue(callFrame, ident);
226                     exceptionValue = callFrame->globalData().exception;
227                     if (exceptionValue)
228                         return false;
229                     ASSERT(result);
230                     callFrame->uncheckedR(dst) = JSValue(result);
231                     return true;
232                 }
233                 if (iter == end)
234                     break;
235                 o = iter->get();
236                 ++iter;
237             } while (true);
238             exceptionValue = createUndefinedVariableError(callFrame, ident);
239             return false;
240         }
241         ++iter;
242     }
243     
244     if (structure == globalObject->structure()) {
245         callFrame->uncheckedR(dst) = JSValue(globalObject->getDirectOffset(offset));
246         ASSERT(callFrame->uncheckedR(dst).jsValue());
247         return true;
248     }
249
250     Identifier& ident = codeBlock->identifier(property);
251     PropertySlot slot(globalObject);
252     if (globalObject->getPropertySlot(callFrame, ident, slot)) {
253         JSValue result = slot.getValue(callFrame, ident);
254         if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
255             vPC[3].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), globalObject->structure());
256             vPC[4] = slot.cachedOffset();
257             ASSERT(result);
258             callFrame->uncheckedR(dst) = JSValue(result);
259             return true;
260         }
261         
262         exceptionValue = callFrame->globalData().exception;
263         if (exceptionValue)
264             return false;
265         ASSERT(result);
266         callFrame->uncheckedR(dst) = JSValue(result);
267         return true;
268     }
269     
270     exceptionValue = createUndefinedVariableError(callFrame, ident);
271     return false;
272 }
273
274 NEVER_INLINE void Interpreter::resolveBase(CallFrame* callFrame, Instruction* vPC)
275 {
276     int dst = vPC[1].u.operand;
277     int property = vPC[2].u.operand;
278     bool isStrictPut = vPC[3].u.operand;
279     Identifier ident = callFrame->codeBlock()->identifier(property);
280     JSValue result = JSC::resolveBase(callFrame, ident, callFrame->scopeChain(), isStrictPut);
281     if (result) {
282         callFrame->uncheckedR(dst) = result;
283         ASSERT(callFrame->uncheckedR(dst).jsValue());
284     } else
285         callFrame->globalData().exception = createErrorForInvalidGlobalAssignment(callFrame, ident.ustring());
286 }
287
288 NEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
289 {
290     int baseDst = vPC[1].u.operand;
291     int propDst = vPC[2].u.operand;
292     int property = vPC[3].u.operand;
293
294     ScopeChainNode* scopeChain = callFrame->scopeChain();
295     ScopeChainIterator iter = scopeChain->begin();
296     ScopeChainIterator end = scopeChain->end();
297
298     // FIXME: add scopeDepthIsZero optimization
299
300     ASSERT(iter != end);
301
302     CodeBlock* codeBlock = callFrame->codeBlock();
303     Identifier& ident = codeBlock->identifier(property);
304     JSObject* base;
305     do {
306         base = iter->get();
307         PropertySlot slot(base);
308         if (base->getPropertySlot(callFrame, ident, slot)) {
309             JSValue result = slot.getValue(callFrame, ident);
310             exceptionValue = callFrame->globalData().exception;
311             if (exceptionValue)
312                 return false;
313             callFrame->uncheckedR(propDst) = JSValue(result);
314             callFrame->uncheckedR(baseDst) = JSValue(base);
315             return true;
316         }
317         ++iter;
318     } while (iter != end);
319
320     exceptionValue = createUndefinedVariableError(callFrame, ident);
321     return false;
322 }
323
324 NEVER_INLINE bool Interpreter::resolveThisAndProperty(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
325 {
326     int thisDst = vPC[1].u.operand;
327     int propDst = vPC[2].u.operand;
328     int property = vPC[3].u.operand;
329
330     ScopeChainNode* scopeChain = callFrame->scopeChain();
331     ScopeChainIterator iter = scopeChain->begin();
332     ScopeChainIterator end = scopeChain->end();
333
334     // FIXME: add scopeDepthIsZero optimization
335
336     ASSERT(iter != end);
337
338     CodeBlock* codeBlock = callFrame->codeBlock();
339     Identifier& ident = codeBlock->identifier(property);
340     JSObject* base;
341     do {
342         base = iter->get();
343         ++iter;
344         PropertySlot slot(base);
345         if (base->getPropertySlot(callFrame, ident, slot)) {
346             JSValue result = slot.getValue(callFrame, ident);
347             exceptionValue = callFrame->globalData().exception;
348             if (exceptionValue)
349                 return false;
350             callFrame->uncheckedR(propDst) = JSValue(result);
351             // All entries on the scope chain should be EnvironmentRecords (activations etc),
352             // other then 'with' object, which are directly referenced from the scope chain,
353             // and the global object. If we hit either an EnvironmentRecord or a global
354             // object at the end of the scope chain, this is undefined. If we hit a non-
355             // EnvironmentRecord within the scope chain, pass the base as the this value.
356             if (iter == end || base->structure()->typeInfo().isEnvironmentRecord())
357                 callFrame->uncheckedR(thisDst) = jsUndefined();
358             else
359                 callFrame->uncheckedR(thisDst) = JSValue(base);
360             return true;
361         }
362     } while (iter != end);
363
364     exceptionValue = createUndefinedVariableError(callFrame, ident);
365     return false;
366 }
367
368 #endif // ENABLE(CLASSIC_INTERPRETER)
369
370 ALWAYS_INLINE CallFrame* Interpreter::slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, CallFrame* callFrame, size_t registerOffset, int argumentCountIncludingThis)
371 {
372     // This ensures enough space for the worst case scenario of zero arguments passed by the caller.
373     if (!registerFile->grow(callFrame->registers() + registerOffset + newCodeBlock->numParameters() + newCodeBlock->m_numCalleeRegisters))
374         return 0;
375
376     if (argumentCountIncludingThis >= newCodeBlock->numParameters()) {
377         Register* newCallFrame = callFrame->registers() + registerOffset;
378         return CallFrame::create(newCallFrame);
379     }
380
381     // Too few arguments -- copy arguments, then fill in missing arguments with undefined.
382     size_t delta = newCodeBlock->numParameters() - argumentCountIncludingThis;
383     CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset + delta);
384
385     Register* dst = &newCallFrame->uncheckedR(CallFrame::thisArgumentOffset());
386     Register* end = dst - argumentCountIncludingThis;
387     for ( ; dst != end; --dst)
388         *dst = *(dst - delta);
389
390     end -= delta;
391     for ( ; dst != end; --dst)
392         *dst = jsUndefined();
393
394     return newCallFrame;
395 }
396
397 #if ENABLE(CLASSIC_INTERPRETER)
398 static NEVER_INLINE bool isInvalidParamForIn(CallFrame* callFrame, JSValue value, JSValue& exceptionData)
399 {
400     if (value.isObject())
401         return false;
402     exceptionData = createInvalidParamError(callFrame, "in" , value);
403     return true;
404 }
405
406 static NEVER_INLINE bool isInvalidParamForInstanceOf(CallFrame* callFrame, JSValue value, JSValue& exceptionData)
407 {
408     if (value.isObject() && asObject(value)->structure()->typeInfo().implementsHasInstance())
409         return false;
410     exceptionData = createInvalidParamError(callFrame, "instanceof" , value);
411     return true;
412 }
413 #endif
414
415 JSValue eval(CallFrame* callFrame)
416 {
417     if (!callFrame->argumentCount())
418         return jsUndefined();
419
420     JSValue program = callFrame->argument(0);
421     if (!program.isString())
422         return program;
423
424     UString programSource = asString(program)->value(callFrame);
425     if (callFrame->hadException())
426         return JSValue();
427     
428     CallFrame* callerFrame = callFrame->callerFrame();
429     CodeBlock* callerCodeBlock = callerFrame->codeBlock();
430     ScopeChainNode* callerScopeChain = callerFrame->scopeChain();
431     EvalExecutable* eval = callerCodeBlock->evalCodeCache().tryGet(callerCodeBlock->isStrictMode(), programSource, callerScopeChain);
432
433     if (!eval) {
434         if (!callerCodeBlock->isStrictMode()) {
435             // FIXME: We can use the preparser in strict mode, we just need additional logic
436             // to prevent duplicates.
437             if (programSource.is8Bit()) {
438                 LiteralParser<LChar> preparser(callFrame, programSource.characters8(), programSource.length(), NonStrictJSON);
439                 if (JSValue parsedObject = preparser.tryLiteralParse())
440                     return parsedObject;
441             } else {
442                 LiteralParser<UChar> preparser(callFrame, programSource.characters16(), programSource.length(), NonStrictJSON);
443                 if (JSValue parsedObject = preparser.tryLiteralParse())
444                     return parsedObject;                
445             }
446         }
447
448         JSValue exceptionValue;
449         eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock->ownerExecutable(), callerCodeBlock->isStrictMode(), programSource, callerScopeChain, exceptionValue);
450         
451         ASSERT(!eval == exceptionValue);
452         if (UNLIKELY(!eval))
453             return throwError(callFrame, exceptionValue);
454     }
455
456     JSValue thisValue = callerFrame->thisValue();
457     ASSERT(isValidThisObject(thisValue, callFrame));
458     Interpreter* interpreter = callFrame->globalData().interpreter;
459     return interpreter->execute(eval, callFrame, thisValue, callerScopeChain, callFrame->registers() - interpreter->registerFile().begin() + 1 + RegisterFile::CallFrameHeaderSize);
460 }
461
462 CallFrame* loadVarargs(CallFrame* callFrame, RegisterFile* registerFile, JSValue thisValue, JSValue arguments, int firstFreeRegister)
463 {
464     if (!arguments) { // f.apply(x, arguments), with arguments unmodified.
465         unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
466         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + argumentCountIncludingThis + RegisterFile::CallFrameHeaderSize);
467         if (argumentCountIncludingThis > Arguments::MaxArguments + 1 || !registerFile->grow(newCallFrame->registers())) {
468             callFrame->globalData().exception = createStackOverflowError(callFrame);
469             return 0;
470         }
471
472         newCallFrame->setArgumentCountIncludingThis(argumentCountIncludingThis);
473         newCallFrame->setThisValue(thisValue);
474         for (size_t i = 0; i < callFrame->argumentCount(); ++i)
475             newCallFrame->setArgument(i, callFrame->argument(i));
476         return newCallFrame;
477     }
478
479     if (arguments.isUndefinedOrNull()) {
480         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + 1 + RegisterFile::CallFrameHeaderSize);
481         if (!registerFile->grow(newCallFrame->registers())) {
482             callFrame->globalData().exception = createStackOverflowError(callFrame);
483             return 0;
484         }
485         newCallFrame->setArgumentCountIncludingThis(1);
486         newCallFrame->setThisValue(thisValue);
487         return newCallFrame;
488     }
489
490     if (!arguments.isObject()) {
491         callFrame->globalData().exception = createInvalidParamError(callFrame, "Function.prototype.apply", arguments);
492         return 0;
493     }
494
495     if (asObject(arguments)->classInfo() == &Arguments::s_info) {
496         Arguments* argsObject = asArguments(arguments);
497         unsigned argCount = argsObject->length(callFrame);
498         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
499         if (argCount > Arguments::MaxArguments || !registerFile->grow(newCallFrame->registers())) {
500             callFrame->globalData().exception = createStackOverflowError(callFrame);
501             return 0;
502         }
503         newCallFrame->setArgumentCountIncludingThis(argCount + 1);
504         newCallFrame->setThisValue(thisValue);
505         argsObject->copyToArguments(callFrame, newCallFrame, argCount);
506         return newCallFrame;
507     }
508
509     if (isJSArray(arguments)) {
510         JSArray* array = asArray(arguments);
511         unsigned argCount = array->length();
512         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
513         if (argCount > Arguments::MaxArguments || !registerFile->grow(newCallFrame->registers())) {
514             callFrame->globalData().exception = createStackOverflowError(callFrame);
515             return 0;
516         }
517         newCallFrame->setArgumentCountIncludingThis(argCount + 1);
518         newCallFrame->setThisValue(thisValue);
519         array->copyToArguments(callFrame, newCallFrame, argCount);
520         return newCallFrame;
521     }
522
523     JSObject* argObject = asObject(arguments);
524     unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
525     CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
526     if (argCount > Arguments::MaxArguments || !registerFile->grow(newCallFrame->registers())) {
527         callFrame->globalData().exception = createStackOverflowError(callFrame);
528         return 0;
529     }
530     newCallFrame->setArgumentCountIncludingThis(argCount + 1);
531     newCallFrame->setThisValue(thisValue);
532     for (size_t i = 0; i < argCount; ++i) {
533         newCallFrame->setArgument(i, asObject(arguments)->get(callFrame, i));
534         if (UNLIKELY(callFrame->globalData().exception))
535             return 0;
536     }
537     return newCallFrame;
538 }
539
540 Interpreter::Interpreter()
541     : m_sampleEntryDepth(0)
542     , m_reentryDepth(0)
543 #if !ASSERT_DISABLED
544     , m_initialized(false)
545 #endif
546     , m_enabled(false)
547 {
548 }
549
550 void Interpreter::initialize(bool canUseJIT)
551 {
552 #if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
553     if (canUseJIT) {
554         // If the JIT is present, don't use jump destinations for opcodes.
555         
556         for (int i = 0; i < numOpcodeIDs; ++i) {
557             Opcode opcode = bitwise_cast<void*>(static_cast<uintptr_t>(i));
558             m_opcodeTable[i] = opcode;
559         }
560     } else {
561         privateExecute(InitializeAndReturn, 0, 0);
562         
563         for (int i = 0; i < numOpcodeIDs; ++i)
564             m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
565         
566         m_enabled = true;
567     }
568 #else
569     UNUSED_PARAM(canUseJIT);
570 #if ENABLE(CLASSIC_INTERPRETER)
571     m_enabled = true;
572 #else
573     m_enabled = false;
574 #endif
575 #endif // ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
576 #if !ASSERT_DISABLED
577     m_initialized = true;
578 #endif
579
580 #if ENABLE(OPCODE_SAMPLING)
581     enableSampler();
582 #endif
583 }
584
585 #ifndef NDEBUG
586
587 void Interpreter::dumpCallFrame(CallFrame* callFrame)
588 {
589     callFrame->codeBlock()->dump(callFrame);
590     dumpRegisters(callFrame);
591 }
592
593 void Interpreter::dumpRegisters(CallFrame* callFrame)
594 {
595     dataLog("Register frame: \n\n");
596     dataLog("-----------------------------------------------------------------------------\n");
597     dataLog("            use            |   address  |                value               \n");
598     dataLog("-----------------------------------------------------------------------------\n");
599
600     CodeBlock* codeBlock = callFrame->codeBlock();
601     const Register* it;
602     const Register* end;
603     JSValue v;
604
605     it = callFrame->registers() - RegisterFile::CallFrameHeaderSize - codeBlock->numParameters();
606     v = (*it).jsValue();
607 #if USE(JSVALUE32_64)
608     dataLog("[this]                     | %10p | %-16s 0x%llx \n", it, v.description(), JSValue::encode(v)); ++it;
609 #else
610     dataLog("[this]                     | %10p | %-16s %p \n", it, v.description(), JSValue::encode(v)); ++it;
611 #endif
612     end = it + max(codeBlock->numParameters() - 1, 0); // - 1 to skip "this"
613     if (it != end) {
614         do {
615             v = (*it).jsValue();
616 #if USE(JSVALUE32_64)
617             dataLog("[param]                    | %10p | %-16s 0x%llx \n", it, v.description(), JSValue::encode(v));
618 #else
619             dataLog("[param]                    | %10p | %-16s %p \n", it, v.description(), JSValue::encode(v));
620 #endif
621             ++it;
622         } while (it != end);
623     }
624     dataLog("-----------------------------------------------------------------------------\n");
625     dataLog("[CodeBlock]                | %10p | %p \n", it, (*it).codeBlock()); ++it;
626     dataLog("[ScopeChain]               | %10p | %p \n", it, (*it).scopeChain()); ++it;
627     dataLog("[CallerRegisters]          | %10p | %d \n", it, (*it).i()); ++it;
628     dataLog("[ReturnPC]                 | %10p | %p \n", it, (*it).vPC()); ++it;
629     dataLog("[ArgumentCount]            | %10p | %d \n", it, (*it).i()); ++it;
630     dataLog("[Callee]                   | %10p | %p \n", it, (*it).function()); ++it;
631     dataLog("-----------------------------------------------------------------------------\n");
632
633     int registerCount = 0;
634
635     end = it + codeBlock->m_numVars;
636     if (it != end) {
637         do {
638             v = (*it).jsValue();
639 #if USE(JSVALUE32_64)
640             dataLog("[r%2d]                      | %10p | %-16s 0x%llx \n", registerCount, it, v.description(), JSValue::encode(v));
641 #else
642             dataLog("[r%2d]                      | %10p | %-16s %p \n", registerCount, it, v.description(), JSValue::encode(v));
643 #endif
644             ++it;
645             ++registerCount;
646         } while (it != end);
647     }
648     dataLog("-----------------------------------------------------------------------------\n");
649
650     end = it + codeBlock->m_numCalleeRegisters - codeBlock->m_numVars;
651     if (it != end) {
652         do {
653             v = (*it).jsValue();
654 #if USE(JSVALUE32_64)
655             dataLog("[r%2d]                      | %10p | %-16s 0x%llx \n", registerCount, it, v.description(), JSValue::encode(v));
656 #else
657             dataLog("[r%2d]                      | %10p | %-16s %p \n", registerCount, it, v.description(), JSValue::encode(v));
658 #endif
659             ++it;
660             ++registerCount;
661         } while (it != end);
662     }
663     dataLog("-----------------------------------------------------------------------------\n");
664 }
665
666 #endif
667
668 bool Interpreter::isOpcode(Opcode opcode)
669 {
670 #if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
671     if (!m_enabled)
672         return opcode >= 0 && static_cast<OpcodeID>(bitwise_cast<uintptr_t>(opcode)) <= op_end;
673     return opcode != HashTraits<Opcode>::emptyValue()
674         && !HashTraits<Opcode>::isDeletedValue(opcode)
675         && m_opcodeIDTable.contains(opcode);
676 #else
677     return opcode >= 0 && opcode <= op_end;
678 #endif
679 }
680
681 NEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValue exceptionValue, unsigned& bytecodeOffset, CodeBlock*& codeBlock)
682 {
683     CodeBlock* oldCodeBlock = codeBlock;
684     ScopeChainNode* scopeChain = callFrame->scopeChain();
685
686     if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) {
687         DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue);
688         if (callFrame->callee())
689             debugger->returnEvent(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->lastLine());
690         else
691             debugger->didExecuteProgram(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->lastLine());
692     }
693
694     // If this call frame created an activation or an 'arguments' object, tear it off.
695     if (oldCodeBlock->codeType() == FunctionCode && oldCodeBlock->needsFullScopeChain()) {
696         if (!callFrame->uncheckedR(oldCodeBlock->activationRegister()).jsValue()) {
697             oldCodeBlock->createActivation(callFrame);
698             scopeChain = callFrame->scopeChain();
699         }
700         while (!scopeChain->object->inherits(&JSActivation::s_info))
701             scopeChain = scopeChain->pop();
702
703         callFrame->setScopeChain(scopeChain);
704         JSActivation* activation = asActivation(scopeChain->object.get());
705         activation->tearOff(*scopeChain->globalData);
706         if (JSValue arguments = callFrame->uncheckedR(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue())
707             asArguments(arguments)->didTearOffActivation(callFrame->globalData(), activation);
708     } else if (oldCodeBlock->usesArguments() && !oldCodeBlock->isStrictMode()) {
709         if (JSValue arguments = callFrame->uncheckedR(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue())
710             asArguments(arguments)->tearOff(callFrame);
711     }
712
713     CallFrame* callerFrame = callFrame->callerFrame();
714     callFrame->globalData().topCallFrame = callerFrame;
715     if (callerFrame->hasHostCallFrameFlag())
716         return false;
717
718     codeBlock = callerFrame->codeBlock();
719     
720     // Because of how the JIT records call site->bytecode offset
721     // information the JIT reports the bytecodeOffset for the returnPC
722     // to be at the beginning of the opcode that has caused the call.
723     // In the interpreter we have an actual return address, which is
724     // the beginning of next instruction to execute. To get an offset
725     // inside the call instruction that triggered the exception we
726     // have to subtract 1.
727 #if ENABLE(JIT) && ENABLE(CLASSIC_INTERPRETER)
728     if (callerFrame->globalData().canUseJIT())
729         bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnPC());
730     else
731         bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC()) - 1;
732 #elif ENABLE(JIT)
733     bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnPC());
734 #else
735     bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC()) - 1;
736 #endif
737
738     callFrame = callerFrame;
739     return true;
740 }
741
742 static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception, unsigned bytecodeOffset)
743 {
744     exception->clearAppendSourceToMessage();
745
746     if (!callFrame->codeBlock()->hasExpressionInfo())
747         return;
748
749     int startOffset = 0;
750     int endOffset = 0;
751     int divotPoint = 0;
752
753     CodeBlock* codeBlock = callFrame->codeBlock();
754     codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divotPoint, startOffset, endOffset);
755
756     int expressionStart = divotPoint - startOffset;
757     int expressionStop = divotPoint + endOffset;
758
759     if (!expressionStop || expressionStart > codeBlock->source()->length())
760         return;
761
762     JSGlobalData* globalData = &callFrame->globalData();
763     JSValue jsMessage = exception->getDirect(*globalData, globalData->propertyNames->message);
764     if (!jsMessage || !jsMessage.isString())
765         return;
766
767     UString message = asString(jsMessage)->value(callFrame);
768
769     if (expressionStart < expressionStop)
770         message =  makeUString(message, " (evaluating '", codeBlock->source()->getRange(expressionStart, expressionStop), "')");
771     else {
772         // No range information, so give a few characters of context
773         const StringImpl* data = codeBlock->source()->data();
774         int dataLength = codeBlock->source()->length();
775         int start = expressionStart;
776         int stop = expressionStart;
777         // Get up to 20 characters of context to the left and right of the divot, clamping to the line.
778         // then strip whitespace.
779         while (start > 0 && (expressionStart - start < 20) && (*data)[start - 1] != '\n')
780             start--;
781         while (start < (expressionStart - 1) && isStrWhiteSpace((*data)[start]))
782             start++;
783         while (stop < dataLength && (stop - expressionStart < 20) && (*data)[stop] != '\n')
784             stop++;
785         while (stop > expressionStart && isStrWhiteSpace((*data)[stop - 1]))
786             stop--;
787         message = makeUString(message, " (near '...", codeBlock->source()->getRange(start, stop), "...')");
788     }
789
790     exception->putDirect(*globalData, globalData->propertyNames->message, jsString(globalData, message));
791 }
792
793 static CallFrame* getCallerInfo(JSGlobalData* globalData, CallFrame* callFrame, int& lineNumber)
794 {
795     UNUSED_PARAM(globalData);
796     unsigned bytecodeOffset = 0;
797     lineNumber = -1;
798     ASSERT(!callFrame->hasHostCallFrameFlag());
799     CallFrame* callerFrame = callFrame->codeBlock() ? callFrame->trueCallerFrame() : 0;
800     bool callframeIsHost = callerFrame->addHostCallFrameFlag() == callFrame->callerFrame();
801     ASSERT(!callerFrame->hasHostCallFrameFlag());
802
803     if (callerFrame == CallFrame::noCaller() || !callerFrame || !callerFrame->codeBlock())
804         return callerFrame;
805
806     CodeBlock* callerCodeBlock = callerFrame->codeBlock();
807
808     if (callframeIsHost) {
809         // Don't need to deal with inline callframes here as by definition we haven't
810         // inlined a call with an intervening native call frame.
811 #if ENABLE(INTERPRETER)
812         if (!globalData->canUseJIT()) {
813             bytecodeOffset = callerFrame->bytecodeOffsetForNonDFGCode();
814             lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
815             return callerFrame;
816         }
817 #endif
818 #if ENABLE(JIT)
819 #if ENABLE(DFG_JIT)
820         if (callerCodeBlock && callerCodeBlock->getJITType() == JITCode::DFGJIT)
821             bytecodeOffset = callerCodeBlock->codeOrigin(callerFrame->codeOriginIndexForDFG()).bytecodeIndex;
822         else
823 #endif
824             bytecodeOffset = callerFrame->bytecodeOffsetForNonDFGCode();
825 #endif
826     } else {
827 #if ENABLE(INTERPRETER)
828         if (!globalData->canUseJIT()) {
829             bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnVPC());
830             lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
831             return callerFrame;
832         }
833 #endif
834 #if ENABLE(JIT)
835     #if ENABLE(DFG_JIT)
836         if (callFrame->isInlineCallFrame()) {
837             InlineCallFrame* icf = callFrame->inlineCallFrame();
838             bytecodeOffset = icf->caller.bytecodeIndex;
839             if (InlineCallFrame* parentCallFrame = icf->caller.inlineCallFrame) {
840                 FunctionExecutable* executable = static_cast<FunctionExecutable*>(parentCallFrame->executable.get());
841                 CodeBlock* newCodeBlock = executable->baselineCodeBlockFor(parentCallFrame->isCall ? CodeForCall : CodeForConstruct);
842                 ASSERT(newCodeBlock);
843                 ASSERT(newCodeBlock->instructionCount() > bytecodeOffset);
844                 callerCodeBlock = newCodeBlock;
845             }
846         } else if (callerCodeBlock && callerCodeBlock->getJITType() == JITCode::DFGJIT) {
847             CodeOrigin origin;
848             if (!callerCodeBlock->codeOriginForReturn(callFrame->returnPC(), origin))
849                 ASSERT_NOT_REACHED();
850             bytecodeOffset = origin.bytecodeIndex;
851             if (InlineCallFrame* icf = origin.inlineCallFrame) {
852                 FunctionExecutable* executable = static_cast<FunctionExecutable*>(icf->executable.get());
853                 CodeBlock* newCodeBlock = executable->baselineCodeBlockFor(icf->isCall ? CodeForCall : CodeForConstruct);
854                 ASSERT(newCodeBlock);
855                 ASSERT(newCodeBlock->instructionCount() > bytecodeOffset);
856                 callerCodeBlock = newCodeBlock;
857             }
858         } else
859     #endif
860             bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC());
861 #endif
862     }
863
864     lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset);
865     return callerFrame;
866 }
867
868 static ALWAYS_INLINE const UString getSourceURLFromCallFrame(CallFrame* callFrame) 
869 {
870     ASSERT(!callFrame->hasHostCallFrameFlag());
871 #if ENABLE(INTERPRETER)
872 #if ENABLE(JIT)
873     if (callFrame->globalData().canUseJIT())
874         return callFrame->codeBlock()->ownerExecutable()->sourceURL();
875 #endif
876     return callFrame->codeBlock()->source()->url();
877
878 #else
879     return callFrame->codeBlock()->ownerExecutable()->sourceURL();
880 #endif
881 }
882
883 static StackFrameCodeType getStackFrameCodeType(CallFrame* callFrame)
884 {
885     ASSERT(!callFrame->hasHostCallFrameFlag());
886
887     switch (callFrame->codeBlock()->codeType()) {
888     case EvalCode:
889         return StackFrameEvalCode;
890     case FunctionCode:
891         return StackFrameFunctionCode;
892     case GlobalCode:
893         return StackFrameGlobalCode;
894     }
895     ASSERT_NOT_REACHED();
896     return StackFrameGlobalCode;
897 }
898
899 void Interpreter::getStackTrace(JSGlobalData* globalData, int line, Vector<StackFrame>& results)
900 {
901     CallFrame* callFrame = globalData->topCallFrame->removeHostCallFrameFlag()->trueCallFrameFromVMCode();
902     if (!callFrame || callFrame == CallFrame::noCaller()) 
903         return;
904
905     while (callFrame && callFrame != CallFrame::noCaller()) {
906         UString sourceURL;
907         if (callFrame->codeBlock()) {
908             sourceURL = getSourceURLFromCallFrame(callFrame);
909             StackFrame s = { Strong<JSObject>(*globalData, callFrame->callee()), getStackFrameCodeType(callFrame), Strong<ExecutableBase>(*globalData, callFrame->codeBlock()->ownerExecutable()), line, sourceURL};
910             results.append(s);
911         } else {
912             StackFrame s = { Strong<JSObject>(*globalData, callFrame->callee()), StackFrameNativeCode, Strong<ExecutableBase>(), -1, UString()};
913             results.append(s);
914         }
915         callFrame = getCallerInfo(globalData, callFrame, line);
916     }
917 }
918
919 NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSValue& exceptionValue, unsigned bytecodeOffset)
920 {
921     CodeBlock* codeBlock = callFrame->codeBlock();
922     bool isInterrupt = false;
923
924     // Set up the exception object
925     if (exceptionValue.isObject()) {
926         JSObject* exception = asObject(exceptionValue);
927
928         if (exception->isErrorInstance() && static_cast<ErrorInstance*>(exception)->appendSourceToMessage())
929             appendSourceToError(callFrame, static_cast<ErrorInstance*>(exception), bytecodeOffset);
930
931         // Using hasExpressionInfo to imply we are interested in rich exception info.
932         if (codeBlock->hasExpressionInfo() && !hasErrorInfo(callFrame, exception)) {
933             ASSERT(codeBlock->hasLineInfo());
934
935             // FIXME: should only really be adding these properties to VM generated exceptions,
936             // but the inspector currently requires these for all thrown objects.
937             Vector<StackFrame> stackTrace;
938             getStackTrace(&callFrame->globalData(), codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), stackTrace);
939             addErrorInfo(callFrame, exception, codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), codeBlock->ownerExecutable()->source(), stackTrace);
940         }
941
942         isInterrupt = isInterruptedExecutionException(exception) || isTerminatedExecutionException(exception);
943     }
944
945     if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) {
946         DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue);
947         bool hasHandler = codeBlock->handlerForBytecodeOffset(bytecodeOffset);
948         debugger->exception(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), hasHandler);
949     }
950
951     // Calculate an exception handler vPC, unwinding call frames as necessary.
952     HandlerInfo* handler = 0;
953     while (isInterrupt || !(handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset))) {
954         if (!unwindCallFrame(callFrame, exceptionValue, bytecodeOffset, codeBlock)) {
955             if (Profiler* profiler = *Profiler::enabledProfilerReference())
956                 profiler->exceptionUnwind(callFrame);
957             return 0;
958         }
959     }
960
961     if (Profiler* profiler = *Profiler::enabledProfilerReference())
962         profiler->exceptionUnwind(callFrame);
963
964     // Shrink the JS stack, in case stack overflow made it huge.
965     Register* highWaterMark = 0;
966     for (CallFrame* callerFrame = callFrame; callerFrame; callerFrame = callerFrame->callerFrame()->removeHostCallFrameFlag()) {
967         CodeBlock* codeBlock = callerFrame->codeBlock();
968         if (!codeBlock)
969             continue;
970         Register* callerHighWaterMark = callerFrame->registers() + codeBlock->m_numCalleeRegisters;
971         highWaterMark = max(highWaterMark, callerHighWaterMark);
972     }
973     m_registerFile.shrink(highWaterMark);
974
975     // Unwind the scope chain within the exception handler's call frame.
976     ScopeChainNode* scopeChain = callFrame->scopeChain();
977     int scopeDelta = 0;
978     if (!codeBlock->needsFullScopeChain() || codeBlock->codeType() != FunctionCode 
979         || callFrame->uncheckedR(codeBlock->activationRegister()).jsValue())
980         scopeDelta = depth(codeBlock, scopeChain) - handler->scopeDepth;
981     ASSERT(scopeDelta >= 0);
982     while (scopeDelta--)
983         scopeChain = scopeChain->pop();
984     callFrame->setScopeChain(scopeChain);
985
986     return handler;
987 }
988
989 static inline JSValue checkedReturn(JSValue returnValue)
990 {
991     ASSERT(returnValue);
992     return returnValue;
993 }
994
995 static inline JSObject* checkedReturn(JSObject* returnValue)
996 {
997     ASSERT(returnValue);
998     return returnValue;
999 }
1000
1001 JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, ScopeChainNode* scopeChain, JSObject* thisObj)
1002 {
1003     ASSERT(isValidThisObject(thisObj, callFrame));
1004     ASSERT(!scopeChain->globalData->exception);
1005     ASSERT(!callFrame->globalData().isCollectorBusy());
1006     if (callFrame->globalData().isCollectorBusy())
1007         return jsNull();
1008
1009     if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth)
1010         return checkedReturn(throwStackOverflowError(callFrame));
1011
1012     DynamicGlobalObjectScope globalObjectScope(*scopeChain->globalData, scopeChain->globalObject.get());
1013     Vector<JSONPData> JSONPData;
1014     bool parseResult;
1015     const UString programSource = program->source().toString();
1016     if (programSource.isNull())
1017         return jsUndefined();
1018     if (programSource.is8Bit()) {
1019         LiteralParser<LChar> literalParser(callFrame, programSource.characters8(), programSource.length(), JSONP);
1020         parseResult = literalParser.tryJSONPParse(JSONPData, scopeChain->globalObject->globalObjectMethodTable()->supportsRichSourceInfo(scopeChain->globalObject.get()));
1021     } else {
1022         LiteralParser<UChar> literalParser(callFrame, programSource.characters16(), programSource.length(), JSONP);
1023         parseResult = literalParser.tryJSONPParse(JSONPData, scopeChain->globalObject->globalObjectMethodTable()->supportsRichSourceInfo(scopeChain->globalObject.get()));
1024     }
1025
1026     if (parseResult) {
1027         JSGlobalObject* globalObject = scopeChain->globalObject.get();
1028         JSValue result;
1029         for (unsigned entry = 0; entry < JSONPData.size(); entry++) {
1030             Vector<JSONPPathEntry> JSONPPath;
1031             JSONPPath.swap(JSONPData[entry].m_path);
1032             JSValue JSONPValue = JSONPData[entry].m_value.get();
1033             if (JSONPPath.size() == 1 && JSONPPath[0].m_type == JSONPPathEntryTypeDeclare) {
1034                 if (globalObject->hasProperty(callFrame, JSONPPath[0].m_pathEntryName)) {
1035                     PutPropertySlot slot;
1036                     globalObject->methodTable()->put(globalObject, callFrame, JSONPPath[0].m_pathEntryName, JSONPValue, slot);
1037                 } else
1038                     globalObject->methodTable()->putDirectVirtual(globalObject, callFrame, JSONPPath[0].m_pathEntryName, JSONPValue, DontEnum | DontDelete);
1039                 // var declarations return undefined
1040                 result = jsUndefined();
1041                 continue;
1042             }
1043             JSValue baseObject(globalObject);
1044             for (unsigned i = 0; i < JSONPPath.size() - 1; i++) {
1045                 ASSERT(JSONPPath[i].m_type != JSONPPathEntryTypeDeclare);
1046                 switch (JSONPPath[i].m_type) {
1047                 case JSONPPathEntryTypeDot: {
1048                     if (i == 0) {
1049                         PropertySlot slot(globalObject);
1050                         if (!globalObject->getPropertySlot(callFrame, JSONPPath[i].m_pathEntryName, slot)) {
1051                             if (entry)
1052                                 return throwError(callFrame, createUndefinedVariableError(globalObject->globalExec(), JSONPPath[i].m_pathEntryName));
1053                             goto failedJSONP;
1054                         }
1055                         baseObject = slot.getValue(callFrame, JSONPPath[i].m_pathEntryName);
1056                     } else
1057                         baseObject = baseObject.get(callFrame, JSONPPath[i].m_pathEntryName);
1058                     if (callFrame->hadException())
1059                         return jsUndefined();
1060                     continue;
1061                 }
1062                 case JSONPPathEntryTypeLookup: {
1063                     baseObject = baseObject.get(callFrame, JSONPPath[i].m_pathIndex);
1064                     if (callFrame->hadException())
1065                         return jsUndefined();
1066                     continue;
1067                 }
1068                 default:
1069                     ASSERT_NOT_REACHED();
1070                     return jsUndefined();
1071                 }
1072             }
1073             PutPropertySlot slot;
1074             switch (JSONPPath.last().m_type) {
1075             case JSONPPathEntryTypeCall: {
1076                 JSValue function = baseObject.get(callFrame, JSONPPath.last().m_pathEntryName);
1077                 if (callFrame->hadException())
1078                     return jsUndefined();
1079                 CallData callData;
1080                 CallType callType = getCallData(function, callData);
1081                 if (callType == CallTypeNone)
1082                     return throwError(callFrame, createNotAFunctionError(callFrame, function));
1083                 MarkedArgumentBuffer jsonArg;
1084                 jsonArg.append(JSONPValue);
1085                 JSValue thisValue = JSONPPath.size() == 1 ? jsUndefined(): baseObject;
1086                 JSONPValue = JSC::call(callFrame, function, callType, callData, thisValue, jsonArg);
1087                 if (callFrame->hadException())
1088                     return jsUndefined();
1089                 break;
1090             }
1091             case JSONPPathEntryTypeDot: {
1092                 baseObject.put(callFrame, JSONPPath.last().m_pathEntryName, JSONPValue, slot);
1093                 if (callFrame->hadException())
1094                     return jsUndefined();
1095                 break;
1096             }
1097             case JSONPPathEntryTypeLookup: {
1098                 baseObject.put(callFrame, JSONPPath.last().m_pathIndex, JSONPValue);
1099                 if (callFrame->hadException())
1100                     return jsUndefined();
1101                 break;
1102             }
1103             default:
1104                 ASSERT_NOT_REACHED();
1105                     return jsUndefined();
1106             }
1107             result = JSONPValue;
1108         }
1109         return result;
1110     }
1111 failedJSONP:
1112     JSObject* error = program->compile(callFrame, scopeChain);
1113     if (error)
1114         return checkedReturn(throwError(callFrame, error));
1115     CodeBlock* codeBlock = &program->generatedBytecode();
1116
1117     Register* oldEnd = m_registerFile.end();
1118     Register* newEnd = oldEnd + codeBlock->numParameters() + RegisterFile::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters;
1119     if (!m_registerFile.grow(newEnd))
1120         return checkedReturn(throwStackOverflowError(callFrame));
1121
1122     CallFrame* newCallFrame = CallFrame::create(oldEnd + codeBlock->numParameters() + RegisterFile::CallFrameHeaderSize);
1123     ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
1124     newCallFrame->init(codeBlock, 0, scopeChain, CallFrame::noCaller(), codeBlock->numParameters(), 0);
1125     newCallFrame->setThisValue(thisObj);
1126     TopCallFrameSetter topCallFrame(callFrame->globalData(), newCallFrame);
1127
1128     Profiler** profiler = Profiler::enabledProfilerReference();
1129     if (*profiler)
1130         (*profiler)->willExecute(callFrame, program->sourceURL(), program->lineNo());
1131
1132     JSValue result;
1133     {
1134         SamplingTool::CallRecord callRecord(m_sampler.get());
1135
1136         m_reentryDepth++;  
1137 #if ENABLE(JIT)
1138         if (callFrame->globalData().canUseJIT())
1139             result = program->generatedJITCode().execute(&m_registerFile, newCallFrame, scopeChain->globalData);
1140         else
1141 #endif
1142             result = privateExecute(Normal, &m_registerFile, newCallFrame);
1143
1144         m_reentryDepth--;
1145     }
1146
1147     if (*profiler)
1148         (*profiler)->didExecute(callFrame, program->sourceURL(), program->lineNo());
1149
1150     m_registerFile.shrink(oldEnd);
1151
1152     return checkedReturn(result);
1153 }
1154
1155 JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args)
1156 {
1157     ASSERT(isValidThisObject(thisValue, callFrame));
1158     ASSERT(!callFrame->hadException());
1159     ASSERT(!callFrame->globalData().isCollectorBusy());
1160     if (callFrame->globalData().isCollectorBusy())
1161         return jsNull();
1162
1163     if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth)
1164         return checkedReturn(throwStackOverflowError(callFrame));
1165
1166     Register* oldEnd = m_registerFile.end();
1167     int argCount = 1 + args.size(); // implicit "this" parameter
1168     size_t registerOffset = argCount + RegisterFile::CallFrameHeaderSize;
1169
1170     CallFrame* newCallFrame = CallFrame::create(oldEnd + registerOffset);
1171     if (!m_registerFile.grow(newCallFrame->registers()))
1172         return checkedReturn(throwStackOverflowError(callFrame));
1173
1174     newCallFrame->setThisValue(thisValue);
1175     for (size_t i = 0; i < args.size(); ++i)
1176         newCallFrame->setArgument(i, args.at(i));
1177
1178     if (callType == CallTypeJS) {
1179         ScopeChainNode* callDataScopeChain = callData.js.scopeChain;
1180
1181         DynamicGlobalObjectScope globalObjectScope(*callDataScopeChain->globalData, callDataScopeChain->globalObject.get());
1182
1183         JSObject* compileError = callData.js.functionExecutable->compileForCall(callFrame, callDataScopeChain);
1184         if (UNLIKELY(!!compileError)) {
1185             m_registerFile.shrink(oldEnd);
1186             return checkedReturn(throwError(callFrame, compileError));
1187         }
1188
1189         CodeBlock* newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall();
1190         newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_registerFile, newCallFrame, 0, argCount);
1191         if (UNLIKELY(!newCallFrame)) {
1192             m_registerFile.shrink(oldEnd);
1193             return checkedReturn(throwStackOverflowError(callFrame));
1194         }
1195
1196         newCallFrame->init(newCodeBlock, 0, callDataScopeChain, callFrame->addHostCallFrameFlag(), argCount, function);
1197
1198         TopCallFrameSetter topCallFrame(callFrame->globalData(), newCallFrame);
1199
1200         Profiler** profiler = Profiler::enabledProfilerReference();
1201         if (*profiler)
1202             (*profiler)->willExecute(callFrame, function);
1203
1204         JSValue result;
1205         {
1206             SamplingTool::CallRecord callRecord(m_sampler.get());
1207
1208             m_reentryDepth++;  
1209 #if ENABLE(JIT)
1210             if (callFrame->globalData().canUseJIT())
1211                 result = callData.js.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, newCallFrame, callDataScopeChain->globalData);
1212             else
1213 #endif
1214                 result = privateExecute(Normal, &m_registerFile, newCallFrame);
1215             m_reentryDepth--;
1216         }
1217
1218         if (*profiler)
1219             (*profiler)->didExecute(callFrame, function);
1220
1221         m_registerFile.shrink(oldEnd);
1222         return checkedReturn(result);
1223     }
1224
1225     ASSERT(callType == CallTypeHost);
1226     ScopeChainNode* scopeChain = callFrame->scopeChain();
1227     newCallFrame->init(0, 0, scopeChain, callFrame->addHostCallFrameFlag(), argCount, function);
1228
1229     TopCallFrameSetter topCallFrame(callFrame->globalData(), newCallFrame);
1230
1231     DynamicGlobalObjectScope globalObjectScope(*scopeChain->globalData, scopeChain->globalObject.get());
1232
1233     Profiler** profiler = Profiler::enabledProfilerReference();
1234     if (*profiler)
1235         (*profiler)->willExecute(callFrame, function);
1236
1237     JSValue result;
1238     {
1239         SamplingTool::HostCallRecord callRecord(m_sampler.get());
1240         result = JSValue::decode(callData.native.function(newCallFrame));
1241     }
1242
1243     if (*profiler)
1244         (*profiler)->didExecute(callFrame, function);
1245
1246     m_registerFile.shrink(oldEnd);
1247     return checkedReturn(result);
1248 }
1249
1250 JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* constructor, ConstructType constructType, const ConstructData& constructData, const ArgList& args)
1251 {
1252     ASSERT(!callFrame->hadException());
1253     ASSERT(!callFrame->globalData().isCollectorBusy());
1254     // We throw in this case because we have to return something "valid" but we're
1255     // already in an invalid state.
1256     if (callFrame->globalData().isCollectorBusy())
1257         return checkedReturn(throwStackOverflowError(callFrame));
1258
1259     if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth)
1260         return checkedReturn(throwStackOverflowError(callFrame));
1261
1262     Register* oldEnd = m_registerFile.end();
1263     int argCount = 1 + args.size(); // implicit "this" parameter
1264     size_t registerOffset = argCount + RegisterFile::CallFrameHeaderSize;
1265
1266     if (!m_registerFile.grow(oldEnd + registerOffset))
1267         return checkedReturn(throwStackOverflowError(callFrame));
1268
1269     CallFrame* newCallFrame = CallFrame::create(oldEnd + registerOffset);
1270     newCallFrame->setThisValue(jsUndefined());
1271     for (size_t i = 0; i < args.size(); ++i)
1272         newCallFrame->setArgument(i, args.at(i));
1273
1274     if (constructType == ConstructTypeJS) {
1275         ScopeChainNode* constructDataScopeChain = constructData.js.scopeChain;
1276
1277         DynamicGlobalObjectScope globalObjectScope(*constructDataScopeChain->globalData, constructDataScopeChain->globalObject.get());
1278
1279         JSObject* compileError = constructData.js.functionExecutable->compileForConstruct(callFrame, constructDataScopeChain);
1280         if (UNLIKELY(!!compileError)) {
1281             m_registerFile.shrink(oldEnd);
1282             return checkedReturn(throwError(callFrame, compileError));
1283         }
1284
1285         CodeBlock* newCodeBlock = &constructData.js.functionExecutable->generatedBytecodeForConstruct();
1286         newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_registerFile, newCallFrame, 0, argCount);
1287         if (UNLIKELY(!newCallFrame)) {
1288             m_registerFile.shrink(oldEnd);
1289             return checkedReturn(throwStackOverflowError(callFrame));
1290         }
1291
1292         newCallFrame->init(newCodeBlock, 0, constructDataScopeChain, callFrame->addHostCallFrameFlag(), argCount, constructor);
1293
1294         TopCallFrameSetter topCallFrame(callFrame->globalData(), newCallFrame);
1295
1296         Profiler** profiler = Profiler::enabledProfilerReference();
1297         if (*profiler)
1298             (*profiler)->willExecute(callFrame, constructor);
1299
1300         JSValue result;
1301         {
1302             SamplingTool::CallRecord callRecord(m_sampler.get());
1303
1304             m_reentryDepth++;  
1305 #if ENABLE(JIT)
1306             if (callFrame->globalData().canUseJIT())
1307                 result = constructData.js.functionExecutable->generatedJITCodeForConstruct().execute(&m_registerFile, newCallFrame, constructDataScopeChain->globalData);
1308             else
1309 #endif
1310                 result = privateExecute(Normal, &m_registerFile, newCallFrame);
1311             m_reentryDepth--;
1312         }
1313
1314         if (*profiler)
1315             (*profiler)->didExecute(callFrame, constructor);
1316
1317         m_registerFile.shrink(oldEnd);
1318         if (callFrame->hadException())
1319             return 0;
1320         ASSERT(result.isObject());
1321         return checkedReturn(asObject(result));
1322     }
1323
1324     ASSERT(constructType == ConstructTypeHost);
1325     ScopeChainNode* scopeChain = callFrame->scopeChain();
1326     newCallFrame->init(0, 0, scopeChain, callFrame->addHostCallFrameFlag(), argCount, constructor);
1327
1328     TopCallFrameSetter topCallFrame(callFrame->globalData(), newCallFrame);
1329
1330     DynamicGlobalObjectScope globalObjectScope(*scopeChain->globalData, scopeChain->globalObject.get());
1331
1332     Profiler** profiler = Profiler::enabledProfilerReference();
1333     if (*profiler)
1334         (*profiler)->willExecute(callFrame, constructor);
1335
1336     JSValue result;
1337     {
1338         SamplingTool::HostCallRecord callRecord(m_sampler.get());
1339         result = JSValue::decode(constructData.native.function(newCallFrame));
1340     }
1341
1342     if (*profiler)
1343         (*profiler)->didExecute(callFrame, constructor);
1344
1345     m_registerFile.shrink(oldEnd);
1346     if (callFrame->hadException())
1347         return 0;
1348     ASSERT(result.isObject());
1349     return checkedReturn(asObject(result));
1350 }
1351
1352 CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionExecutable, CallFrame* callFrame, JSFunction* function, int argumentCountIncludingThis, ScopeChainNode* scopeChain)
1353 {
1354     ASSERT(!scopeChain->globalData->exception);
1355     
1356     if (callFrame->globalData().isCollectorBusy())
1357         return CallFrameClosure();
1358
1359     if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth) {
1360         throwStackOverflowError(callFrame);
1361         return CallFrameClosure();
1362     }
1363
1364     Register* oldEnd = m_registerFile.end();
1365     size_t registerOffset = argumentCountIncludingThis + RegisterFile::CallFrameHeaderSize;
1366
1367     CallFrame* newCallFrame = CallFrame::create(oldEnd + registerOffset);
1368     if (!m_registerFile.grow(newCallFrame->registers())) {
1369         throwStackOverflowError(callFrame);
1370         return CallFrameClosure();
1371     }
1372
1373     JSObject* error = functionExecutable->compileForCall(callFrame, scopeChain);
1374     if (error) {
1375         throwError(callFrame, error);
1376         m_registerFile.shrink(oldEnd);
1377         return CallFrameClosure();
1378     }
1379     CodeBlock* codeBlock = &functionExecutable->generatedBytecodeForCall();
1380
1381     newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, 0, argumentCountIncludingThis);
1382     if (UNLIKELY(!newCallFrame)) {
1383         throwStackOverflowError(callFrame);
1384         m_registerFile.shrink(oldEnd);
1385         return CallFrameClosure();
1386     }
1387     newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), argumentCountIncludingThis, function);  
1388     scopeChain->globalData->topCallFrame = newCallFrame;
1389     CallFrameClosure result = { callFrame, newCallFrame, function, functionExecutable, scopeChain->globalData, oldEnd, scopeChain, codeBlock->numParameters(), argumentCountIncludingThis };
1390     return result;
1391 }
1392
1393 JSValue Interpreter::execute(CallFrameClosure& closure) 
1394 {
1395     ASSERT(!closure.oldCallFrame->globalData().isCollectorBusy());
1396     if (closure.oldCallFrame->globalData().isCollectorBusy())
1397         return jsNull();
1398     closure.resetCallFrame();
1399     Profiler** profiler = Profiler::enabledProfilerReference();
1400     if (*profiler)
1401         (*profiler)->willExecute(closure.oldCallFrame, closure.function);
1402
1403     TopCallFrameSetter topCallFrame(*closure.globalData, closure.newCallFrame);
1404
1405     JSValue result;
1406     {
1407         SamplingTool::CallRecord callRecord(m_sampler.get());
1408         
1409         m_reentryDepth++;  
1410 #if ENABLE(JIT)
1411 #if ENABLE(CLASSIC_INTERPRETER)
1412         if (closure.newCallFrame->globalData().canUseJIT())
1413 #endif
1414             result = closure.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, closure.newCallFrame, closure.globalData);
1415 #if ENABLE(CLASSIC_INTERPRETER)
1416         else
1417 #endif
1418 #endif
1419 #if ENABLE(CLASSIC_INTERPRETER)
1420             result = privateExecute(Normal, &m_registerFile, closure.newCallFrame);
1421 #endif
1422         m_reentryDepth--;
1423     }
1424
1425     if (*profiler)
1426         (*profiler)->didExecute(closure.oldCallFrame, closure.function);
1427     return checkedReturn(result);
1428 }
1429
1430 void Interpreter::endRepeatCall(CallFrameClosure& closure)
1431 {
1432     closure.globalData->topCallFrame = closure.oldCallFrame;
1433     m_registerFile.shrink(closure.oldEnd);
1434 }
1435
1436 JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue thisValue, ScopeChainNode* scopeChain, int globalRegisterOffset)
1437 {
1438     ASSERT(isValidThisObject(thisValue, callFrame));
1439     ASSERT(!scopeChain->globalData->exception);
1440     ASSERT(!callFrame->globalData().isCollectorBusy());
1441     if (callFrame->globalData().isCollectorBusy())
1442         return jsNull();
1443
1444     DynamicGlobalObjectScope globalObjectScope(*scopeChain->globalData, scopeChain->globalObject.get());
1445
1446     if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth)
1447         return checkedReturn(throwStackOverflowError(callFrame));
1448
1449     JSObject* compileError = eval->compile(callFrame, scopeChain);
1450     if (UNLIKELY(!!compileError))
1451         return checkedReturn(throwError(callFrame, compileError));
1452     EvalCodeBlock* codeBlock = &eval->generatedBytecode();
1453
1454     JSObject* variableObject;
1455     for (ScopeChainNode* node = scopeChain; ; node = node->next.get()) {
1456         ASSERT(node);
1457         if (node->object->isVariableObject() && !node->object->isStaticScopeObject()) {
1458             variableObject = static_cast<JSVariableObject*>(node->object.get());
1459             break;
1460         }
1461     }
1462
1463     unsigned numVariables = codeBlock->numVariables();
1464     int numFunctions = codeBlock->numberOfFunctionDecls();
1465     bool pushedScope = false;
1466     if (numVariables || numFunctions) {
1467         if (codeBlock->isStrictMode()) {
1468             variableObject = StrictEvalActivation::create(callFrame);
1469             scopeChain = scopeChain->push(variableObject);
1470             pushedScope = true;
1471         }
1472         // Scope for BatchedTransitionOptimizer
1473         BatchedTransitionOptimizer optimizer(callFrame->globalData(), variableObject);
1474
1475         for (unsigned i = 0; i < numVariables; ++i) {
1476             const Identifier& ident = codeBlock->variable(i);
1477             if (!variableObject->hasProperty(callFrame, ident)) {
1478                 PutPropertySlot slot;
1479                 variableObject->methodTable()->put(variableObject, callFrame, ident, jsUndefined(), slot);
1480             }
1481         }
1482
1483         for (int i = 0; i < numFunctions; ++i) {
1484             FunctionExecutable* function = codeBlock->functionDecl(i);
1485             PutPropertySlot slot;
1486             variableObject->methodTable()->put(variableObject, callFrame, function->name(), function->make(callFrame, scopeChain), slot);
1487         }
1488     }
1489
1490     Register* oldEnd = m_registerFile.end();
1491     Register* newEnd = m_registerFile.begin() + globalRegisterOffset + codeBlock->m_numCalleeRegisters;
1492     if (!m_registerFile.grow(newEnd)) {
1493         if (pushedScope)
1494             scopeChain->pop();
1495         return checkedReturn(throwStackOverflowError(callFrame));
1496     }
1497
1498     CallFrame* newCallFrame = CallFrame::create(m_registerFile.begin() + globalRegisterOffset);
1499
1500     ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
1501     newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), codeBlock->numParameters(), 0);
1502     newCallFrame->setThisValue(thisValue);
1503
1504     TopCallFrameSetter topCallFrame(callFrame->globalData(), newCallFrame);
1505
1506     Profiler** profiler = Profiler::enabledProfilerReference();
1507     if (*profiler)
1508         (*profiler)->willExecute(callFrame, eval->sourceURL(), eval->lineNo());
1509
1510     JSValue result;
1511     {
1512         SamplingTool::CallRecord callRecord(m_sampler.get());
1513
1514         m_reentryDepth++;
1515         
1516 #if ENABLE(JIT)
1517 #if ENABLE(CLASSIC_INTERPRETER)
1518         if (callFrame->globalData().canUseJIT())
1519 #endif
1520             result = eval->generatedJITCode().execute(&m_registerFile, newCallFrame, scopeChain->globalData);
1521 #if ENABLE(CLASSIC_INTERPRETER)
1522         else
1523 #endif
1524 #endif
1525 #if ENABLE(CLASSIC_INTERPRETER)
1526             result = privateExecute(Normal, &m_registerFile, newCallFrame);
1527 #endif
1528         m_reentryDepth--;
1529     }
1530
1531     if (*profiler)
1532         (*profiler)->didExecute(callFrame, eval->sourceURL(), eval->lineNo());
1533
1534     m_registerFile.shrink(oldEnd);
1535     if (pushedScope)
1536         scopeChain->pop();
1537     return checkedReturn(result);
1538 }
1539
1540 NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHookID, int firstLine, int lastLine)
1541 {
1542     Debugger* debugger = callFrame->dynamicGlobalObject()->debugger();
1543     if (!debugger)
1544         return;
1545
1546     switch (debugHookID) {
1547         case DidEnterCallFrame:
1548             debugger->callEvent(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine);
1549             return;
1550         case WillLeaveCallFrame:
1551             debugger->returnEvent(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine);
1552             return;
1553         case WillExecuteStatement:
1554             debugger->atStatement(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine);
1555             return;
1556         case WillExecuteProgram:
1557             debugger->willExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine);
1558             return;
1559         case DidExecuteProgram:
1560             debugger->didExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine);
1561             return;
1562         case DidReachBreakpoint:
1563             debugger->didReachBreakpoint(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine);
1564             return;
1565     }
1566 }
1567     
1568 #if ENABLE(CLASSIC_INTERPRETER)
1569 NEVER_INLINE ScopeChainNode* Interpreter::createExceptionScope(CallFrame* callFrame, const Instruction* vPC)
1570 {
1571     int dst = vPC[1].u.operand;
1572     CodeBlock* codeBlock = callFrame->codeBlock();
1573     Identifier& property = codeBlock->identifier(vPC[2].u.operand);
1574     JSValue value = callFrame->r(vPC[3].u.operand).jsValue();
1575     JSObject* scope = JSStaticScopeObject::create(callFrame, property, value, DontDelete);
1576     callFrame->uncheckedR(dst) = JSValue(scope);
1577
1578     return callFrame->scopeChain()->push(scope);
1579 }
1580
1581 NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValue baseValue, const PutPropertySlot& slot)
1582 {
1583     // Recursive invocation may already have specialized this instruction.
1584     if (vPC[0].u.opcode != getOpcode(op_put_by_id))
1585         return;
1586
1587     if (!baseValue.isCell())
1588         return;
1589
1590     // Uncacheable: give up.
1591     if (!slot.isCacheable()) {
1592         vPC[0] = getOpcode(op_put_by_id_generic);
1593         return;
1594     }
1595     
1596     JSCell* baseCell = baseValue.asCell();
1597     Structure* structure = baseCell->structure();
1598
1599     if (structure->isUncacheableDictionary() || structure->typeInfo().prohibitsPropertyCaching()) {
1600         vPC[0] = getOpcode(op_put_by_id_generic);
1601         return;
1602     }
1603
1604     // Cache miss: record Structure to compare against next time.
1605     Structure* lastStructure = vPC[4].u.structure.get();
1606     if (structure != lastStructure) {
1607         // First miss: record Structure to compare against next time.
1608         if (!lastStructure) {
1609             vPC[4].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), structure);
1610             return;
1611         }
1612
1613         // Second miss: give up.
1614         vPC[0] = getOpcode(op_put_by_id_generic);
1615         return;
1616     }
1617
1618     // Cache hit: Specialize instruction and ref Structures.
1619
1620     // If baseCell != slot.base(), then baseCell must be a proxy for another object.
1621     if (baseCell != slot.base()) {
1622         vPC[0] = getOpcode(op_put_by_id_generic);
1623         return;
1624     }
1625
1626     // Structure transition, cache transition info
1627     if (slot.type() == PutPropertySlot::NewProperty) {
1628         if (structure->isDictionary()) {
1629             vPC[0] = getOpcode(op_put_by_id_generic);
1630             return;
1631         }
1632
1633         // put_by_id_transition checks the prototype chain for setters.
1634         normalizePrototypeChain(callFrame, baseCell);
1635         JSCell* owner = codeBlock->ownerExecutable();
1636         JSGlobalData& globalData = callFrame->globalData();
1637         // Get the prototype here because the call to prototypeChain could cause a 
1638         // GC allocation, which we don't want to happen while we're in the middle of 
1639         // initializing the union.
1640         StructureChain* prototypeChain = structure->prototypeChain(callFrame);
1641         vPC[0] = getOpcode(op_put_by_id_transition);
1642         vPC[4].u.structure.set(globalData, owner, structure->previousID());
1643         vPC[5].u.structure.set(globalData, owner, structure);
1644         vPC[6].u.structureChain.set(callFrame->globalData(), codeBlock->ownerExecutable(), prototypeChain);
1645         ASSERT(vPC[6].u.structureChain);
1646         vPC[7] = slot.cachedOffset();
1647         return;
1648     }
1649
1650     vPC[0] = getOpcode(op_put_by_id_replace);
1651     vPC[5] = slot.cachedOffset();
1652 }
1653
1654 NEVER_INLINE void Interpreter::uncachePutByID(CodeBlock*, Instruction* vPC)
1655 {
1656     vPC[0] = getOpcode(op_put_by_id);
1657     vPC[4] = 0;
1658 }
1659
1660 NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot)
1661 {
1662     // Recursive invocation may already have specialized this instruction.
1663     if (vPC[0].u.opcode != getOpcode(op_get_by_id))
1664         return;
1665
1666     // FIXME: Cache property access for immediates.
1667     if (!baseValue.isCell()) {
1668         vPC[0] = getOpcode(op_get_by_id_generic);
1669         return;
1670     }
1671
1672     if (isJSArray(baseValue) && propertyName == callFrame->propertyNames().length) {
1673         vPC[0] = getOpcode(op_get_array_length);
1674         return;
1675     }
1676
1677     if (isJSString(baseValue) && propertyName == callFrame->propertyNames().length) {
1678         vPC[0] = getOpcode(op_get_string_length);
1679         return;
1680     }
1681
1682     // Uncacheable: give up.
1683     if (!slot.isCacheable()) {
1684         vPC[0] = getOpcode(op_get_by_id_generic);
1685         return;
1686     }
1687
1688     Structure* structure = baseValue.asCell()->structure();
1689
1690     if (structure->isUncacheableDictionary() || structure->typeInfo().prohibitsPropertyCaching()) {
1691         vPC[0] = getOpcode(op_get_by_id_generic);
1692         return;
1693     }
1694
1695     // Cache miss
1696     Structure* lastStructure = vPC[4].u.structure.get();
1697     if (structure != lastStructure) {
1698         // First miss: record Structure to compare against next time.
1699         if (!lastStructure) {
1700             vPC[4].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), structure);
1701             return;
1702         }
1703
1704         // Second miss: give up.
1705         vPC[0] = getOpcode(op_get_by_id_generic);
1706         return;
1707     }
1708
1709     // Cache hit: Specialize instruction and ref Structures.
1710
1711     if (slot.slotBase() == baseValue) {
1712         switch (slot.cachedPropertyType()) {
1713         case PropertySlot::Getter:
1714             vPC[0] = getOpcode(op_get_by_id_getter_self);
1715             vPC[5] = slot.cachedOffset();
1716             break;
1717         case PropertySlot::Custom:
1718             vPC[0] = getOpcode(op_get_by_id_custom_self);
1719             vPC[5] = slot.customGetter();
1720             break;
1721         default:
1722             vPC[0] = getOpcode(op_get_by_id_self);
1723             vPC[5] = slot.cachedOffset();
1724             break;
1725         }
1726         return;
1727     }
1728
1729     if (structure->isDictionary()) {
1730         vPC[0] = getOpcode(op_get_by_id_generic);
1731         return;
1732     }
1733
1734     if (slot.slotBase() == structure->prototypeForLookup(callFrame)) {
1735         ASSERT(slot.slotBase().isObject());
1736
1737         JSObject* baseObject = asObject(slot.slotBase());
1738         size_t offset = slot.cachedOffset();
1739
1740         // Since we're accessing a prototype in a loop, it's a good bet that it
1741         // should not be treated as a dictionary.
1742         if (baseObject->structure()->isDictionary()) {
1743             baseObject->flattenDictionaryObject(callFrame->globalData());
1744             offset = baseObject->structure()->get(callFrame->globalData(), propertyName);
1745         }
1746
1747         ASSERT(!baseObject->structure()->isUncacheableDictionary());
1748         
1749         switch (slot.cachedPropertyType()) {
1750         case PropertySlot::Getter:
1751             vPC[0] = getOpcode(op_get_by_id_getter_proto);
1752             vPC[6] = offset;
1753             break;
1754         case PropertySlot::Custom:
1755             vPC[0] = getOpcode(op_get_by_id_custom_proto);
1756             vPC[6] = slot.customGetter();
1757             break;
1758         default:
1759             vPC[0] = getOpcode(op_get_by_id_proto);
1760             vPC[6] = offset;
1761             break;
1762         }
1763         vPC[5].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), baseObject->structure());
1764         return;
1765     }
1766
1767     size_t offset = slot.cachedOffset();
1768     size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset);
1769     if (!count) {
1770         vPC[0] = getOpcode(op_get_by_id_generic);
1771         return;
1772     }
1773
1774     
1775     switch (slot.cachedPropertyType()) {
1776     case PropertySlot::Getter:
1777         vPC[0] = getOpcode(op_get_by_id_getter_chain);
1778         vPC[7] = offset;
1779         break;
1780     case PropertySlot::Custom:
1781         vPC[0] = getOpcode(op_get_by_id_custom_chain);
1782         vPC[7] = slot.customGetter();
1783         break;
1784     default:
1785         vPC[0] = getOpcode(op_get_by_id_chain);
1786         vPC[7] = offset;
1787         break;
1788     }
1789     vPC[4].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), structure);
1790     vPC[5].u.structureChain.set(callFrame->globalData(), codeBlock->ownerExecutable(), structure->prototypeChain(callFrame));
1791     vPC[6] = count;
1792 }
1793
1794 NEVER_INLINE void Interpreter::uncacheGetByID(CodeBlock*, Instruction* vPC)
1795 {
1796     vPC[0] = getOpcode(op_get_by_id);
1797     vPC[4] = 0;
1798 }
1799
1800 #endif // ENABLE(CLASSIC_INTERPRETER)
1801
1802 JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFile, CallFrame* callFrame)
1803 {
1804     // One-time initialization of our address tables. We have to put this code
1805     // here because our labels are only in scope inside this function.
1806     if (UNLIKELY(flag == InitializeAndReturn)) {
1807         #if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
1808             #define LIST_OPCODE_LABEL(id, length) &&id,
1809                 static Opcode labels[] = { FOR_EACH_OPCODE_ID(LIST_OPCODE_LABEL) };
1810                 for (size_t i = 0; i < WTF_ARRAY_LENGTH(labels); ++i)
1811                     m_opcodeTable[i] = labels[i];
1812             #undef LIST_OPCODE_LABEL
1813         #endif // ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
1814         return JSValue();
1815     }
1816     
1817     ASSERT(m_initialized);
1818     ASSERT(m_enabled);
1819     
1820 #if ENABLE(JIT)
1821 #if ENABLE(CLASSIC_INTERPRETER)
1822     // Mixing Interpreter + JIT is not supported.
1823     if (callFrame->globalData().canUseJIT())
1824 #endif
1825         ASSERT_NOT_REACHED();
1826 #endif
1827
1828 #if !ENABLE(CLASSIC_INTERPRETER)
1829     UNUSED_PARAM(registerFile);
1830     UNUSED_PARAM(callFrame);
1831     return JSValue();
1832 #else
1833
1834     ASSERT(callFrame->globalData().topCallFrame == callFrame);
1835
1836     JSGlobalData* globalData = &callFrame->globalData();
1837     JSValue exceptionValue;
1838     HandlerInfo* handler = 0;
1839     CallFrame** topCallFrameSlot = &globalData->topCallFrame;
1840
1841     CodeBlock* codeBlock = callFrame->codeBlock();
1842     Instruction* vPC = codeBlock->instructions().begin();
1843     Profiler** enabledProfilerReference = Profiler::enabledProfilerReference();
1844     unsigned tickCount = globalData->timeoutChecker.ticksUntilNextCheck();
1845     JSValue functionReturnValue;
1846
1847 #define CHECK_FOR_EXCEPTION() \
1848     do { \
1849         if (UNLIKELY(globalData->exception != JSValue())) { \
1850             exceptionValue = globalData->exception; \
1851             goto vm_throw; \
1852         } \
1853     } while (0)
1854
1855 #if ENABLE(OPCODE_STATS)
1856     OpcodeStats::resetLastInstruction();
1857 #endif
1858
1859 #define CHECK_FOR_TIMEOUT() \
1860     if (!--tickCount) { \
1861         if (globalData->terminator.shouldTerminate() || globalData->timeoutChecker.didTimeOut(callFrame)) { \
1862             exceptionValue = jsNull(); \
1863             goto vm_throw; \
1864         } \
1865         tickCount = globalData->timeoutChecker.ticksUntilNextCheck(); \
1866     }
1867     
1868 #if ENABLE(OPCODE_SAMPLING)
1869     #define SAMPLE(codeBlock, vPC) m_sampler->sample(codeBlock, vPC)
1870 #else
1871     #define SAMPLE(codeBlock, vPC)
1872 #endif
1873
1874 #define UPDATE_BYTECODE_OFFSET() \
1875     do {\
1876         callFrame->setBytecodeOffsetForNonDFGCode(vPC - codeBlock->instructions().data() + 1);\
1877     } while (0)
1878
1879 #if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER)
1880     #define NEXT_INSTRUCTION() SAMPLE(codeBlock, vPC); goto *vPC->u.opcode
1881 #if ENABLE(OPCODE_STATS)
1882     #define DEFINE_OPCODE(opcode) \
1883         opcode:\
1884             OpcodeStats::recordInstruction(opcode);\
1885             UPDATE_BYTECODE_OFFSET();
1886 #else
1887     #define DEFINE_OPCODE(opcode) opcode: UPDATE_BYTECODE_OFFSET();
1888 #endif
1889     NEXT_INSTRUCTION();
1890 #else
1891     #define NEXT_INSTRUCTION() SAMPLE(codeBlock, vPC); goto interpreterLoopStart
1892 #if ENABLE(OPCODE_STATS)
1893     #define DEFINE_OPCODE(opcode) \
1894         case opcode:\
1895             OpcodeStats::recordInstruction(opcode);\
1896             UPDATE_BYTECODE_OFFSET();
1897 #else
1898     #define DEFINE_OPCODE(opcode) case opcode: UPDATE_BYTECODE_OFFSET();
1899 #endif
1900     while (1) { // iterator loop begins
1901     interpreterLoopStart:;
1902     switch (vPC->u.opcode)
1903 #endif
1904     {
1905     DEFINE_OPCODE(op_new_object) {
1906         /* new_object dst(r)
1907
1908            Constructs a new empty Object instance using the original
1909            constructor, and puts the result in register dst.
1910         */
1911         int dst = vPC[1].u.operand;
1912         callFrame->uncheckedR(dst) = JSValue(constructEmptyObject(callFrame));
1913
1914         vPC += OPCODE_LENGTH(op_new_object);
1915         NEXT_INSTRUCTION();
1916     }
1917     DEFINE_OPCODE(op_new_array) {
1918         /* new_array dst(r) firstArg(r) argCount(n)
1919
1920            Constructs a new Array instance using the original
1921            constructor, and puts the result in register dst.
1922            The array will contain argCount elements with values
1923            taken from registers starting at register firstArg.
1924         */
1925         int dst = vPC[1].u.operand;
1926         int firstArg = vPC[2].u.operand;
1927         int argCount = vPC[3].u.operand;
1928         callFrame->uncheckedR(dst) = JSValue(constructArray(callFrame, reinterpret_cast<JSValue*>(&callFrame->registers()[firstArg]), argCount));
1929
1930         vPC += OPCODE_LENGTH(op_new_array);
1931         NEXT_INSTRUCTION();
1932     }
1933     DEFINE_OPCODE(op_new_array_buffer) {
1934         /* new_array_buffer dst(r) index(n) argCount(n)
1935          
1936          Constructs a new Array instance using the original
1937          constructor, and puts the result in register dst.
1938          The array be initialized with the values from constantBuffer[index]
1939          */
1940         int dst = vPC[1].u.operand;
1941         int firstArg = vPC[2].u.operand;
1942         int argCount = vPC[3].u.operand;
1943         callFrame->uncheckedR(dst) = JSValue(constructArray(callFrame, codeBlock->constantBuffer(firstArg), argCount));
1944         
1945         vPC += OPCODE_LENGTH(op_new_array);
1946         NEXT_INSTRUCTION();
1947     }
1948     DEFINE_OPCODE(op_new_regexp) {
1949         /* new_regexp dst(r) regExp(re)
1950
1951            Constructs a new RegExp instance using the original
1952            constructor from regexp regExp, and puts the result in
1953            register dst.
1954         */
1955         int dst = vPC[1].u.operand;
1956         RegExp* regExp = codeBlock->regexp(vPC[2].u.operand);
1957         if (!regExp->isValid()) {
1958             exceptionValue = createSyntaxError(callFrame, "Invalid flags supplied to RegExp constructor.");
1959             goto vm_throw;
1960         }
1961         callFrame->uncheckedR(dst) = JSValue(RegExpObject::create(*globalData, callFrame->lexicalGlobalObject(), callFrame->scopeChain()->globalObject->regExpStructure(), regExp));
1962
1963         vPC += OPCODE_LENGTH(op_new_regexp);
1964         NEXT_INSTRUCTION();
1965     }
1966     DEFINE_OPCODE(op_mov) {
1967         /* mov dst(r) src(r)
1968
1969            Copies register src to register dst.
1970         */
1971         int dst = vPC[1].u.operand;
1972         int src = vPC[2].u.operand;
1973         
1974         callFrame->uncheckedR(dst) = callFrame->r(src);
1975
1976         vPC += OPCODE_LENGTH(op_mov);
1977         NEXT_INSTRUCTION();
1978     }
1979     DEFINE_OPCODE(op_eq) {
1980         /* eq dst(r) src1(r) src2(r)
1981
1982            Checks whether register src1 and register src2 are equal,
1983            as with the ECMAScript '==' operator, and puts the result
1984            as a boolean in register dst.
1985         */
1986         int dst = vPC[1].u.operand;
1987         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
1988         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
1989         if (src1.isInt32() && src2.isInt32())
1990             callFrame->uncheckedR(dst) = jsBoolean(src1.asInt32() == src2.asInt32());
1991         else {
1992             JSValue result = jsBoolean(JSValue::equalSlowCase(callFrame, src1, src2));
1993             CHECK_FOR_EXCEPTION();
1994             callFrame->uncheckedR(dst) = result;
1995         }
1996
1997         vPC += OPCODE_LENGTH(op_eq);
1998         NEXT_INSTRUCTION();
1999     }
2000     DEFINE_OPCODE(op_eq_null) {
2001         /* eq_null dst(r) src(r)
2002
2003            Checks whether register src is null, as with the ECMAScript '!='
2004            operator, and puts the result as a boolean in register dst.
2005         */
2006         int dst = vPC[1].u.operand;
2007         JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
2008
2009         if (src.isUndefinedOrNull()) {
2010             callFrame->uncheckedR(dst) = jsBoolean(true);
2011             vPC += OPCODE_LENGTH(op_eq_null);
2012             NEXT_INSTRUCTION();
2013         }
2014         
2015         callFrame->uncheckedR(dst) = jsBoolean(src.isCell() && src.asCell()->structure()->typeInfo().masqueradesAsUndefined());
2016         vPC += OPCODE_LENGTH(op_eq_null);
2017         NEXT_INSTRUCTION();
2018     }
2019     DEFINE_OPCODE(op_neq) {
2020         /* neq dst(r) src1(r) src2(r)
2021
2022            Checks whether register src1 and register src2 are not
2023            equal, as with the ECMAScript '!=' operator, and puts the
2024            result as a boolean in register dst.
2025         */
2026         int dst = vPC[1].u.operand;
2027         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
2028         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
2029         if (src1.isInt32() && src2.isInt32())
2030             callFrame->uncheckedR(dst) = jsBoolean(src1.asInt32() != src2.asInt32());
2031         else {
2032             JSValue result = jsBoolean(!JSValue::equalSlowCase(callFrame, src1, src2));
2033             CHECK_FOR_EXCEPTION();
2034             callFrame->uncheckedR(dst) = result;
2035         }
2036
2037         vPC += OPCODE_LENGTH(op_neq);
2038         NEXT_INSTRUCTION();
2039     }
2040     DEFINE_OPCODE(op_neq_null) {
2041         /* neq_null dst(r) src(r)
2042
2043            Checks whether register src is not null, as with the ECMAScript '!='
2044            operator, and puts the result as a boolean in register dst.
2045         */
2046         int dst = vPC[1].u.operand;
2047         JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
2048
2049         if (src.isUndefinedOrNull()) {
2050             callFrame->uncheckedR(dst) = jsBoolean(false);
2051             vPC += OPCODE_LENGTH(op_neq_null);
2052             NEXT_INSTRUCTION();
2053         }
2054         
2055         callFrame->uncheckedR(dst) = jsBoolean(!src.isCell() || !src.asCell()->structure()->typeInfo().masqueradesAsUndefined());
2056         vPC += OPCODE_LENGTH(op_neq_null);
2057         NEXT_INSTRUCTION();
2058     }
2059     DEFINE_OPCODE(op_stricteq) {
2060         /* stricteq dst(r) src1(r) src2(r)
2061
2062            Checks whether register src1 and register src2 are strictly
2063            equal, as with the ECMAScript '===' operator, and puts the
2064            result as a boolean in register dst.
2065         */
2066         int dst = vPC[1].u.operand;
2067         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
2068         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
2069         bool result = JSValue::strictEqual(callFrame, src1, src2);
2070         CHECK_FOR_EXCEPTION();
2071         callFrame->uncheckedR(dst) = jsBoolean(result);
2072
2073         vPC += OPCODE_LENGTH(op_stricteq);
2074         NEXT_INSTRUCTION();
2075     }
2076     DEFINE_OPCODE(op_nstricteq) {
2077         /* nstricteq dst(r) src1(r) src2(r)
2078
2079            Checks whether register src1 and register src2 are not
2080            strictly equal, as with the ECMAScript '!==' operator, and
2081            puts the result as a boolean in register dst.
2082         */
2083         int dst = vPC[1].u.operand;
2084         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
2085         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
2086         bool result = !JSValue::strictEqual(callFrame, src1, src2);
2087         CHECK_FOR_EXCEPTION();
2088         callFrame->uncheckedR(dst) = jsBoolean(result);
2089
2090         vPC += OPCODE_LENGTH(op_nstricteq);
2091         NEXT_INSTRUCTION();
2092     }
2093     DEFINE_OPCODE(op_less) {
2094         /* less dst(r) src1(r) src2(r)
2095
2096            Checks whether register src1 is less than register src2, as
2097            with the ECMAScript '<' operator, and puts the result as
2098            a boolean in register dst.
2099         */
2100         int dst = vPC[1].u.operand;
2101         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
2102         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
2103         JSValue result = jsBoolean(jsLess<true>(callFrame, src1, src2));
2104         CHECK_FOR_EXCEPTION();
2105         callFrame->uncheckedR(dst) = result;
2106
2107         vPC += OPCODE_LENGTH(op_less);
2108         NEXT_INSTRUCTION();
2109     }
2110     DEFINE_OPCODE(op_lesseq) {
2111         /* lesseq dst(r) src1(r) src2(r)
2112
2113            Checks whether register src1 is less than or equal to
2114            register src2, as with the ECMAScript '<=' operator, and
2115            puts the result as a boolean in register dst.
2116         */
2117         int dst = vPC[1].u.operand;
2118         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
2119         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
2120         JSValue result = jsBoolean(jsLessEq<true>(callFrame, src1, src2));
2121         CHECK_FOR_EXCEPTION();
2122         callFrame->uncheckedR(dst) = result;
2123
2124         vPC += OPCODE_LENGTH(op_lesseq);
2125         NEXT_INSTRUCTION();
2126     }
2127     DEFINE_OPCODE(op_greater) {
2128         /* greater dst(r) src1(r) src2(r)
2129
2130            Checks whether register src1 is greater than register src2, as
2131            with the ECMAScript '>' operator, and puts the result as
2132            a boolean in register dst.
2133         */
2134         int dst = vPC[1].u.operand;
2135         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
2136         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
2137         JSValue result = jsBoolean(jsLess<false>(callFrame, src2, src1));
2138         CHECK_FOR_EXCEPTION();
2139         callFrame->uncheckedR(dst) = result;
2140
2141         vPC += OPCODE_LENGTH(op_greater);
2142         NEXT_INSTRUCTION();
2143     }
2144     DEFINE_OPCODE(op_greatereq) {
2145         /* greatereq dst(r) src1(r) src2(r)
2146
2147            Checks whether register src1 is greater than or equal to
2148            register src2, as with the ECMAScript '>=' operator, and
2149            puts the result as a boolean in register dst.
2150         */
2151         int dst = vPC[1].u.operand;
2152         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
2153         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
2154         JSValue result = jsBoolean(jsLessEq<false>(callFrame, src2, src1));
2155         CHECK_FOR_EXCEPTION();
2156         callFrame->uncheckedR(dst) = result;
2157
2158         vPC += OPCODE_LENGTH(op_greatereq);
2159         NEXT_INSTRUCTION();
2160     }
2161     DEFINE_OPCODE(op_pre_inc) {
2162         /* pre_inc srcDst(r)
2163
2164            Converts register srcDst to number, adds one, and puts the result
2165            back in register srcDst.
2166         */
2167         int srcDst = vPC[1].u.operand;
2168         JSValue v = callFrame->r(srcDst).jsValue();
2169         if (v.isInt32() && v.asInt32() < INT_MAX)
2170             callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() + 1);
2171         else {
2172             JSValue result = jsNumber(v.toNumber(callFrame) + 1);
2173             CHECK_FOR_EXCEPTION();
2174             callFrame->uncheckedR(srcDst) = result;
2175         }
2176
2177         vPC += OPCODE_LENGTH(op_pre_inc);
2178         NEXT_INSTRUCTION();
2179     }
2180     DEFINE_OPCODE(op_pre_dec) {
2181         /* pre_dec srcDst(r)
2182
2183            Converts register srcDst to number, subtracts one, and puts the result
2184            back in register srcDst.
2185         */
2186         int srcDst = vPC[1].u.operand;
2187         JSValue v = callFrame->r(srcDst).jsValue();
2188         if (v.isInt32() && v.asInt32() > INT_MIN)
2189             callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() - 1);
2190         else {
2191             JSValue result = jsNumber(v.toNumber(callFrame) - 1);
2192             CHECK_FOR_EXCEPTION();
2193             callFrame->uncheckedR(srcDst) = result;
2194         }
2195
2196         vPC += OPCODE_LENGTH(op_pre_dec);
2197         NEXT_INSTRUCTION();
2198     }
2199     DEFINE_OPCODE(op_post_inc) {
2200         /* post_inc dst(r) srcDst(r)
2201
2202            Converts register srcDst to number. The number itself is
2203            written to register dst, and the number plus one is written
2204            back to register srcDst.
2205         */
2206         int dst = vPC[1].u.operand;
2207         int srcDst = vPC[2].u.operand;
2208         JSValue v = callFrame->r(srcDst).jsValue();
2209         if (v.isInt32() && v.asInt32() < INT_MAX) {
2210             callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() + 1);
2211             callFrame->uncheckedR(dst) = v;
2212         } else {
2213             double number = callFrame->r(srcDst).jsValue().toNumber(callFrame);
2214             CHECK_FOR_EXCEPTION();
2215             callFrame->uncheckedR(srcDst) = jsNumber(number + 1);
2216             callFrame->uncheckedR(dst) = jsNumber(number);
2217         }
2218
2219         vPC += OPCODE_LENGTH(op_post_inc);
2220         NEXT_INSTRUCTION();
2221     }
2222     DEFINE_OPCODE(op_post_dec) {
2223         /* post_dec dst(r) srcDst(r)
2224
2225            Converts register srcDst to number. The number itself is
2226            written to register dst, and the number minus one is written
2227            back to register srcDst.
2228         */
2229         int dst = vPC[1].u.operand;
2230         int srcDst = vPC[2].u.operand;
2231         JSValue v = callFrame->r(srcDst).jsValue();
2232         if (v.isInt32() && v.asInt32() > INT_MIN) {
2233             callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() - 1);
2234             callFrame->uncheckedR(dst) = v;
2235         } else {
2236             double number = callFrame->r(srcDst).jsValue().toNumber(callFrame);
2237             CHECK_FOR_EXCEPTION();
2238             callFrame->uncheckedR(srcDst) = jsNumber(number - 1);
2239             callFrame->uncheckedR(dst) = jsNumber(number);
2240         }
2241
2242         vPC += OPCODE_LENGTH(op_post_dec);
2243         NEXT_INSTRUCTION();
2244     }
2245     DEFINE_OPCODE(op_to_jsnumber) {
2246         /* to_jsnumber dst(r) src(r)
2247
2248            Converts register src to number, and puts the result
2249            in register dst.
2250         */
2251         int dst = vPC[1].u.operand;
2252         int src = vPC[2].u.operand;
2253
2254         JSValue srcVal = callFrame->r(src).jsValue();
2255
2256         if (LIKELY(srcVal.isNumber()))
2257             callFrame->uncheckedR(dst) = callFrame->r(src);
2258         else {
2259             double number = srcVal.toNumber(callFrame);
2260             CHECK_FOR_EXCEPTION();
2261             callFrame->uncheckedR(dst) = jsNumber(number);
2262         }
2263
2264         vPC += OPCODE_LENGTH(op_to_jsnumber);
2265         NEXT_INSTRUCTION();
2266     }
2267     DEFINE_OPCODE(op_negate) {
2268         /* negate dst(r) src(r)
2269
2270            Converts register src to number, negates it, and puts the
2271            result in register dst.
2272         */
2273         int dst = vPC[1].u.operand;
2274         JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
2275         if (src.isInt32() && (src.asInt32() & 0x7fffffff)) // non-zero and no overflow
2276             callFrame->uncheckedR(dst) = jsNumber(-src.asInt32());
2277         else {
2278             JSValue result = jsNumber(-src.toNumber(callFrame));
2279             CHECK_FOR_EXCEPTION();
2280             callFrame->uncheckedR(dst) = result;
2281         }
2282
2283         vPC += OPCODE_LENGTH(op_negate);
2284         NEXT_INSTRUCTION();
2285     }
2286     DEFINE_OPCODE(op_add) {
2287         /* add dst(r) src1(r) src2(r)
2288
2289            Adds register src1 and register src2, and puts the result
2290            in register dst. (JS add may be string concatenation or
2291            numeric add, depending on the types of the operands.)
2292         */
2293         int dst = vPC[1].u.operand;
2294         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
2295         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
2296         if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | (src2.asInt32() & 0xc0000000))) // no overflow
2297             callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() + src2.asInt32());
2298         else {
2299             JSValue result = jsAdd(callFrame, src1, src2);
2300             CHECK_FOR_EXCEPTION();
2301             callFrame->uncheckedR(dst) = result;
2302         }
2303         vPC += OPCODE_LENGTH(op_add);
2304         NEXT_INSTRUCTION();
2305     }
2306     DEFINE_OPCODE(op_mul) {
2307         /* mul dst(r) src1(r) src2(r)
2308
2309            Multiplies register src1 and register src2 (converted to
2310            numbers), and puts the product in register dst.
2311         */
2312         int dst = vPC[1].u.operand;
2313         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
2314         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
2315         if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() >> 15)) // no overflow
2316                 callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() * src2.asInt32());
2317         else {
2318             JSValue result = jsNumber(src1.toNumber(callFrame) * src2.toNumber(callFrame));
2319             CHECK_FOR_EXCEPTION();
2320             callFrame->uncheckedR(dst) = result;
2321         }
2322
2323         vPC += OPCODE_LENGTH(op_mul);
2324         NEXT_INSTRUCTION();
2325     }
2326     DEFINE_OPCODE(op_div) {
2327         /* div dst(r) dividend(r) divisor(r)
2328
2329            Divides register dividend (converted to number) by the
2330            register divisor (converted to number), and puts the
2331            quotient in register dst.
2332         */
2333         int dst = vPC[1].u.operand;
2334         JSValue dividend = callFrame->r(vPC[2].u.operand).jsValue();
2335         JSValue divisor = callFrame->r(vPC[3].u.operand).jsValue();
2336
2337         JSValue result = jsNumber(dividend.toNumber(callFrame) / divisor.toNumber(callFrame));
2338         CHECK_FOR_EXCEPTION();
2339         callFrame->uncheckedR(dst) = result;
2340
2341         vPC += OPCODE_LENGTH(op_div);
2342         NEXT_INSTRUCTION();
2343     }
2344     DEFINE_OPCODE(op_mod) {
2345         /* mod dst(r) dividend(r) divisor(r)
2346
2347            Divides register dividend (converted to number) by
2348            register divisor (converted to number), and puts the
2349            remainder in register dst.
2350         */
2351         int dst = vPC[1].u.operand;
2352         JSValue dividend = callFrame->r(vPC[2].u.operand).jsValue();
2353         JSValue divisor = callFrame->r(vPC[3].u.operand).jsValue();
2354
2355         if (dividend.isInt32() && divisor.isInt32() && divisor.asInt32() != 0) {
2356             JSValue result = jsNumber(dividend.asInt32() % divisor.asInt32());
2357             ASSERT(result);
2358             callFrame->uncheckedR(dst) = result;
2359             vPC += OPCODE_LENGTH(op_mod);
2360             NEXT_INSTRUCTION();
2361         }
2362
2363         // Conversion to double must happen outside the call to fmod since the
2364         // order of argument evaluation is not guaranteed.
2365         double d1 = dividend.toNumber(callFrame);
2366         double d2 = divisor.toNumber(callFrame);
2367         JSValue result = jsNumber(fmod(d1, d2));
2368         CHECK_FOR_EXCEPTION();
2369         callFrame->uncheckedR(dst) = result;
2370         vPC += OPCODE_LENGTH(op_mod);
2371         NEXT_INSTRUCTION();
2372     }
2373     DEFINE_OPCODE(op_sub) {
2374         /* sub dst(r) src1(r) src2(r)
2375
2376            Subtracts register src2 (converted to number) from register
2377            src1 (converted to number), and puts the difference in
2378            register dst.
2379         */
2380         int dst = vPC[1].u.operand;
2381         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
2382         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
2383         if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | (src2.asInt32() & 0xc0000000))) // no overflow
2384             callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() - src2.asInt32());
2385         else {
2386             JSValue result = jsNumber(src1.toNumber(callFrame) - src2.toNumber(callFrame));
2387             CHECK_FOR_EXCEPTION();
2388             callFrame->uncheckedR(dst) = result;
2389         }
2390         vPC += OPCODE_LENGTH(op_sub);
2391         NEXT_INSTRUCTION();
2392     }
2393     DEFINE_OPCODE(op_lshift) {
2394         /* lshift dst(r) val(r) shift(r)
2395
2396            Performs left shift of register val (converted to int32) by
2397            register shift (converted to uint32), and puts the result
2398            in register dst.
2399         */
2400         int dst = vPC[1].u.operand;
2401         JSValue val = callFrame->r(vPC[2].u.operand).jsValue();
2402         JSValue shift = callFrame->r(vPC[3].u.operand).jsValue();
2403
2404         if (val.isInt32() && shift.isInt32())
2405             callFrame->uncheckedR(dst) = jsNumber(val.asInt32() << (shift.asInt32() & 0x1f));
2406         else {
2407             JSValue result = jsNumber((val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f));
2408             CHECK_FOR_EXCEPTION();
2409             callFrame->uncheckedR(dst) = result;
2410         }
2411
2412         vPC += OPCODE_LENGTH(op_lshift);
2413         NEXT_INSTRUCTION();
2414     }
2415     DEFINE_OPCODE(op_rshift) {
2416         /* rshift dst(r) val(r) shift(r)
2417
2418            Performs arithmetic right shift of register val (converted
2419            to int32) by register shift (converted to
2420            uint32), and puts the result in register dst.
2421         */
2422         int dst = vPC[1].u.operand;
2423         JSValue val = callFrame->r(vPC[2].u.operand).jsValue();
2424         JSValue shift = callFrame->r(vPC[3].u.operand).jsValue();
2425
2426         if (val.isInt32() && shift.isInt32())
2427             callFrame->uncheckedR(dst) = jsNumber(val.asInt32() >> (shift.asInt32() & 0x1f));
2428         else {
2429             JSValue result = jsNumber((val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
2430             CHECK_FOR_EXCEPTION();
2431             callFrame->uncheckedR(dst) = result;
2432         }
2433
2434         vPC += OPCODE_LENGTH(op_rshift);
2435         NEXT_INSTRUCTION();
2436     }
2437     DEFINE_OPCODE(op_urshift) {
2438         /* rshift dst(r) val(r) shift(r)
2439
2440            Performs logical right shift of register val (converted
2441            to uint32) by register shift (converted to
2442            uint32), and puts the result in register dst.
2443         */
2444         int dst = vPC[1].u.operand;
2445         JSValue val = callFrame->r(vPC[2].u.operand).jsValue();
2446         JSValue shift = callFrame->r(vPC[3].u.operand).jsValue();
2447         if (val.isUInt32() && shift.isInt32())
2448             callFrame->uncheckedR(dst) = jsNumber(val.asInt32() >> (shift.asInt32() & 0x1f));
2449         else {
2450             JSValue result = jsNumber((val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
2451             CHECK_FOR_EXCEPTION();
2452             callFrame->uncheckedR(dst) = result;
2453         }
2454
2455         vPC += OPCODE_LENGTH(op_urshift);
2456         NEXT_INSTRUCTION();
2457     }
2458     DEFINE_OPCODE(op_bitand) {
2459         /* bitand dst(r) src1(r) src2(r)
2460
2461            Computes bitwise AND of register src1 (converted to int32)
2462            and register src2 (converted to int32), and puts the result
2463            in register dst.
2464         */
2465         int dst = vPC[1].u.operand;
2466         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
2467         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
2468         if (src1.isInt32() && src2.isInt32())
2469             callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() & src2.asInt32());
2470         else {
2471             JSValue result = jsNumber(src1.toInt32(callFrame) & src2.toInt32(callFrame));
2472             CHECK_FOR_EXCEPTION();
2473             callFrame->uncheckedR(dst) = result;
2474         }
2475
2476         vPC += OPCODE_LENGTH(op_bitand);
2477         NEXT_INSTRUCTION();
2478     }
2479     DEFINE_OPCODE(op_bitxor) {
2480         /* bitxor dst(r) src1(r) src2(r)
2481
2482            Computes bitwise XOR of register src1 (converted to int32)
2483            and register src2 (converted to int32), and puts the result
2484            in register dst.
2485         */
2486         int dst = vPC[1].u.operand;
2487         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
2488         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
2489         if (src1.isInt32() && src2.isInt32())
2490             callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() ^ src2.asInt32());
2491         else {
2492             JSValue result = jsNumber(src1.toInt32(callFrame) ^ src2.toInt32(callFrame));
2493             CHECK_FOR_EXCEPTION();
2494             callFrame->uncheckedR(dst) = result;
2495         }
2496
2497         vPC += OPCODE_LENGTH(op_bitxor);
2498         NEXT_INSTRUCTION();
2499     }
2500     DEFINE_OPCODE(op_bitor) {
2501         /* bitor dst(r) src1(r) src2(r)
2502
2503            Computes bitwise OR of register src1 (converted to int32)
2504            and register src2 (converted to int32), and puts the
2505            result in register dst.
2506         */
2507         int dst = vPC[1].u.operand;
2508         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
2509         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
2510         if (src1.isInt32() && src2.isInt32())
2511             callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() | src2.asInt32());
2512         else {
2513             JSValue result = jsNumber(src1.toInt32(callFrame) | src2.toInt32(callFrame));
2514             CHECK_FOR_EXCEPTION();
2515             callFrame->uncheckedR(dst) = result;
2516         }
2517
2518         vPC += OPCODE_LENGTH(op_bitor);
2519         NEXT_INSTRUCTION();
2520     }
2521     DEFINE_OPCODE(op_bitnot) {
2522         /* bitnot dst(r) src(r)
2523
2524            Computes bitwise NOT of register src1 (converted to int32),
2525            and puts the result in register dst.
2526         */
2527         int dst = vPC[1].u.operand;
2528         JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
2529         if (src.isInt32())
2530             callFrame->uncheckedR(dst) = jsNumber(~src.asInt32());
2531         else {
2532             JSValue result = jsNumber(~src.toInt32(callFrame));
2533             CHECK_FOR_EXCEPTION();
2534             callFrame->uncheckedR(dst) = result;
2535         }
2536         vPC += OPCODE_LENGTH(op_bitnot);
2537         NEXT_INSTRUCTION();
2538     }
2539     DEFINE_OPCODE(op_not) {
2540         /* not dst(r) src(r)
2541
2542            Computes logical NOT of register src (converted to
2543            boolean), and puts the result in register dst.
2544         */
2545         int dst = vPC[1].u.operand;
2546         int src = vPC[2].u.operand;
2547         JSValue result = jsBoolean(!callFrame->r(src).jsValue().toBoolean(callFrame));
2548         CHECK_FOR_EXCEPTION();
2549         callFrame->uncheckedR(dst) = result;
2550
2551         vPC += OPCODE_LENGTH(op_not);
2552         NEXT_INSTRUCTION();
2553     }
2554     DEFINE_OPCODE(op_check_has_instance) {
2555         /* check_has_instance constructor(r)
2556
2557            Check 'constructor' is an object with the internal property
2558            [HasInstance] (i.e. is a function ... *shakes head sadly at
2559            JSC API*). Raises an exception if register constructor is not
2560            an valid parameter for instanceof.
2561         */
2562         int base = vPC[1].u.operand;
2563         JSValue baseVal = callFrame->r(base).jsValue();
2564
2565         if (isInvalidParamForInstanceOf(callFrame, baseVal, exceptionValue))
2566             goto vm_throw;
2567
2568         vPC += OPCODE_LENGTH(op_check_has_instance);
2569         NEXT_INSTRUCTION();
2570     }
2571     DEFINE_OPCODE(op_instanceof) {
2572         /* instanceof dst(r) value(r) constructor(r) constructorProto(r)
2573
2574            Tests whether register value is an instance of register
2575            constructor, and puts the boolean result in register
2576            dst. Register constructorProto must contain the "prototype"
2577            property (not the actual prototype) of the object in
2578            register constructor. This lookup is separated so that
2579            polymorphic inline caching can apply.
2580
2581            Raises an exception if register constructor is not an
2582            object.
2583         */
2584         int dst = vPC[1].u.operand;
2585         int value = vPC[2].u.operand;
2586         int base = vPC[3].u.operand;
2587         int baseProto = vPC[4].u.operand;
2588
2589         JSValue baseVal = callFrame->r(base).jsValue();
2590
2591         ASSERT(!isInvalidParamForInstanceOf(callFrame, baseVal, exceptionValue));
2592
2593         bool result = asObject(baseVal)->methodTable()->hasInstance(asObject(baseVal), callFrame, callFrame->r(value).jsValue(), callFrame->r(baseProto).jsValue());
2594         CHECK_FOR_EXCEPTION();
2595         callFrame->uncheckedR(dst) = jsBoolean(result);
2596
2597         vPC += OPCODE_LENGTH(op_instanceof);
2598         NEXT_INSTRUCTION();
2599     }
2600     DEFINE_OPCODE(op_typeof) {
2601         /* typeof dst(r) src(r)
2602
2603            Determines the type string for src according to ECMAScript
2604            rules, and puts the result in register dst.
2605         */
2606         int dst = vPC[1].u.operand;
2607         int src = vPC[2].u.operand;
2608         callFrame->uncheckedR(dst) = JSValue(jsTypeStringForValue(callFrame, callFrame->r(src).jsValue()));
2609
2610         vPC += OPCODE_LENGTH(op_typeof);
2611         NEXT_INSTRUCTION();
2612     }
2613     DEFINE_OPCODE(op_is_undefined) {
2614         /* is_undefined dst(r) src(r)
2615
2616            Determines whether the type string for src according to
2617            the ECMAScript rules is "undefined", and puts the result
2618            in register dst.
2619         */
2620         int dst = vPC[1].u.operand;
2621         int src = vPC[2].u.operand;
2622         JSValue v = callFrame->r(src).jsValue();
2623         callFrame->uncheckedR(dst) = jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined());
2624
2625         vPC += OPCODE_LENGTH(op_is_undefined);
2626         NEXT_INSTRUCTION();
2627     }
2628     DEFINE_OPCODE(op_is_boolean) {
2629         /* is_boolean dst(r) src(r)
2630
2631            Determines whether the type string for src according to
2632            the ECMAScript rules is "boolean", and puts the result
2633            in register dst.
2634         */
2635         int dst = vPC[1].u.operand;
2636         int src = vPC[2].u.operand;
2637         callFrame->uncheckedR(dst) = jsBoolean(callFrame->r(src).jsValue().isBoolean());
2638
2639         vPC += OPCODE_LENGTH(op_is_boolean);
2640         NEXT_INSTRUCTION();
2641     }
2642     DEFINE_OPCODE(op_is_number) {
2643         /* is_number dst(r) src(r)
2644
2645            Determines whether the type string for src according to
2646            the ECMAScript rules is "number", and puts the result
2647            in register dst.
2648         */
2649         int dst = vPC[1].u.operand;
2650         int src = vPC[2].u.operand;
2651         callFrame->uncheckedR(dst) = jsBoolean(callFrame->r(src).jsValue().isNumber());
2652
2653         vPC += OPCODE_LENGTH(op_is_number);
2654         NEXT_INSTRUCTION();
2655     }
2656     DEFINE_OPCODE(op_is_string) {
2657         /* is_string dst(r) src(r)
2658
2659            Determines whether the type string for src according to
2660            the ECMAScript rules is "string", and puts the result
2661            in register dst.
2662         */
2663         int dst = vPC[1].u.operand;
2664         int src = vPC[2].u.operand;
2665         callFrame->uncheckedR(dst) = jsBoolean(callFrame->r(src).jsValue().isString());
2666
2667         vPC += OPCODE_LENGTH(op_is_string);
2668         NEXT_INSTRUCTION();
2669     }
2670     DEFINE_OPCODE(op_is_object) {
2671         /* is_object dst(r) src(r)
2672
2673            Determines whether the type string for src according to
2674            the ECMAScript rules is "object", and puts the result
2675            in register dst.
2676         */
2677         int dst = vPC[1].u.operand;
2678         int src = vPC[2].u.operand;
2679         callFrame->uncheckedR(dst) = jsBoolean(jsIsObjectType(callFrame->r(src).jsValue()));
2680
2681         vPC += OPCODE_LENGTH(op_is_object);
2682         NEXT_INSTRUCTION();
2683     }
2684     DEFINE_OPCODE(op_is_function) {
2685         /* is_function dst(r) src(r)
2686
2687            Determines whether the type string for src according to
2688            the ECMAScript rules is "function", and puts the result
2689            in register dst.
2690         */
2691         int dst = vPC[1].u.operand;
2692         int src = vPC[2].u.operand;
2693         callFrame->uncheckedR(dst) = jsBoolean(jsIsFunctionType(callFrame->r(src).jsValue()));
2694
2695         vPC += OPCODE_LENGTH(op_is_function);
2696         NEXT_INSTRUCTION();
2697     }
2698     DEFINE_OPCODE(op_in) {
2699         /* in dst(r) property(r) base(r)
2700
2701            Tests whether register base has a property named register
2702            property, and puts the boolean result in register dst.
2703
2704            Raises an exception if register constructor is not an
2705            object.
2706         */
2707         int dst = vPC[1].u.operand;
2708         int property = vPC[2].u.operand;
2709         int base = vPC[3].u.operand;
2710
2711         JSValue baseVal = callFrame->r(base).jsValue();
2712         if (isInvalidParamForIn(callFrame, baseVal, exceptionValue))
2713             goto vm_throw;
2714
2715         JSObject* baseObj = asObject(baseVal);
2716
2717         JSValue propName = callFrame->r(property).jsValue();
2718
2719         uint32_t i;
2720         if (propName.getUInt32(i))
2721             callFrame->uncheckedR(dst) = jsBoolean(baseObj->hasProperty(callFrame, i));
2722         else {
2723             Identifier property(callFrame, propName.toString(callFrame)->value(callFrame));
2724             CHECK_FOR_EXCEPTION();
2725             callFrame->uncheckedR(dst) = jsBoolean(baseObj->hasProperty(callFrame, property));
2726         }
2727
2728         vPC += OPCODE_LENGTH(op_in);
2729         NEXT_INSTRUCTION();
2730     }
2731     DEFINE_OPCODE(op_resolve) {
2732         /* resolve dst(r) property(id)
2733
2734            Looks up the property named by identifier property in the
2735            scope chain, and writes the resulting value to register
2736            dst. If the property is not found, raises an exception.
2737         */
2738         if (UNLIKELY(!resolve(callFrame, vPC, exceptionValue)))
2739             goto vm_throw;
2740
2741         vPC += OPCODE_LENGTH(op_resolve);
2742         NEXT_INSTRUCTION();
2743     }
2744     DEFINE_OPCODE(op_resolve_skip) {
2745         /* resolve_skip dst(r) property(id) skip(n)
2746
2747          Looks up the property named by identifier property in the
2748          scope chain skipping the top 'skip' levels, and writes the resulting
2749          value to register dst. If the property is not found, raises an exception.
2750          */
2751         if (UNLIKELY(!resolveSkip(callFrame, vPC, exceptionValue)))
2752             goto vm_throw;
2753
2754         vPC += OPCODE_LENGTH(op_resolve_skip);
2755
2756         NEXT_INSTRUCTION();
2757     }
2758     DEFINE_OPCODE(op_resolve_global) {
2759         /* resolve_skip dst(r) globalObject(c) property(id) structure(sID) offset(n)
2760          
2761            Performs a dynamic property lookup for the given property, on the provided
2762            global object.  If structure matches the Structure of the global then perform
2763            a fast lookup using the case offset, otherwise fall back to a full resolve and
2764            cache the new structure and offset
2765          */
2766         if (UNLIKELY(!resolveGlobal(callFrame, vPC, exceptionValue)))
2767             goto vm_throw;
2768         
2769         vPC += OPCODE_LENGTH(op_resolve_global);
2770         
2771         NEXT_INSTRUCTION();
2772     }
2773     DEFINE_OPCODE(op_resolve_global_dynamic) {
2774         /* resolve_skip dst(r) globalObject(c) property(id) structure(sID) offset(n), depth(n)
2775          
2776          Performs a dynamic property lookup for the given property, on the provided
2777          global object.  If structure matches the Structure of the global then perform
2778          a fast lookup using the case offset, otherwise fall back to a full resolve and
2779          cache the new structure and offset.
2780          
2781          This walks through n levels of the scope chain to verify that none of those levels
2782          in the scope chain include dynamically added properties.
2783          */
2784         if (UNLIKELY(!resolveGlobalDynamic(callFrame, vPC, exceptionValue)))
2785             goto vm_throw;
2786         
2787         vPC += OPCODE_LENGTH(op_resolve_global_dynamic);
2788         
2789         NEXT_INSTRUCTION();
2790     }
2791     DEFINE_OPCODE(op_get_global_var) {
2792         /* get_global_var dst(r) globalObject(c) index(n)
2793
2794            Gets the global var at global slot index and places it in register dst.
2795          */
2796         int dst = vPC[1].u.operand;
2797         JSGlobalObject* scope = codeBlock->globalObject();
2798         ASSERT(scope->isGlobalObject());
2799         int index = vPC[2].u.operand;
2800
2801         callFrame->uncheckedR(dst) = scope->registerAt(index).get();
2802         vPC += OPCODE_LENGTH(op_get_global_var);
2803         NEXT_INSTRUCTION();
2804     }
2805     DEFINE_OPCODE(op_put_global_var) {
2806         /* put_global_var globalObject(c) index(n) value(r)
2807          
2808            Puts value into global slot index.
2809          */
2810         JSGlobalObject* scope = codeBlock->globalObject();
2811         ASSERT(scope->isGlobalObject());
2812         int index = vPC[1].u.operand;
2813         int value = vPC[2].u.operand;
2814         
2815         scope->registerAt(index).set(*globalData, scope, callFrame->r(value).jsValue());
2816         vPC += OPCODE_LENGTH(op_put_global_var);
2817         NEXT_INSTRUCTION();
2818     }
2819     DEFINE_OPCODE(op_get_scoped_var) {
2820         /* get_scoped_var dst(r) index(n) skip(n)
2821
2822          Loads the contents of the index-th local from the scope skip nodes from
2823          the top of the scope chain, and places it in register dst.
2824          */
2825         int dst = vPC[1].u.operand;
2826         int index = vPC[2].u.operand;
2827         int skip = vPC[3].u.operand;
2828
2829         ScopeChainNode* scopeChain = callFrame->scopeChain();
2830         ScopeChainIterator iter = scopeChain->begin();
2831         ScopeChainIterator end = scopeChain->end();
2832         ASSERT_UNUSED(end, iter != end);
2833         ASSERT(codeBlock == callFrame->codeBlock());
2834         bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain();
2835         ASSERT(skip || !checkTopLevel);
2836         if (checkTopLevel && skip--) {
2837             if (callFrame->r(codeBlock->activationRegister()).jsValue())
2838                 ++iter;
2839         }
2840         while (skip--) {
2841             ++iter;
2842             ASSERT_UNUSED(end, iter != end);
2843         }
2844         ASSERT((*iter)->isVariableObject());
2845         JSVariableObject* scope = static_cast<JSVariableObject*>(iter->get());
2846         callFrame->uncheckedR(dst) = scope->registerAt(index).get();
2847         ASSERT(callFrame->r(dst).jsValue());
2848         vPC += OPCODE_LENGTH(op_get_scoped_var);
2849         NEXT_INSTRUCTION();
2850     }
2851     DEFINE_OPCODE(op_put_scoped_var) {
2852         /* put_scoped_var index(n) skip(n) value(r)
2853
2854          */
2855         int index = vPC[1].u.operand;
2856         int skip = vPC[2].u.operand;
2857         int value = vPC[3].u.operand;
2858
2859         ScopeChainNode* scopeChain = callFrame->scopeChain();
2860         ScopeChainIterator iter = scopeChain->begin();
2861         ScopeChainIterator end = scopeChain->end();
2862         ASSERT(codeBlock == callFrame->codeBlock());
2863         ASSERT_UNUSED(end, iter != end);
2864         bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain();
2865         ASSERT(skip || !checkTopLevel);
2866         if (checkTopLevel && skip--) {
2867             if (callFrame->r(codeBlock->activationRegister()).jsValue())
2868                 ++iter;
2869         }
2870         while (skip--) {
2871             ++iter;
2872             ASSERT_UNUSED(end, iter != end);
2873         }
2874
2875         ASSERT((*iter)->isVariableObject());
2876         JSVariableObject* scope = static_cast<JSVariableObject*>(iter->get());
2877         ASSERT(callFrame->r(value).jsValue());
2878         scope->registerAt(index).set(*globalData, scope, callFrame->r(value).jsValue());
2879         vPC += OPCODE_LENGTH(op_put_scoped_var);
2880         NEXT_INSTRUCTION();
2881     }
2882     DEFINE_OPCODE(op_resolve_base) {
2883         /* resolve_base dst(r) property(id) isStrict(bool)
2884
2885            Searches the scope chain for an object containing
2886            identifier property, and if one is found, writes it to
2887            register dst. If none is found and isStrict is false, the
2888            outermost scope (which will be the global object) is
2889            stored in register dst.
2890         */
2891         resolveBase(callFrame, vPC);
2892         CHECK_FOR_EXCEPTION();
2893
2894         vPC += OPCODE_LENGTH(op_resolve_base);
2895         NEXT_INSTRUCTION();
2896     }
2897     DEFINE_OPCODE(op_ensure_property_exists) {
2898         /* ensure_property_exists base(r) property(id)
2899
2900            Throws an exception if property does not exist on base
2901          */
2902         int base = vPC[1].u.operand;
2903         int property = vPC[2].u.operand;
2904         Identifier& ident = codeBlock->identifier(property);
2905         
2906         JSValue baseVal = callFrame->r(base).jsValue();
2907         JSObject* baseObject = asObject(baseVal);
2908         PropertySlot slot(baseVal);
2909         if (!baseObject->getPropertySlot(callFrame, ident, slot)) {
2910             exceptionValue = createErrorForInvalidGlobalAssignment(callFrame, ident.ustring());
2911             goto vm_throw;
2912         }
2913
2914         vPC += OPCODE_LENGTH(op_ensure_property_exists);
2915         NEXT_INSTRUCTION();
2916     }
2917     DEFINE_OPCODE(op_resolve_with_base) {
2918         /* resolve_with_base baseDst(r) propDst(r) property(id)
2919
2920            Searches the scope chain for an object containing
2921            identifier property, and if one is found, writes it to
2922            register srcDst, and the retrieved property value to register
2923            propDst. If the property is not found, raises an exception.
2924
2925            This is more efficient than doing resolve_base followed by
2926            resolve, or resolve_base followed by get_by_id, as it
2927            avoids duplicate hash lookups.
2928         */
2929         if (UNLIKELY(!resolveBaseAndProperty(callFrame, vPC, exceptionValue)))
2930             goto vm_throw;
2931
2932         vPC += OPCODE_LENGTH(op_resolve_with_base);
2933         NEXT_INSTRUCTION();
2934     }
2935     DEFINE_OPCODE(op_resolve_with_this) {
2936         /* resolve_with_this thisDst(r) propDst(r) property(id)
2937
2938            Searches the scope chain for an object containing
2939            identifier property, and if one is found, writes the
2940            retrieved property value to register propDst, and the
2941            this object to pass in a call to thisDst.
2942
2943            If the property is not found, raises an exception.
2944         */
2945         if (UNLIKELY(!resolveThisAndProperty(callFrame, vPC, exceptionValue)))
2946             goto vm_throw;
2947
2948         vPC += OPCODE_LENGTH(op_resolve_with_this);
2949         NEXT_INSTRUCTION();
2950     }
2951     DEFINE_OPCODE(op_get_by_id) {
2952         /* get_by_id dst(r) base(r) property(id) structure(sID) nop(n) nop(n) nop(n)
2953
2954            Generic property access: Gets the property named by identifier
2955            property from the value base, and puts the result in register dst.
2956         */
2957         int dst = vPC[1].u.operand;
2958         int base = vPC[2].u.operand;
2959         int property = vPC[3].u.operand;
2960
2961         Identifier& ident = codeBlock->identifier(property);
2962         JSValue baseValue = callFrame->r(base).jsValue();
2963         PropertySlot slot(baseValue);
2964         JSValue result = baseValue.get(callFrame, ident, slot);
2965         CHECK_FOR_EXCEPTION();
2966
2967         tryCacheGetByID(callFrame, codeBlock, vPC, baseValue, ident, slot);
2968
2969         callFrame->uncheckedR(dst) = result;
2970         vPC += OPCODE_LENGTH(op_get_by_id);
2971         NEXT_INSTRUCTION();
2972     }
2973     DEFINE_OPCODE(op_get_by_id_self) {
2974         /* op_get_by_id_self dst(r) base(r) property(id) structure(sID) offset(n) nop(n) nop(n)
2975
2976            Cached property access: Attempts to get a cached property from the
2977            value base. If the cache misses, op_get_by_id_self reverts to
2978            op_get_by_id.
2979         */
2980         int base = vPC[2].u.operand;
2981         JSValue baseValue = callFrame->r(base).jsValue();
2982
2983         if (LIKELY(baseValue.isCell())) {
2984             JSCell* baseCell = baseValue.asCell();
2985             Structure* structure = vPC[4].u.structure.get();
2986
2987             if (LIKELY(baseCell->structure() == structure)) {
2988                 ASSERT(baseCell->isObject());
2989                 JSObject* baseObject = asObject(baseCell);
2990                 int dst = vPC[1].u.operand;
2991                 int offset = vPC[5].u.operand;
2992
2993                 ASSERT(baseObject->get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
2994                 callFrame->uncheckedR(dst) = JSValue(baseObject->getDirectOffset(offset));
2995
2996                 vPC += OPCODE_LENGTH(op_get_by_id_self);
2997                 NEXT_INSTRUCTION();
2998             }
2999         }
3000
3001         uncacheGetByID(codeBlock, vPC);
3002         NEXT_INSTRUCTION();
3003     }
3004     DEFINE_OPCODE(op_get_by_id_proto) {
3005         /* op_get_by_id_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n)
3006
3007            Cached property access: Attempts to get a cached property from the
3008            value base's prototype. If the cache misses, op_get_by_id_proto
3009            reverts to op_get_by_id.
3010         */
3011         int base = vPC[2].u.operand;
3012         JSValue baseValue = callFrame->r(base).jsValue();
3013
3014         if (LIKELY(baseValue.isCell())) {
3015             JSCell* baseCell = baseValue.asCell();
3016             Structure* structure = vPC[4].u.structure.get();
3017
3018             if (LIKELY(baseCell->structure() == structure)) {
3019                 ASSERT(structure->prototypeForLookup(callFrame).isObject());
3020                 JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
3021                 Structure* prototypeStructure = vPC[5].u.structure.get();
3022
3023                 if (LIKELY(protoObject->structure() == prototypeStructure)) {
3024                     int dst = vPC[1].u.operand;
3025                     int offset = vPC[6].u.operand;
3026
3027                     ASSERT(protoObject->get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset));
3028                     ASSERT(baseValue.get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset));
3029                     callFrame->uncheckedR(dst) = JSValue(protoObject->getDirectOffset(offset));
3030
3031                     vPC += OPCODE_LENGTH(op_get_by_id_proto);
3032                     NEXT_INSTRUCTION();
3033                 }
3034             }
3035         }
3036
3037         uncacheGetByID(codeBlock, vPC);
3038         NEXT_INSTRUCTION();
3039     }
3040 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
3041     goto *(&&skip_id_getter_proto);
3042 #endif
3043     DEFINE_OPCODE(op_get_by_id_getter_proto) {
3044         /* op_get_by_id_getter_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n)
3045          
3046          Cached property access: Attempts to get a cached getter property from the
3047          value base's prototype. If the cache misses, op_get_by_id_getter_proto
3048          reverts to op_get_by_id.
3049          */
3050         int base = vPC[2].u.operand;
3051         JSValue baseValue = callFrame->r(base).jsValue();
3052         
3053         if (LIKELY(baseValue.isCell())) {
3054             JSCell* baseCell = baseValue.asCell();
3055             Structure* structure = vPC[4].u.structure.get();
3056             
3057             if (LIKELY(baseCell->structure() == structure)) {
3058                 ASSERT(structure->prototypeForLookup(callFrame).isObject());
3059                 JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
3060                 Structure* prototypeStructure = vPC[5].u.structure.get();
3061                 
3062                 if (LIKELY(protoObject->structure() == prototypeStructure)) {
3063                     int dst = vPC[1].u.operand;
3064                     int offset = vPC[6].u.operand;
3065                     if (GetterSetter* getterSetter = asGetterSetter(protoObject->getDirectOffset(offset).asCell())) {
3066                         JSObject* getter = getterSetter->getter();
3067                         CallData callData;
3068                         CallType callType = getter->methodTable()->getCallData(getter, callData);
3069                         JSValue result = call(callFrame, getter, callType, callData, asObject(baseCell), ArgList());
3070                         CHECK_FOR_EXCEPTION();
3071                         callFrame->uncheckedR(dst) = result;
3072                     } else
3073                         callFrame->uncheckedR(dst) = jsUndefined();
3074                     vPC += OPCODE_LENGTH(op_get_by_id_getter_proto);
3075                     NEXT_INSTRUCTION();
3076                 }
3077             }
3078         }
3079         uncacheGetByID(codeBlock, vPC);
3080         NEXT_INSTRUCTION();
3081     }
3082 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
3083     skip_id_getter_proto:
3084 #endif
3085 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
3086     goto *(&&skip_id_custom_proto);
3087 #endif
3088     DEFINE_OPCODE(op_get_by_id_custom_proto) {
3089         /* op_get_by_id_custom_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n)
3090          
3091          Cached property access: Attempts to use a cached named property getter
3092          from the value base's prototype. If the cache misses, op_get_by_id_custom_proto
3093          reverts to op_get_by_id.
3094          */
3095         int base = vPC[2].u.operand;
3096         JSValue baseValue = callFrame->r(base).jsValue();
3097         
3098         if (LIKELY(baseValue.isCell())) {
3099             JSCell* baseCell = baseValue.asCell();
3100             Structure* structure = vPC[4].u.structure.get();
3101             
3102             if (LIKELY(baseCell->structure() == structure)) {
3103                 ASSERT(structure->prototypeForLookup(callFrame).isObject());
3104                 JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
3105                 Structure* prototypeStructure = vPC[5].u.structure.get();
3106                 
3107                 if (LIKELY(protoObject->structure() == prototypeStructure)) {
3108                     int dst = vPC[1].u.operand;
3109                     int property = vPC[3].u.operand;
3110                     Identifier& ident = codeBlock->identifier(property);
3111                     
3112                     PropertySlot::GetValueFunc getter = vPC[6].u.getterFunc;
3113                     JSValue result = getter(callFrame, protoObject, ident);
3114                     CHECK_FOR_EXCEPTION();
3115                     callFrame->uncheckedR(dst) = result;
3116                     vPC += OPCODE_LENGTH(op_get_by_id_custom_proto);
3117                     NEXT_INSTRUCTION();
3118                 }
3119             }
3120         }
3121         uncacheGetByID(codeBlock, vPC);
3122         NEXT_INSTRUCTION();
3123     }
3124 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
3125     skip_id_custom_proto:
3126 #endif
3127 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
3128     goto *(&&skip_get_by_id_chain);
3129 #endif
3130     DEFINE_OPCODE(op_get_by_id_chain) {
3131         /* op_get_by_id_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n)
3132
3133            Cached property access: Attempts to get a cached property from the
3134            value base's prototype chain. If the cache misses, op_get_by_id_chain
3135            reverts to op_get_by_id.
3136         */
3137         int base = vPC[2].u.operand;
3138         JSValue baseValue = callFrame->r(base).jsValue();
3139
3140         if (LIKELY(baseValue.isCell())) {
3141             JSCell* baseCell = baseValue.asCell();
3142             Structure* structure = vPC[4].u.structure.get();
3143
3144             if (LIKELY(baseCell->structure() == structure)) {
3145                 WriteBarrier<Structure>* it = vPC[5].u.structureChain->head();
3146                 size_t count = vPC[6].u.operand;
3147                 WriteBarrier<Structure>* end = it + count;
3148
3149                 while (true) {
3150                     JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame));
3151
3152                     if (UNLIKELY(baseObject->structure() != (*it).get()))
3153                         break;
3154
3155                     if (++it == end) {
3156                         int dst = vPC[1].u.operand;
3157                         int offset = vPC[7].u.operand;
3158
3159                         ASSERT(baseObject->get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
3160                         ASSERT(baseValue.get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
3161                         callFrame->uncheckedR(dst) = JSValue(baseObject->getDirectOffset(offset));
3162
3163                         vPC += OPCODE_LENGTH(op_get_by_id_chain);
3164                         NEXT_INSTRUCTION();
3165                     }
3166
3167                     // Update baseCell, so that next time around the loop we'll pick up the prototype's prototype.
3168                     baseCell = baseObject;
3169                 }
3170             }
3171         }
3172
3173         uncacheGetByID(codeBlock, vPC);
3174         NEXT_INSTRUCTION();
3175     }
3176 #if USE(GCC_COMPUTED_GOTO_WORKAROUND)
3177     skip_get_by_id_chain:
3178     goto *(&&skip_id_getter_self);
3179 #endif
3180     DEFINE_OPCODE(op_get_by_id_getter_self) {
3181         /* op_get_by_id_self dst(r) base(r) property(id) structure(sID) offset(n) nop(n) nop(n)
3182          
3183          Cached property access: Attempts to get a cached property from the
3184          value base. If the cache misses, op_get_by_id_getter_self reverts to
3185          op_get_by_id.
3186          */
3187         int base = vPC[2].u.operand;
3188         JSValue baseValue = callFrame->r(base).jsValue();
3189         
3190         if (LIKELY(baseValue.isCell())) {
3191             JSCell* baseCell = baseValue.asCell();
3192             Structure* structure = vPC[4].u.structure.get();
3193             
3194             if (LIKELY(baseCell->structure() == structure)) {
3195                 ASSERT(baseCell->isObject());
3196                 JSObject* baseObject = asObject(baseCell);
3197                 int dst = vPC[1].u.operand;
3198                 int offset = vPC[5].u.operand;
3199
3200                 if (GetterSetter* getterSetter = asGetterSetter(baseObject->getDirectOffset(offset).asCell())) {
3201                     JSObject* getter = getterSetter->getter();