1/*
2 * Copyright (C) 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
4 * Copyright (C) 2012 Igalia, S.L.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1.  Redistributions of source code must retain the above copyright
11 *     notice, this list of conditions and the following disclaimer.
12 * 2.  Redistributions in binary form must reproduce the above copyright
13 *     notice, this list of conditions and the following disclaimer in the
14 *     documentation and/or other materials provided with the distribution.
15 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16 *     its contributors may be used to endorse or promote products derived
17 *     from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "config.h"
32#include "BytecodeGenerator.h"
33
34#include "BatchedTransitionOptimizer.h"
35#include "Interpreter.h"
36#include "JSActivation.h"
37#include "JSFunction.h"
38#include "JSNameScope.h"
39#include "LowLevelInterpreter.h"
40#include "Operations.h"
41#include "Options.h"
42#include "StrongInlines.h"
43#include "UnlinkedCodeBlock.h"
44#include <wtf/text/WTFString.h>
45
46using namespace std;
47
48namespace JSC {
49
50void Label::setLocation(unsigned location)
51{
52    m_location = location;
53
54    unsigned size = m_unresolvedJumps.size();
55    for (unsigned i = 0; i < size; ++i)
56        m_generator->m_instructions[m_unresolvedJumps[i].second].u.operand = m_location - m_unresolvedJumps[i].first;
57}
58
59#ifndef NDEBUG
60void ResolveResult::checkValidity()
61{
62    switch (m_type) {
63    case Register:
64    case ReadOnlyRegister:
65        ASSERT(m_local);
66        return;
67    case Dynamic:
68        ASSERT(!m_local);
69        return;
70    case Lexical:
71    case ReadOnlyLexical:
72        ASSERT(!m_local);
73        return;
74    default:
75        RELEASE_ASSERT_NOT_REACHED();
76    }
77}
78#endif
79
80ParserError BytecodeGenerator::generate()
81{
82    SamplingRegion samplingRegion("Bytecode Generation");
83
84    m_codeBlock->setThisRegister(m_thisRegister.index());
85
86    m_scopeNode->emitBytecode(*this);
87
88    m_staticPropertyAnalyzer.kill();
89
90    for (unsigned i = 0; i < m_tryRanges.size(); ++i) {
91        TryRange& range = m_tryRanges[i];
92        int start = range.start->bind();
93        int end = range.end->bind();
94
95        // This will happen for empty try blocks and for some cases of finally blocks:
96        //
97        // try {
98        //    try {
99        //    } finally {
100        //        return 42;
101        //        // *HERE*
102        //    }
103        // } finally {
104        //    print("things");
105        // }
106        //
107        // The return will pop scopes to execute the outer finally block. But this includes
108        // popping the try context for the inner try. The try context is live in the fall-through
109        // part of the finally block not because we will emit a handler that overlaps the finally,
110        // but because we haven't yet had a chance to plant the catch target. Then when we finish
111        // emitting code for the outer finally block, we repush the try contex, this time with a
112        // new start index. But that means that the start index for the try range corresponding
113        // to the inner-finally-following-the-return (marked as "*HERE*" above) will be greater
114        // than the end index of the try block. This is harmless since end < start handlers will
115        // never get matched in our logic, but we do the runtime a favor and choose to not emit
116        // such handlers at all.
117        if (end <= start)
118            continue;
119
120        ASSERT(range.tryData->targetScopeDepth != UINT_MAX);
121        UnlinkedHandlerInfo info = {
122            static_cast<uint32_t>(start), static_cast<uint32_t>(end),
123            static_cast<uint32_t>(range.tryData->target->bind()),
124            range.tryData->targetScopeDepth
125        };
126        m_codeBlock->addExceptionHandler(info);
127    }
128
129    m_codeBlock->instructions() = RefCountedArray<UnlinkedInstruction>(m_instructions);
130
131    m_codeBlock->shrinkToFit();
132
133    if (m_expressionTooDeep)
134        return ParserError(ParserError::OutOfMemory);
135    return ParserError(ParserError::ErrorNone);
136}
137
138bool BytecodeGenerator::addVar(const Identifier& ident, bool isConstant, RegisterID*& r0)
139{
140    int index = m_calleeRegisters.size();
141    SymbolTableEntry newEntry(index, isConstant ? ReadOnly : 0);
142    SymbolTable::AddResult result = symbolTable().add(ident.impl(), newEntry);
143
144    if (!result.isNewEntry) {
145        r0 = &registerFor(result.iterator->value.getIndex());
146        return false;
147    }
148
149    r0 = addVar();
150    return true;
151}
152
153void BytecodeGenerator::preserveLastVar()
154{
155    if ((m_firstConstantIndex = m_calleeRegisters.size()) != 0)
156        m_lastVar = &m_calleeRegisters.last();
157}
158
159BytecodeGenerator::BytecodeGenerator(VM& vm, JSScope*, ProgramNode* programNode, UnlinkedProgramCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
160    : m_shouldEmitDebugHooks(debuggerMode == DebuggerOn)
161    , m_shouldEmitProfileHooks(profilerMode == ProfilerOn)
162    , m_symbolTable(0)
163    , m_scopeNode(programNode)
164    , m_codeBlock(vm, codeBlock)
165    , m_thisRegister(CallFrame::thisArgumentOffset())
166    , m_emptyValueRegister(0)
167    , m_globalObjectRegister(0)
168    , m_finallyDepth(0)
169    , m_dynamicScopeDepth(0)
170    , m_codeType(GlobalCode)
171    , m_nextConstantOffset(0)
172    , m_globalConstantIndex(0)
173    , m_hasCreatedActivation(true)
174    , m_firstLazyFunction(0)
175    , m_lastLazyFunction(0)
176    , m_staticPropertyAnalyzer(&m_instructions)
177    , m_vm(&vm)
178    , m_lastOpcodeID(op_end)
179#ifndef NDEBUG
180    , m_lastOpcodePosition(0)
181#endif
182    , m_stack(wtfThreadData().stack())
183    , m_usesExceptions(false)
184    , m_expressionTooDeep(false)
185{
186    if (m_shouldEmitDebugHooks)
187        m_codeBlock->setNeedsFullScopeChain(true);
188
189    m_codeBlock->setNumParameters(1); // Allocate space for "this"
190
191    emitOpcode(op_enter);
192
193    const VarStack& varStack = programNode->varStack();
194    const FunctionStack& functionStack = programNode->functionStack();
195
196    for (size_t i = 0; i < functionStack.size(); ++i) {
197        FunctionBodyNode* function = functionStack[i];
198        UnlinkedFunctionExecutable* unlinkedFunction = makeFunction(function);
199        codeBlock->addFunctionDeclaration(*m_vm, function->ident(), unlinkedFunction);
200    }
201
202    for (size_t i = 0; i < varStack.size(); ++i)
203        codeBlock->addVariableDeclaration(*varStack[i].first, !!(varStack[i].second & DeclarationStacks::IsConstant));
204
205}
206
207BytecodeGenerator::BytecodeGenerator(VM& vm, JSScope* scope, FunctionBodyNode* functionBody, UnlinkedFunctionCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
208    : m_shouldEmitDebugHooks(debuggerMode == DebuggerOn)
209    , m_shouldEmitProfileHooks(profilerMode == ProfilerOn)
210    , m_symbolTable(codeBlock->symbolTable())
211    , m_scopeNode(functionBody)
212    , m_scope(vm, scope)
213    , m_codeBlock(vm, codeBlock)
214    , m_activationRegister(0)
215    , m_emptyValueRegister(0)
216    , m_globalObjectRegister(0)
217    , m_finallyDepth(0)
218    , m_dynamicScopeDepth(0)
219    , m_codeType(FunctionCode)
220    , m_nextConstantOffset(0)
221    , m_globalConstantIndex(0)
222    , m_hasCreatedActivation(false)
223    , m_firstLazyFunction(0)
224    , m_lastLazyFunction(0)
225    , m_staticPropertyAnalyzer(&m_instructions)
226    , m_vm(&vm)
227    , m_lastOpcodeID(op_end)
228#ifndef NDEBUG
229    , m_lastOpcodePosition(0)
230#endif
231    , m_stack(wtfThreadData().stack())
232    , m_usesExceptions(false)
233    , m_expressionTooDeep(false)
234{
235    if (m_shouldEmitDebugHooks)
236        m_codeBlock->setNeedsFullScopeChain(true);
237
238    m_symbolTable->setUsesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode());
239    m_symbolTable->setParameterCountIncludingThis(functionBody->parameters()->size() + 1);
240
241    emitOpcode(op_enter);
242    if (m_codeBlock->needsFullScopeChain()) {
243        m_activationRegister = addVar();
244        emitInitLazyRegister(m_activationRegister);
245        m_codeBlock->setActivationRegister(m_activationRegister->index());
246    }
247
248    m_symbolTable->setCaptureStart(m_codeBlock->m_numVars);
249
250    if (functionBody->usesArguments() || codeBlock->usesEval() || m_shouldEmitDebugHooks) { // May reify arguments object.
251        RegisterID* unmodifiedArgumentsRegister = addVar(); // Anonymous, so it can't be modified by user code.
252        RegisterID* argumentsRegister = addVar(propertyNames().arguments, false); // Can be changed by assigning to 'arguments'.
253
254        // We can save a little space by hard-coding the knowledge that the two
255        // 'arguments' values are stored in consecutive registers, and storing
256        // only the index of the assignable one.
257        codeBlock->setArgumentsRegister(argumentsRegister->index());
258        ASSERT_UNUSED(unmodifiedArgumentsRegister, unmodifiedArgumentsRegister->index() == JSC::unmodifiedArgumentsRegister(codeBlock->argumentsRegister()));
259
260        emitInitLazyRegister(argumentsRegister);
261        emitInitLazyRegister(unmodifiedArgumentsRegister);
262
263        if (m_codeBlock->isStrictMode()) {
264            emitOpcode(op_create_arguments);
265            instructions().append(argumentsRegister->index());
266        }
267
268        // The debugger currently retrieves the arguments object from an activation rather than pulling
269        // it from a call frame.  In the long-term it should stop doing that (<rdar://problem/6911886>),
270        // but for now we force eager creation of the arguments object when debugging.
271        if (m_shouldEmitDebugHooks) {
272            emitOpcode(op_create_arguments);
273            instructions().append(argumentsRegister->index());
274        }
275    }
276
277    bool shouldCaptureAllTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval();
278
279    bool capturesAnyArgumentByName = false;
280    Vector<RegisterID*, 0, UnsafeVectorOverflow> capturedArguments;
281    if (functionBody->hasCapturedVariables() || shouldCaptureAllTheThings) {
282        FunctionParameters& parameters = *functionBody->parameters();
283        capturedArguments.resize(parameters.size());
284        for (size_t i = 0; i < parameters.size(); ++i) {
285            capturedArguments[i] = 0;
286            if (!functionBody->captures(parameters.at(i)) && !shouldCaptureAllTheThings)
287                continue;
288            capturesAnyArgumentByName = true;
289            capturedArguments[i] = addVar();
290        }
291    }
292
293    if (capturesAnyArgumentByName && !codeBlock->isStrictMode()) {
294        size_t parameterCount = m_symbolTable->parameterCount();
295        OwnArrayPtr<SlowArgument> slowArguments = adoptArrayPtr(new SlowArgument[parameterCount]);
296        for (size_t i = 0; i < parameterCount; ++i) {
297            if (!capturedArguments[i]) {
298                ASSERT(slowArguments[i].status == SlowArgument::Normal);
299                slowArguments[i].index = CallFrame::argumentOffset(i);
300                continue;
301            }
302            slowArguments[i].status = SlowArgument::Captured;
303            slowArguments[i].index = capturedArguments[i]->index();
304        }
305        m_symbolTable->setSlowArguments(slowArguments.release());
306    }
307
308    RegisterID* calleeRegister = resolveCallee(functionBody); // May push to the scope chain and/or add a captured var.
309
310    const DeclarationStacks::FunctionStack& functionStack = functionBody->functionStack();
311    const DeclarationStacks::VarStack& varStack = functionBody->varStack();
312
313    // Captured variables and functions go first so that activations don't have
314    // to step over the non-captured locals to mark them.
315    m_hasCreatedActivation = false;
316    if (functionBody->hasCapturedVariables()) {
317        for (size_t i = 0; i < functionStack.size(); ++i) {
318            FunctionBodyNode* function = functionStack[i];
319            const Identifier& ident = function->ident();
320            if (functionBody->captures(ident)) {
321                if (!m_hasCreatedActivation) {
322                    m_hasCreatedActivation = true;
323                    emitOpcode(op_create_activation);
324                    instructions().append(m_activationRegister->index());
325                }
326                m_functions.add(ident.impl());
327                emitNewFunction(addVar(ident, false), function);
328            }
329        }
330        for (size_t i = 0; i < varStack.size(); ++i) {
331            const Identifier& ident = *varStack[i].first;
332            if (functionBody->captures(ident))
333                addVar(ident, varStack[i].second & DeclarationStacks::IsConstant);
334        }
335    }
336    bool canLazilyCreateFunctions = !functionBody->needsActivationForMoreThanVariables() && !m_shouldEmitDebugHooks;
337    if (!canLazilyCreateFunctions && !m_hasCreatedActivation) {
338        m_hasCreatedActivation = true;
339        emitOpcode(op_create_activation);
340        instructions().append(m_activationRegister->index());
341    }
342
343    m_symbolTable->setCaptureEnd(codeBlock->m_numVars);
344
345    m_firstLazyFunction = codeBlock->m_numVars;
346    for (size_t i = 0; i < functionStack.size(); ++i) {
347        FunctionBodyNode* function = functionStack[i];
348        const Identifier& ident = function->ident();
349        if (!functionBody->captures(ident)) {
350            m_functions.add(ident.impl());
351            RefPtr<RegisterID> reg = addVar(ident, false);
352            // Don't lazily create functions that override the name 'arguments'
353            // as this would complicate lazy instantiation of actual arguments.
354            if (!canLazilyCreateFunctions || ident == propertyNames().arguments)
355                emitNewFunction(reg.get(), function);
356            else {
357                emitInitLazyRegister(reg.get());
358                m_lazyFunctions.set(reg->index(), function);
359            }
360        }
361    }
362    m_lastLazyFunction = canLazilyCreateFunctions ? codeBlock->m_numVars : m_firstLazyFunction;
363    for (size_t i = 0; i < varStack.size(); ++i) {
364        const Identifier& ident = *varStack[i].first;
365        if (!functionBody->captures(ident))
366            addVar(ident, varStack[i].second & DeclarationStacks::IsConstant);
367    }
368
369    if (shouldCaptureAllTheThings)
370        m_symbolTable->setCaptureEnd(codeBlock->m_numVars);
371
372    FunctionParameters& parameters = *functionBody->parameters();
373    m_parameters.grow(parameters.size() + 1); // reserve space for "this"
374
375    // Add "this" as a parameter
376    int nextParameterIndex = CallFrame::thisArgumentOffset();
377    m_thisRegister.setIndex(nextParameterIndex--);
378    m_codeBlock->addParameter();
379
380    for (size_t i = 0; i < parameters.size(); ++i, --nextParameterIndex) {
381        int index = nextParameterIndex;
382        if (capturedArguments.size() && capturedArguments[i]) {
383            ASSERT((functionBody->hasCapturedVariables() && functionBody->captures(parameters.at(i))) || shouldCaptureAllTheThings);
384            index = capturedArguments[i]->index();
385            RegisterID original(nextParameterIndex);
386            emitMove(capturedArguments[i], &original);
387        }
388        addParameter(parameters.at(i), index);
389    }
390    preserveLastVar();
391
392    // We declare the callee's name last because it should lose to a var, function, and/or parameter declaration.
393    addCallee(functionBody, calleeRegister);
394
395    if (isConstructor()) {
396        emitCreateThis(&m_thisRegister);
397    } else if (!codeBlock->isStrictMode() && (functionBody->usesThis() || codeBlock->usesEval() || m_shouldEmitDebugHooks)) {
398        UnlinkedValueProfile profile = emitProfiledOpcode(op_convert_this);
399        instructions().append(kill(&m_thisRegister));
400        instructions().append(profile);
401    }
402}
403
404BytecodeGenerator::BytecodeGenerator(VM& vm, JSScope* scope, EvalNode* evalNode, UnlinkedEvalCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode)
405    : m_shouldEmitDebugHooks(debuggerMode == DebuggerOn)
406    , m_shouldEmitProfileHooks(profilerMode == ProfilerOn)
407    , m_symbolTable(codeBlock->symbolTable())
408    , m_scopeNode(evalNode)
409    , m_scope(vm, scope)
410    , m_codeBlock(vm, codeBlock)
411    , m_thisRegister(CallFrame::thisArgumentOffset())
412    , m_emptyValueRegister(0)
413    , m_globalObjectRegister(0)
414    , m_finallyDepth(0)
415    , m_dynamicScopeDepth(0)
416    , m_codeType(EvalCode)
417    , m_nextConstantOffset(0)
418    , m_globalConstantIndex(0)
419    , m_hasCreatedActivation(true)
420    , m_firstLazyFunction(0)
421    , m_lastLazyFunction(0)
422    , m_staticPropertyAnalyzer(&m_instructions)
423    , m_vm(&vm)
424    , m_lastOpcodeID(op_end)
425#ifndef NDEBUG
426    , m_lastOpcodePosition(0)
427#endif
428    , m_stack(wtfThreadData().stack())
429    , m_usesExceptions(false)
430    , m_expressionTooDeep(false)
431{
432    m_codeBlock->setNeedsFullScopeChain(true);
433
434    m_symbolTable->setUsesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode());
435    m_codeBlock->setNumParameters(1);
436
437    emitOpcode(op_enter);
438
439    const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack();
440    for (size_t i = 0; i < functionStack.size(); ++i)
441        m_codeBlock->addFunctionDecl(makeFunction(functionStack[i]));
442
443    const DeclarationStacks::VarStack& varStack = evalNode->varStack();
444    unsigned numVariables = varStack.size();
445    Vector<Identifier, 0, UnsafeVectorOverflow> variables;
446    variables.reserveCapacity(numVariables);
447    for (size_t i = 0; i < numVariables; ++i)
448        variables.append(*varStack[i].first);
449    codeBlock->adoptVariables(variables);
450    preserveLastVar();
451}
452
453BytecodeGenerator::~BytecodeGenerator()
454{
455}
456
457RegisterID* BytecodeGenerator::emitInitLazyRegister(RegisterID* reg)
458{
459    emitOpcode(op_init_lazy_reg);
460    instructions().append(reg->index());
461    return reg;
462}
463
464RegisterID* BytecodeGenerator::resolveCallee(FunctionBodyNode* functionBodyNode)
465{
466    if (functionBodyNode->ident().isNull() || !functionBodyNode->functionNameIsInScope())
467        return 0;
468
469    m_calleeRegister.setIndex(JSStack::Callee);
470
471    // If non-strict eval is in play, we use a separate object in the scope chain for the callee's name.
472    if ((m_codeBlock->usesEval() && !m_codeBlock->isStrictMode()) || m_shouldEmitDebugHooks) {
473        emitOpcode(op_push_name_scope);
474        instructions().append(addConstant(functionBodyNode->ident()));
475        instructions().append(m_calleeRegister.index());
476        instructions().append(ReadOnly | DontDelete);
477        return 0;
478    }
479
480    if (!functionBodyNode->captures(functionBodyNode->ident()))
481        return &m_calleeRegister;
482
483    // Move the callee into the captured section of the stack.
484    return emitMove(addVar(), &m_calleeRegister);
485}
486
487void BytecodeGenerator::addCallee(FunctionBodyNode* functionBodyNode, RegisterID* calleeRegister)
488{
489    if (functionBodyNode->ident().isNull() || !functionBodyNode->functionNameIsInScope())
490        return;
491
492    // If non-strict eval is in play, we use a separate object in the scope chain for the callee's name.
493    if ((m_codeBlock->usesEval() && !m_codeBlock->isStrictMode()) || m_shouldEmitDebugHooks)
494        return;
495
496    ASSERT(calleeRegister);
497    symbolTable().add(functionBodyNode->ident().impl(), SymbolTableEntry(calleeRegister->index(), ReadOnly));
498}
499
500void BytecodeGenerator::addParameter(const Identifier& ident, int parameterIndex)
501{
502    // Parameters overwrite var declarations, but not function declarations.
503    StringImpl* rep = ident.impl();
504    if (!m_functions.contains(rep)) {
505        symbolTable().set(rep, parameterIndex);
506        RegisterID& parameter = registerFor(parameterIndex);
507        parameter.setIndex(parameterIndex);
508    }
509
510    // To maintain the calling convention, we have to allocate unique space for
511    // each parameter, even if the parameter doesn't make it into the symbol table.
512    m_codeBlock->addParameter();
513}
514
515bool BytecodeGenerator::willResolveToArguments(const Identifier& ident)
516{
517    if (ident != propertyNames().arguments)
518        return false;
519
520    if (!shouldOptimizeLocals())
521        return false;
522
523    SymbolTableEntry entry = symbolTable().get(ident.impl());
524    if (entry.isNull())
525        return false;
526
527    if (m_codeBlock->usesArguments() && m_codeType == FunctionCode)
528        return true;
529
530    return false;
531}
532
533RegisterID* BytecodeGenerator::uncheckedRegisterForArguments()
534{
535    ASSERT(willResolveToArguments(propertyNames().arguments));
536
537    SymbolTableEntry entry = symbolTable().get(propertyNames().arguments.impl());
538    ASSERT(!entry.isNull());
539    return &registerFor(entry.getIndex());
540}
541
542RegisterID* BytecodeGenerator::createLazyRegisterIfNecessary(RegisterID* reg)
543{
544    if (m_lastLazyFunction <= reg->index() || reg->index() < m_firstLazyFunction)
545        return reg;
546    emitLazyNewFunction(reg, m_lazyFunctions.get(reg->index()));
547    return reg;
548}
549
550RegisterID* BytecodeGenerator::newRegister()
551{
552    m_calleeRegisters.append(m_calleeRegisters.size());
553    m_codeBlock->m_numCalleeRegisters = max<int>(m_codeBlock->m_numCalleeRegisters, m_calleeRegisters.size());
554    return &m_calleeRegisters.last();
555}
556
557RegisterID* BytecodeGenerator::newTemporary()
558{
559    // Reclaim free register IDs.
560    while (m_calleeRegisters.size() && !m_calleeRegisters.last().refCount())
561        m_calleeRegisters.removeLast();
562
563    RegisterID* result = newRegister();
564    result->setTemporary();
565    return result;
566}
567
568LabelScopePtr BytecodeGenerator::newLabelScope(LabelScope::Type type, const Identifier* name)
569{
570    // Reclaim free label scopes.
571    while (m_labelScopes.size() && !m_labelScopes.last().refCount())
572        m_labelScopes.removeLast();
573
574    // Allocate new label scope.
575    LabelScope scope(type, name, scopeDepth(), newLabel(), type == LabelScope::Loop ? newLabel() : PassRefPtr<Label>()); // Only loops have continue targets.
576    m_labelScopes.append(scope);
577    return LabelScopePtr(&m_labelScopes, m_labelScopes.size() - 1);
578}
579
580PassRefPtr<Label> BytecodeGenerator::newLabel()
581{
582    // Reclaim free label IDs.
583    while (m_labels.size() && !m_labels.last().refCount())
584        m_labels.removeLast();
585
586    // Allocate new label ID.
587    m_labels.append(this);
588    return &m_labels.last();
589}
590
591PassRefPtr<Label> BytecodeGenerator::emitLabel(Label* l0)
592{
593    unsigned newLabelIndex = instructions().size();
594    l0->setLocation(newLabelIndex);
595
596    if (m_codeBlock->numberOfJumpTargets()) {
597        unsigned lastLabelIndex = m_codeBlock->lastJumpTarget();
598        ASSERT(lastLabelIndex <= newLabelIndex);
599        if (newLabelIndex == lastLabelIndex) {
600            // Peephole optimizations have already been disabled by emitting the last label
601            return l0;
602        }
603    }
604
605    m_codeBlock->addJumpTarget(newLabelIndex);
606
607    // This disables peephole optimizations when an instruction is a jump target
608    m_lastOpcodeID = op_end;
609    return l0;
610}
611
612void BytecodeGenerator::emitOpcode(OpcodeID opcodeID)
613{
614#ifndef NDEBUG
615    size_t opcodePosition = instructions().size();
616    ASSERT(opcodePosition - m_lastOpcodePosition == opcodeLength(m_lastOpcodeID) || m_lastOpcodeID == op_end);
617    m_lastOpcodePosition = opcodePosition;
618#endif
619    instructions().append(opcodeID);
620    m_lastOpcodeID = opcodeID;
621}
622
623UnlinkedArrayProfile BytecodeGenerator::newArrayProfile()
624{
625#if ENABLE(VALUE_PROFILER)
626    return m_codeBlock->addArrayProfile();
627#else
628    return 0;
629#endif
630}
631
632UnlinkedArrayAllocationProfile BytecodeGenerator::newArrayAllocationProfile()
633{
634#if ENABLE(VALUE_PROFILER)
635    return m_codeBlock->addArrayAllocationProfile();
636#else
637    return 0;
638#endif
639}
640
641UnlinkedObjectAllocationProfile BytecodeGenerator::newObjectAllocationProfile()
642{
643    return m_codeBlock->addObjectAllocationProfile();
644}
645
646UnlinkedValueProfile BytecodeGenerator::emitProfiledOpcode(OpcodeID opcodeID)
647{
648#if ENABLE(VALUE_PROFILER)
649    UnlinkedValueProfile result = m_codeBlock->addValueProfile();
650#else
651    UnlinkedValueProfile result = 0;
652#endif
653    emitOpcode(opcodeID);
654    return result;
655}
656
657void BytecodeGenerator::emitLoopHint()
658{
659    emitOpcode(op_loop_hint);
660}
661
662void BytecodeGenerator::retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index)
663{
664    ASSERT(instructions().size() >= 4);
665    size_t size = instructions().size();
666    dstIndex = instructions().at(size - 3).u.operand;
667    src1Index = instructions().at(size - 2).u.operand;
668    src2Index = instructions().at(size - 1).u.operand;
669}
670
671void BytecodeGenerator::retrieveLastUnaryOp(int& dstIndex, int& srcIndex)
672{
673    ASSERT(instructions().size() >= 3);
674    size_t size = instructions().size();
675    dstIndex = instructions().at(size - 2).u.operand;
676    srcIndex = instructions().at(size - 1).u.operand;
677}
678
679void ALWAYS_INLINE BytecodeGenerator::rewindBinaryOp()
680{
681    ASSERT(instructions().size() >= 4);
682    instructions().shrink(instructions().size() - 4);
683    m_lastOpcodeID = op_end;
684}
685
686void ALWAYS_INLINE BytecodeGenerator::rewindUnaryOp()
687{
688    ASSERT(instructions().size() >= 3);
689    instructions().shrink(instructions().size() - 3);
690    m_lastOpcodeID = op_end;
691}
692
693PassRefPtr<Label> BytecodeGenerator::emitJump(Label* target)
694{
695    size_t begin = instructions().size();
696    emitOpcode(op_jmp);
697    instructions().append(target->bind(begin, instructions().size()));
698    return target;
699}
700
701PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* target)
702{
703    if (m_lastOpcodeID == op_less) {
704        int dstIndex;
705        int src1Index;
706        int src2Index;
707
708        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
709
710        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
711            rewindBinaryOp();
712
713            size_t begin = instructions().size();
714            emitOpcode(op_jless);
715            instructions().append(src1Index);
716            instructions().append(src2Index);
717            instructions().append(target->bind(begin, instructions().size()));
718            return target;
719        }
720    } else if (m_lastOpcodeID == op_lesseq) {
721        int dstIndex;
722        int src1Index;
723        int src2Index;
724
725        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
726
727        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
728            rewindBinaryOp();
729
730            size_t begin = instructions().size();
731            emitOpcode(op_jlesseq);
732            instructions().append(src1Index);
733            instructions().append(src2Index);
734            instructions().append(target->bind(begin, instructions().size()));
735            return target;
736        }
737    } else if (m_lastOpcodeID == op_greater) {
738        int dstIndex;
739        int src1Index;
740        int src2Index;
741
742        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
743
744        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
745            rewindBinaryOp();
746
747            size_t begin = instructions().size();
748            emitOpcode(op_jgreater);
749            instructions().append(src1Index);
750            instructions().append(src2Index);
751            instructions().append(target->bind(begin, instructions().size()));
752            return target;
753        }
754    } else if (m_lastOpcodeID == op_greatereq) {
755        int dstIndex;
756        int src1Index;
757        int src2Index;
758
759        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
760
761        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
762            rewindBinaryOp();
763
764            size_t begin = instructions().size();
765            emitOpcode(op_jgreatereq);
766            instructions().append(src1Index);
767            instructions().append(src2Index);
768            instructions().append(target->bind(begin, instructions().size()));
769            return target;
770        }
771    } else if (m_lastOpcodeID == op_eq_null && target->isForward()) {
772        int dstIndex;
773        int srcIndex;
774
775        retrieveLastUnaryOp(dstIndex, srcIndex);
776
777        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
778            rewindUnaryOp();
779
780            size_t begin = instructions().size();
781            emitOpcode(op_jeq_null);
782            instructions().append(srcIndex);
783            instructions().append(target->bind(begin, instructions().size()));
784            return target;
785        }
786    } else if (m_lastOpcodeID == op_neq_null && target->isForward()) {
787        int dstIndex;
788        int srcIndex;
789
790        retrieveLastUnaryOp(dstIndex, srcIndex);
791
792        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
793            rewindUnaryOp();
794
795            size_t begin = instructions().size();
796            emitOpcode(op_jneq_null);
797            instructions().append(srcIndex);
798            instructions().append(target->bind(begin, instructions().size()));
799            return target;
800        }
801    }
802
803    size_t begin = instructions().size();
804
805    emitOpcode(op_jtrue);
806    instructions().append(cond->index());
807    instructions().append(target->bind(begin, instructions().size()));
808    return target;
809}
810
811PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* target)
812{
813    if (m_lastOpcodeID == op_less && target->isForward()) {
814        int dstIndex;
815        int src1Index;
816        int src2Index;
817
818        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
819
820        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
821            rewindBinaryOp();
822
823            size_t begin = instructions().size();
824            emitOpcode(op_jnless);
825            instructions().append(src1Index);
826            instructions().append(src2Index);
827            instructions().append(target->bind(begin, instructions().size()));
828            return target;
829        }
830    } else if (m_lastOpcodeID == op_lesseq && target->isForward()) {
831        int dstIndex;
832        int src1Index;
833        int src2Index;
834
835        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
836
837        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
838            rewindBinaryOp();
839
840            size_t begin = instructions().size();
841            emitOpcode(op_jnlesseq);
842            instructions().append(src1Index);
843            instructions().append(src2Index);
844            instructions().append(target->bind(begin, instructions().size()));
845            return target;
846        }
847    } else if (m_lastOpcodeID == op_greater && target->isForward()) {
848        int dstIndex;
849        int src1Index;
850        int src2Index;
851
852        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
853
854        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
855            rewindBinaryOp();
856
857            size_t begin = instructions().size();
858            emitOpcode(op_jngreater);
859            instructions().append(src1Index);
860            instructions().append(src2Index);
861            instructions().append(target->bind(begin, instructions().size()));
862            return target;
863        }
864    } else if (m_lastOpcodeID == op_greatereq && target->isForward()) {
865        int dstIndex;
866        int src1Index;
867        int src2Index;
868
869        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
870
871        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
872            rewindBinaryOp();
873
874            size_t begin = instructions().size();
875            emitOpcode(op_jngreatereq);
876            instructions().append(src1Index);
877            instructions().append(src2Index);
878            instructions().append(target->bind(begin, instructions().size()));
879            return target;
880        }
881    } else if (m_lastOpcodeID == op_not) {
882        int dstIndex;
883        int srcIndex;
884
885        retrieveLastUnaryOp(dstIndex, srcIndex);
886
887        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
888            rewindUnaryOp();
889
890            size_t begin = instructions().size();
891            emitOpcode(op_jtrue);
892            instructions().append(srcIndex);
893            instructions().append(target->bind(begin, instructions().size()));
894            return target;
895        }
896    } else if (m_lastOpcodeID == op_eq_null && target->isForward()) {
897        int dstIndex;
898        int srcIndex;
899
900        retrieveLastUnaryOp(dstIndex, srcIndex);
901
902        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
903            rewindUnaryOp();
904
905            size_t begin = instructions().size();
906            emitOpcode(op_jneq_null);
907            instructions().append(srcIndex);
908            instructions().append(target->bind(begin, instructions().size()));
909            return target;
910        }
911    } else if (m_lastOpcodeID == op_neq_null && target->isForward()) {
912        int dstIndex;
913        int srcIndex;
914
915        retrieveLastUnaryOp(dstIndex, srcIndex);
916
917        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
918            rewindUnaryOp();
919
920            size_t begin = instructions().size();
921            emitOpcode(op_jeq_null);
922            instructions().append(srcIndex);
923            instructions().append(target->bind(begin, instructions().size()));
924            return target;
925        }
926    }
927
928    size_t begin = instructions().size();
929    emitOpcode(op_jfalse);
930    instructions().append(cond->index());
931    instructions().append(target->bind(begin, instructions().size()));
932    return target;
933}
934
935PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionCall(RegisterID* cond, Label* target)
936{
937    size_t begin = instructions().size();
938
939    emitOpcode(op_jneq_ptr);
940    instructions().append(cond->index());
941    instructions().append(Special::CallFunction);
942    instructions().append(target->bind(begin, instructions().size()));
943    return target;
944}
945
946PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond, Label* target)
947{
948    size_t begin = instructions().size();
949
950    emitOpcode(op_jneq_ptr);
951    instructions().append(cond->index());
952    instructions().append(Special::ApplyFunction);
953    instructions().append(target->bind(begin, instructions().size()));
954    return target;
955}
956
957unsigned BytecodeGenerator::addConstant(const Identifier& ident)
958{
959    StringImpl* rep = ident.impl();
960    IdentifierMap::AddResult result = m_identifierMap.add(rep, m_codeBlock->numberOfIdentifiers());
961    if (result.isNewEntry)
962        m_codeBlock->addIdentifier(Identifier(m_vm, rep));
963
964    return result.iterator->value;
965}
966
967// We can't hash JSValue(), so we use a dedicated data member to cache it.
968RegisterID* BytecodeGenerator::addConstantEmptyValue()
969{
970    if (!m_emptyValueRegister) {
971        int index = m_nextConstantOffset;
972        m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
973        ++m_nextConstantOffset;
974        m_codeBlock->addConstant(JSValue());
975        m_emptyValueRegister = &m_constantPoolRegisters[index];
976    }
977
978    return m_emptyValueRegister;
979}
980
981RegisterID* BytecodeGenerator::addConstantValue(JSValue v)
982{
983    if (!v)
984        return addConstantEmptyValue();
985
986    int index = m_nextConstantOffset;
987    JSValueMap::AddResult result = m_jsValueMap.add(JSValue::encode(v), m_nextConstantOffset);
988    if (result.isNewEntry) {
989        m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
990        ++m_nextConstantOffset;
991        m_codeBlock->addConstant(v);
992    } else
993        index = result.iterator->value;
994    return &m_constantPoolRegisters[index];
995}
996
997unsigned BytecodeGenerator::addRegExp(RegExp* r)
998{
999    return m_codeBlock->addRegExp(r);
1000}
1001
1002RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, RegisterID* src)
1003{
1004    m_staticPropertyAnalyzer.mov(dst->index(), src->index());
1005
1006    emitOpcode(op_mov);
1007    instructions().append(dst->index());
1008    instructions().append(src->index());
1009    return dst;
1010}
1011
1012RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src)
1013{
1014    emitOpcode(opcodeID);
1015    instructions().append(dst->index());
1016    instructions().append(src->index());
1017    return dst;
1018}
1019
1020RegisterID* BytecodeGenerator::emitInc(RegisterID* srcDst)
1021{
1022    emitOpcode(op_inc);
1023    instructions().append(srcDst->index());
1024    return srcDst;
1025}
1026
1027RegisterID* BytecodeGenerator::emitDec(RegisterID* srcDst)
1028{
1029    emitOpcode(op_dec);
1030    instructions().append(srcDst->index());
1031    return srcDst;
1032}
1033
1034RegisterID* BytecodeGenerator::emitBinaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes types)
1035{
1036    emitOpcode(opcodeID);
1037    instructions().append(dst->index());
1038    instructions().append(src1->index());
1039    instructions().append(src2->index());
1040
1041    if (opcodeID == op_bitor || opcodeID == op_bitand || opcodeID == op_bitxor ||
1042        opcodeID == op_add || opcodeID == op_mul || opcodeID == op_sub || opcodeID == op_div)
1043        instructions().append(types.toInt());
1044
1045    return dst;
1046}
1047
1048RegisterID* BytecodeGenerator::emitEqualityOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2)
1049{
1050    if (m_lastOpcodeID == op_typeof) {
1051        int dstIndex;
1052        int srcIndex;
1053
1054        retrieveLastUnaryOp(dstIndex, srcIndex);
1055
1056        if (src1->index() == dstIndex
1057            && src1->isTemporary()
1058            && m_codeBlock->isConstantRegisterIndex(src2->index())
1059            && m_codeBlock->constantRegister(src2->index()).get().isString()) {
1060            const String& value = asString(m_codeBlock->constantRegister(src2->index()).get())->tryGetValue();
1061            if (value == "undefined") {
1062                rewindUnaryOp();
1063                emitOpcode(op_is_undefined);
1064                instructions().append(dst->index());
1065                instructions().append(srcIndex);
1066                return dst;
1067            }
1068            if (value == "boolean") {
1069                rewindUnaryOp();
1070                emitOpcode(op_is_boolean);
1071                instructions().append(dst->index());
1072                instructions().append(srcIndex);
1073                return dst;
1074            }
1075            if (value == "number") {
1076                rewindUnaryOp();
1077                emitOpcode(op_is_number);
1078                instructions().append(dst->index());
1079                instructions().append(srcIndex);
1080                return dst;
1081            }
1082            if (value == "string") {
1083                rewindUnaryOp();
1084                emitOpcode(op_is_string);
1085                instructions().append(dst->index());
1086                instructions().append(srcIndex);
1087                return dst;
1088            }
1089            if (value == "object") {
1090                rewindUnaryOp();
1091                emitOpcode(op_is_object);
1092                instructions().append(dst->index());
1093                instructions().append(srcIndex);
1094                return dst;
1095            }
1096            if (value == "function") {
1097                rewindUnaryOp();
1098                emitOpcode(op_is_function);
1099                instructions().append(dst->index());
1100                instructions().append(srcIndex);
1101                return dst;
1102            }
1103        }
1104    }
1105
1106    emitOpcode(opcodeID);
1107    instructions().append(dst->index());
1108    instructions().append(src1->index());
1109    instructions().append(src2->index());
1110    return dst;
1111}
1112
1113RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, bool b)
1114{
1115    return emitLoad(dst, jsBoolean(b));
1116}
1117
1118RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, double number)
1119{
1120    // FIXME: Our hash tables won't hold infinity, so we make a new JSValue each time.
1121    // Later we can do the extra work to handle that like the other cases.  They also don't
1122    // work correctly with NaN as a key.
1123    if (std::isnan(number) || number == HashTraits<double>::emptyValue() || HashTraits<double>::isDeletedValue(number))
1124        return emitLoad(dst, jsNumber(number));
1125    JSValue& valueInMap = m_numberMap.add(number, JSValue()).iterator->value;
1126    if (!valueInMap)
1127        valueInMap = jsNumber(number);
1128    return emitLoad(dst, valueInMap);
1129}
1130
1131RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& identifier)
1132{
1133    JSString*& stringInMap = m_stringMap.add(identifier.impl(), 0).iterator->value;
1134    if (!stringInMap)
1135        stringInMap = jsOwnedString(vm(), identifier.string());
1136    return emitLoad(dst, JSValue(stringInMap));
1137}
1138
1139RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValue v)
1140{
1141    RegisterID* constantID = addConstantValue(v);
1142    if (dst)
1143        return emitMove(dst, constantID);
1144    return constantID;
1145}
1146
1147RegisterID* BytecodeGenerator::emitLoadGlobalObject(RegisterID* dst)
1148{
1149    if (!m_globalObjectRegister) {
1150        int index = m_nextConstantOffset;
1151        m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
1152        ++m_nextConstantOffset;
1153        m_codeBlock->addConstant(JSValue());
1154        m_globalObjectRegister = &m_constantPoolRegisters[index];
1155        m_codeBlock->setGlobalObjectRegister(index);
1156    }
1157    if (dst)
1158        emitMove(dst, m_globalObjectRegister);
1159    return m_globalObjectRegister;
1160}
1161
1162ResolveResult BytecodeGenerator::resolve(const Identifier& property)
1163{
1164    if (property == propertyNames().thisIdentifier)
1165        return ResolveResult::registerResolve(thisRegister(), ResolveResult::ReadOnlyFlag);
1166
1167    // Check if the property should be allocated in a register.
1168    if (m_codeType != GlobalCode && shouldOptimizeLocals() && m_symbolTable) {
1169        SymbolTableEntry entry = symbolTable().get(property.impl());
1170        if (!entry.isNull()) {
1171            if (property == propertyNames().arguments)
1172                createArgumentsIfNecessary();
1173            unsigned flags = entry.isReadOnly() ? ResolveResult::ReadOnlyFlag : 0;
1174            RegisterID* local = createLazyRegisterIfNecessary(&registerFor(entry.getIndex()));
1175            return ResolveResult::registerResolve(local, flags);
1176        }
1177    }
1178    // Cases where we cannot statically optimize the lookup.
1179    if (property == propertyNames().arguments || !canOptimizeNonLocals())
1180        return ResolveResult::dynamicResolve();
1181
1182    if (!m_scope || m_codeType != FunctionCode || m_shouldEmitDebugHooks)
1183        return ResolveResult::dynamicResolve();
1184
1185    ScopeChainIterator iter = m_scope->begin();
1186    ScopeChainIterator end = m_scope->end();
1187    size_t depth = m_codeBlock->needsFullScopeChain();
1188    unsigned flags = 0;
1189    for (; iter != end; ++iter, ++depth) {
1190        JSObject* currentScope = iter.get();
1191        if (!currentScope->isStaticScopeObject())
1192            return ResolveResult::dynamicResolve();
1193
1194        JSSymbolTableObject* currentVariableObject = jsCast<JSSymbolTableObject*>(currentScope);
1195        SymbolTableEntry entry = currentVariableObject->symbolTable()->get(property.impl());
1196
1197        // Found the property
1198        if (!entry.isNull()) {
1199            if (entry.isReadOnly())
1200                flags |= ResolveResult::ReadOnlyFlag;
1201            if (++iter == end)
1202                return ResolveResult::dynamicResolve();
1203#if !ASSERT_DISABLED
1204            if (JSActivation* activation = jsDynamicCast<JSActivation*>(currentVariableObject))
1205                ASSERT(activation->isValid(entry));
1206#endif
1207            return ResolveResult::lexicalResolve(entry.getIndex(), depth, flags);
1208        }
1209        bool scopeRequiresDynamicChecks = false;
1210        if (currentVariableObject->isDynamicScope(scopeRequiresDynamicChecks))
1211            break;
1212        if (scopeRequiresDynamicChecks)
1213            flags |= ResolveResult::DynamicFlag;
1214    }
1215
1216    return ResolveResult::dynamicResolve();
1217}
1218
1219ResolveResult BytecodeGenerator::resolveConstDecl(const Identifier& property)
1220{
1221    // Register-allocated const declarations.
1222    if (m_codeType == FunctionCode && m_symbolTable) {
1223        SymbolTableEntry entry = symbolTable().get(property.impl());
1224        if (!entry.isNull()) {
1225            unsigned flags = entry.isReadOnly() ? ResolveResult::ReadOnlyFlag : 0;
1226            RegisterID* local = createLazyRegisterIfNecessary(&registerFor(entry.getIndex()));
1227            return ResolveResult::registerResolve(local, flags);
1228        }
1229    }
1230
1231    return ResolveResult::dynamicResolve();
1232}
1233
1234void BytecodeGenerator::emitCheckHasInstance(RegisterID* dst, RegisterID* value, RegisterID* base, Label* target)
1235{
1236    size_t begin = instructions().size();
1237    emitOpcode(op_check_has_instance);
1238    instructions().append(dst->index());
1239    instructions().append(value->index());
1240    instructions().append(base->index());
1241    instructions().append(target->bind(begin, instructions().size()));
1242}
1243
1244RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype)
1245{
1246    emitOpcode(op_instanceof);
1247    instructions().append(dst->index());
1248    instructions().append(value->index());
1249    instructions().append(basePrototype->index());
1250    return dst;
1251}
1252
1253bool BytecodeGenerator::shouldAvoidResolveGlobal()
1254{
1255    return !m_labelScopes.size();
1256}
1257
1258RegisterID* BytecodeGenerator::emitResolve(RegisterID* dst, const ResolveResult& resolveResult, const Identifier& property)
1259{
1260
1261    if (resolveResult.isStatic())
1262        return emitGetStaticVar(dst, resolveResult, property);
1263
1264    UnlinkedValueProfile profile = emitProfiledOpcode(op_resolve);
1265    instructions().append(kill(dst));
1266    instructions().append(addConstant(property));
1267    instructions().append(getResolveOperations(property));
1268    instructions().append(profile);
1269    return dst;
1270}
1271
1272RegisterID* BytecodeGenerator::emitResolveBase(RegisterID* dst, const ResolveResult& resolveResult, const Identifier& property)
1273{
1274    if (!resolveResult.isDynamic()) {
1275        // Global object is the base
1276        return emitLoadGlobalObject(dst);
1277    }
1278
1279    // We can't optimise at all :-(
1280    UnlinkedValueProfile profile = emitProfiledOpcode(op_resolve_base);
1281    instructions().append(kill(dst));
1282    instructions().append(addConstant(property));
1283    instructions().append(false);
1284    instructions().append(getResolveBaseOperations(property));
1285    instructions().append(0);
1286    instructions().append(profile);
1287    return dst;
1288}
1289
1290RegisterID* BytecodeGenerator::emitResolveBaseForPut(RegisterID* dst, const ResolveResult&, const Identifier& property, NonlocalResolveInfo& verifier)
1291{
1292    // We can't optimise at all :-(
1293    UnlinkedValueProfile profile = emitProfiledOpcode(op_resolve_base);
1294    instructions().append(kill(dst));
1295    instructions().append(addConstant(property));
1296    instructions().append(m_codeBlock->isStrictMode());
1297    uint32_t putToBaseIndex = 0;
1298    instructions().append(getResolveBaseForPutOperations(property, putToBaseIndex));
1299    verifier.resolved(putToBaseIndex);
1300    instructions().append(putToBaseIndex);
1301    instructions().append(profile);
1302    return dst;
1303}
1304
1305RegisterID* BytecodeGenerator::emitResolveWithBaseForPut(RegisterID* baseDst, RegisterID* propDst, const ResolveResult& resolveResult, const Identifier& property, NonlocalResolveInfo& verifier)
1306{
1307    ASSERT_UNUSED(resolveResult, !resolveResult.isStatic());
1308    UnlinkedValueProfile profile = emitProfiledOpcode(op_resolve_with_base);
1309    instructions().append(kill(baseDst));
1310    instructions().append(propDst->index());
1311    instructions().append(addConstant(property));
1312    uint32_t putToBaseIndex = 0;
1313    instructions().append(getResolveWithBaseForPutOperations(property, putToBaseIndex));
1314    verifier.resolved(putToBaseIndex);
1315    instructions().append(putToBaseIndex);
1316    instructions().append(profile);
1317    return baseDst;
1318}
1319
1320RegisterID* BytecodeGenerator::emitResolveWithThis(RegisterID* baseDst, RegisterID* propDst, const ResolveResult& resolveResult, const Identifier& property)
1321{
1322    if (resolveResult.isStatic()) {
1323        emitLoad(baseDst, jsUndefined());
1324        emitGetStaticVar(propDst, resolveResult, property);
1325        return baseDst;
1326    }
1327
1328    UnlinkedValueProfile profile = emitProfiledOpcode(op_resolve_with_this);
1329    instructions().append(kill(baseDst));
1330    instructions().append(propDst->index());
1331    instructions().append(addConstant(property));
1332    instructions().append(getResolveWithThisOperations(property));
1333    instructions().append(profile);
1334    return baseDst;
1335}
1336
1337RegisterID* BytecodeGenerator::emitGetStaticVar(RegisterID* dst, const ResolveResult& resolveResult, const Identifier&)
1338{
1339    ASSERT(m_codeType == FunctionCode);
1340    switch (resolveResult.type()) {
1341    case ResolveResult::Register:
1342    case ResolveResult::ReadOnlyRegister:
1343        if (dst == ignoredResult())
1344            return 0;
1345        return moveToDestinationIfNeeded(dst, resolveResult.local());
1346
1347    case ResolveResult::Lexical:
1348    case ResolveResult::ReadOnlyLexical: {
1349        UnlinkedValueProfile profile = emitProfiledOpcode(op_get_scoped_var);
1350        instructions().append(dst->index());
1351        instructions().append(resolveResult.index());
1352        instructions().append(resolveResult.depth());
1353        instructions().append(profile);
1354        return dst;
1355    }
1356
1357    default:
1358        RELEASE_ASSERT_NOT_REACHED();
1359        return 0;
1360    }
1361}
1362
1363RegisterID* BytecodeGenerator::emitInitGlobalConst(const Identifier& identifier, RegisterID* value)
1364{
1365    ASSERT(m_codeType == GlobalCode);
1366    emitOpcode(op_init_global_const_nop);
1367    instructions().append(0);
1368    instructions().append(value->index());
1369    instructions().append(0);
1370    instructions().append(addConstant(identifier));
1371    return value;
1372}
1373
1374RegisterID* BytecodeGenerator::emitPutStaticVar(const ResolveResult& resolveResult, const Identifier&, RegisterID* value)
1375{
1376    ASSERT(m_codeType == FunctionCode);
1377    switch (resolveResult.type()) {
1378    case ResolveResult::Register:
1379    case ResolveResult::ReadOnlyRegister:
1380        return moveToDestinationIfNeeded(resolveResult.local(), value);
1381
1382    case ResolveResult::Lexical:
1383    case ResolveResult::ReadOnlyLexical:
1384        emitOpcode(op_put_scoped_var);
1385        instructions().append(resolveResult.index());
1386        instructions().append(resolveResult.depth());
1387        instructions().append(value->index());
1388        return value;
1389
1390    default:
1391        RELEASE_ASSERT_NOT_REACHED();
1392        return 0;
1393    }
1394}
1395
1396RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
1397{
1398    m_codeBlock->addPropertyAccessInstruction(instructions().size());
1399
1400    UnlinkedValueProfile profile = emitProfiledOpcode(op_get_by_id);
1401    instructions().append(kill(dst));
1402    instructions().append(base->index());
1403    instructions().append(addConstant(property));
1404    instructions().append(0);
1405    instructions().append(0);
1406    instructions().append(0);
1407    instructions().append(0);
1408    instructions().append(profile);
1409    return dst;
1410}
1411
1412RegisterID* BytecodeGenerator::emitGetArgumentsLength(RegisterID* dst, RegisterID* base)
1413{
1414    emitOpcode(op_get_arguments_length);
1415    instructions().append(dst->index());
1416    ASSERT(base->index() == m_codeBlock->argumentsRegister());
1417    instructions().append(base->index());
1418    instructions().append(addConstant(propertyNames().length));
1419    return dst;
1420}
1421
1422RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
1423{
1424    unsigned propertyIndex = addConstant(property);
1425
1426    m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
1427
1428    m_codeBlock->addPropertyAccessInstruction(instructions().size());
1429
1430    emitOpcode(op_put_by_id);
1431    instructions().append(base->index());
1432    instructions().append(propertyIndex);
1433    instructions().append(value->index());
1434    instructions().append(0);
1435    instructions().append(0);
1436    instructions().append(0);
1437    instructions().append(0);
1438    instructions().append(0);
1439    return value;
1440}
1441
1442RegisterID* BytecodeGenerator::emitPutToBase(RegisterID* base, const Identifier& property, RegisterID* value, NonlocalResolveInfo& resolveInfo)
1443{
1444    emitOpcode(op_put_to_base);
1445    instructions().append(base->index());
1446    instructions().append(addConstant(property));
1447    instructions().append(value->index());
1448    instructions().append(resolveInfo.put());
1449    return value;
1450}
1451
1452RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value)
1453{
1454    unsigned propertyIndex = addConstant(property);
1455
1456    m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
1457
1458    m_codeBlock->addPropertyAccessInstruction(instructions().size());
1459
1460    emitOpcode(op_put_by_id);
1461    instructions().append(base->index());
1462    instructions().append(propertyIndex);
1463    instructions().append(value->index());
1464    instructions().append(0);
1465    instructions().append(0);
1466    instructions().append(0);
1467    instructions().append(0);
1468    instructions().append(
1469        property != m_vm->propertyNames->underscoreProto
1470        && PropertyName(property).asIndex() == PropertyName::NotAnIndex);
1471    return value;
1472}
1473
1474void BytecodeGenerator::emitPutGetterSetter(RegisterID* base, const Identifier& property, RegisterID* getter, RegisterID* setter)
1475{
1476    unsigned propertyIndex = addConstant(property);
1477
1478    m_staticPropertyAnalyzer.putById(base->index(), propertyIndex);
1479
1480    emitOpcode(op_put_getter_setter);
1481    instructions().append(base->index());
1482    instructions().append(propertyIndex);
1483    instructions().append(getter->index());
1484    instructions().append(setter->index());
1485}
1486
1487RegisterID* BytecodeGenerator::emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier& property)
1488{
1489    emitOpcode(op_del_by_id);
1490    instructions().append(dst->index());
1491    instructions().append(base->index());
1492    instructions().append(addConstant(property));
1493    return dst;
1494}
1495
1496RegisterID* BytecodeGenerator::emitGetArgumentByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
1497{
1498    UnlinkedArrayProfile arrayProfile = newArrayProfile();
1499    UnlinkedValueProfile profile = emitProfiledOpcode(op_get_argument_by_val);
1500    instructions().append(kill(dst));
1501    ASSERT(base->index() == m_codeBlock->argumentsRegister());
1502    instructions().append(base->index());
1503    instructions().append(property->index());
1504    instructions().append(arrayProfile);
1505    instructions().append(profile);
1506    return dst;
1507}
1508
1509RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
1510{
1511    for (size_t i = m_forInContextStack.size(); i > 0; i--) {
1512        ForInContext& context = m_forInContextStack[i - 1];
1513        if (context.propertyRegister == property) {
1514            emitOpcode(op_get_by_pname);
1515            instructions().append(dst->index());
1516            instructions().append(base->index());
1517            instructions().append(property->index());
1518            instructions().append(context.expectedSubscriptRegister->index());
1519            instructions().append(context.iterRegister->index());
1520            instructions().append(context.indexRegister->index());
1521            return dst;
1522        }
1523    }
1524    UnlinkedArrayProfile arrayProfile = newArrayProfile();
1525    UnlinkedValueProfile profile = emitProfiledOpcode(op_get_by_val);
1526    instructions().append(kill(dst));
1527    instructions().append(base->index());
1528    instructions().append(property->index());
1529    instructions().append(arrayProfile);
1530    instructions().append(profile);
1531    return dst;
1532}
1533
1534RegisterID* BytecodeGenerator::emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value)
1535{
1536    UnlinkedArrayProfile arrayProfile = newArrayProfile();
1537    emitOpcode(op_put_by_val);
1538    instructions().append(base->index());
1539    instructions().append(property->index());
1540    instructions().append(value->index());
1541    instructions().append(arrayProfile);
1542    return value;
1543}
1544
1545RegisterID* BytecodeGenerator::emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
1546{
1547    emitOpcode(op_del_by_val);
1548    instructions().append(dst->index());
1549    instructions().append(base->index());
1550    instructions().append(property->index());
1551    return dst;
1552}
1553
1554RegisterID* BytecodeGenerator::emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value)
1555{
1556    emitOpcode(op_put_by_index);
1557    instructions().append(base->index());
1558    instructions().append(index);
1559    instructions().append(value->index());
1560    return value;
1561}
1562
1563RegisterID* BytecodeGenerator::emitCreateThis(RegisterID* dst)
1564{
1565    RefPtr<RegisterID> func = newTemporary();
1566
1567    UnlinkedValueProfile profile = emitProfiledOpcode(op_get_callee);
1568    instructions().append(func->index());
1569    instructions().append(profile);
1570
1571    size_t begin = instructions().size();
1572    m_staticPropertyAnalyzer.createThis(m_thisRegister.index(), begin + 3);
1573
1574    emitOpcode(op_create_this);
1575    instructions().append(m_thisRegister.index());
1576    instructions().append(func->index());
1577    instructions().append(0);
1578    return dst;
1579}
1580
1581RegisterID* BytecodeGenerator::emitNewObject(RegisterID* dst)
1582{
1583    size_t begin = instructions().size();
1584    m_staticPropertyAnalyzer.newObject(dst->index(), begin + 2);
1585
1586    emitOpcode(op_new_object);
1587    instructions().append(dst->index());
1588    instructions().append(0);
1589    instructions().append(newObjectAllocationProfile());
1590    return dst;
1591}
1592
1593unsigned BytecodeGenerator::addConstantBuffer(unsigned length)
1594{
1595    return m_codeBlock->addConstantBuffer(length);
1596}
1597
1598JSString* BytecodeGenerator::addStringConstant(const Identifier& identifier)
1599{
1600    JSString*& stringInMap = m_stringMap.add(identifier.impl(), 0).iterator->value;
1601    if (!stringInMap) {
1602        stringInMap = jsString(vm(), identifier.string());
1603        addConstantValue(stringInMap);
1604    }
1605    return stringInMap;
1606}
1607
1608RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements, unsigned length)
1609{
1610#if !ASSERT_DISABLED
1611    unsigned checkLength = 0;
1612#endif
1613    bool hadVariableExpression = false;
1614    if (length) {
1615        for (ElementNode* n = elements; n; n = n->next()) {
1616            if (!n->value()->isConstant()) {
1617                hadVariableExpression = true;
1618                break;
1619            }
1620            if (n->elision())
1621                break;
1622#if !ASSERT_DISABLED
1623            checkLength++;
1624#endif
1625        }
1626        if (!hadVariableExpression) {
1627            ASSERT(length == checkLength);
1628            unsigned constantBufferIndex = addConstantBuffer(length);
1629            JSValue* constantBuffer = m_codeBlock->constantBuffer(constantBufferIndex).data();
1630            unsigned index = 0;
1631            for (ElementNode* n = elements; index < length; n = n->next()) {
1632                ASSERT(n->value()->isConstant());
1633                constantBuffer[index++] = static_cast<ConstantNode*>(n->value())->jsValue(*this);
1634            }
1635            emitOpcode(op_new_array_buffer);
1636            instructions().append(dst->index());
1637            instructions().append(constantBufferIndex);
1638            instructions().append(length);
1639            instructions().append(newArrayAllocationProfile());
1640            return dst;
1641        }
1642    }
1643
1644    Vector<RefPtr<RegisterID>, 16, UnsafeVectorOverflow> argv;
1645    for (ElementNode* n = elements; n; n = n->next()) {
1646        if (n->elision())
1647            break;
1648        argv.append(newTemporary());
1649        // op_new_array requires the initial values to be a sequential range of registers
1650        ASSERT(argv.size() == 1 || argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1);
1651        emitNode(argv.last().get(), n->value());
1652    }
1653    emitOpcode(op_new_array);
1654    instructions().append(dst->index());
1655    instructions().append(argv.size() ? argv[0]->index() : 0); // argv
1656    instructions().append(argv.size()); // argc
1657    instructions().append(newArrayAllocationProfile());
1658    return dst;
1659}
1660
1661RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionBodyNode* function)
1662{
1663    return emitNewFunctionInternal(dst, m_codeBlock->addFunctionDecl(makeFunction(function)), false);
1664}
1665
1666RegisterID* BytecodeGenerator::emitLazyNewFunction(RegisterID* dst, FunctionBodyNode* function)
1667{
1668    FunctionOffsetMap::AddResult ptr = m_functionOffsets.add(function, 0);
1669    if (ptr.isNewEntry)
1670        ptr.iterator->value = m_codeBlock->addFunctionDecl(makeFunction(function));
1671    return emitNewFunctionInternal(dst, ptr.iterator->value, true);
1672}
1673
1674RegisterID* BytecodeGenerator::emitNewFunctionInternal(RegisterID* dst, unsigned index, bool doNullCheck)
1675{
1676    createActivationIfNecessary();
1677    emitOpcode(op_new_func);
1678    instructions().append(dst->index());
1679    instructions().append(index);
1680    instructions().append(doNullCheck);
1681    return dst;
1682}
1683
1684RegisterID* BytecodeGenerator::emitNewRegExp(RegisterID* dst, RegExp* regExp)
1685{
1686    emitOpcode(op_new_regexp);
1687    instructions().append(dst->index());
1688    instructions().append(addRegExp(regExp));
1689    return dst;
1690}
1691
1692RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExprNode* n)
1693{
1694    FunctionBodyNode* function = n->body();
1695    unsigned index = m_codeBlock->addFunctionExpr(makeFunction(function));
1696
1697    createActivationIfNecessary();
1698    emitOpcode(op_new_func_exp);
1699    instructions().append(r0->index());
1700    instructions().append(index);
1701    return r0;
1702}
1703
1704RegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned line, unsigned lineStart)
1705{
1706    return emitCall(op_call, dst, func, expectedFunction, callArguments, divot, startOffset, endOffset, line, lineStart);
1707}
1708
1709void BytecodeGenerator::createArgumentsIfNecessary()
1710{
1711    if (m_codeType != FunctionCode)
1712        return;
1713
1714    if (!m_codeBlock->usesArguments())
1715        return;
1716
1717    // If we're in strict mode we tear off the arguments on function
1718    // entry, so there's no need to check if we need to create them
1719    // now
1720    if (m_codeBlock->isStrictMode())
1721        return;
1722
1723    emitOpcode(op_create_arguments);
1724    instructions().append(m_codeBlock->argumentsRegister());
1725}
1726
1727void BytecodeGenerator::createActivationIfNecessary()
1728{
1729    if (m_hasCreatedActivation)
1730        return;
1731    if (!m_codeBlock->needsFullScopeChain())
1732        return;
1733    emitOpcode(op_create_activation);
1734    instructions().append(m_activationRegister->index());
1735}
1736
1737RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned line, unsigned lineStart)
1738{
1739    return emitCall(op_call_eval, dst, func, NoExpectedFunction, callArguments, divot, startOffset, endOffset, line, lineStart);
1740}
1741
1742ExpectedFunction BytecodeGenerator::expectedFunctionForIdentifier(const Identifier& identifier)
1743{
1744    if (identifier == m_vm->propertyNames->Object)
1745        return ExpectObjectConstructor;
1746    if (identifier == m_vm->propertyNames->Array)
1747        return ExpectArrayConstructor;
1748    return NoExpectedFunction;
1749}
1750
1751ExpectedFunction BytecodeGenerator::emitExpectedFunctionSnippet(RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, Label* done)
1752{
1753    RefPtr<Label> realCall = newLabel();
1754    switch (expectedFunction) {
1755    case ExpectObjectConstructor: {
1756        // If the number of arguments is non-zero, then we can't do anything interesting.
1757        if (callArguments.argumentCountIncludingThis() >= 2)
1758            return NoExpectedFunction;
1759
1760        size_t begin = instructions().size();
1761        emitOpcode(op_jneq_ptr);
1762        instructions().append(func->index());
1763        instructions().append(Special::ObjectConstructor);
1764        instructions().append(realCall->bind(begin, instructions().size()));
1765
1766        if (dst != ignoredResult())
1767            emitNewObject(dst);
1768        break;
1769    }
1770
1771    case ExpectArrayConstructor: {
1772        // If you're doing anything other than "new Array()" or "new Array(foo)" then we
1773        // don't do inline it, for now. The only reason is that call arguments are in
1774        // the opposite order of what op_new_array expects, so we'd either need to change
1775        // how op_new_array works or we'd need an op_new_array_reverse. Neither of these
1776        // things sounds like it's worth it.
1777        if (callArguments.argumentCountIncludingThis() > 2)
1778            return NoExpectedFunction;
1779
1780        size_t begin = instructions().size();
1781        emitOpcode(op_jneq_ptr);
1782        instructions().append(func->index());
1783        instructions().append(Special::ArrayConstructor);
1784        instructions().append(realCall->bind(begin, instructions().size()));
1785
1786        if (dst != ignoredResult()) {
1787            if (callArguments.argumentCountIncludingThis() == 2) {
1788                emitOpcode(op_new_array_with_size);
1789                instructions().append(dst->index());
1790                instructions().append(callArguments.argumentRegister(0)->index());
1791                instructions().append(newArrayAllocationProfile());
1792            } else {
1793                ASSERT(callArguments.argumentCountIncludingThis() == 1);
1794                emitOpcode(op_new_array);
1795                instructions().append(dst->index());
1796                instructions().append(0);
1797                instructions().append(0);
1798                instructions().append(newArrayAllocationProfile());
1799            }
1800        }
1801        break;
1802    }
1803
1804    default:
1805        ASSERT(expectedFunction == NoExpectedFunction);
1806        return NoExpectedFunction;
1807    }
1808
1809    size_t begin = instructions().size();
1810    emitOpcode(op_jmp);
1811    instructions().append(done->bind(begin, instructions().size()));
1812    emitLabel(realCall.get());
1813
1814    return expectedFunction;
1815}
1816
1817RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned line, unsigned lineStart)
1818{
1819    ASSERT(opcodeID == op_call || opcodeID == op_call_eval);
1820    ASSERT(func->refCount());
1821
1822    if (m_shouldEmitProfileHooks)
1823        emitMove(callArguments.profileHookRegister(), func);
1824
1825    // Generate code for arguments.
1826    unsigned argument = 0;
1827    for (ArgumentListNode* n = callArguments.argumentsNode()->m_listNode; n; n = n->m_next)
1828        emitNode(callArguments.argumentRegister(argument++), n);
1829
1830    // Reserve space for call frame.
1831    Vector<RefPtr<RegisterID>, JSStack::CallFrameHeaderSize, UnsafeVectorOverflow> callFrame;
1832    for (int i = 0; i < JSStack::CallFrameHeaderSize; ++i)
1833        callFrame.append(newTemporary());
1834
1835    if (m_shouldEmitProfileHooks) {
1836        emitOpcode(op_profile_will_call);
1837        instructions().append(callArguments.profileHookRegister()->index());
1838    }
1839
1840    emitExpressionInfo(divot, startOffset, endOffset, line, lineStart);
1841
1842    RefPtr<Label> done = newLabel();
1843    expectedFunction = emitExpectedFunctionSnippet(dst, func, expectedFunction, callArguments, done.get());
1844
1845    // Emit call.
1846    UnlinkedArrayProfile arrayProfile = newArrayProfile();
1847    emitOpcode(opcodeID);
1848    instructions().append(func->index()); // func
1849    instructions().append(callArguments.argumentCountIncludingThis()); // argCount
1850    instructions().append(callArguments.registerOffset()); // registerOffset
1851#if ENABLE(LLINT)
1852    instructions().append(m_codeBlock->addLLIntCallLinkInfo());
1853#else
1854    instructions().append(0);
1855#endif
1856    instructions().append(arrayProfile);
1857    if (dst != ignoredResult()) {
1858        UnlinkedValueProfile profile = emitProfiledOpcode(op_call_put_result);
1859        instructions().append(kill(dst));
1860        instructions().append(profile);
1861    }
1862
1863    if (expectedFunction != NoExpectedFunction)
1864        emitLabel(done.get());
1865
1866    if (m_shouldEmitProfileHooks) {
1867        emitOpcode(op_profile_did_call);
1868        instructions().append(callArguments.profileHookRegister()->index());
1869    }
1870
1871    return dst;
1872}
1873
1874RegisterID* BytecodeGenerator::emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, RegisterID* profileHookRegister, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned line, unsigned lineStart)
1875{
1876    if (m_shouldEmitProfileHooks) {
1877        emitMove(profileHookRegister, func);
1878        emitOpcode(op_profile_will_call);
1879        instructions().append(profileHookRegister->index());
1880    }
1881
1882    emitExpressionInfo(divot, startOffset, endOffset, line, lineStart);
1883
1884    // Emit call.
1885    emitOpcode(op_call_varargs);
1886    instructions().append(func->index());
1887    instructions().append(thisRegister->index());
1888    instructions().append(arguments->index());
1889    instructions().append(firstFreeRegister->index());
1890    if (dst != ignoredResult()) {
1891        UnlinkedValueProfile profile = emitProfiledOpcode(op_call_put_result);
1892        instructions().append(kill(dst));
1893        instructions().append(profile);
1894    }
1895    if (m_shouldEmitProfileHooks) {
1896        emitOpcode(op_profile_did_call);
1897        instructions().append(profileHookRegister->index());
1898    }
1899    return dst;
1900}
1901
1902RegisterID* BytecodeGenerator::emitReturn(RegisterID* src)
1903{
1904    if (m_codeBlock->needsFullScopeChain()) {
1905        emitOpcode(op_tear_off_activation);
1906        instructions().append(m_activationRegister->index());
1907    }
1908
1909    if (m_codeBlock->usesArguments() && m_codeBlock->numParameters() != 1 && !m_codeBlock->isStrictMode()) {
1910        emitOpcode(op_tear_off_arguments);
1911        instructions().append(m_codeBlock->argumentsRegister());
1912        instructions().append(m_activationRegister ? m_activationRegister->index() : emitLoad(0, JSValue())->index());
1913    }
1914
1915    // Constructors use op_ret_object_or_this to check the result is an
1916    // object, unless we can trivially determine the check is not
1917    // necessary (currently, if the return value is 'this').
1918    if (isConstructor() && (src->index() != m_thisRegister.index())) {
1919        emitOpcode(op_ret_object_or_this);
1920        instructions().append(src->index());
1921        instructions().append(m_thisRegister.index());
1922        return src;
1923    }
1924    return emitUnaryNoDstOp(op_ret, src);
1925}
1926
1927RegisterID* BytecodeGenerator::emitUnaryNoDstOp(OpcodeID opcodeID, RegisterID* src)
1928{
1929    emitOpcode(opcodeID);
1930    instructions().append(src->index());
1931    return src;
1932}
1933
1934RegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, ExpectedFunction expectedFunction, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned line, unsigned lineStart)
1935{
1936    ASSERT(func->refCount());
1937
1938    if (m_shouldEmitProfileHooks)
1939        emitMove(callArguments.profileHookRegister(), func);
1940
1941    // Generate code for arguments.
1942    unsigned argument = 0;
1943    if (ArgumentsNode* argumentsNode = callArguments.argumentsNode()) {
1944        for (ArgumentListNode* n = argumentsNode->m_listNode; n; n = n->m_next)
1945            emitNode(callArguments.argumentRegister(argument++), n);
1946    }
1947
1948    if (m_shouldEmitProfileHooks) {
1949        emitOpcode(op_profile_will_call);
1950        instructions().append(callArguments.profileHookRegister()->index());
1951    }
1952
1953    // Reserve space for call frame.
1954    Vector<RefPtr<RegisterID>, JSStack::CallFrameHeaderSize, UnsafeVectorOverflow> callFrame;
1955    for (int i = 0; i < JSStack::CallFrameHeaderSize; ++i)
1956        callFrame.append(newTemporary());
1957
1958    emitExpressionInfo(divot, startOffset, endOffset, line, lineStart);
1959
1960    RefPtr<Label> done = newLabel();
1961    expectedFunction = emitExpectedFunctionSnippet(dst, func, expectedFunction, callArguments, done.get());
1962
1963    emitOpcode(op_construct);
1964    instructions().append(func->index()); // func
1965    instructions().append(callArguments.argumentCountIncludingThis()); // argCount
1966    instructions().append(callArguments.registerOffset()); // registerOffset
1967#if ENABLE(LLINT)
1968    instructions().append(m_codeBlock->addLLIntCallLinkInfo());
1969#else
1970    instructions().append(0);
1971#endif
1972    instructions().append(0);
1973    if (dst != ignoredResult()) {
1974        UnlinkedValueProfile profile = emitProfiledOpcode(op_call_put_result);
1975        instructions().append(kill(dst));
1976        instructions().append(profile);
1977    }
1978
1979    if (expectedFunction != NoExpectedFunction)
1980        emitLabel(done.get());
1981
1982    if (m_shouldEmitProfileHooks) {
1983        emitOpcode(op_profile_did_call);
1984        instructions().append(callArguments.profileHookRegister()->index());
1985    }
1986
1987    return dst;
1988}
1989
1990RegisterID* BytecodeGenerator::emitStrcat(RegisterID* dst, RegisterID* src, int count)
1991{
1992    emitOpcode(op_strcat);
1993    instructions().append(dst->index());
1994    instructions().append(src->index());
1995    instructions().append(count);
1996
1997    return dst;
1998}
1999
2000void BytecodeGenerator::emitToPrimitive(RegisterID* dst, RegisterID* src)
2001{
2002    emitOpcode(op_to_primitive);
2003    instructions().append(dst->index());
2004    instructions().append(src->index());
2005}
2006
2007RegisterID* BytecodeGenerator::emitPushWithScope(RegisterID* scope)
2008{
2009    ControlFlowContext context;
2010    context.isFinallyBlock = false;
2011    m_scopeContextStack.append(context);
2012    m_dynamicScopeDepth++;
2013
2014    return emitUnaryNoDstOp(op_push_with_scope, scope);
2015}
2016
2017void BytecodeGenerator::emitPopScope()
2018{
2019    ASSERT(m_scopeContextStack.size());
2020    ASSERT(!m_scopeContextStack.last().isFinallyBlock);
2021
2022    emitOpcode(op_pop_scope);
2023
2024    m_scopeContextStack.removeLast();
2025    m_dynamicScopeDepth--;
2026}
2027
2028void BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, unsigned firstLine, unsigned lastLine, unsigned charOffset, unsigned lineStart)
2029{
2030#if ENABLE(DEBUG_WITH_BREAKPOINT)
2031    if (debugHookID != DidReachBreakpoint)
2032        return;
2033#else
2034    if (!m_shouldEmitDebugHooks)
2035        return;
2036#endif
2037    emitExpressionInfo(charOffset, 0, 0, firstLine, lineStart);
2038    unsigned charPosition = charOffset - m_scopeNode->source().startOffset();
2039    emitOpcode(op_debug);
2040    instructions().append(debugHookID);
2041    instructions().append(firstLine);
2042    instructions().append(lastLine);
2043    instructions().append(charPosition);
2044}
2045
2046void BytecodeGenerator::pushFinallyContext(StatementNode* finallyBlock)
2047{
2048    ControlFlowContext scope;
2049    scope.isFinallyBlock = true;
2050    FinallyContext context = {
2051        finallyBlock,
2052        static_cast<unsigned>(m_scopeContextStack.size()),
2053        static_cast<unsigned>(m_switchContextStack.size()),
2054        static_cast<unsigned>(m_forInContextStack.size()),
2055        static_cast<unsigned>(m_tryContextStack.size()),
2056        static_cast<unsigned>(m_labelScopes.size()),
2057        m_finallyDepth,
2058        m_dynamicScopeDepth
2059    };
2060    scope.finallyContext = context;
2061    m_scopeContextStack.append(scope);
2062    m_finallyDepth++;
2063}
2064
2065void BytecodeGenerator::popFinallyContext()
2066{
2067    ASSERT(m_scopeContextStack.size());
2068    ASSERT(m_scopeContextStack.last().isFinallyBlock);
2069    ASSERT(m_finallyDepth > 0);
2070    m_scopeContextStack.removeLast();
2071    m_finallyDepth--;
2072}
2073
2074LabelScope* BytecodeGenerator::breakTarget(const Identifier& name)
2075{
2076    // Reclaim free label scopes.
2077    //
2078    // The condition was previously coded as 'm_labelScopes.size() && !m_labelScopes.last().refCount()',
2079    // however sometimes this appears to lead to GCC going a little haywire and entering the loop with
2080    // size 0, leading to segfaulty badness.  We are yet to identify a valid cause within our code to
2081    // cause the GCC codegen to misbehave in this fashion, and as such the following refactoring of the
2082    // loop condition is a workaround.
2083    while (m_labelScopes.size()) {
2084        if  (m_labelScopes.last().refCount())
2085            break;
2086        m_labelScopes.removeLast();
2087    }
2088
2089    if (!m_labelScopes.size())
2090        return 0;
2091
2092    // We special-case the following, which is a syntax error in Firefox:
2093    // label:
2094    //     break;
2095    if (name.isEmpty()) {
2096        for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
2097            LabelScope* scope = &m_labelScopes[i];
2098            if (scope->type() != LabelScope::NamedLabel) {
2099                ASSERT(scope->breakTarget());
2100                return scope;
2101            }
2102        }
2103        return 0;
2104    }
2105
2106    for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
2107        LabelScope* scope = &m_labelScopes[i];
2108        if (scope->name() && *scope->name() == name) {
2109            ASSERT(scope->breakTarget());
2110            return scope;
2111        }
2112    }
2113    return 0;
2114}
2115
2116LabelScope* BytecodeGenerator::continueTarget(const Identifier& name)
2117{
2118    // Reclaim free label scopes.
2119    while (m_labelScopes.size() && !m_labelScopes.last().refCount())
2120        m_labelScopes.removeLast();
2121
2122    if (!m_labelScopes.size())
2123        return 0;
2124
2125    if (name.isEmpty()) {
2126        for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
2127            LabelScope* scope = &m_labelScopes[i];
2128            if (scope->type() == LabelScope::Loop) {
2129                ASSERT(scope->continueTarget());
2130                return scope;
2131            }
2132        }
2133        return 0;
2134    }
2135
2136    // Continue to the loop nested nearest to the label scope that matches
2137    // 'name'.
2138    LabelScope* result = 0;
2139    for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
2140        LabelScope* scope = &m_labelScopes[i];
2141        if (scope->type() == LabelScope::Loop) {
2142            ASSERT(scope->continueTarget());
2143            result = scope;
2144        }
2145        if (scope->name() && *scope->name() == name)
2146            return result; // may be 0
2147    }
2148    return 0;
2149}
2150
2151void BytecodeGenerator::emitComplexPopScopes(ControlFlowContext* topScope, ControlFlowContext* bottomScope)
2152{
2153    while (topScope > bottomScope) {
2154        // First we count the number of dynamic scopes we need to remove to get
2155        // to a finally block.
2156        int nNormalScopes = 0;
2157        while (topScope > bottomScope) {
2158            if (topScope->isFinallyBlock)
2159                break;
2160            ++nNormalScopes;
2161            --topScope;
2162        }
2163
2164        if (nNormalScopes) {
2165            // We need to remove a number of dynamic scopes to get to the next
2166            // finally block
2167            while (nNormalScopes--)
2168                emitOpcode(op_pop_scope);
2169
2170            // If topScope == bottomScope then there isn't a finally block left to emit.
2171            if (topScope == bottomScope)
2172                return;
2173        }
2174
2175        Vector<ControlFlowContext> savedScopeContextStack;
2176        Vector<SwitchInfo> savedSwitchContextStack;
2177        Vector<ForInContext> savedForInContextStack;
2178        Vector<TryContext> poppedTryContexts;
2179        LabelScopeStore savedLabelScopes;
2180        while (topScope > bottomScope && topScope->isFinallyBlock) {
2181            RefPtr<Label> beforeFinally = emitLabel(newLabel().get());
2182
2183            // Save the current state of the world while instating the state of the world
2184            // for the finally block.
2185            FinallyContext finallyContext = topScope->finallyContext;
2186            bool flipScopes = finallyContext.scopeContextStackSize != m_scopeContextStack.size();
2187            bool flipSwitches = finallyContext.switchContextStackSize != m_switchContextStack.size();
2188            bool flipForIns = finallyContext.forInContextStackSize != m_forInContextStack.size();
2189            bool flipTries = finallyContext.tryContextStackSize != m_tryContextStack.size();
2190            bool flipLabelScopes = finallyContext.labelScopesSize != m_labelScopes.size();
2191            int topScopeIndex = -1;
2192            int bottomScopeIndex = -1;
2193            if (flipScopes) {
2194                topScopeIndex = topScope - m_scopeContextStack.begin();
2195                bottomScopeIndex = bottomScope - m_scopeContextStack.begin();
2196                savedScopeContextStack = m_scopeContextStack;
2197                m_scopeContextStack.shrink(finallyContext.scopeContextStackSize);
2198            }
2199            if (flipSwitches) {
2200                savedSwitchContextStack = m_switchContextStack;
2201                m_switchContextStack.shrink(finallyContext.switchContextStackSize);
2202            }
2203            if (flipForIns) {
2204                savedForInContextStack = m_forInContextStack;
2205                m_forInContextStack.shrink(finallyContext.forInContextStackSize);
2206            }
2207            if (flipTries) {
2208                while (m_tryContextStack.size() != finallyContext.tryContextStackSize) {
2209                    ASSERT(m_tryContextStack.size() > finallyContext.tryContextStackSize);
2210                    TryContext context = m_tryContextStack.last();
2211                    m_tryContextStack.removeLast();
2212                    TryRange range;
2213                    range.start = context.start;
2214                    range.end = beforeFinally;
2215                    range.tryData = context.tryData;
2216                    m_tryRanges.append(range);
2217                    poppedTryContexts.append(context);
2218                }
2219            }
2220            if (flipLabelScopes) {
2221                savedLabelScopes = m_labelScopes;
2222                while (m_labelScopes.size() > finallyContext.labelScopesSize)
2223                    m_labelScopes.removeLast();
2224            }
2225            int savedFinallyDepth = m_finallyDepth;
2226            m_finallyDepth = finallyContext.finallyDepth;
2227            int savedDynamicScopeDepth = m_dynamicScopeDepth;
2228            m_dynamicScopeDepth = finallyContext.dynamicScopeDepth;
2229
2230            // Emit the finally block.
2231            emitNode(finallyContext.finallyBlock);
2232
2233            RefPtr<Label> afterFinally = emitLabel(newLabel().get());
2234
2235            // Restore the state of the world.
2236            if (flipScopes) {
2237                m_scopeContextStack = savedScopeContextStack;
2238                topScope = &m_scopeContextStack[topScopeIndex]; // assert it's within bounds
2239                bottomScope = m_scopeContextStack.begin() + bottomScopeIndex; // don't assert, since it the index might be -1.
2240            }
2241            if (flipSwitches)
2242                m_switchContextStack = savedSwitchContextStack;
2243            if (flipForIns)
2244                m_forInContextStack = savedForInContextStack;
2245            if (flipTries) {
2246                ASSERT(m_tryContextStack.size() == finallyContext.tryContextStackSize);
2247                for (unsigned i = poppedTryContexts.size(); i--;) {
2248                    TryContext context = poppedTryContexts[i];
2249                    context.start = afterFinally;
2250                    m_tryContextStack.append(context);
2251                }
2252                poppedTryContexts.clear();
2253            }
2254            if (flipLabelScopes)
2255                m_labelScopes = savedLabelScopes;
2256            m_finallyDepth = savedFinallyDepth;
2257            m_dynamicScopeDepth = savedDynamicScopeDepth;
2258
2259            --topScope;
2260        }
2261    }
2262}
2263
2264void BytecodeGenerator::emitPopScopes(int targetScopeDepth)
2265{
2266    ASSERT(scopeDepth() - targetScopeDepth >= 0);
2267
2268    size_t scopeDelta = scopeDepth() - targetScopeDepth;
2269    ASSERT(scopeDelta <= m_scopeContextStack.size());
2270    if (!scopeDelta)
2271        return;
2272
2273    if (!m_finallyDepth) {
2274        while (scopeDelta--)
2275            emitOpcode(op_pop_scope);
2276        return;
2277    }
2278
2279    emitComplexPopScopes(&m_scopeContextStack.last(), &m_scopeContextStack.last() - scopeDelta);
2280}
2281
2282RegisterID* BytecodeGenerator::emitGetPropertyNames(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, Label* breakTarget)
2283{
2284    size_t begin = instructions().size();
2285
2286    emitOpcode(op_get_pnames);
2287    instructions().append(dst->index());
2288    instructions().append(base->index());
2289    instructions().append(i->index());
2290    instructions().append(size->index());
2291    instructions().append(breakTarget->bind(begin, instructions().size()));
2292    return dst;
2293}
2294
2295RegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, RegisterID* iter, Label* target)
2296{
2297    size_t begin = instructions().size();
2298
2299    emitOpcode(op_next_pname);
2300    instructions().append(dst->index());
2301    instructions().append(base->index());
2302    instructions().append(i->index());
2303    instructions().append(size->index());
2304    instructions().append(iter->index());
2305    instructions().append(target->bind(begin, instructions().size()));
2306    return dst;
2307}
2308
2309TryData* BytecodeGenerator::pushTry(Label* start)
2310{
2311    TryData tryData;
2312    tryData.target = newLabel();
2313    tryData.targetScopeDepth = UINT_MAX;
2314    m_tryData.append(tryData);
2315    TryData* result = &m_tryData.last();
2316
2317    TryContext tryContext;
2318    tryContext.start = start;
2319    tryContext.tryData = result;
2320
2321    m_tryContextStack.append(tryContext);
2322
2323    return result;
2324}
2325
2326RegisterID* BytecodeGenerator::popTryAndEmitCatch(TryData* tryData, RegisterID* targetRegister, Label* end)
2327{
2328    m_usesExceptions = true;
2329
2330    ASSERT_UNUSED(tryData, m_tryContextStack.last().tryData == tryData);
2331
2332    TryRange tryRange;
2333    tryRange.start = m_tryContextStack.last().start;
2334    tryRange.end = end;
2335    tryRange.tryData = m_tryContextStack.last().tryData;
2336    m_tryRanges.append(tryRange);
2337    m_tryContextStack.removeLast();
2338
2339    emitLabel(tryRange.tryData->target.get());
2340    tryRange.tryData->targetScopeDepth = m_dynamicScopeDepth;
2341
2342    emitOpcode(op_catch);
2343    instructions().append(targetRegister->index());
2344    return targetRegister;
2345}
2346
2347void BytecodeGenerator::emitThrowReferenceError(const String& message)
2348{
2349    emitOpcode(op_throw_static_error);
2350    instructions().append(addConstantValue(addStringConstant(Identifier(m_vm, message)))->index());
2351    instructions().append(true);
2352}
2353
2354void BytecodeGenerator::emitPushNameScope(const Identifier& property, RegisterID* value, unsigned attributes)
2355{
2356    ControlFlowContext context;
2357    context.isFinallyBlock = false;
2358    m_scopeContextStack.append(context);
2359    m_dynamicScopeDepth++;
2360
2361    emitOpcode(op_push_name_scope);
2362    instructions().append(addConstant(property));
2363    instructions().append(value->index());
2364    instructions().append(attributes);
2365}
2366
2367void BytecodeGenerator::beginSwitch(RegisterID* scrutineeRegister, SwitchInfo::SwitchType type)
2368{
2369    SwitchInfo info = { static_cast<uint32_t>(instructions().size()), type };
2370    switch (type) {
2371        case SwitchInfo::SwitchImmediate:
2372            emitOpcode(op_switch_imm);
2373            break;
2374        case SwitchInfo::SwitchCharacter:
2375            emitOpcode(op_switch_char);
2376            break;
2377        case SwitchInfo::SwitchString:
2378            emitOpcode(op_switch_string);
2379            break;
2380        default:
2381            RELEASE_ASSERT_NOT_REACHED();
2382    }
2383
2384    instructions().append(0); // place holder for table index
2385    instructions().append(0); // place holder for default target
2386    instructions().append(scrutineeRegister->index());
2387    m_switchContextStack.append(info);
2388}
2389
2390static int32_t keyForImmediateSwitch(ExpressionNode* node, int32_t min, int32_t max)
2391{
2392    UNUSED_PARAM(max);
2393    ASSERT(node->isNumber());
2394    double value = static_cast<NumberNode*>(node)->value();
2395    int32_t key = static_cast<int32_t>(value);
2396    ASSERT(key == value);
2397    ASSERT(key >= min);
2398    ASSERT(key <= max);
2399    return key - min;
2400}
2401
2402static void prepareJumpTableForImmediateSwitch(UnlinkedSimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, int32_t min, int32_t max)
2403{
2404    jumpTable.min = min;
2405    jumpTable.branchOffsets.resize(max - min + 1);
2406    jumpTable.branchOffsets.fill(0);
2407    for (uint32_t i = 0; i < clauseCount; ++i) {
2408        // We're emitting this after the clause labels should have been fixed, so
2409        // the labels should not be "forward" references
2410        ASSERT(!labels[i]->isForward());
2411        jumpTable.add(keyForImmediateSwitch(nodes[i], min, max), labels[i]->bind(switchAddress, switchAddress + 3));
2412    }
2413}
2414
2415static int32_t keyForCharacterSwitch(ExpressionNode* node, int32_t min, int32_t max)
2416{
2417    UNUSED_PARAM(max);
2418    ASSERT(node->isString());
2419    StringImpl* clause = static_cast<StringNode*>(node)->value().impl();
2420    ASSERT(clause->length() == 1);
2421
2422    int32_t key = (*clause)[0];
2423    ASSERT(key >= min);
2424    ASSERT(key <= max);
2425    return key - min;
2426}
2427
2428static void prepareJumpTableForCharacterSwitch(UnlinkedSimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, int32_t min, int32_t max)
2429{
2430    jumpTable.min = min;
2431    jumpTable.branchOffsets.resize(max - min + 1);
2432    jumpTable.branchOffsets.fill(0);
2433    for (uint32_t i = 0; i < clauseCount; ++i) {
2434        // We're emitting this after the clause labels should have been fixed, so
2435        // the labels should not be "forward" references
2436        ASSERT(!labels[i]->isForward());
2437        jumpTable.add(keyForCharacterSwitch(nodes[i], min, max), labels[i]->bind(switchAddress, switchAddress + 3));
2438    }
2439}
2440
2441static void prepareJumpTableForStringSwitch(UnlinkedStringJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes)
2442{
2443    for (uint32_t i = 0; i < clauseCount; ++i) {
2444        // We're emitting this after the clause labels should have been fixed, so
2445        // the labels should not be "forward" references
2446        ASSERT(!labels[i]->isForward());
2447
2448        ASSERT(nodes[i]->isString());
2449        StringImpl* clause = static_cast<StringNode*>(nodes[i])->value().impl();
2450        jumpTable.offsetTable.add(clause, labels[i]->bind(switchAddress, switchAddress + 3));
2451    }
2452}
2453
2454void BytecodeGenerator::endSwitch(uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, Label* defaultLabel, int32_t min, int32_t max)
2455{
2456    SwitchInfo switchInfo = m_switchContextStack.last();
2457    m_switchContextStack.removeLast();
2458    if (switchInfo.switchType == SwitchInfo::SwitchImmediate) {
2459        instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfImmediateSwitchJumpTables();
2460        instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
2461
2462        UnlinkedSimpleJumpTable& jumpTable = m_codeBlock->addImmediateSwitchJumpTable();
2463        prepareJumpTableForImmediateSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max);
2464    } else if (switchInfo.switchType == SwitchInfo::SwitchCharacter) {
2465        instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfCharacterSwitchJumpTables();
2466        instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
2467
2468        UnlinkedSimpleJumpTable& jumpTable = m_codeBlock->addCharacterSwitchJumpTable();
2469        prepareJumpTableForCharacterSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max);
2470    } else {
2471        ASSERT(switchInfo.switchType == SwitchInfo::SwitchString);
2472        instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfStringSwitchJumpTables();
2473        instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
2474
2475        UnlinkedStringJumpTable& jumpTable = m_codeBlock->addStringSwitchJumpTable();
2476        prepareJumpTableForStringSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes);
2477    }
2478}
2479
2480RegisterID* BytecodeGenerator::emitThrowExpressionTooDeepException()
2481{
2482    // It would be nice to do an even better job of identifying exactly where the expression is.
2483    // And we could make the caller pass the node pointer in, if there was some way of getting
2484    // that from an arbitrary node. However, calling emitExpressionInfo without any useful data
2485    // is still good enough to get us an accurate line number.
2486    m_expressionTooDeep = true;
2487    return newTemporary();
2488}
2489
2490void BytecodeGenerator::setIsNumericCompareFunction(bool isNumericCompareFunction)
2491{
2492    m_codeBlock->setIsNumericCompareFunction(isNumericCompareFunction);
2493}
2494
2495bool BytecodeGenerator::isArgumentNumber(const Identifier& ident, int argumentNumber)
2496{
2497    RegisterID* registerID = resolve(ident).local();
2498    if (!registerID || registerID->index() >= 0)
2499         return 0;
2500    return registerID->index() == CallFrame::argumentOffset(argumentNumber);
2501}
2502
2503void BytecodeGenerator::emitReadOnlyExceptionIfNeeded()
2504{
2505    if (!isStrictMode())
2506        return;
2507    emitOpcode(op_throw_static_error);
2508    instructions().append(addConstantValue(addStringConstant(Identifier(m_vm, StrictModeReadonlyPropertyWriteError)))->index());
2509    instructions().append(false);
2510}
2511
2512} // namespace JSC
2513