1/*
2 * Copyright (C) 2008, 2009 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 "BytecodeGenerator.h"
32
33#include "BatchedTransitionOptimizer.h"
34#include "JSFunction.h"
35#include "Interpreter.h"
36#include "ScopeChain.h"
37#include "UString.h"
38
39using namespace std;
40
41namespace JSC {
42
43/*
44    The layout of a register frame looks like this:
45
46    For
47
48    function f(x, y) {
49        var v1;
50        function g() { }
51        var v2;
52        return (x) * (y);
53    }
54
55    assuming (x) and (y) generated temporaries t1 and t2, you would have
56
57    ------------------------------------
58    |  x |  y |  g | v2 | v1 | t1 | t2 | <-- value held
59    ------------------------------------
60    | -5 | -4 | -3 | -2 | -1 | +0 | +1 | <-- register index
61    ------------------------------------
62    | params->|<-locals      | temps->
63
64    Because temporary registers are allocated in a stack-like fashion, we
65    can reclaim them with a simple popping algorithm. The same goes for labels.
66    (We never reclaim parameter or local registers, because parameters and
67    locals are DontDelete.)
68
69    The register layout before a function call looks like this:
70
71    For
72
73    function f(x, y)
74    {
75    }
76
77    f(1);
78
79    >                        <------------------------------
80    <                        >  reserved: call frame  |  1 | <-- value held
81    >         >snip<         <------------------------------
82    <                        > +0 | +1 | +2 | +3 | +4 | +5 | <-- register index
83    >                        <------------------------------
84    | params->|<-locals      | temps->
85
86    The call instruction fills in the "call frame" registers. It also pads
87    missing arguments at the end of the call:
88
89    >                        <-----------------------------------
90    <                        >  reserved: call frame  |  1 |  ? | <-- value held ("?" stands for "undefined")
91    >         >snip<         <-----------------------------------
92    <                        > +0 | +1 | +2 | +3 | +4 | +5 | +6 | <-- register index
93    >                        <-----------------------------------
94    | params->|<-locals      | temps->
95
96    After filling in missing arguments, the call instruction sets up the new
97    stack frame to overlap the end of the old stack frame:
98
99                             |---------------------------------->                        <
100                             |  reserved: call frame  |  1 |  ? <                        > <-- value held ("?" stands for "undefined")
101                             |---------------------------------->         >snip<         <
102                             | -7 | -6 | -5 | -4 | -3 | -2 | -1 <                        > <-- register index
103                             |---------------------------------->                        <
104                             |                        | params->|<-locals       | temps->
105
106    That way, arguments are "copied" into the callee's stack frame for free.
107
108    If the caller supplies too many arguments, this trick doesn't work. The
109    extra arguments protrude into space reserved for locals and temporaries.
110    In that case, the call instruction makes a real copy of the call frame header,
111    along with just the arguments expected by the callee, leaving the original
112    call frame header and arguments behind. (The call instruction can't just discard
113    extra arguments, because the "arguments" object may access them later.)
114    This copying strategy ensures that all named values will be at the indices
115    expected by the callee.
116*/
117
118#ifndef NDEBUG
119static bool s_dumpsGeneratedCode = false;
120#endif
121
122void BytecodeGenerator::setDumpsGeneratedCode(bool dumpsGeneratedCode)
123{
124#ifndef NDEBUG
125    s_dumpsGeneratedCode = dumpsGeneratedCode;
126#else
127    UNUSED_PARAM(dumpsGeneratedCode);
128#endif
129}
130
131bool BytecodeGenerator::dumpsGeneratedCode()
132{
133#ifndef NDEBUG
134    return s_dumpsGeneratedCode;
135#else
136    return false;
137#endif
138}
139
140JSObject* BytecodeGenerator::generate()
141{
142    m_codeBlock->setThisRegister(m_thisRegister.index());
143
144    m_scopeNode->emitBytecode(*this);
145
146#ifndef NDEBUG
147    m_codeBlock->setInstructionCount(m_codeBlock->instructions().size());
148
149    if (s_dumpsGeneratedCode)
150        m_codeBlock->dump(m_scopeChain->globalObject->globalExec());
151#endif
152
153    if ((m_codeType == FunctionCode && !m_codeBlock->needsFullScopeChain() && !m_codeBlock->usesArguments()) || m_codeType == EvalCode)
154        symbolTable().clear();
155
156    m_codeBlock->shrinkToFit();
157
158    if (m_expressionTooDeep)
159        return createOutOfMemoryError(m_scopeChain->globalObject.get());
160    return 0;
161}
162
163bool BytecodeGenerator::addVar(const Identifier& ident, bool isConstant, RegisterID*& r0)
164{
165    int index = m_calleeRegisters.size();
166    SymbolTableEntry newEntry(index, isConstant ? ReadOnly : 0);
167    pair<SymbolTable::iterator, bool> result = symbolTable().add(ident.impl(), newEntry);
168
169    if (!result.second) {
170        r0 = &registerFor(result.first->second.getIndex());
171        return false;
172    }
173
174    r0 = addVar();
175    return true;
176}
177
178bool BytecodeGenerator::addGlobalVar(const Identifier& ident, bool isConstant, RegisterID*& r0)
179{
180    int index = m_nextGlobalIndex;
181    SymbolTableEntry newEntry(index, isConstant ? ReadOnly : 0);
182    pair<SymbolTable::iterator, bool> result = symbolTable().add(ident.impl(), newEntry);
183
184    if (!result.second)
185        index = result.first->second.getIndex();
186    else {
187        --m_nextGlobalIndex;
188        m_globals.append(index + m_globalVarStorageOffset);
189    }
190
191    r0 = &registerFor(index);
192    return result.second;
193}
194
195void BytecodeGenerator::preserveLastVar()
196{
197    if ((m_firstConstantIndex = m_calleeRegisters.size()) != 0)
198        m_lastVar = &m_calleeRegisters.last();
199}
200
201BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, ScopeChainNode* scopeChain, SymbolTable* symbolTable, ProgramCodeBlock* codeBlock)
202    : m_shouldEmitDebugHooks(scopeChain->globalObject->debugger())
203    , m_shouldEmitProfileHooks(scopeChain->globalObject->supportsProfiling())
204    , m_shouldEmitRichSourceInfo(scopeChain->globalObject->supportsRichSourceInfo())
205    , m_scopeChain(*scopeChain->globalData, scopeChain)
206    , m_symbolTable(symbolTable)
207    , m_scopeNode(programNode)
208    , m_codeBlock(codeBlock)
209    , m_thisRegister(RegisterFile::ProgramCodeThisRegister)
210    , m_finallyDepth(0)
211    , m_dynamicScopeDepth(0)
212    , m_baseScopeDepth(0)
213    , m_codeType(GlobalCode)
214    , m_nextGlobalIndex(-1)
215    , m_nextConstantOffset(0)
216    , m_globalConstantIndex(0)
217    , m_hasCreatedActivation(true)
218    , m_firstLazyFunction(0)
219    , m_lastLazyFunction(0)
220    , m_globalData(scopeChain->globalData)
221    , m_lastOpcodeID(op_end)
222#ifndef NDEBUG
223    , m_lastOpcodePosition(0)
224#endif
225    , m_stack(m_globalData->stack())
226    , m_usesExceptions(false)
227    , m_expressionTooDeep(false)
228{
229    if (m_shouldEmitDebugHooks)
230        m_codeBlock->setNeedsFullScopeChain(true);
231
232    emitOpcode(op_enter);
233    codeBlock->setGlobalData(m_globalData);
234
235    // FIXME: Move code that modifies the global object to Interpreter::execute.
236
237    m_codeBlock->m_numParameters = 1; // Allocate space for "this"
238
239    JSGlobalObject* globalObject = scopeChain->globalObject.get();
240    ExecState* exec = globalObject->globalExec();
241    RegisterFile* registerFile = &exec->globalData().interpreter->registerFile();
242
243    // Shift register indexes in generated code to elide registers allocated by intermediate stack frames.
244    m_globalVarStorageOffset = -RegisterFile::CallFrameHeaderSize - m_codeBlock->m_numParameters - registerFile->size();
245
246    // Add previously defined symbols to bookkeeping.
247    m_globals.grow(symbolTable->size());
248    SymbolTable::iterator end = symbolTable->end();
249    for (SymbolTable::iterator it = symbolTable->begin(); it != end; ++it)
250        registerFor(it->second.getIndex()).setIndex(it->second.getIndex() + m_globalVarStorageOffset);
251
252    BatchedTransitionOptimizer optimizer(*m_globalData, globalObject);
253
254    const VarStack& varStack = programNode->varStack();
255    const FunctionStack& functionStack = programNode->functionStack();
256    bool canOptimizeNewGlobals = symbolTable->size() + functionStack.size() + varStack.size() < registerFile->maxGlobals();
257    if (canOptimizeNewGlobals) {
258        // Shift new symbols so they get stored prior to existing symbols.
259        m_nextGlobalIndex -= symbolTable->size();
260
261        HashSet<StringImpl*, IdentifierRepHash> newGlobals;
262        Vector<std::pair<int, bool>, 16> functionInfo(functionStack.size());
263        for (size_t i = 0; i < functionStack.size(); ++i) {
264            FunctionBodyNode* function = functionStack[i];
265            globalObject->removeDirect(*m_globalData, function->ident()); // Make sure our new function is not shadowed by an old property.
266            SymbolTableEntry entry = symbolTable->inlineGet(function->ident().impl());
267
268            if (entry.isNull())
269                newGlobals.add(function->ident().impl());
270            functionInfo[i] = make_pair(entry.getIndex(), entry.isReadOnly());
271        }
272
273        Vector<bool, 16> shouldCreateVar(varStack.size());
274        for (size_t i = 0; i < varStack.size(); ++i) {
275            if (newGlobals.contains(varStack[i].first->impl()) || globalObject->hasProperty(exec, *varStack[i].first)) {
276                shouldCreateVar[i] = false;
277                continue;
278            }
279            shouldCreateVar[i] = true;
280            newGlobals.add(varStack[i].first->impl());
281        }
282
283        int expectedSize = symbolTable->size() + newGlobals.size();
284        globalObject->resizeRegisters(symbolTable->size(), expectedSize);
285
286        for (size_t i = 0; i < functionStack.size(); ++i) {
287            FunctionBodyNode* function = functionStack[i];
288            if (functionInfo[i].second)
289                continue;
290            RegisterID* dst = addGlobalVar(function->ident(), false);
291            JSValue value = new (exec) JSFunction(exec, makeFunction(exec, function), scopeChain);
292            globalObject->registerAt(dst->index() - m_globalVarStorageOffset).set(*m_globalData, globalObject, value);
293        }
294
295        for (size_t i = 0; i < varStack.size(); ++i) {
296            if (!shouldCreateVar[i])
297                continue;
298            addGlobalVar(*varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant);
299        }
300        if (symbolTable->size() != expectedSize)
301            CRASH();
302
303        preserveLastVar();
304    } else {
305        for (size_t i = 0; i < functionStack.size(); ++i) {
306            FunctionBodyNode* function = functionStack[i];
307            globalObject->putWithAttributes(exec, function->ident(), new (exec) JSFunction(exec, makeFunction(exec, function), scopeChain), DontDelete);
308        }
309        for (size_t i = 0; i < varStack.size(); ++i) {
310            if (globalObject->symbolTableHasProperty(*varStack[i].first) || globalObject->hasProperty(exec, *varStack[i].first))
311                continue;
312            int attributes = DontDelete;
313            if (varStack[i].second & DeclarationStacks::IsConstant)
314                attributes |= ReadOnly;
315            globalObject->putWithAttributes(exec, *varStack[i].first, jsUndefined(), attributes);
316        }
317
318        preserveLastVar();
319    }
320    codeBlock->m_numCapturedVars = codeBlock->m_numVars;
321}
322
323BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, ScopeChainNode* scopeChain, SymbolTable* symbolTable, CodeBlock* codeBlock)
324    : m_shouldEmitDebugHooks(scopeChain->globalObject->debugger())
325    , m_shouldEmitProfileHooks(scopeChain->globalObject->supportsProfiling())
326    , m_shouldEmitRichSourceInfo(scopeChain->globalObject->supportsRichSourceInfo())
327    , m_scopeChain(*scopeChain->globalData, scopeChain)
328    , m_symbolTable(symbolTable)
329    , m_scopeNode(functionBody)
330    , m_codeBlock(codeBlock)
331    , m_activationRegister(0)
332    , m_finallyDepth(0)
333    , m_dynamicScopeDepth(0)
334    , m_baseScopeDepth(0)
335    , m_codeType(FunctionCode)
336    , m_nextConstantOffset(0)
337    , m_globalConstantIndex(0)
338    , m_hasCreatedActivation(false)
339    , m_firstLazyFunction(0)
340    , m_lastLazyFunction(0)
341    , m_globalData(scopeChain->globalData)
342    , m_lastOpcodeID(op_end)
343#ifndef NDEBUG
344    , m_lastOpcodePosition(0)
345#endif
346    , m_stack(m_globalData->stack())
347    , m_usesExceptions(false)
348    , m_expressionTooDeep(false)
349{
350    if (m_shouldEmitDebugHooks)
351        m_codeBlock->setNeedsFullScopeChain(true);
352
353    codeBlock->setGlobalData(m_globalData);
354
355    emitOpcode(op_enter);
356    if (m_codeBlock->needsFullScopeChain()) {
357        m_activationRegister = addVar();
358        emitInitLazyRegister(m_activationRegister);
359        m_codeBlock->setActivationRegister(m_activationRegister->index());
360    }
361
362    // Both op_tear_off_activation and op_tear_off_arguments tear off the 'arguments'
363    // object, if created.
364    if (m_codeBlock->needsFullScopeChain() || functionBody->usesArguments()) {
365        RegisterID* unmodifiedArgumentsRegister = addVar(); // Anonymous, so it can't be modified by user code.
366        RegisterID* argumentsRegister = addVar(propertyNames().arguments, false); // Can be changed by assigning to 'arguments'.
367
368        // We can save a little space by hard-coding the knowledge that the two
369        // 'arguments' values are stored in consecutive registers, and storing
370        // only the index of the assignable one.
371        codeBlock->setArgumentsRegister(argumentsRegister->index());
372        ASSERT_UNUSED(unmodifiedArgumentsRegister, unmodifiedArgumentsRegister->index() == JSC::unmodifiedArgumentsRegister(codeBlock->argumentsRegister()));
373
374        emitInitLazyRegister(argumentsRegister);
375        emitInitLazyRegister(unmodifiedArgumentsRegister);
376
377        if (m_codeBlock->isStrictMode()) {
378            emitOpcode(op_create_arguments);
379            instructions().append(argumentsRegister->index());
380        }
381
382        // The debugger currently retrieves the arguments object from an activation rather than pulling
383        // it from a call frame.  In the long-term it should stop doing that (<rdar://problem/6911886>),
384        // but for now we force eager creation of the arguments object when debugging.
385        if (m_shouldEmitDebugHooks) {
386            emitOpcode(op_create_arguments);
387            instructions().append(argumentsRegister->index());
388        }
389    }
390
391    const DeclarationStacks::FunctionStack& functionStack = functionBody->functionStack();
392    const DeclarationStacks::VarStack& varStack = functionBody->varStack();
393
394    // Captured variables and functions go first so that activations don't have
395    // to step over the non-captured locals to mark them.
396    m_hasCreatedActivation = false;
397    if (functionBody->hasCapturedVariables()) {
398        for (size_t i = 0; i < functionStack.size(); ++i) {
399            FunctionBodyNode* function = functionStack[i];
400            const Identifier& ident = function->ident();
401            if (functionBody->captures(ident)) {
402                if (!m_hasCreatedActivation) {
403                    m_hasCreatedActivation = true;
404                    emitOpcode(op_create_activation);
405                    instructions().append(m_activationRegister->index());
406                }
407                m_functions.add(ident.impl());
408                emitNewFunction(addVar(ident, false), function);
409            }
410        }
411        for (size_t i = 0; i < varStack.size(); ++i) {
412            const Identifier& ident = *varStack[i].first;
413            if (functionBody->captures(ident))
414                addVar(ident, varStack[i].second & DeclarationStacks::IsConstant);
415        }
416    }
417    bool canLazilyCreateFunctions = !functionBody->needsActivationForMoreThanVariables() && !m_shouldEmitDebugHooks;
418    if (!canLazilyCreateFunctions && !m_hasCreatedActivation) {
419        m_hasCreatedActivation = true;
420        emitOpcode(op_create_activation);
421        instructions().append(m_activationRegister->index());
422    }
423
424    codeBlock->m_numCapturedVars = codeBlock->m_numVars;
425    m_firstLazyFunction = codeBlock->m_numVars;
426    for (size_t i = 0; i < functionStack.size(); ++i) {
427        FunctionBodyNode* function = functionStack[i];
428        const Identifier& ident = function->ident();
429        if (!functionBody->captures(ident)) {
430            m_functions.add(ident.impl());
431            RefPtr<RegisterID> reg = addVar(ident, false);
432            // Don't lazily create functions that override the name 'arguments'
433            // as this would complicate lazy instantiation of actual arguments.
434            if (!canLazilyCreateFunctions || ident == propertyNames().arguments)
435                emitNewFunction(reg.get(), function);
436            else {
437                emitInitLazyRegister(reg.get());
438                m_lazyFunctions.set(reg->index(), function);
439            }
440        }
441    }
442    m_lastLazyFunction = canLazilyCreateFunctions ? codeBlock->m_numVars : m_firstLazyFunction;
443    for (size_t i = 0; i < varStack.size(); ++i) {
444        const Identifier& ident = *varStack[i].first;
445        if (!functionBody->captures(ident))
446            addVar(ident, varStack[i].second & DeclarationStacks::IsConstant);
447    }
448
449    if (m_shouldEmitDebugHooks)
450        codeBlock->m_numCapturedVars = codeBlock->m_numVars;
451
452    FunctionParameters& parameters = *functionBody->parameters();
453    size_t parameterCount = parameters.size();
454    int nextParameterIndex = -RegisterFile::CallFrameHeaderSize - parameterCount - 1;
455    m_parameters.grow(1 + parameterCount); // reserve space for "this"
456
457    // Add "this" as a parameter
458    m_thisRegister.setIndex(nextParameterIndex);
459    ++m_codeBlock->m_numParameters;
460
461    for (size_t i = 0; i < parameterCount; ++i)
462        addParameter(parameters[i], ++nextParameterIndex);
463
464    preserveLastVar();
465
466    if (isConstructor()) {
467        RefPtr<RegisterID> func = newTemporary();
468        RefPtr<RegisterID> funcProto = newTemporary();
469
470        emitOpcode(op_get_callee);
471        instructions().append(func->index());
472        // Load prototype.
473        emitGetById(funcProto.get(), func.get(), globalData()->propertyNames->prototype);
474
475        emitOpcode(op_create_this);
476        instructions().append(m_thisRegister.index());
477        instructions().append(funcProto->index());
478    } else if (functionBody->usesThis() || m_shouldEmitDebugHooks) {
479        if (codeBlock->isStrictMode())
480            emitOpcode(op_convert_this_strict);
481        else
482            emitOpcode(op_convert_this);
483        instructions().append(m_thisRegister.index());
484    }
485}
486
487BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, ScopeChainNode* scopeChain, SymbolTable* symbolTable, EvalCodeBlock* codeBlock)
488    : m_shouldEmitDebugHooks(scopeChain->globalObject->debugger())
489    , m_shouldEmitProfileHooks(scopeChain->globalObject->supportsProfiling())
490    , m_shouldEmitRichSourceInfo(scopeChain->globalObject->supportsRichSourceInfo())
491    , m_scopeChain(*scopeChain->globalData, scopeChain)
492    , m_symbolTable(symbolTable)
493    , m_scopeNode(evalNode)
494    , m_codeBlock(codeBlock)
495    , m_thisRegister(RegisterFile::ProgramCodeThisRegister)
496    , m_finallyDepth(0)
497    , m_dynamicScopeDepth(0)
498    , m_baseScopeDepth(codeBlock->baseScopeDepth())
499    , m_codeType(EvalCode)
500    , m_nextConstantOffset(0)
501    , m_globalConstantIndex(0)
502    , m_hasCreatedActivation(true)
503    , m_firstLazyFunction(0)
504    , m_lastLazyFunction(0)
505    , m_globalData(scopeChain->globalData)
506    , m_lastOpcodeID(op_end)
507#ifndef NDEBUG
508    , m_lastOpcodePosition(0)
509#endif
510    , m_stack(m_globalData->stack())
511    , m_usesExceptions(false)
512    , m_expressionTooDeep(false)
513{
514    if (m_shouldEmitDebugHooks || m_baseScopeDepth)
515        m_codeBlock->setNeedsFullScopeChain(true);
516
517    emitOpcode(op_enter);
518    codeBlock->setGlobalData(m_globalData);
519    m_codeBlock->m_numParameters = 1; // Allocate space for "this"
520
521    const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack();
522    for (size_t i = 0; i < functionStack.size(); ++i)
523        m_codeBlock->addFunctionDecl(makeFunction(m_globalData, functionStack[i]));
524
525    const DeclarationStacks::VarStack& varStack = evalNode->varStack();
526    unsigned numVariables = varStack.size();
527    Vector<Identifier> variables;
528    variables.reserveCapacity(numVariables);
529    for (size_t i = 0; i < numVariables; ++i)
530        variables.append(*varStack[i].first);
531    codeBlock->adoptVariables(variables);
532    codeBlock->m_numCapturedVars = codeBlock->m_numVars;
533    preserveLastVar();
534}
535
536RegisterID* BytecodeGenerator::emitInitLazyRegister(RegisterID* reg)
537{
538    emitOpcode(op_init_lazy_reg);
539    instructions().append(reg->index());
540    return reg;
541}
542
543void BytecodeGenerator::addParameter(const Identifier& ident, int parameterIndex)
544{
545    // Parameters overwrite var declarations, but not function declarations.
546    StringImpl* rep = ident.impl();
547    if (!m_functions.contains(rep)) {
548        symbolTable().set(rep, parameterIndex);
549        RegisterID& parameter = registerFor(parameterIndex);
550        parameter.setIndex(parameterIndex);
551    }
552
553    // To maintain the calling convention, we have to allocate unique space for
554    // each parameter, even if the parameter doesn't make it into the symbol table.
555    ++m_codeBlock->m_numParameters;
556}
557
558RegisterID* BytecodeGenerator::registerFor(const Identifier& ident)
559{
560    if (ident == propertyNames().thisIdentifier)
561        return &m_thisRegister;
562
563    if (!shouldOptimizeLocals())
564        return 0;
565
566    SymbolTableEntry entry = symbolTable().get(ident.impl());
567    if (entry.isNull())
568        return 0;
569
570    if (ident == propertyNames().arguments)
571        createArgumentsIfNecessary();
572
573    return createLazyRegisterIfNecessary(&registerFor(entry.getIndex()));
574}
575
576bool BytecodeGenerator::willResolveToArguments(const Identifier& ident)
577{
578    if (ident != propertyNames().arguments)
579        return false;
580
581    if (!shouldOptimizeLocals())
582        return false;
583
584    SymbolTableEntry entry = symbolTable().get(ident.impl());
585    if (entry.isNull())
586        return false;
587
588    if (m_codeBlock->usesArguments() && m_codeType == FunctionCode)
589        return true;
590
591    return false;
592}
593
594RegisterID* BytecodeGenerator::uncheckedRegisterForArguments()
595{
596    ASSERT(willResolveToArguments(propertyNames().arguments));
597
598    SymbolTableEntry entry = symbolTable().get(propertyNames().arguments.impl());
599    ASSERT(!entry.isNull());
600    return &registerFor(entry.getIndex());
601}
602
603RegisterID* BytecodeGenerator::createLazyRegisterIfNecessary(RegisterID* reg)
604{
605    if (m_lastLazyFunction <= reg->index() || reg->index() < m_firstLazyFunction)
606        return reg;
607    emitLazyNewFunction(reg, m_lazyFunctions.get(reg->index()));
608    return reg;
609}
610
611RegisterID* BytecodeGenerator::constRegisterFor(const Identifier& ident)
612{
613    if (m_codeType == EvalCode)
614        return 0;
615
616    SymbolTableEntry entry = symbolTable().get(ident.impl());
617    if (entry.isNull())
618        return 0;
619
620    return createLazyRegisterIfNecessary(&registerFor(entry.getIndex()));
621}
622
623bool BytecodeGenerator::isLocal(const Identifier& ident)
624{
625    if (ident == propertyNames().thisIdentifier)
626        return true;
627
628    return shouldOptimizeLocals() && symbolTable().contains(ident.impl());
629}
630
631bool BytecodeGenerator::isLocalConstant(const Identifier& ident)
632{
633    return symbolTable().get(ident.impl()).isReadOnly();
634}
635
636RegisterID* BytecodeGenerator::newRegister()
637{
638    m_calleeRegisters.append(m_calleeRegisters.size());
639    m_codeBlock->m_numCalleeRegisters = max<int>(m_codeBlock->m_numCalleeRegisters, m_calleeRegisters.size());
640    return &m_calleeRegisters.last();
641}
642
643RegisterID* BytecodeGenerator::newTemporary()
644{
645    // Reclaim free register IDs.
646    while (m_calleeRegisters.size() && !m_calleeRegisters.last().refCount())
647        m_calleeRegisters.removeLast();
648
649    RegisterID* result = newRegister();
650    result->setTemporary();
651    return result;
652}
653
654RegisterID* BytecodeGenerator::highestUsedRegister()
655{
656    size_t count = m_codeBlock->m_numCalleeRegisters;
657    while (m_calleeRegisters.size() < count)
658        newRegister();
659    return &m_calleeRegisters.last();
660}
661
662PassRefPtr<LabelScope> BytecodeGenerator::newLabelScope(LabelScope::Type type, const Identifier* name)
663{
664    // Reclaim free label scopes.
665    while (m_labelScopes.size() && !m_labelScopes.last().refCount())
666        m_labelScopes.removeLast();
667
668    // Allocate new label scope.
669    LabelScope scope(type, name, scopeDepth(), newLabel(), type == LabelScope::Loop ? newLabel() : PassRefPtr<Label>()); // Only loops have continue targets.
670    m_labelScopes.append(scope);
671    return &m_labelScopes.last();
672}
673
674PassRefPtr<Label> BytecodeGenerator::newLabel()
675{
676    // Reclaim free label IDs.
677    while (m_labels.size() && !m_labels.last().refCount())
678        m_labels.removeLast();
679
680    // Allocate new label ID.
681    m_labels.append(m_codeBlock);
682    return &m_labels.last();
683}
684
685PassRefPtr<Label> BytecodeGenerator::emitLabel(Label* l0)
686{
687    unsigned newLabelIndex = instructions().size();
688    l0->setLocation(newLabelIndex);
689
690    if (m_codeBlock->numberOfJumpTargets()) {
691        unsigned lastLabelIndex = m_codeBlock->lastJumpTarget();
692        ASSERT(lastLabelIndex <= newLabelIndex);
693        if (newLabelIndex == lastLabelIndex) {
694            // Peephole optimizations have already been disabled by emitting the last label
695            return l0;
696        }
697    }
698
699    m_codeBlock->addJumpTarget(newLabelIndex);
700
701    // This disables peephole optimizations when an instruction is a jump target
702    m_lastOpcodeID = op_end;
703    return l0;
704}
705
706void BytecodeGenerator::emitOpcode(OpcodeID opcodeID)
707{
708#ifndef NDEBUG
709    size_t opcodePosition = instructions().size();
710    ASSERT(opcodePosition - m_lastOpcodePosition == opcodeLength(m_lastOpcodeID) || m_lastOpcodeID == op_end);
711    m_lastOpcodePosition = opcodePosition;
712#endif
713    instructions().append(globalData()->interpreter->getOpcode(opcodeID));
714    m_lastOpcodeID = opcodeID;
715}
716
717void BytecodeGenerator::retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index)
718{
719    ASSERT(instructions().size() >= 4);
720    size_t size = instructions().size();
721    dstIndex = instructions().at(size - 3).u.operand;
722    src1Index = instructions().at(size - 2).u.operand;
723    src2Index = instructions().at(size - 1).u.operand;
724}
725
726void BytecodeGenerator::retrieveLastUnaryOp(int& dstIndex, int& srcIndex)
727{
728    ASSERT(instructions().size() >= 3);
729    size_t size = instructions().size();
730    dstIndex = instructions().at(size - 2).u.operand;
731    srcIndex = instructions().at(size - 1).u.operand;
732}
733
734void ALWAYS_INLINE BytecodeGenerator::rewindBinaryOp()
735{
736    ASSERT(instructions().size() >= 4);
737    instructions().shrink(instructions().size() - 4);
738    m_lastOpcodeID = op_end;
739}
740
741void ALWAYS_INLINE BytecodeGenerator::rewindUnaryOp()
742{
743    ASSERT(instructions().size() >= 3);
744    instructions().shrink(instructions().size() - 3);
745    m_lastOpcodeID = op_end;
746}
747
748PassRefPtr<Label> BytecodeGenerator::emitJump(Label* target)
749{
750    size_t begin = instructions().size();
751    emitOpcode(target->isForward() ? op_jmp : op_loop);
752    instructions().append(target->bind(begin, instructions().size()));
753    return target;
754}
755
756PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* target)
757{
758    if (m_lastOpcodeID == op_less) {
759        int dstIndex;
760        int src1Index;
761        int src2Index;
762
763        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
764
765        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
766            rewindBinaryOp();
767
768            size_t begin = instructions().size();
769            emitOpcode(target->isForward() ? op_jless : op_loop_if_less);
770            instructions().append(src1Index);
771            instructions().append(src2Index);
772            instructions().append(target->bind(begin, instructions().size()));
773            return target;
774        }
775    } else if (m_lastOpcodeID == op_lesseq) {
776        int dstIndex;
777        int src1Index;
778        int src2Index;
779
780        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
781
782        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
783            rewindBinaryOp();
784
785            size_t begin = instructions().size();
786            emitOpcode(target->isForward() ? op_jlesseq : op_loop_if_lesseq);
787            instructions().append(src1Index);
788            instructions().append(src2Index);
789            instructions().append(target->bind(begin, instructions().size()));
790            return target;
791        }
792    } else if (m_lastOpcodeID == op_eq_null && target->isForward()) {
793        int dstIndex;
794        int srcIndex;
795
796        retrieveLastUnaryOp(dstIndex, srcIndex);
797
798        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
799            rewindUnaryOp();
800
801            size_t begin = instructions().size();
802            emitOpcode(op_jeq_null);
803            instructions().append(srcIndex);
804            instructions().append(target->bind(begin, instructions().size()));
805            return target;
806        }
807    } else if (m_lastOpcodeID == op_neq_null && target->isForward()) {
808        int dstIndex;
809        int srcIndex;
810
811        retrieveLastUnaryOp(dstIndex, srcIndex);
812
813        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
814            rewindUnaryOp();
815
816            size_t begin = instructions().size();
817            emitOpcode(op_jneq_null);
818            instructions().append(srcIndex);
819            instructions().append(target->bind(begin, instructions().size()));
820            return target;
821        }
822    }
823
824    size_t begin = instructions().size();
825
826    emitOpcode(target->isForward() ? op_jtrue : op_loop_if_true);
827    instructions().append(cond->index());
828    instructions().append(target->bind(begin, instructions().size()));
829    return target;
830}
831
832PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* target)
833{
834    if (m_lastOpcodeID == op_less && target->isForward()) {
835        int dstIndex;
836        int src1Index;
837        int src2Index;
838
839        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
840
841        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
842            rewindBinaryOp();
843
844            size_t begin = instructions().size();
845            emitOpcode(op_jnless);
846            instructions().append(src1Index);
847            instructions().append(src2Index);
848            instructions().append(target->bind(begin, instructions().size()));
849            return target;
850        }
851    } else if (m_lastOpcodeID == op_lesseq && target->isForward()) {
852        int dstIndex;
853        int src1Index;
854        int src2Index;
855
856        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
857
858        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
859            rewindBinaryOp();
860
861            size_t begin = instructions().size();
862            emitOpcode(op_jnlesseq);
863            instructions().append(src1Index);
864            instructions().append(src2Index);
865            instructions().append(target->bind(begin, instructions().size()));
866            return target;
867        }
868    } else if (m_lastOpcodeID == op_not) {
869        int dstIndex;
870        int srcIndex;
871
872        retrieveLastUnaryOp(dstIndex, srcIndex);
873
874        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
875            rewindUnaryOp();
876
877            size_t begin = instructions().size();
878            emitOpcode(target->isForward() ? op_jtrue : op_loop_if_true);
879            instructions().append(srcIndex);
880            instructions().append(target->bind(begin, instructions().size()));
881            return target;
882        }
883    } else if (m_lastOpcodeID == op_eq_null && target->isForward()) {
884        int dstIndex;
885        int srcIndex;
886
887        retrieveLastUnaryOp(dstIndex, srcIndex);
888
889        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
890            rewindUnaryOp();
891
892            size_t begin = instructions().size();
893            emitOpcode(op_jneq_null);
894            instructions().append(srcIndex);
895            instructions().append(target->bind(begin, instructions().size()));
896            return target;
897        }
898    } else if (m_lastOpcodeID == op_neq_null && target->isForward()) {
899        int dstIndex;
900        int srcIndex;
901
902        retrieveLastUnaryOp(dstIndex, srcIndex);
903
904        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
905            rewindUnaryOp();
906
907            size_t begin = instructions().size();
908            emitOpcode(op_jeq_null);
909            instructions().append(srcIndex);
910            instructions().append(target->bind(begin, instructions().size()));
911            return target;
912        }
913    }
914
915    size_t begin = instructions().size();
916    emitOpcode(target->isForward() ? op_jfalse : op_loop_if_false);
917    instructions().append(cond->index());
918    instructions().append(target->bind(begin, instructions().size()));
919    return target;
920}
921
922PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionCall(RegisterID* cond, Label* target)
923{
924    size_t begin = instructions().size();
925
926    emitOpcode(op_jneq_ptr);
927    instructions().append(cond->index());
928    instructions().append(Instruction(*m_globalData, m_codeBlock->ownerExecutable(), m_scopeChain->globalObject->callFunction()));
929    instructions().append(target->bind(begin, instructions().size()));
930    return target;
931}
932
933PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond, Label* target)
934{
935    size_t begin = instructions().size();
936
937    emitOpcode(op_jneq_ptr);
938    instructions().append(cond->index());
939    instructions().append(Instruction(*m_globalData, m_codeBlock->ownerExecutable(), m_scopeChain->globalObject->applyFunction()));
940    instructions().append(target->bind(begin, instructions().size()));
941    return target;
942}
943
944unsigned BytecodeGenerator::addConstant(const Identifier& ident)
945{
946    StringImpl* rep = ident.impl();
947    pair<IdentifierMap::iterator, bool> result = m_identifierMap.add(rep, m_codeBlock->numberOfIdentifiers());
948    if (result.second) // new entry
949        m_codeBlock->addIdentifier(Identifier(m_globalData, rep));
950
951    return result.first->second;
952}
953
954RegisterID* BytecodeGenerator::addConstantValue(JSValue v)
955{
956    int index = m_nextConstantOffset;
957
958    pair<JSValueMap::iterator, bool> result = m_jsValueMap.add(JSValue::encode(v), m_nextConstantOffset);
959    if (result.second) {
960        m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
961        ++m_nextConstantOffset;
962        m_codeBlock->addConstant(JSValue(v));
963    } else
964        index = result.first->second;
965
966    return &m_constantPoolRegisters[index];
967}
968
969unsigned BytecodeGenerator::addRegExp(PassRefPtr<RegExp> r)
970{
971    return m_codeBlock->addRegExp(r);
972}
973
974RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, RegisterID* src)
975{
976    emitOpcode(op_mov);
977    instructions().append(dst->index());
978    instructions().append(src->index());
979    return dst;
980}
981
982RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src)
983{
984    emitOpcode(opcodeID);
985    instructions().append(dst->index());
986    instructions().append(src->index());
987    return dst;
988}
989
990RegisterID* BytecodeGenerator::emitPreInc(RegisterID* srcDst)
991{
992    emitOpcode(op_pre_inc);
993    instructions().append(srcDst->index());
994    return srcDst;
995}
996
997RegisterID* BytecodeGenerator::emitPreDec(RegisterID* srcDst)
998{
999    emitOpcode(op_pre_dec);
1000    instructions().append(srcDst->index());
1001    return srcDst;
1002}
1003
1004RegisterID* BytecodeGenerator::emitPostInc(RegisterID* dst, RegisterID* srcDst)
1005{
1006    emitOpcode(op_post_inc);
1007    instructions().append(dst->index());
1008    instructions().append(srcDst->index());
1009    return dst;
1010}
1011
1012RegisterID* BytecodeGenerator::emitPostDec(RegisterID* dst, RegisterID* srcDst)
1013{
1014    emitOpcode(op_post_dec);
1015    instructions().append(dst->index());
1016    instructions().append(srcDst->index());
1017    return dst;
1018}
1019
1020RegisterID* BytecodeGenerator::emitBinaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes types)
1021{
1022    emitOpcode(opcodeID);
1023    instructions().append(dst->index());
1024    instructions().append(src1->index());
1025    instructions().append(src2->index());
1026
1027    if (opcodeID == op_bitor || opcodeID == op_bitand || opcodeID == op_bitxor ||
1028        opcodeID == op_add || opcodeID == op_mul || opcodeID == op_sub || opcodeID == op_div)
1029        instructions().append(types.toInt());
1030
1031    return dst;
1032}
1033
1034RegisterID* BytecodeGenerator::emitEqualityOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2)
1035{
1036    if (m_lastOpcodeID == op_typeof) {
1037        int dstIndex;
1038        int srcIndex;
1039
1040        retrieveLastUnaryOp(dstIndex, srcIndex);
1041
1042        if (src1->index() == dstIndex
1043            && src1->isTemporary()
1044            && m_codeBlock->isConstantRegisterIndex(src2->index())
1045            && m_codeBlock->constantRegister(src2->index()).get().isString()) {
1046            const UString& value = asString(m_codeBlock->constantRegister(src2->index()).get())->tryGetValue();
1047            if (value == "undefined") {
1048                rewindUnaryOp();
1049                emitOpcode(op_is_undefined);
1050                instructions().append(dst->index());
1051                instructions().append(srcIndex);
1052                return dst;
1053            }
1054            if (value == "boolean") {
1055                rewindUnaryOp();
1056                emitOpcode(op_is_boolean);
1057                instructions().append(dst->index());
1058                instructions().append(srcIndex);
1059                return dst;
1060            }
1061            if (value == "number") {
1062                rewindUnaryOp();
1063                emitOpcode(op_is_number);
1064                instructions().append(dst->index());
1065                instructions().append(srcIndex);
1066                return dst;
1067            }
1068            if (value == "string") {
1069                rewindUnaryOp();
1070                emitOpcode(op_is_string);
1071                instructions().append(dst->index());
1072                instructions().append(srcIndex);
1073                return dst;
1074            }
1075            if (value == "object") {
1076                rewindUnaryOp();
1077                emitOpcode(op_is_object);
1078                instructions().append(dst->index());
1079                instructions().append(srcIndex);
1080                return dst;
1081            }
1082            if (value == "function") {
1083                rewindUnaryOp();
1084                emitOpcode(op_is_function);
1085                instructions().append(dst->index());
1086                instructions().append(srcIndex);
1087                return dst;
1088            }
1089        }
1090    }
1091
1092    emitOpcode(opcodeID);
1093    instructions().append(dst->index());
1094    instructions().append(src1->index());
1095    instructions().append(src2->index());
1096    return dst;
1097}
1098
1099RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, bool b)
1100{
1101    return emitLoad(dst, jsBoolean(b));
1102}
1103
1104RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, double number)
1105{
1106    // FIXME: Our hash tables won't hold infinity, so we make a new JSValue each time.
1107    // Later we can do the extra work to handle that like the other cases.  They also don't
1108    // work correctly with NaN as a key.
1109    if (isnan(number) || number == HashTraits<double>::emptyValue() || HashTraits<double>::isDeletedValue(number))
1110        return emitLoad(dst, jsNumber(number));
1111    JSValue& valueInMap = m_numberMap.add(number, JSValue()).first->second;
1112    if (!valueInMap)
1113        valueInMap = jsNumber(number);
1114    return emitLoad(dst, valueInMap);
1115}
1116
1117RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& identifier)
1118{
1119    JSString*& stringInMap = m_stringMap.add(identifier.impl(), 0).first->second;
1120    if (!stringInMap)
1121        stringInMap = jsOwnedString(globalData(), identifier.ustring());
1122    return emitLoad(dst, JSValue(stringInMap));
1123}
1124
1125RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValue v)
1126{
1127    RegisterID* constantID = addConstantValue(v);
1128    if (dst)
1129        return emitMove(dst, constantID);
1130    return constantID;
1131}
1132
1133bool BytecodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting, bool& requiresDynamicChecks, JSObject*& globalObject)
1134{
1135    // Cases where we cannot statically optimize the lookup.
1136    if (property == propertyNames().arguments || !canOptimizeNonLocals()) {
1137        stackDepth = 0;
1138        index = missingSymbolMarker();
1139
1140        if (shouldOptimizeLocals() && m_codeType == GlobalCode) {
1141            ScopeChainIterator iter = m_scopeChain->begin();
1142            globalObject = iter->get();
1143            ASSERT((++iter) == m_scopeChain->end());
1144        }
1145        return false;
1146    }
1147
1148    size_t depth = 0;
1149    requiresDynamicChecks = false;
1150    ScopeChainIterator iter = m_scopeChain->begin();
1151    ScopeChainIterator end = m_scopeChain->end();
1152    for (; iter != end; ++iter, ++depth) {
1153        JSObject* currentScope = iter->get();
1154        if (!currentScope->isVariableObject())
1155            break;
1156        JSVariableObject* currentVariableObject = static_cast<JSVariableObject*>(currentScope);
1157        SymbolTableEntry entry = currentVariableObject->symbolTable().get(property.impl());
1158
1159        // Found the property
1160        if (!entry.isNull()) {
1161            if (entry.isReadOnly() && forWriting) {
1162                stackDepth = 0;
1163                index = missingSymbolMarker();
1164                if (++iter == end)
1165                    globalObject = currentVariableObject;
1166                return false;
1167            }
1168            stackDepth = depth + m_codeBlock->needsFullScopeChain();
1169            index = entry.getIndex();
1170            if (++iter == end)
1171                globalObject = currentVariableObject;
1172            return true;
1173        }
1174        bool scopeRequiresDynamicChecks = false;
1175        if (currentVariableObject->isDynamicScope(scopeRequiresDynamicChecks))
1176            break;
1177        requiresDynamicChecks |= scopeRequiresDynamicChecks;
1178    }
1179    // Can't locate the property but we're able to avoid a few lookups.
1180    stackDepth = depth + m_codeBlock->needsFullScopeChain();
1181    index = missingSymbolMarker();
1182    JSObject* scope = iter->get();
1183    if (++iter == end)
1184        globalObject = scope;
1185    return true;
1186}
1187
1188void BytecodeGenerator::emitCheckHasInstance(RegisterID* base)
1189{
1190    emitOpcode(op_check_has_instance);
1191    instructions().append(base->index());
1192}
1193
1194RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base, RegisterID* basePrototype)
1195{
1196    emitOpcode(op_instanceof);
1197    instructions().append(dst->index());
1198    instructions().append(value->index());
1199    instructions().append(base->index());
1200    instructions().append(basePrototype->index());
1201    return dst;
1202}
1203
1204RegisterID* BytecodeGenerator::emitResolve(RegisterID* dst, const Identifier& property)
1205{
1206    size_t depth = 0;
1207    int index = 0;
1208    JSObject* globalObject = 0;
1209    bool requiresDynamicChecks = false;
1210    if (!findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject) && !globalObject) {
1211        // We can't optimise at all :-(
1212        emitOpcode(op_resolve);
1213        instructions().append(dst->index());
1214        instructions().append(addConstant(property));
1215        return dst;
1216    }
1217
1218    if (globalObject) {
1219        bool forceGlobalResolve = false;
1220
1221        if (index != missingSymbolMarker() && !forceGlobalResolve && !requiresDynamicChecks) {
1222            // Directly index the property lookup across multiple scopes.
1223            return emitGetScopedVar(dst, depth, index, globalObject);
1224        }
1225
1226#if ENABLE(JIT)
1227        m_codeBlock->addGlobalResolveInfo(instructions().size());
1228#else
1229        m_codeBlock->addGlobalResolveInstruction(instructions().size());
1230#endif
1231        emitOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
1232        instructions().append(dst->index());
1233        instructions().append(addConstant(property));
1234        instructions().append(0);
1235        instructions().append(0);
1236        if (requiresDynamicChecks)
1237            instructions().append(depth);
1238        return dst;
1239    }
1240
1241    if (requiresDynamicChecks) {
1242        // If we get here we have eval nested inside a |with| just give up
1243        emitOpcode(op_resolve);
1244        instructions().append(dst->index());
1245        instructions().append(addConstant(property));
1246        return dst;
1247    }
1248
1249    if (index != missingSymbolMarker()) {
1250        // Directly index the property lookup across multiple scopes.
1251        return emitGetScopedVar(dst, depth, index, globalObject);
1252    }
1253
1254    // In this case we are at least able to drop a few scope chains from the
1255    // lookup chain, although we still need to hash from then on.
1256    emitOpcode(op_resolve_skip);
1257    instructions().append(dst->index());
1258    instructions().append(addConstant(property));
1259    instructions().append(depth);
1260    return dst;
1261}
1262
1263RegisterID* BytecodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, int index, JSValue globalObject)
1264{
1265    if (globalObject) {
1266        emitOpcode(op_get_global_var);
1267        instructions().append(dst->index());
1268        instructions().append(index);
1269        return dst;
1270    }
1271
1272    emitOpcode(op_get_scoped_var);
1273    instructions().append(dst->index());
1274    instructions().append(index);
1275    instructions().append(depth);
1276    return dst;
1277}
1278
1279RegisterID* BytecodeGenerator::emitPutScopedVar(size_t depth, int index, RegisterID* value, JSValue globalObject)
1280{
1281    if (globalObject) {
1282        emitOpcode(op_put_global_var);
1283        instructions().append(index);
1284        instructions().append(value->index());
1285        return value;
1286    }
1287    emitOpcode(op_put_scoped_var);
1288    instructions().append(index);
1289    instructions().append(depth);
1290    instructions().append(value->index());
1291    return value;
1292}
1293
1294RegisterID* BytecodeGenerator::emitResolveBase(RegisterID* dst, const Identifier& property)
1295{
1296    size_t depth = 0;
1297    int index = 0;
1298    JSObject* globalObject = 0;
1299    bool requiresDynamicChecks = false;
1300    findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject);
1301    if (!globalObject || requiresDynamicChecks) {
1302        // We can't optimise at all :-(
1303        emitOpcode(op_resolve_base);
1304        instructions().append(dst->index());
1305        instructions().append(addConstant(property));
1306        instructions().append(false);
1307        return dst;
1308    }
1309
1310    // Global object is the base
1311    return emitLoad(dst, JSValue(globalObject));
1312}
1313
1314RegisterID* BytecodeGenerator::emitResolveBaseForPut(RegisterID* dst, const Identifier& property)
1315{
1316    if (!m_codeBlock->isStrictMode())
1317        return emitResolveBase(dst, property);
1318    size_t depth = 0;
1319    int index = 0;
1320    JSObject* globalObject = 0;
1321    bool requiresDynamicChecks = false;
1322    findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject);
1323    if (!globalObject || requiresDynamicChecks) {
1324        // We can't optimise at all :-(
1325        emitOpcode(op_resolve_base);
1326        instructions().append(dst->index());
1327        instructions().append(addConstant(property));
1328        instructions().append(true);
1329        return dst;
1330    }
1331
1332    // Global object is the base
1333    RefPtr<RegisterID> result = emitLoad(dst, JSValue(globalObject));
1334    emitOpcode(op_ensure_property_exists);
1335    instructions().append(dst->index());
1336    instructions().append(addConstant(property));
1337    return result.get();
1338}
1339
1340RegisterID* BytecodeGenerator::emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property)
1341{
1342    size_t depth = 0;
1343    int index = 0;
1344    JSObject* globalObject = 0;
1345    bool requiresDynamicChecks = false;
1346    if (!findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject) || !globalObject || requiresDynamicChecks) {
1347        // We can't optimise at all :-(
1348        emitOpcode(op_resolve_with_base);
1349        instructions().append(baseDst->index());
1350        instructions().append(propDst->index());
1351        instructions().append(addConstant(property));
1352        return baseDst;
1353    }
1354
1355    bool forceGlobalResolve = false;
1356
1357    // Global object is the base
1358    emitLoad(baseDst, JSValue(globalObject));
1359
1360    if (index != missingSymbolMarker() && !forceGlobalResolve) {
1361        // Directly index the property lookup across multiple scopes.
1362        emitGetScopedVar(propDst, depth, index, globalObject);
1363        return baseDst;
1364    }
1365
1366#if ENABLE(JIT)
1367    m_codeBlock->addGlobalResolveInfo(instructions().size());
1368#else
1369    m_codeBlock->addGlobalResolveInstruction(instructions().size());
1370#endif
1371    emitOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
1372    instructions().append(propDst->index());
1373    instructions().append(addConstant(property));
1374    instructions().append(0);
1375    instructions().append(0);
1376    if (requiresDynamicChecks)
1377        instructions().append(depth);
1378    return baseDst;
1379}
1380
1381void BytecodeGenerator::emitMethodCheck()
1382{
1383    emitOpcode(op_method_check);
1384}
1385
1386RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
1387{
1388#if ENABLE(JIT)
1389    m_codeBlock->addStructureStubInfo(StructureStubInfo(access_get_by_id));
1390#else
1391    m_codeBlock->addPropertyAccessInstruction(instructions().size());
1392#endif
1393
1394    emitOpcode(op_get_by_id);
1395    instructions().append(dst->index());
1396    instructions().append(base->index());
1397    instructions().append(addConstant(property));
1398    instructions().append(0);
1399    instructions().append(0);
1400    instructions().append(0);
1401    instructions().append(0);
1402    return dst;
1403}
1404
1405RegisterID* BytecodeGenerator::emitGetArgumentsLength(RegisterID* dst, RegisterID* base)
1406{
1407    emitOpcode(op_get_arguments_length);
1408    instructions().append(dst->index());
1409    ASSERT(base->index() == m_codeBlock->argumentsRegister());
1410    instructions().append(base->index());
1411    instructions().append(addConstant(propertyNames().length));
1412    return dst;
1413}
1414
1415RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
1416{
1417#if ENABLE(JIT)
1418    m_codeBlock->addStructureStubInfo(StructureStubInfo(access_put_by_id));
1419#else
1420    m_codeBlock->addPropertyAccessInstruction(instructions().size());
1421#endif
1422
1423    emitOpcode(op_put_by_id);
1424    instructions().append(base->index());
1425    instructions().append(addConstant(property));
1426    instructions().append(value->index());
1427    instructions().append(0);
1428    instructions().append(0);
1429    instructions().append(0);
1430    instructions().append(0);
1431    instructions().append(0);
1432    return value;
1433}
1434
1435RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value)
1436{
1437#if ENABLE(JIT)
1438    m_codeBlock->addStructureStubInfo(StructureStubInfo(access_put_by_id));
1439#else
1440    m_codeBlock->addPropertyAccessInstruction(instructions().size());
1441#endif
1442
1443    emitOpcode(op_put_by_id);
1444    instructions().append(base->index());
1445    instructions().append(addConstant(property));
1446    instructions().append(value->index());
1447    instructions().append(0);
1448    instructions().append(0);
1449    instructions().append(0);
1450    instructions().append(0);
1451    instructions().append(property != m_globalData->propertyNames->underscoreProto);
1452    return value;
1453}
1454
1455RegisterID* BytecodeGenerator::emitPutGetter(RegisterID* base, const Identifier& property, RegisterID* value)
1456{
1457    emitOpcode(op_put_getter);
1458    instructions().append(base->index());
1459    instructions().append(addConstant(property));
1460    instructions().append(value->index());
1461    return value;
1462}
1463
1464RegisterID* BytecodeGenerator::emitPutSetter(RegisterID* base, const Identifier& property, RegisterID* value)
1465{
1466    emitOpcode(op_put_setter);
1467    instructions().append(base->index());
1468    instructions().append(addConstant(property));
1469    instructions().append(value->index());
1470    return value;
1471}
1472
1473RegisterID* BytecodeGenerator::emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier& property)
1474{
1475    emitOpcode(op_del_by_id);
1476    instructions().append(dst->index());
1477    instructions().append(base->index());
1478    instructions().append(addConstant(property));
1479    return dst;
1480}
1481
1482RegisterID* BytecodeGenerator::emitGetArgumentByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
1483{
1484    emitOpcode(op_get_argument_by_val);
1485    instructions().append(dst->index());
1486    ASSERT(base->index() == m_codeBlock->argumentsRegister());
1487    instructions().append(base->index());
1488    instructions().append(property->index());
1489    return dst;
1490}
1491
1492RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
1493{
1494    for (size_t i = m_forInContextStack.size(); i > 0; i--) {
1495        ForInContext& context = m_forInContextStack[i - 1];
1496        if (context.propertyRegister == property) {
1497            emitOpcode(op_get_by_pname);
1498            instructions().append(dst->index());
1499            instructions().append(base->index());
1500            instructions().append(property->index());
1501            instructions().append(context.expectedSubscriptRegister->index());
1502            instructions().append(context.iterRegister->index());
1503            instructions().append(context.indexRegister->index());
1504            return dst;
1505        }
1506    }
1507    emitOpcode(op_get_by_val);
1508    instructions().append(dst->index());
1509    instructions().append(base->index());
1510    instructions().append(property->index());
1511    return dst;
1512}
1513
1514RegisterID* BytecodeGenerator::emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value)
1515{
1516    emitOpcode(op_put_by_val);
1517    instructions().append(base->index());
1518    instructions().append(property->index());
1519    instructions().append(value->index());
1520    return value;
1521}
1522
1523RegisterID* BytecodeGenerator::emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
1524{
1525    emitOpcode(op_del_by_val);
1526    instructions().append(dst->index());
1527    instructions().append(base->index());
1528    instructions().append(property->index());
1529    return dst;
1530}
1531
1532RegisterID* BytecodeGenerator::emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value)
1533{
1534    emitOpcode(op_put_by_index);
1535    instructions().append(base->index());
1536    instructions().append(index);
1537    instructions().append(value->index());
1538    return value;
1539}
1540
1541RegisterID* BytecodeGenerator::emitNewObject(RegisterID* dst)
1542{
1543    emitOpcode(op_new_object);
1544    instructions().append(dst->index());
1545    return dst;
1546}
1547
1548RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements)
1549{
1550    Vector<RefPtr<RegisterID>, 16> argv;
1551    for (ElementNode* n = elements; n; n = n->next()) {
1552        if (n->elision())
1553            break;
1554        argv.append(newTemporary());
1555        // op_new_array requires the initial values to be a sequential range of registers
1556        ASSERT(argv.size() == 1 || argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1);
1557        emitNode(argv.last().get(), n->value());
1558    }
1559    emitOpcode(op_new_array);
1560    instructions().append(dst->index());
1561    instructions().append(argv.size() ? argv[0]->index() : 0); // argv
1562    instructions().append(argv.size()); // argc
1563    return dst;
1564}
1565
1566RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionBodyNode* function)
1567{
1568    return emitNewFunctionInternal(dst, m_codeBlock->addFunctionDecl(makeFunction(m_globalData, function)), false);
1569}
1570
1571RegisterID* BytecodeGenerator::emitLazyNewFunction(RegisterID* dst, FunctionBodyNode* function)
1572{
1573    std::pair<FunctionOffsetMap::iterator, bool> ptr = m_functionOffsets.add(function, 0);
1574    if (ptr.second)
1575        ptr.first->second = m_codeBlock->addFunctionDecl(makeFunction(m_globalData, function));
1576    return emitNewFunctionInternal(dst, ptr.first->second, true);
1577}
1578
1579RegisterID* BytecodeGenerator::emitNewFunctionInternal(RegisterID* dst, unsigned index, bool doNullCheck)
1580{
1581    createActivationIfNecessary();
1582    emitOpcode(op_new_func);
1583    instructions().append(dst->index());
1584    instructions().append(index);
1585    instructions().append(doNullCheck);
1586    return dst;
1587}
1588
1589RegisterID* BytecodeGenerator::emitNewRegExp(RegisterID* dst, PassRefPtr<RegExp> regExp)
1590{
1591    emitOpcode(op_new_regexp);
1592    instructions().append(dst->index());
1593    instructions().append(addRegExp(regExp));
1594    return dst;
1595}
1596
1597RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExprNode* n)
1598{
1599    FunctionBodyNode* function = n->body();
1600    unsigned index = m_codeBlock->addFunctionExpr(makeFunction(m_globalData, function));
1601
1602    createActivationIfNecessary();
1603    emitOpcode(op_new_func_exp);
1604    instructions().append(r0->index());
1605    instructions().append(index);
1606    return r0;
1607}
1608
1609RegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset)
1610{
1611    return emitCall(op_call, dst, func, callArguments, divot, startOffset, endOffset);
1612}
1613
1614void BytecodeGenerator::createArgumentsIfNecessary()
1615{
1616    if (m_codeType != FunctionCode)
1617        return;
1618
1619    if (!m_codeBlock->usesArguments())
1620        return;
1621
1622    // If we're in strict mode we tear off the arguments on function
1623    // entry, so there's no need to check if we need to create them
1624    // now
1625    if (m_codeBlock->isStrictMode())
1626        return;
1627
1628    emitOpcode(op_create_arguments);
1629    instructions().append(m_codeBlock->argumentsRegister());
1630}
1631
1632void BytecodeGenerator::createActivationIfNecessary()
1633{
1634    if (m_hasCreatedActivation)
1635        return;
1636    if (!m_codeBlock->needsFullScopeChain())
1637        return;
1638    emitOpcode(op_create_activation);
1639    instructions().append(m_activationRegister->index());
1640}
1641
1642RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset)
1643{
1644    return emitCall(op_call_eval, dst, func, callArguments, divot, startOffset, endOffset);
1645}
1646
1647RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset)
1648{
1649    ASSERT(opcodeID == op_call || opcodeID == op_call_eval);
1650    ASSERT(func->refCount());
1651
1652    if (m_shouldEmitProfileHooks)
1653        emitMove(callArguments.profileHookRegister(), func);
1654
1655    // Generate code for arguments.
1656    unsigned argumentIndex = 0;
1657    for (ArgumentListNode* n = callArguments.argumentsNode()->m_listNode; n; n = n->m_next)
1658        emitNode(callArguments.argumentRegister(argumentIndex++), n);
1659
1660    // Reserve space for call frame.
1661    Vector<RefPtr<RegisterID>, RegisterFile::CallFrameHeaderSize> callFrame;
1662    for (int i = 0; i < RegisterFile::CallFrameHeaderSize; ++i)
1663        callFrame.append(newTemporary());
1664
1665    if (m_shouldEmitProfileHooks) {
1666        emitOpcode(op_profile_will_call);
1667        instructions().append(callArguments.profileHookRegister()->index());
1668    }
1669
1670    emitExpressionInfo(divot, startOffset, endOffset);
1671
1672#if ENABLE(JIT)
1673    m_codeBlock->addCallLinkInfo();
1674#endif
1675
1676    // Emit call.
1677    emitOpcode(opcodeID);
1678    instructions().append(func->index()); // func
1679    instructions().append(callArguments.count()); // argCount
1680    instructions().append(callArguments.callFrame()); // registerOffset
1681    if (dst != ignoredResult()) {
1682        emitOpcode(op_call_put_result);
1683        instructions().append(dst->index()); // dst
1684    }
1685
1686    if (m_shouldEmitProfileHooks) {
1687        emitOpcode(op_profile_did_call);
1688        instructions().append(callArguments.profileHookRegister()->index());
1689    }
1690
1691    return dst;
1692}
1693
1694RegisterID* BytecodeGenerator::emitLoadVarargs(RegisterID* argCountDst, RegisterID* thisRegister, RegisterID* arguments)
1695{
1696    ASSERT(argCountDst->index() < arguments->index());
1697    emitOpcode(op_load_varargs);
1698    instructions().append(argCountDst->index());
1699    instructions().append(arguments->index());
1700    instructions().append(thisRegister->index() + RegisterFile::CallFrameHeaderSize); // initial registerOffset
1701    return argCountDst;
1702}
1703
1704RegisterID* BytecodeGenerator::emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* argCountRegister, unsigned divot, unsigned startOffset, unsigned endOffset)
1705{
1706    ASSERT(func->refCount());
1707    ASSERT(thisRegister->refCount());
1708    ASSERT(dst != func);
1709    if (m_shouldEmitProfileHooks) {
1710        emitOpcode(op_profile_will_call);
1711        instructions().append(func->index());
1712    }
1713
1714    emitExpressionInfo(divot, startOffset, endOffset);
1715
1716    // Emit call.
1717    emitOpcode(op_call_varargs);
1718    instructions().append(func->index()); // func
1719    instructions().append(argCountRegister->index()); // arg count
1720    instructions().append(thisRegister->index() + RegisterFile::CallFrameHeaderSize); // initial registerOffset
1721    if (dst != ignoredResult()) {
1722        emitOpcode(op_call_put_result);
1723        instructions().append(dst->index()); // dst
1724    }
1725    if (m_shouldEmitProfileHooks) {
1726        emitOpcode(op_profile_did_call);
1727        instructions().append(func->index());
1728    }
1729    return dst;
1730}
1731
1732RegisterID* BytecodeGenerator::emitReturn(RegisterID* src)
1733{
1734    if (m_codeBlock->needsFullScopeChain()) {
1735        emitOpcode(op_tear_off_activation);
1736        instructions().append(m_activationRegister->index());
1737        instructions().append(m_codeBlock->argumentsRegister());
1738    } else if (m_codeBlock->usesArguments() && m_codeBlock->m_numParameters > 1
1739               && !m_codeBlock->isStrictMode()) { // If there are no named parameters, there's nothing to tear off, since extra / unnamed parameters get copied to the arguments object at construct time.
1740        emitOpcode(op_tear_off_arguments);
1741        instructions().append(m_codeBlock->argumentsRegister());
1742    }
1743
1744    // Constructors use op_ret_object_or_this to check the result is an
1745    // object, unless we can trivially determine the check is not
1746    // necessary (currently, if the return value is 'this').
1747    if (isConstructor() && (src->index() != m_thisRegister.index())) {
1748        emitOpcode(op_ret_object_or_this);
1749        instructions().append(src->index());
1750        instructions().append(m_thisRegister.index());
1751        return src;
1752    }
1753    return emitUnaryNoDstOp(op_ret, src);
1754}
1755
1756RegisterID* BytecodeGenerator::emitUnaryNoDstOp(OpcodeID opcodeID, RegisterID* src)
1757{
1758    emitOpcode(opcodeID);
1759    instructions().append(src->index());
1760    return src;
1761}
1762
1763RegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset)
1764{
1765    ASSERT(func->refCount());
1766
1767    if (m_shouldEmitProfileHooks)
1768        emitMove(callArguments.profileHookRegister(), func);
1769
1770    // Generate code for arguments.
1771    unsigned argumentIndex = 0;
1772    if (ArgumentsNode* argumentsNode = callArguments.argumentsNode()) {
1773        for (ArgumentListNode* n = argumentsNode->m_listNode; n; n = n->m_next)
1774            emitNode(callArguments.argumentRegister(argumentIndex++), n);
1775    }
1776
1777    if (m_shouldEmitProfileHooks) {
1778        emitOpcode(op_profile_will_call);
1779        instructions().append(callArguments.profileHookRegister()->index());
1780    }
1781
1782    // Reserve space for call frame.
1783    Vector<RefPtr<RegisterID>, RegisterFile::CallFrameHeaderSize> callFrame;
1784    for (int i = 0; i < RegisterFile::CallFrameHeaderSize; ++i)
1785        callFrame.append(newTemporary());
1786
1787    emitExpressionInfo(divot, startOffset, endOffset);
1788
1789#if ENABLE(JIT)
1790    m_codeBlock->addCallLinkInfo();
1791#endif
1792
1793    emitOpcode(op_construct);
1794    instructions().append(func->index()); // func
1795    instructions().append(callArguments.count()); // argCount
1796    instructions().append(callArguments.callFrame()); // registerOffset
1797    if (dst != ignoredResult()) {
1798        emitOpcode(op_call_put_result);
1799        instructions().append(dst->index()); // dst
1800    }
1801
1802    if (m_shouldEmitProfileHooks) {
1803        emitOpcode(op_profile_did_call);
1804        instructions().append(callArguments.profileHookRegister()->index());
1805    }
1806
1807    return dst;
1808}
1809
1810RegisterID* BytecodeGenerator::emitStrcat(RegisterID* dst, RegisterID* src, int count)
1811{
1812    emitOpcode(op_strcat);
1813    instructions().append(dst->index());
1814    instructions().append(src->index());
1815    instructions().append(count);
1816
1817    return dst;
1818}
1819
1820void BytecodeGenerator::emitToPrimitive(RegisterID* dst, RegisterID* src)
1821{
1822    emitOpcode(op_to_primitive);
1823    instructions().append(dst->index());
1824    instructions().append(src->index());
1825}
1826
1827RegisterID* BytecodeGenerator::emitPushScope(RegisterID* scope)
1828{
1829    ASSERT(scope->isTemporary());
1830    ControlFlowContext context;
1831    context.isFinallyBlock = false;
1832    m_scopeContextStack.append(context);
1833    m_dynamicScopeDepth++;
1834
1835    return emitUnaryNoDstOp(op_push_scope, scope);
1836}
1837
1838void BytecodeGenerator::emitPopScope()
1839{
1840    ASSERT(m_scopeContextStack.size());
1841    ASSERT(!m_scopeContextStack.last().isFinallyBlock);
1842
1843    emitOpcode(op_pop_scope);
1844
1845    m_scopeContextStack.removeLast();
1846    m_dynamicScopeDepth--;
1847}
1848
1849void BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, int lastLine)
1850{
1851#if ENABLE(DEBUG_WITH_BREAKPOINT)
1852    if (debugHookID != DidReachBreakpoint)
1853        return;
1854#else
1855    if (!m_shouldEmitDebugHooks)
1856        return;
1857#endif
1858    emitOpcode(op_debug);
1859    instructions().append(debugHookID);
1860    instructions().append(firstLine);
1861    instructions().append(lastLine);
1862}
1863
1864void BytecodeGenerator::pushFinallyContext(Label* target, RegisterID* retAddrDst)
1865{
1866    ControlFlowContext scope;
1867    scope.isFinallyBlock = true;
1868    FinallyContext context = { target, retAddrDst };
1869    scope.finallyContext = context;
1870    m_scopeContextStack.append(scope);
1871    m_finallyDepth++;
1872}
1873
1874void BytecodeGenerator::popFinallyContext()
1875{
1876    ASSERT(m_scopeContextStack.size());
1877    ASSERT(m_scopeContextStack.last().isFinallyBlock);
1878    ASSERT(m_finallyDepth > 0);
1879    m_scopeContextStack.removeLast();
1880    m_finallyDepth--;
1881}
1882
1883LabelScope* BytecodeGenerator::breakTarget(const Identifier& name)
1884{
1885    // Reclaim free label scopes.
1886    //
1887    // The condition was previously coded as 'm_labelScopes.size() && !m_labelScopes.last().refCount()',
1888    // however sometimes this appears to lead to GCC going a little haywire and entering the loop with
1889    // size 0, leading to segfaulty badness.  We are yet to identify a valid cause within our code to
1890    // cause the GCC codegen to misbehave in this fashion, and as such the following refactoring of the
1891    // loop condition is a workaround.
1892    while (m_labelScopes.size()) {
1893        if  (m_labelScopes.last().refCount())
1894            break;
1895        m_labelScopes.removeLast();
1896    }
1897
1898    if (!m_labelScopes.size())
1899        return 0;
1900
1901    // We special-case the following, which is a syntax error in Firefox:
1902    // label:
1903    //     break;
1904    if (name.isEmpty()) {
1905        for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
1906            LabelScope* scope = &m_labelScopes[i];
1907            if (scope->type() != LabelScope::NamedLabel) {
1908                ASSERT(scope->breakTarget());
1909                return scope;
1910            }
1911        }
1912        return 0;
1913    }
1914
1915    for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
1916        LabelScope* scope = &m_labelScopes[i];
1917        if (scope->name() && *scope->name() == name) {
1918            ASSERT(scope->breakTarget());
1919            return scope;
1920        }
1921    }
1922    return 0;
1923}
1924
1925LabelScope* BytecodeGenerator::continueTarget(const Identifier& name)
1926{
1927    // Reclaim free label scopes.
1928    while (m_labelScopes.size() && !m_labelScopes.last().refCount())
1929        m_labelScopes.removeLast();
1930
1931    if (!m_labelScopes.size())
1932        return 0;
1933
1934    if (name.isEmpty()) {
1935        for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
1936            LabelScope* scope = &m_labelScopes[i];
1937            if (scope->type() == LabelScope::Loop) {
1938                ASSERT(scope->continueTarget());
1939                return scope;
1940            }
1941        }
1942        return 0;
1943    }
1944
1945    // Continue to the loop nested nearest to the label scope that matches
1946    // 'name'.
1947    LabelScope* result = 0;
1948    for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
1949        LabelScope* scope = &m_labelScopes[i];
1950        if (scope->type() == LabelScope::Loop) {
1951            ASSERT(scope->continueTarget());
1952            result = scope;
1953        }
1954        if (scope->name() && *scope->name() == name)
1955            return result; // may be 0
1956    }
1957    return 0;
1958}
1959
1960PassRefPtr<Label> BytecodeGenerator::emitComplexJumpScopes(Label* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope)
1961{
1962    while (topScope > bottomScope) {
1963        // First we count the number of dynamic scopes we need to remove to get
1964        // to a finally block.
1965        int nNormalScopes = 0;
1966        while (topScope > bottomScope) {
1967            if (topScope->isFinallyBlock)
1968                break;
1969            ++nNormalScopes;
1970            --topScope;
1971        }
1972
1973        if (nNormalScopes) {
1974            size_t begin = instructions().size();
1975
1976            // We need to remove a number of dynamic scopes to get to the next
1977            // finally block
1978            emitOpcode(op_jmp_scopes);
1979            instructions().append(nNormalScopes);
1980
1981            // If topScope == bottomScope then there isn't actually a finally block
1982            // left to emit, so make the jmp_scopes jump directly to the target label
1983            if (topScope == bottomScope) {
1984                instructions().append(target->bind(begin, instructions().size()));
1985                return target;
1986            }
1987
1988            // Otherwise we just use jmp_scopes to pop a group of scopes and go
1989            // to the next instruction
1990            RefPtr<Label> nextInsn = newLabel();
1991            instructions().append(nextInsn->bind(begin, instructions().size()));
1992            emitLabel(nextInsn.get());
1993        }
1994
1995        while (topScope > bottomScope && topScope->isFinallyBlock) {
1996            emitJumpSubroutine(topScope->finallyContext.retAddrDst, topScope->finallyContext.finallyAddr);
1997            --topScope;
1998        }
1999    }
2000    return emitJump(target);
2001}
2002
2003PassRefPtr<Label> BytecodeGenerator::emitJumpScopes(Label* target, int targetScopeDepth)
2004{
2005    ASSERT(scopeDepth() - targetScopeDepth >= 0);
2006    ASSERT(target->isForward());
2007
2008    size_t scopeDelta = scopeDepth() - targetScopeDepth;
2009    ASSERT(scopeDelta <= m_scopeContextStack.size());
2010    if (!scopeDelta)
2011        return emitJump(target);
2012
2013    if (m_finallyDepth)
2014        return emitComplexJumpScopes(target, &m_scopeContextStack.last(), &m_scopeContextStack.last() - scopeDelta);
2015
2016    size_t begin = instructions().size();
2017
2018    emitOpcode(op_jmp_scopes);
2019    instructions().append(scopeDelta);
2020    instructions().append(target->bind(begin, instructions().size()));
2021    return target;
2022}
2023
2024RegisterID* BytecodeGenerator::emitGetPropertyNames(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, Label* breakTarget)
2025{
2026    size_t begin = instructions().size();
2027
2028    emitOpcode(op_get_pnames);
2029    instructions().append(dst->index());
2030    instructions().append(base->index());
2031    instructions().append(i->index());
2032    instructions().append(size->index());
2033    instructions().append(breakTarget->bind(begin, instructions().size()));
2034    return dst;
2035}
2036
2037RegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, RegisterID* iter, Label* target)
2038{
2039    size_t begin = instructions().size();
2040
2041    emitOpcode(op_next_pname);
2042    instructions().append(dst->index());
2043    instructions().append(base->index());
2044    instructions().append(i->index());
2045    instructions().append(size->index());
2046    instructions().append(iter->index());
2047    instructions().append(target->bind(begin, instructions().size()));
2048    return dst;
2049}
2050
2051RegisterID* BytecodeGenerator::emitCatch(RegisterID* targetRegister, Label* start, Label* end)
2052{
2053    m_usesExceptions = true;
2054#if ENABLE(JIT)
2055    HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() };
2056#else
2057    HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth };
2058#endif
2059
2060    m_codeBlock->addExceptionHandler(info);
2061    emitOpcode(op_catch);
2062    instructions().append(targetRegister->index());
2063    return targetRegister;
2064}
2065
2066void BytecodeGenerator::emitThrowReferenceError(const UString& message)
2067{
2068    emitOpcode(op_throw_reference_error);
2069    instructions().append(addConstantValue(jsString(globalData(), message))->index());
2070}
2071
2072PassRefPtr<Label> BytecodeGenerator::emitJumpSubroutine(RegisterID* retAddrDst, Label* finally)
2073{
2074    size_t begin = instructions().size();
2075
2076    emitOpcode(op_jsr);
2077    instructions().append(retAddrDst->index());
2078    instructions().append(finally->bind(begin, instructions().size()));
2079    emitLabel(newLabel().get()); // Record the fact that the next instruction is implicitly labeled, because op_sret will return to it.
2080    return finally;
2081}
2082
2083void BytecodeGenerator::emitSubroutineReturn(RegisterID* retAddrSrc)
2084{
2085    emitOpcode(op_sret);
2086    instructions().append(retAddrSrc->index());
2087}
2088
2089void BytecodeGenerator::emitPushNewScope(RegisterID* dst, const Identifier& property, RegisterID* value)
2090{
2091    ControlFlowContext context;
2092    context.isFinallyBlock = false;
2093    m_scopeContextStack.append(context);
2094    m_dynamicScopeDepth++;
2095
2096    emitOpcode(op_push_new_scope);
2097    instructions().append(dst->index());
2098    instructions().append(addConstant(property));
2099    instructions().append(value->index());
2100}
2101
2102void BytecodeGenerator::beginSwitch(RegisterID* scrutineeRegister, SwitchInfo::SwitchType type)
2103{
2104    SwitchInfo info = { instructions().size(), type };
2105    switch (type) {
2106        case SwitchInfo::SwitchImmediate:
2107            emitOpcode(op_switch_imm);
2108            break;
2109        case SwitchInfo::SwitchCharacter:
2110            emitOpcode(op_switch_char);
2111            break;
2112        case SwitchInfo::SwitchString:
2113            emitOpcode(op_switch_string);
2114            break;
2115        default:
2116            ASSERT_NOT_REACHED();
2117    }
2118
2119    instructions().append(0); // place holder for table index
2120    instructions().append(0); // place holder for default target
2121    instructions().append(scrutineeRegister->index());
2122    m_switchContextStack.append(info);
2123}
2124
2125static int32_t keyForImmediateSwitch(ExpressionNode* node, int32_t min, int32_t max)
2126{
2127    UNUSED_PARAM(max);
2128    ASSERT(node->isNumber());
2129    double value = static_cast<NumberNode*>(node)->value();
2130    int32_t key = static_cast<int32_t>(value);
2131    ASSERT(key == value);
2132    ASSERT(key >= min);
2133    ASSERT(key <= max);
2134    return key - min;
2135}
2136
2137static void prepareJumpTableForImmediateSwitch(SimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, int32_t min, int32_t max)
2138{
2139    jumpTable.min = min;
2140    jumpTable.branchOffsets.resize(max - min + 1);
2141    jumpTable.branchOffsets.fill(0);
2142    for (uint32_t i = 0; i < clauseCount; ++i) {
2143        // We're emitting this after the clause labels should have been fixed, so
2144        // the labels should not be "forward" references
2145        ASSERT(!labels[i]->isForward());
2146        jumpTable.add(keyForImmediateSwitch(nodes[i], min, max), labels[i]->bind(switchAddress, switchAddress + 3));
2147    }
2148}
2149
2150static int32_t keyForCharacterSwitch(ExpressionNode* node, int32_t min, int32_t max)
2151{
2152    UNUSED_PARAM(max);
2153    ASSERT(node->isString());
2154    StringImpl* clause = static_cast<StringNode*>(node)->value().impl();
2155    ASSERT(clause->length() == 1);
2156
2157    int32_t key = clause->characters()[0];
2158    ASSERT(key >= min);
2159    ASSERT(key <= max);
2160    return key - min;
2161}
2162
2163static void prepareJumpTableForCharacterSwitch(SimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, int32_t min, int32_t max)
2164{
2165    jumpTable.min = min;
2166    jumpTable.branchOffsets.resize(max - min + 1);
2167    jumpTable.branchOffsets.fill(0);
2168    for (uint32_t i = 0; i < clauseCount; ++i) {
2169        // We're emitting this after the clause labels should have been fixed, so
2170        // the labels should not be "forward" references
2171        ASSERT(!labels[i]->isForward());
2172        jumpTable.add(keyForCharacterSwitch(nodes[i], min, max), labels[i]->bind(switchAddress, switchAddress + 3));
2173    }
2174}
2175
2176static void prepareJumpTableForStringSwitch(StringJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes)
2177{
2178    for (uint32_t i = 0; i < clauseCount; ++i) {
2179        // We're emitting this after the clause labels should have been fixed, so
2180        // the labels should not be "forward" references
2181        ASSERT(!labels[i]->isForward());
2182
2183        ASSERT(nodes[i]->isString());
2184        StringImpl* clause = static_cast<StringNode*>(nodes[i])->value().impl();
2185        OffsetLocation location;
2186        location.branchOffset = labels[i]->bind(switchAddress, switchAddress + 3);
2187        jumpTable.offsetTable.add(clause, location);
2188    }
2189}
2190
2191void BytecodeGenerator::endSwitch(uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, Label* defaultLabel, int32_t min, int32_t max)
2192{
2193    SwitchInfo switchInfo = m_switchContextStack.last();
2194    m_switchContextStack.removeLast();
2195    if (switchInfo.switchType == SwitchInfo::SwitchImmediate) {
2196        instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfImmediateSwitchJumpTables();
2197        instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
2198
2199        SimpleJumpTable& jumpTable = m_codeBlock->addImmediateSwitchJumpTable();
2200        prepareJumpTableForImmediateSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max);
2201    } else if (switchInfo.switchType == SwitchInfo::SwitchCharacter) {
2202        instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfCharacterSwitchJumpTables();
2203        instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
2204
2205        SimpleJumpTable& jumpTable = m_codeBlock->addCharacterSwitchJumpTable();
2206        prepareJumpTableForCharacterSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max);
2207    } else {
2208        ASSERT(switchInfo.switchType == SwitchInfo::SwitchString);
2209        instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfStringSwitchJumpTables();
2210        instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
2211
2212        StringJumpTable& jumpTable = m_codeBlock->addStringSwitchJumpTable();
2213        prepareJumpTableForStringSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes);
2214    }
2215}
2216
2217RegisterID* BytecodeGenerator::emitThrowExpressionTooDeepException()
2218{
2219    // It would be nice to do an even better job of identifying exactly where the expression is.
2220    // And we could make the caller pass the node pointer in, if there was some way of getting
2221    // that from an arbitrary node. However, calling emitExpressionInfo without any useful data
2222    // is still good enough to get us an accurate line number.
2223    m_expressionTooDeep = true;
2224    return newTemporary();
2225}
2226
2227void BytecodeGenerator::setIsNumericCompareFunction(bool isNumericCompareFunction)
2228{
2229    m_codeBlock->setIsNumericCompareFunction(isNumericCompareFunction);
2230}
2231
2232int BytecodeGenerator::argumentNumberFor(const Identifier& ident)
2233{
2234    int parameterCount = m_parameters.size(); // includes 'this'
2235    RegisterID* registerID = registerFor(ident);
2236    if (!registerID)
2237        return 0;
2238    int index = registerID->index() + RegisterFile::CallFrameHeaderSize + parameterCount;
2239    return (index > 0 && index < parameterCount) ? index : 0;
2240}
2241
2242} // namespace JSC
2243