18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
2635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1.  Redistributions of source code must retain the above copyright
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     notice, this list of conditions and the following disclaimer.
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2.  Redistributions in binary form must reproduce the above copyright
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     notice, this list of conditions and the following disclaimer in the
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     documentation and/or other materials provided with the distribution.
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     its contributors may be used to endorse or promote products derived
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     from this software without specific prior written permission.
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "BytecodeGenerator.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "BatchedTransitionOptimizer.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSFunction.h"
35635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Interpreter.h"
3681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "ScopeChain.h"
37635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "UString.h"
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std;
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace JSC {
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    The layout of a register frame looks like this:
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    For
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    function f(x, y) {
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        var v1;
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        function g() { }
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        var v2;
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return (x) * (y);
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assuming (x) and (y) generated temporaries t1 and t2, you would have
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ------------------------------------
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    |  x |  y |  g | v2 | v1 | t1 | t2 | <-- value held
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ------------------------------------
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    | -5 | -4 | -3 | -2 | -1 | +0 | +1 | <-- register index
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ------------------------------------
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    | params->|<-locals      | temps->
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Because temporary registers are allocated in a stack-like fashion, we
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    can reclaim them with a simple popping algorithm. The same goes for labels.
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    (We never reclaim parameter or local registers, because parameters and
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    locals are DontDelete.)
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    The register layout before a function call looks like this:
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    For
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    function f(x, y)
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    f(1);
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    >                        <------------------------------
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    <                        >  reserved: call frame  |  1 | <-- value held
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    >         >snip<         <------------------------------
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    <                        > +0 | +1 | +2 | +3 | +4 | +5 | <-- register index
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    >                        <------------------------------
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    | params->|<-locals      | temps->
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    The call instruction fills in the "call frame" registers. It also pads
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    missing arguments at the end of the call:
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    >                        <-----------------------------------
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    <                        >  reserved: call frame  |  1 |  ? | <-- value held ("?" stands for "undefined")
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    >         >snip<         <-----------------------------------
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    <                        > +0 | +1 | +2 | +3 | +4 | +5 | +6 | <-- register index
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    >                        <-----------------------------------
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    | params->|<-locals      | temps->
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    After filling in missing arguments, the call instruction sets up the new
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    stack frame to overlap the end of the old stack frame:
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                             |---------------------------------->                        <
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                             |  reserved: call frame  |  1 |  ? <                        > <-- value held ("?" stands for "undefined")
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                             |---------------------------------->         >snip<         <
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                             | -7 | -6 | -5 | -4 | -3 | -2 | -1 <                        > <-- register index
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                             |---------------------------------->                        <
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                             |                        | params->|<-locals       | temps->
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    That way, arguments are "copied" into the callee's stack frame for free.
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    If the caller supplies too many arguments, this trick doesn't work. The
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    extra arguments protrude into space reserved for locals and temporaries.
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    In that case, the call instruction makes a real copy of the call frame header,
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    along with just the arguments expected by the callee, leaving the original
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    call frame header and arguments behind. (The call instruction can't just discard
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    extra arguments, because the "arguments" object may access them later.)
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    This copying strategy ensures that all named values will be at the indices
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    expected by the callee.
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project*/
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG
119635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic bool s_dumpsGeneratedCode = false;
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
122635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::setDumpsGeneratedCode(bool dumpsGeneratedCode)
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    s_dumpsGeneratedCode = dumpsGeneratedCode;
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(dumpsGeneratedCode);
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
131635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool BytecodeGenerator::dumpsGeneratedCode()
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
133635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#ifndef NDEBUG
134635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return s_dumpsGeneratedCode;
135635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#else
136635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return false;
137635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif
138635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
139635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
14065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben MurdochJSObject* BytecodeGenerator::generate()
141635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
142635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    m_codeBlock->setThisRegister(m_thisRegister.index());
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
144635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    m_scopeNode->emitBytecode(*this);
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG
147635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    m_codeBlock->setInstructionCount(m_codeBlock->instructions().size());
148635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
149635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (s_dumpsGeneratedCode)
15081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_codeBlock->dump(m_scopeChain->globalObject->globalExec());
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
153635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if ((m_codeType == FunctionCode && !m_codeBlock->needsFullScopeChain() && !m_codeBlock->usesArguments()) || m_codeType == EvalCode)
154635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        symbolTable().clear();
155635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
156635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    m_codeBlock->shrinkToFit();
15765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
15865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (m_expressionTooDeep)
15981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return createOutOfMemoryError(m_scopeChain->globalObject.get());
16065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return 0;
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
163635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool BytecodeGenerator::addVar(const Identifier& ident, bool isConstant, RegisterID*& r0)
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int index = m_calleeRegisters.size();
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SymbolTableEntry newEntry(index, isConstant ? ReadOnly : 0);
167f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    pair<SymbolTable::iterator, bool> result = symbolTable().add(ident.impl(), newEntry);
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!result.second) {
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        r0 = &registerFor(result.first->second.getIndex());
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
174e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    r0 = addVar();
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
178635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool BytecodeGenerator::addGlobalVar(const Identifier& ident, bool isConstant, RegisterID*& r0)
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
180635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int index = m_nextGlobalIndex;
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SymbolTableEntry newEntry(index, isConstant ? ReadOnly : 0);
182f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    pair<SymbolTable::iterator, bool> result = symbolTable().add(ident.impl(), newEntry);
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!result.second)
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        index = result.first->second.getIndex();
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
187635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        --m_nextGlobalIndex;
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_globals.append(index + m_globalVarStorageOffset);
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    r0 = &registerFor(index);
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result.second;
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid BytecodeGenerator::preserveLastVar()
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if ((m_firstConstantIndex = m_calleeRegisters.size()) != 0)
1980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        m_lastVar = &m_calleeRegisters.last();
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
20181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochBytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, ScopeChainNode* scopeChain, SymbolTable* symbolTable, ProgramCodeBlock* codeBlock)
20281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    : m_shouldEmitDebugHooks(scopeChain->globalObject->debugger())
20381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_shouldEmitProfileHooks(scopeChain->globalObject->supportsProfiling())
20481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_shouldEmitRichSourceInfo(scopeChain->globalObject->supportsRichSourceInfo())
20581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_scopeChain(*scopeChain->globalData, scopeChain)
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_symbolTable(symbolTable)
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_scopeNode(programNode)
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_codeBlock(codeBlock)
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_thisRegister(RegisterFile::ProgramCodeThisRegister)
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_finallyDepth(0)
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_dynamicScopeDepth(0)
212635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    , m_baseScopeDepth(0)
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_codeType(GlobalCode)
214635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    , m_nextGlobalIndex(-1)
2150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    , m_nextConstantOffset(0)
2165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    , m_globalConstantIndex(0)
217a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    , m_hasCreatedActivation(true)
218bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    , m_firstLazyFunction(0)
219bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    , m_lastLazyFunction(0)
22081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_globalData(scopeChain->globalData)
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_lastOpcodeID(op_end)
222dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#ifndef NDEBUG
223dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    , m_lastOpcodePosition(0)
224dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#endif
225f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    , m_stack(m_globalData->stack())
22606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    , m_usesExceptions(false)
22765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    , m_expressionTooDeep(false)
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_shouldEmitDebugHooks)
230635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        m_codeBlock->setNeedsFullScopeChain(true);
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_enter);
233635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    codeBlock->setGlobalData(m_globalData);
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
235635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // FIXME: Move code that modifies the global object to Interpreter::execute.
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
237635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    m_codeBlock->m_numParameters = 1; // Allocate space for "this"
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
23981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    JSGlobalObject* globalObject = scopeChain->globalObject.get();
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ExecState* exec = globalObject->globalExec();
241635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    RegisterFile* registerFile = &exec->globalData().interpreter->registerFile();
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Shift register indexes in generated code to elide registers allocated by intermediate stack frames.
244635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    m_globalVarStorageOffset = -RegisterFile::CallFrameHeaderSize - m_codeBlock->m_numParameters - registerFile->size();
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Add previously defined symbols to bookkeeping.
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_globals.grow(symbolTable->size());
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SymbolTable::iterator end = symbolTable->end();
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (SymbolTable::iterator it = symbolTable->begin(); it != end; ++it)
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        registerFor(it->second.getIndex()).setIndex(it->second.getIndex() + m_globalVarStorageOffset);
2512bde8e466a4451c7319e3a072d118917957d6554Steve Block
2522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    BatchedTransitionOptimizer optimizer(*m_globalData, globalObject);
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
254635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    const VarStack& varStack = programNode->varStack();
255635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    const FunctionStack& functionStack = programNode->functionStack();
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool canOptimizeNewGlobals = symbolTable->size() + functionStack.size() + varStack.size() < registerFile->maxGlobals();
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (canOptimizeNewGlobals) {
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Shift new symbols so they get stored prior to existing symbols.
259635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        m_nextGlobalIndex -= symbolTable->size();
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2612bde8e466a4451c7319e3a072d118917957d6554Steve Block        HashSet<StringImpl*, IdentifierRepHash> newGlobals;
2622bde8e466a4451c7319e3a072d118917957d6554Steve Block        Vector<std::pair<int, bool>, 16> functionInfo(functionStack.size());
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (size_t i = 0; i < functionStack.size(); ++i) {
264231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            FunctionBodyNode* function = functionStack[i];
2652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            globalObject->removeDirect(*m_globalData, function->ident()); // Make sure our new function is not shadowed by an old property.
2662bde8e466a4451c7319e3a072d118917957d6554Steve Block            SymbolTableEntry entry = symbolTable->inlineGet(function->ident().impl());
2672bde8e466a4451c7319e3a072d118917957d6554Steve Block
2682bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (entry.isNull())
2692bde8e466a4451c7319e3a072d118917957d6554Steve Block                newGlobals.add(function->ident().impl());
2702bde8e466a4451c7319e3a072d118917957d6554Steve Block            functionInfo[i] = make_pair(entry.getIndex(), entry.isReadOnly());
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2722bde8e466a4451c7319e3a072d118917957d6554Steve Block
2732bde8e466a4451c7319e3a072d118917957d6554Steve Block        Vector<bool, 16> shouldCreateVar(varStack.size());
27481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        for (size_t i = 0; i < varStack.size(); ++i) {
2752bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (newGlobals.contains(varStack[i].first->impl()) || globalObject->hasProperty(exec, *varStack[i].first)) {
2762bde8e466a4451c7319e3a072d118917957d6554Steve Block                shouldCreateVar[i] = false;
27781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                continue;
2782bde8e466a4451c7319e3a072d118917957d6554Steve Block            }
2792bde8e466a4451c7319e3a072d118917957d6554Steve Block            shouldCreateVar[i] = true;
2802bde8e466a4451c7319e3a072d118917957d6554Steve Block            newGlobals.add(varStack[i].first->impl());
28181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
28281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
2832bde8e466a4451c7319e3a072d118917957d6554Steve Block        int expectedSize = symbolTable->size() + newGlobals.size();
2842bde8e466a4451c7319e3a072d118917957d6554Steve Block        globalObject->resizeRegisters(symbolTable->size(), expectedSize);
2852bde8e466a4451c7319e3a072d118917957d6554Steve Block
2862bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (size_t i = 0; i < functionStack.size(); ++i) {
2872bde8e466a4451c7319e3a072d118917957d6554Steve Block            FunctionBodyNode* function = functionStack[i];
2882bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (functionInfo[i].second)
2892bde8e466a4451c7319e3a072d118917957d6554Steve Block                continue;
2902bde8e466a4451c7319e3a072d118917957d6554Steve Block            RegisterID* dst = addGlobalVar(function->ident(), false);
2912bde8e466a4451c7319e3a072d118917957d6554Steve Block            JSValue value = new (exec) JSFunction(exec, makeFunction(exec, function), scopeChain);
2922bde8e466a4451c7319e3a072d118917957d6554Steve Block            globalObject->registerAt(dst->index() - m_globalVarStorageOffset).set(*m_globalData, globalObject, value);
2932bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2952bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (size_t i = 0; i < varStack.size(); ++i) {
2962bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (!shouldCreateVar[i])
2972bde8e466a4451c7319e3a072d118917957d6554Steve Block                continue;
2982bde8e466a4451c7319e3a072d118917957d6554Steve Block            addGlobalVar(*varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant);
2992bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
3002bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (symbolTable->size() != expectedSize)
3012bde8e466a4451c7319e3a072d118917957d6554Steve Block            CRASH();
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3032bde8e466a4451c7319e3a072d118917957d6554Steve Block        preserveLastVar();
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (size_t i = 0; i < functionStack.size(); ++i) {
306231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            FunctionBodyNode* function = functionStack[i];
30781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            globalObject->putWithAttributes(exec, function->ident(), new (exec) JSFunction(exec, makeFunction(exec, function), scopeChain), DontDelete);
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (size_t i = 0; i < varStack.size(); ++i) {
31081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (globalObject->symbolTableHasProperty(*varStack[i].first) || globalObject->hasProperty(exec, *varStack[i].first))
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int attributes = DontDelete;
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (varStack[i].second & DeclarationStacks::IsConstant)
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                attributes |= ReadOnly;
315231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            globalObject->putWithAttributes(exec, *varStack[i].first, jsUndefined(), attributes);
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        preserveLastVar();
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
320bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    codeBlock->m_numCapturedVars = codeBlock->m_numVars;
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
32381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochBytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, ScopeChainNode* scopeChain, SymbolTable* symbolTable, CodeBlock* codeBlock)
32481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    : m_shouldEmitDebugHooks(scopeChain->globalObject->debugger())
32581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_shouldEmitProfileHooks(scopeChain->globalObject->supportsProfiling())
32681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_shouldEmitRichSourceInfo(scopeChain->globalObject->supportsRichSourceInfo())
32781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_scopeChain(*scopeChain->globalData, scopeChain)
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_symbolTable(symbolTable)
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_scopeNode(functionBody)
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_codeBlock(codeBlock)
331e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    , m_activationRegister(0)
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_finallyDepth(0)
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_dynamicScopeDepth(0)
334635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    , m_baseScopeDepth(0)
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_codeType(FunctionCode)
3360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    , m_nextConstantOffset(0)
3375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    , m_globalConstantIndex(0)
338a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    , m_hasCreatedActivation(false)
339bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    , m_firstLazyFunction(0)
340bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    , m_lastLazyFunction(0)
34181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_globalData(scopeChain->globalData)
3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_lastOpcodeID(op_end)
343a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#ifndef NDEBUG
344a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    , m_lastOpcodePosition(0)
345a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#endif
346f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    , m_stack(m_globalData->stack())
34706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    , m_usesExceptions(false)
34865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    , m_expressionTooDeep(false)
3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_shouldEmitDebugHooks)
351635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        m_codeBlock->setNeedsFullScopeChain(true);
3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
353635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    codeBlock->setGlobalData(m_globalData);
354a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
355a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    emitOpcode(op_enter);
356635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (m_codeBlock->needsFullScopeChain()) {
357e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        m_activationRegister = addVar();
358a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        emitInitLazyRegister(m_activationRegister);
359a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_codeBlock->setActivationRegister(m_activationRegister->index());
360a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
362e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    // Both op_tear_off_activation and op_tear_off_arguments tear off the 'arguments'
363e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    // object, if created.
364e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (m_codeBlock->needsFullScopeChain() || functionBody->usesArguments()) {
365e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        RegisterID* unmodifiedArgumentsRegister = addVar(); // Anonymous, so it can't be modified by user code.
366e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        RegisterID* argumentsRegister = addVar(propertyNames().arguments, false); // Can be changed by assigning to 'arguments'.
367e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block
368e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        // We can save a little space by hard-coding the knowledge that the two
369e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        // 'arguments' values are stored in consecutive registers, and storing
370e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        // only the index of the assignable one.
371e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        codeBlock->setArgumentsRegister(argumentsRegister->index());
372e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        ASSERT_UNUSED(unmodifiedArgumentsRegister, unmodifiedArgumentsRegister->index() == JSC::unmodifiedArgumentsRegister(codeBlock->argumentsRegister()));
373e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block
374bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        emitInitLazyRegister(argumentsRegister);
375bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        emitInitLazyRegister(unmodifiedArgumentsRegister);
376a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
377a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (m_codeBlock->isStrictMode()) {
378a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            emitOpcode(op_create_arguments);
379a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            instructions().append(argumentsRegister->index());
380a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
3815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // The debugger currently retrieves the arguments object from an activation rather than pulling
3835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // it from a call frame.  In the long-term it should stop doing that (<rdar://problem/6911886>),
3845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // but for now we force eager creation of the arguments object when debugging.
385e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        if (m_shouldEmitDebugHooks) {
3865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            emitOpcode(op_create_arguments);
387e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            instructions().append(argumentsRegister->index());
388e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        }
3895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
391635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    const DeclarationStacks::FunctionStack& functionStack = functionBody->functionStack();
392bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    const DeclarationStacks::VarStack& varStack = functionBody->varStack();
393bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
394bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // Captured variables and functions go first so that activations don't have
395bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // to step over the non-captured locals to mark them.
396a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_hasCreatedActivation = false;
397bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (functionBody->hasCapturedVariables()) {
398bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        for (size_t i = 0; i < functionStack.size(); ++i) {
399bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            FunctionBodyNode* function = functionStack[i];
400bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            const Identifier& ident = function->ident();
401bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            if (functionBody->captures(ident)) {
402a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                if (!m_hasCreatedActivation) {
403a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    m_hasCreatedActivation = true;
404a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    emitOpcode(op_create_activation);
405a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                    instructions().append(m_activationRegister->index());
406a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                }
407bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                m_functions.add(ident.impl());
408bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                emitNewFunction(addVar(ident, false), function);
409bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            }
410bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        }
411bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        for (size_t i = 0; i < varStack.size(); ++i) {
412bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            const Identifier& ident = *varStack[i].first;
413bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            if (functionBody->captures(ident))
414bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                addVar(ident, varStack[i].second & DeclarationStacks::IsConstant);
415bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        }
416bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    }
4174576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    bool canLazilyCreateFunctions = !functionBody->needsActivationForMoreThanVariables() && !m_shouldEmitDebugHooks;
418a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!canLazilyCreateFunctions && !m_hasCreatedActivation) {
419a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_hasCreatedActivation = true;
420a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        emitOpcode(op_create_activation);
421a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        instructions().append(m_activationRegister->index());
422a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
423a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
424bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    codeBlock->m_numCapturedVars = codeBlock->m_numVars;
425bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_firstLazyFunction = codeBlock->m_numVars;
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (size_t i = 0; i < functionStack.size(); ++i) {
427231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        FunctionBodyNode* function = functionStack[i];
428231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        const Identifier& ident = function->ident();
429bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (!functionBody->captures(ident)) {
430bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            m_functions.add(ident.impl());
431bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            RefPtr<RegisterID> reg = addVar(ident, false);
432bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            // Don't lazily create functions that override the name 'arguments'
433bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            // as this would complicate lazy instantiation of actual arguments.
434bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            if (!canLazilyCreateFunctions || ident == propertyNames().arguments)
435bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                emitNewFunction(reg.get(), function);
436bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            else {
437bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                emitInitLazyRegister(reg.get());
438bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                m_lazyFunctions.set(reg->index(), function);
439bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            }
440bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        }
4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
442bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_lastLazyFunction = canLazilyCreateFunctions ? codeBlock->m_numVars : m_firstLazyFunction;
443bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    for (size_t i = 0; i < varStack.size(); ++i) {
444bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        const Identifier& ident = *varStack[i].first;
445bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (!functionBody->captures(ident))
446bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            addVar(ident, varStack[i].second & DeclarationStacks::IsConstant);
447bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    }
448bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
4494576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    if (m_shouldEmitDebugHooks)
450bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        codeBlock->m_numCapturedVars = codeBlock->m_numVars;
4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
452231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    FunctionParameters& parameters = *functionBody->parameters();
453231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    size_t parameterCount = parameters.size();
454545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    int nextParameterIndex = -RegisterFile::CallFrameHeaderSize - parameterCount - 1;
4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_parameters.grow(1 + parameterCount); // reserve space for "this"
4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Add "this" as a parameter
458545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    m_thisRegister.setIndex(nextParameterIndex);
459635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ++m_codeBlock->m_numParameters;
4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (size_t i = 0; i < parameterCount; ++i)
462545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        addParameter(parameters[i], ++nextParameterIndex);
4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    preserveLastVar();
4655af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
4665af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (isConstructor()) {
4675af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        RefPtr<RegisterID> func = newTemporary();
4685af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        RefPtr<RegisterID> funcProto = newTemporary();
4695af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
4705af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        emitOpcode(op_get_callee);
4715af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        instructions().append(func->index());
4725af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        // Load prototype.
4735af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        emitGetById(funcProto.get(), func.get(), globalData()->propertyNames->prototype);
4745af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
4755af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        emitOpcode(op_create_this);
4765af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        instructions().append(m_thisRegister.index());
4775af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        instructions().append(funcProto->index());
4785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    } else if (functionBody->usesThis() || m_shouldEmitDebugHooks) {
479a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (codeBlock->isStrictMode())
480a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            emitOpcode(op_convert_this_strict);
481a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
482a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            emitOpcode(op_convert_this);
4835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        instructions().append(m_thisRegister.index());
4845af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    }
4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochBytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, ScopeChainNode* scopeChain, SymbolTable* symbolTable, EvalCodeBlock* codeBlock)
48881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    : m_shouldEmitDebugHooks(scopeChain->globalObject->debugger())
48981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_shouldEmitProfileHooks(scopeChain->globalObject->supportsProfiling())
49081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_shouldEmitRichSourceInfo(scopeChain->globalObject->supportsRichSourceInfo())
49181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_scopeChain(*scopeChain->globalData, scopeChain)
4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_symbolTable(symbolTable)
4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_scopeNode(evalNode)
4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_codeBlock(codeBlock)
4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_thisRegister(RegisterFile::ProgramCodeThisRegister)
4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_finallyDepth(0)
4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_dynamicScopeDepth(0)
498635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    , m_baseScopeDepth(codeBlock->baseScopeDepth())
4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_codeType(EvalCode)
5000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    , m_nextConstantOffset(0)
5015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    , m_globalConstantIndex(0)
502a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    , m_hasCreatedActivation(true)
503bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    , m_firstLazyFunction(0)
504bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    , m_lastLazyFunction(0)
50581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_globalData(scopeChain->globalData)
5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_lastOpcodeID(op_end)
507a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#ifndef NDEBUG
508a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    , m_lastOpcodePosition(0)
509a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#endif
510f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    , m_stack(m_globalData->stack())
51106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    , m_usesExceptions(false)
51265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    , m_expressionTooDeep(false)
5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
514635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (m_shouldEmitDebugHooks || m_baseScopeDepth)
515635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        m_codeBlock->setNeedsFullScopeChain(true);
5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_enter);
518635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    codeBlock->setGlobalData(m_globalData);
519635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    m_codeBlock->m_numParameters = 1; // Allocate space for "this"
5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
521231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack();
522231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    for (size_t i = 0; i < functionStack.size(); ++i)
523231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        m_codeBlock->addFunctionDecl(makeFunction(m_globalData, functionStack[i]));
524231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
525231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    const DeclarationStacks::VarStack& varStack = evalNode->varStack();
526231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    unsigned numVariables = varStack.size();
527231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    Vector<Identifier> variables;
528231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    variables.reserveCapacity(numVariables);
529231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    for (size_t i = 0; i < numVariables; ++i)
530231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        variables.append(*varStack[i].first);
531231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    codeBlock->adoptVariables(variables);
532bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    codeBlock->m_numCapturedVars = codeBlock->m_numVars;
5330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    preserveLastVar();
5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
536bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenRegisterID* BytecodeGenerator::emitInitLazyRegister(RegisterID* reg)
537bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{
538bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    emitOpcode(op_init_lazy_reg);
539bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    instructions().append(reg->index());
540bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return reg;
541bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen}
542bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
543545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid BytecodeGenerator::addParameter(const Identifier& ident, int parameterIndex)
5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Parameters overwrite var declarations, but not function declarations.
546f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    StringImpl* rep = ident.impl();
5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_functions.contains(rep)) {
548545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        symbolTable().set(rep, parameterIndex);
549545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        RegisterID& parameter = registerFor(parameterIndex);
550545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        parameter.setIndex(parameterIndex);
5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // To maintain the calling convention, we have to allocate unique space for
5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // each parameter, even if the parameter doesn't make it into the symbol table.
555635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ++m_codeBlock->m_numParameters;
5568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
558635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::registerFor(const Identifier& ident)
5598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ident == propertyNames().thisIdentifier)
5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return &m_thisRegister;
5628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!shouldOptimizeLocals())
5648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
566f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    SymbolTableEntry entry = symbolTable().get(ident.impl());
5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (entry.isNull())
5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (ident == propertyNames().arguments)
5715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        createArgumentsIfNecessary();
5725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
573bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return createLazyRegisterIfNecessary(&registerFor(entry.getIndex()));
5745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
5755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool BytecodeGenerator::willResolveToArguments(const Identifier& ident)
5775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
5785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (ident != propertyNames().arguments)
5795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return false;
5805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (!shouldOptimizeLocals())
5825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return false;
5835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
584f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    SymbolTableEntry entry = symbolTable().get(ident.impl());
5855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (entry.isNull())
5865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return false;
5875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (m_codeBlock->usesArguments() && m_codeType == FunctionCode)
5895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return true;
5905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return false;
5925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
5935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5945f1ab04193ad0130ca8204aadaceae083aca9881Feng QianRegisterID* BytecodeGenerator::uncheckedRegisterForArguments()
5955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
5965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(willResolveToArguments(propertyNames().arguments));
5975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
598f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    SymbolTableEntry entry = symbolTable().get(propertyNames().arguments.impl());
5995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(!entry.isNull());
6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return &registerFor(entry.getIndex());
6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
603bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenRegisterID* BytecodeGenerator::createLazyRegisterIfNecessary(RegisterID* reg)
604bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{
605bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (m_lastLazyFunction <= reg->index() || reg->index() < m_firstLazyFunction)
606bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        return reg;
607bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    emitLazyNewFunction(reg, m_lazyFunctions.get(reg->index()));
608bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return reg;
609bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen}
610bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
611635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::constRegisterFor(const Identifier& ident)
6128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_codeType == EvalCode)
6148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
6158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
616f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    SymbolTableEntry entry = symbolTable().get(ident.impl());
617231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (entry.isNull())
618231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return 0;
6198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
620bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return createLazyRegisterIfNecessary(&registerFor(entry.getIndex()));
6218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
623635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool BytecodeGenerator::isLocal(const Identifier& ident)
6248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ident == propertyNames().thisIdentifier)
6268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
628f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    return shouldOptimizeLocals() && symbolTable().contains(ident.impl());
6298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
631635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool BytecodeGenerator::isLocalConstant(const Identifier& ident)
6328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
633f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    return symbolTable().get(ident.impl()).isReadOnly();
6348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
636635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::newRegister()
6378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_calleeRegisters.append(m_calleeRegisters.size());
639635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    m_codeBlock->m_numCalleeRegisters = max<int>(m_codeBlock->m_numCalleeRegisters, m_calleeRegisters.size());
6408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return &m_calleeRegisters.last();
6418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
643635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::newTemporary()
6448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Reclaim free register IDs.
6468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (m_calleeRegisters.size() && !m_calleeRegisters.last().refCount())
6478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_calleeRegisters.removeLast();
6488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RegisterID* result = newRegister();
6508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    result->setTemporary();
6518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
6528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
654635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::highestUsedRegister()
6558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
656635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    size_t count = m_codeBlock->m_numCalleeRegisters;
6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (m_calleeRegisters.size() < count)
6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        newRegister();
6598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return &m_calleeRegisters.last();
6608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
662635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<LabelScope> BytecodeGenerator::newLabelScope(LabelScope::Type type, const Identifier* name)
6638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Reclaim free label scopes.
6658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (m_labelScopes.size() && !m_labelScopes.last().refCount())
6668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_labelScopes.removeLast();
6678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Allocate new label scope.
6690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    LabelScope scope(type, name, scopeDepth(), newLabel(), type == LabelScope::Loop ? newLabel() : PassRefPtr<Label>()); // Only loops have continue targets.
6708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_labelScopes.append(scope);
6718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return &m_labelScopes.last();
6728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
674635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<Label> BytecodeGenerator::newLabel()
6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Reclaim free label IDs.
6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (m_labels.size() && !m_labels.last().refCount())
6788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_labels.removeLast();
6798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Allocate new label ID.
6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_labels.append(m_codeBlock);
6828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return &m_labels.last();
6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
685635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<Label> BytecodeGenerator::emitLabel(Label* l0)
6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
687635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    unsigned newLabelIndex = instructions().size();
688635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    l0->setLocation(newLabelIndex);
689635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
690635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (m_codeBlock->numberOfJumpTargets()) {
691635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        unsigned lastLabelIndex = m_codeBlock->lastJumpTarget();
692635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        ASSERT(lastLabelIndex <= newLabelIndex);
693635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (newLabelIndex == lastLabelIndex) {
694635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // Peephole optimizations have already been disabled by emitting the last label
695635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            return l0;
696635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
697635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
698635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
699635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    m_codeBlock->addJumpTarget(newLabelIndex);
700635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // This disables peephole optimizations when an instruction is a jump target
7028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_lastOpcodeID = op_end;
7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return l0;
7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
706635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::emitOpcode(OpcodeID opcodeID)
7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
708dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#ifndef NDEBUG
709dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    size_t opcodePosition = instructions().size();
710dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    ASSERT(opcodePosition - m_lastOpcodePosition == opcodeLength(m_lastOpcodeID) || m_lastOpcodeID == op_end);
711dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    m_lastOpcodePosition = opcodePosition;
712dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#endif
713635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    instructions().append(globalData()->interpreter->getOpcode(opcodeID));
7148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_lastOpcodeID = opcodeID;
7158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
717635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index)
7188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(instructions().size() >= 4);
7208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    size_t size = instructions().size();
7218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    dstIndex = instructions().at(size - 3).u.operand;
7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    src1Index = instructions().at(size - 2).u.operand;
7238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    src2Index = instructions().at(size - 1).u.operand;
7248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
726635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::retrieveLastUnaryOp(int& dstIndex, int& srcIndex)
7278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(instructions().size() >= 3);
7298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    size_t size = instructions().size();
7308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    dstIndex = instructions().at(size - 2).u.operand;
7318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    srcIndex = instructions().at(size - 1).u.operand;
7328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
734635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ALWAYS_INLINE BytecodeGenerator::rewindBinaryOp()
7358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(instructions().size() >= 4);
7378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().shrink(instructions().size() - 4);
738dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    m_lastOpcodeID = op_end;
7398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
741635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ALWAYS_INLINE BytecodeGenerator::rewindUnaryOp()
7428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(instructions().size() >= 3);
7448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().shrink(instructions().size() - 3);
745dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    m_lastOpcodeID = op_end;
7468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
748635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<Label> BytecodeGenerator::emitJump(Label* target)
7498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
750cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    size_t begin = instructions().size();
751635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    emitOpcode(target->isForward() ? op_jmp : op_loop);
752cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    instructions().append(target->bind(begin, instructions().size()));
7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return target;
7548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
756635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* target)
7578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
758643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (m_lastOpcodeID == op_less) {
7598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int dstIndex;
7608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int src1Index;
7618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int src2Index;
7628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
7648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
7668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            rewindBinaryOp();
767cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
768cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            size_t begin = instructions().size();
769643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            emitOpcode(target->isForward() ? op_jless : op_loop_if_less);
7708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            instructions().append(src1Index);
7718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            instructions().append(src2Index);
772cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            instructions().append(target->bind(begin, instructions().size()));
7738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return target;
7748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
77521939df44de1705786c545cd1bf519d47250322dBen Murdoch    } else if (m_lastOpcodeID == op_lesseq) {
7768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int dstIndex;
7778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int src1Index;
7788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int src2Index;
7798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
7818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
7838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            rewindBinaryOp();
784cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
785cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            size_t begin = instructions().size();
78621939df44de1705786c545cd1bf519d47250322dBen Murdoch            emitOpcode(target->isForward() ? op_jlesseq : op_loop_if_lesseq);
7878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            instructions().append(src1Index);
7888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            instructions().append(src2Index);
789cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            instructions().append(target->bind(begin, instructions().size()));
7908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return target;
7918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
792635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    } else if (m_lastOpcodeID == op_eq_null && target->isForward()) {
7938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int dstIndex;
7948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int srcIndex;
7958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        retrieveLastUnaryOp(dstIndex, srcIndex);
7978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
7998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            rewindUnaryOp();
800cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
801cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            size_t begin = instructions().size();
8028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            emitOpcode(op_jeq_null);
8038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            instructions().append(srcIndex);
804cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            instructions().append(target->bind(begin, instructions().size()));
8058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return target;
8068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
807635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    } else if (m_lastOpcodeID == op_neq_null && target->isForward()) {
8088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int dstIndex;
8098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int srcIndex;
8108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        retrieveLastUnaryOp(dstIndex, srcIndex);
8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
8148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            rewindUnaryOp();
815cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
816cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            size_t begin = instructions().size();
8178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            emitOpcode(op_jneq_null);
8188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            instructions().append(srcIndex);
819cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            instructions().append(target->bind(begin, instructions().size()));
8208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return target;
8218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
8228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
824cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    size_t begin = instructions().size();
825cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
826635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    emitOpcode(target->isForward() ? op_jtrue : op_loop_if_true);
8278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(cond->index());
828cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    instructions().append(target->bind(begin, instructions().size()));
8298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return target;
8308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
832635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* target)
8338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
834643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (m_lastOpcodeID == op_less && target->isForward()) {
8358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int dstIndex;
8368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int src1Index;
8378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int src2Index;
8388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
8408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
8428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            rewindBinaryOp();
843cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
844cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            size_t begin = instructions().size();
8458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            emitOpcode(op_jnless);
8468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            instructions().append(src1Index);
8478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            instructions().append(src2Index);
848cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            instructions().append(target->bind(begin, instructions().size()));
8498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return target;
8508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
851643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    } else if (m_lastOpcodeID == op_lesseq && target->isForward()) {
8525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        int dstIndex;
8535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        int src1Index;
8545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        int src2Index;
8555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
8565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
8575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
8585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
8595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            rewindBinaryOp();
860cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
861cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            size_t begin = instructions().size();
8625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            emitOpcode(op_jnlesseq);
8635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            instructions().append(src1Index);
8645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            instructions().append(src2Index);
865cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            instructions().append(target->bind(begin, instructions().size()));
8665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            return target;
8675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
8688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (m_lastOpcodeID == op_not) {
8698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int dstIndex;
8708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int srcIndex;
8718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        retrieveLastUnaryOp(dstIndex, srcIndex);
8738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
8758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            rewindUnaryOp();
876cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
877cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            size_t begin = instructions().size();
878643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            emitOpcode(target->isForward() ? op_jtrue : op_loop_if_true);
8798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            instructions().append(srcIndex);
880cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            instructions().append(target->bind(begin, instructions().size()));
8818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return target;
8828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
883643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    } else if (m_lastOpcodeID == op_eq_null && target->isForward()) {
8848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int dstIndex;
8858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int srcIndex;
8868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        retrieveLastUnaryOp(dstIndex, srcIndex);
8888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
8908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            rewindUnaryOp();
891cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
892cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            size_t begin = instructions().size();
8938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            emitOpcode(op_jneq_null);
8948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            instructions().append(srcIndex);
895cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            instructions().append(target->bind(begin, instructions().size()));
8968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return target;
8978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
898643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    } else if (m_lastOpcodeID == op_neq_null && target->isForward()) {
8998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int dstIndex;
9008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int srcIndex;
9018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        retrieveLastUnaryOp(dstIndex, srcIndex);
9038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
9058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            rewindUnaryOp();
906cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
907cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            size_t begin = instructions().size();
9088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            emitOpcode(op_jeq_null);
9098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            instructions().append(srcIndex);
910cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            instructions().append(target->bind(begin, instructions().size()));
9118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return target;
9128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
9138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
915cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    size_t begin = instructions().size();
916643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    emitOpcode(target->isForward() ? op_jfalse : op_loop_if_false);
9178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(cond->index());
918cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    instructions().append(target->bind(begin, instructions().size()));
9198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return target;
9208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9225f1ab04193ad0130ca8204aadaceae083aca9881Feng QianPassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionCall(RegisterID* cond, Label* target)
9235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
924cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    size_t begin = instructions().size();
925cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
9265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    emitOpcode(op_jneq_ptr);
9275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    instructions().append(cond->index());
9282bde8e466a4451c7319e3a072d118917957d6554Steve Block    instructions().append(Instruction(*m_globalData, m_codeBlock->ownerExecutable(), m_scopeChain->globalObject->callFunction()));
929cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    instructions().append(target->bind(begin, instructions().size()));
9305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return target;
9315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
9325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
9335f1ab04193ad0130ca8204aadaceae083aca9881Feng QianPassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond, Label* target)
9345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
935cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    size_t begin = instructions().size();
936cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
9375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    emitOpcode(op_jneq_ptr);
9385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    instructions().append(cond->index());
9392bde8e466a4451c7319e3a072d118917957d6554Steve Block    instructions().append(Instruction(*m_globalData, m_codeBlock->ownerExecutable(), m_scopeChain->globalObject->applyFunction()));
940cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    instructions().append(target->bind(begin, instructions().size()));
9415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return target;
9425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
9435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
944635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectunsigned BytecodeGenerator::addConstant(const Identifier& ident)
9458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
946f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    StringImpl* rep = ident.impl();
947635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    pair<IdentifierMap::iterator, bool> result = m_identifierMap.add(rep, m_codeBlock->numberOfIdentifiers());
9488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (result.second) // new entry
949635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        m_codeBlock->addIdentifier(Identifier(m_globalData, rep));
9508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result.first->second;
9528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochRegisterID* BytecodeGenerator::addConstantValue(JSValue v)
9558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int index = m_nextConstantOffset;
9578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    pair<JSValueMap::iterator, bool> result = m_jsValueMap.add(JSValue::encode(v), m_nextConstantOffset);
9590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (result.second) {
9600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
9610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ++m_nextConstantOffset;
9622bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_codeBlock->addConstant(JSValue(v));
9630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    } else
9640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        index = result.first->second;
9658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return &m_constantPoolRegisters[index];
9675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
9685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
9692bde8e466a4451c7319e3a072d118917957d6554Steve Blockunsigned BytecodeGenerator::addRegExp(PassRefPtr<RegExp> r)
9706c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{
9716c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    return m_codeBlock->addRegExp(r);
9726c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen}
9736c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
974635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitMove(RegisterID* dst, RegisterID* src)
9758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_mov);
9778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(dst->index());
9788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(src->index());
9798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return dst;
9808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
982635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src)
9838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
984635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    emitOpcode(opcodeID);
9858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(dst->index());
9868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(src->index());
9878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return dst;
9888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
990635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitPreInc(RegisterID* srcDst)
9918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_pre_inc);
9938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(srcDst->index());
9948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return srcDst;
9958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
997635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitPreDec(RegisterID* srcDst)
9988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_pre_dec);
10008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(srcDst->index());
10018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return srcDst;
10028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1004635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitPostInc(RegisterID* dst, RegisterID* srcDst)
10058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_post_inc);
10078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(dst->index());
10088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(srcDst->index());
10098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return dst;
10108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1012635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitPostDec(RegisterID* dst, RegisterID* srcDst)
10138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_post_dec);
10158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(dst->index());
10168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(srcDst->index());
10178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return dst;
10188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1020635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitBinaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes types)
10218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1022635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    emitOpcode(opcodeID);
10238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(dst->index());
10248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(src1->index());
10258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(src2->index());
10268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1027635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (opcodeID == op_bitor || opcodeID == op_bitand || opcodeID == op_bitxor ||
10280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        opcodeID == op_add || opcodeID == op_mul || opcodeID == op_sub || opcodeID == op_div)
10298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        instructions().append(types.toInt());
10308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return dst;
10328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1034635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitEqualityOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2)
10358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_lastOpcodeID == op_typeof) {
10378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int dstIndex;
10388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int srcIndex;
10398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        retrieveLastUnaryOp(dstIndex, srcIndex);
10418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (src1->index() == dstIndex
10438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            && src1->isTemporary()
1044635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            && m_codeBlock->isConstantRegisterIndex(src2->index())
10452bde8e466a4451c7319e3a072d118917957d6554Steve Block            && m_codeBlock->constantRegister(src2->index()).get().isString()) {
10462bde8e466a4451c7319e3a072d118917957d6554Steve Block            const UString& value = asString(m_codeBlock->constantRegister(src2->index()).get())->tryGetValue();
10478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (value == "undefined") {
10488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                rewindUnaryOp();
10498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                emitOpcode(op_is_undefined);
10508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                instructions().append(dst->index());
10518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                instructions().append(srcIndex);
10528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return dst;
10538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
10548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (value == "boolean") {
10558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                rewindUnaryOp();
10568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                emitOpcode(op_is_boolean);
10578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                instructions().append(dst->index());
10588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                instructions().append(srcIndex);
10598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return dst;
10608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
10618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (value == "number") {
10628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                rewindUnaryOp();
10638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                emitOpcode(op_is_number);
10648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                instructions().append(dst->index());
10658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                instructions().append(srcIndex);
10668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return dst;
10678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
10688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (value == "string") {
10698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                rewindUnaryOp();
10708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                emitOpcode(op_is_string);
10718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                instructions().append(dst->index());
10728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                instructions().append(srcIndex);
10738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return dst;
10748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
10758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (value == "object") {
10768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                rewindUnaryOp();
10778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                emitOpcode(op_is_object);
10788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                instructions().append(dst->index());
10798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                instructions().append(srcIndex);
10808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return dst;
10818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
10828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (value == "function") {
10838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                rewindUnaryOp();
10848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                emitOpcode(op_is_function);
10858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                instructions().append(dst->index());
10868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                instructions().append(srcIndex);
10878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return dst;
10888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
10898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
10908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1092635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    emitOpcode(opcodeID);
10938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(dst->index());
10948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(src1->index());
10958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(src2->index());
10968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return dst;
10978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1099635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, bool b)
11008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return emitLoad(dst, jsBoolean(b));
11028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1104635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, double number)
11058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // FIXME: Our hash tables won't hold infinity, so we make a new JSValue each time.
1107ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    // Later we can do the extra work to handle that like the other cases.  They also don't
1108ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    // work correctly with NaN as a key.
1109ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    if (isnan(number) || number == HashTraits<double>::emptyValue() || HashTraits<double>::isDeletedValue(number))
1110e14391e94c850b8bd03680c23b38978db68687a8John Reck        return emitLoad(dst, jsNumber(number));
11115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    JSValue& valueInMap = m_numberMap.add(number, JSValue()).first->second;
11128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!valueInMap)
1113e14391e94c850b8bd03680c23b38978db68687a8John Reck        valueInMap = jsNumber(number);
11148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return emitLoad(dst, valueInMap);
11158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1117635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& identifier)
11188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1119f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    JSString*& stringInMap = m_stringMap.add(identifier.impl(), 0).first->second;
1120635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!stringInMap)
1121635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        stringInMap = jsOwnedString(globalData(), identifier.ustring());
11225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return emitLoad(dst, JSValue(stringInMap));
11238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11255f1ab04193ad0130ca8204aadaceae083aca9881Feng QianRegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValue v)
11268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    RegisterID* constantID = addConstantValue(v);
11288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (dst)
11298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return emitMove(dst, constantID);
11308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return constantID;
11318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11336c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenbool BytecodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting, bool& requiresDynamicChecks, JSObject*& globalObject)
11348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Cases where we cannot statically optimize the lookup.
11368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (property == propertyNames().arguments || !canOptimizeNonLocals()) {
11378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        stackDepth = 0;
11388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        index = missingSymbolMarker();
11398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (shouldOptimizeLocals() && m_codeType == GlobalCode) {
11418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ScopeChainIterator iter = m_scopeChain->begin();
11422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            globalObject = iter->get();
11438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT((++iter) == m_scopeChain->end());
11448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
11458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
11468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
11478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    size_t depth = 0;
11496c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    requiresDynamicChecks = false;
11508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ScopeChainIterator iter = m_scopeChain->begin();
11518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ScopeChainIterator end = m_scopeChain->end();
11528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (; iter != end; ++iter, ++depth) {
11532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        JSObject* currentScope = iter->get();
11548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!currentScope->isVariableObject())
11558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
11568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        JSVariableObject* currentVariableObject = static_cast<JSVariableObject*>(currentScope);
1157f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        SymbolTableEntry entry = currentVariableObject->symbolTable().get(property.impl());
11588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Found the property
11608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!entry.isNull()) {
11618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (entry.isReadOnly() && forWriting) {
11628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                stackDepth = 0;
11638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                index = missingSymbolMarker();
11648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (++iter == end)
11658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    globalObject = currentVariableObject;
11668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return false;
11678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1168e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block            stackDepth = depth + m_codeBlock->needsFullScopeChain();
11698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            index = entry.getIndex();
11708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (++iter == end)
11718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                globalObject = currentVariableObject;
11728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
11738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
11746c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        bool scopeRequiresDynamicChecks = false;
11756c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (currentVariableObject->isDynamicScope(scopeRequiresDynamicChecks))
11768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
11776c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        requiresDynamicChecks |= scopeRequiresDynamicChecks;
11788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
11798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Can't locate the property but we're able to avoid a few lookups.
1180e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    stackDepth = depth + m_codeBlock->needsFullScopeChain();
11818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    index = missingSymbolMarker();
11822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    JSObject* scope = iter->get();
11838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (++iter == end)
11848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        globalObject = scope;
11858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
11868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11886b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid BytecodeGenerator::emitCheckHasInstance(RegisterID* base)
11896b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{
11906b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    emitOpcode(op_check_has_instance);
11916b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    instructions().append(base->index());
11926b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner}
11936b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
1194635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base, RegisterID* basePrototype)
11958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_instanceof);
11978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(dst->index());
11988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(value->index());
11998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(base->index());
12008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(basePrototype->index());
12018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return dst;
12028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
12038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1204635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitResolve(RegisterID* dst, const Identifier& property)
12058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
12068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    size_t depth = 0;
12078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int index = 0;
12088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObject* globalObject = 0;
12096c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    bool requiresDynamicChecks = false;
12106c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (!findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject) && !globalObject) {
12118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We can't optimise at all :-(
12128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        emitOpcode(op_resolve);
12138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        instructions().append(dst->index());
12148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        instructions().append(addConstant(property));
12158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return dst;
12168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (globalObject) {
1219635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        bool forceGlobalResolve = false;
1220635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
12216c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (index != missingSymbolMarker() && !forceGlobalResolve && !requiresDynamicChecks) {
1222635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // Directly index the property lookup across multiple scopes.
1223635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            return emitGetScopedVar(dst, depth, index, globalObject);
1224635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
1225635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1226635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if ENABLE(JIT)
1227635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        m_codeBlock->addGlobalResolveInfo(instructions().size());
1228635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#else
1229635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        m_codeBlock->addGlobalResolveInstruction(instructions().size());
1230635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif
12316c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        emitOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
12328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        instructions().append(dst->index());
12338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        instructions().append(addConstant(property));
12348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        instructions().append(0);
12358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        instructions().append(0);
12366c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (requiresDynamicChecks)
12376c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            instructions().append(depth);
12386c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        return dst;
12396c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
12406c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
12416c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (requiresDynamicChecks) {
12426c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        // If we get here we have eval nested inside a |with| just give up
12436c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        emitOpcode(op_resolve);
12446c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        instructions().append(dst->index());
12456c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        instructions().append(addConstant(property));
12468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return dst;
12478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1249635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (index != missingSymbolMarker()) {
1250635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // Directly index the property lookup across multiple scopes.
1251635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return emitGetScopedVar(dst, depth, index, globalObject);
1252635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
1253635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
12548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // In this case we are at least able to drop a few scope chains from the
12558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // lookup chain, although we still need to hash from then on.
12568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_resolve_skip);
12578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(dst->index());
12588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(addConstant(property));
12598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(depth);
12608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return dst;
12618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
12628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12635f1ab04193ad0130ca8204aadaceae083aca9881Feng QianRegisterID* BytecodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, int index, JSValue globalObject)
12648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
12658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (globalObject) {
12668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        emitOpcode(op_get_global_var);
12678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        instructions().append(dst->index());
12688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        instructions().append(index);
12698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return dst;
12708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_get_scoped_var);
12738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(dst->index());
12748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(index);
12758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(depth);
12768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return dst;
12778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
12788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12795f1ab04193ad0130ca8204aadaceae083aca9881Feng QianRegisterID* BytecodeGenerator::emitPutScopedVar(size_t depth, int index, RegisterID* value, JSValue globalObject)
12808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
12818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (globalObject) {
12828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        emitOpcode(op_put_global_var);
12838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        instructions().append(index);
12848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        instructions().append(value->index());
12858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return value;
12868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
12878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_put_scoped_var);
12888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(index);
12898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(depth);
12908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(value->index());
12918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return value;
12928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
12938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1294635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitResolveBase(RegisterID* dst, const Identifier& property)
12958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
12965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    size_t depth = 0;
12975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    int index = 0;
12985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    JSObject* globalObject = 0;
12996c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    bool requiresDynamicChecks = false;
13006c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject);
13016c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (!globalObject || requiresDynamicChecks) {
13025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // We can't optimise at all :-(
13035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        emitOpcode(op_resolve_base);
13045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        instructions().append(dst->index());
13055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        instructions().append(addConstant(property));
1306a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        instructions().append(false);
13075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return dst;
13085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
13095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
13105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Global object is the base
13110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return emitLoad(dst, JSValue(globalObject));
13128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1314a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochRegisterID* BytecodeGenerator::emitResolveBaseForPut(RegisterID* dst, const Identifier& property)
1315a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
1316a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!m_codeBlock->isStrictMode())
1317a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return emitResolveBase(dst, property);
1318a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    size_t depth = 0;
1319a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int index = 0;
1320a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    JSObject* globalObject = 0;
1321a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool requiresDynamicChecks = false;
1322a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject);
1323a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!globalObject || requiresDynamicChecks) {
1324a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // We can't optimise at all :-(
1325a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        emitOpcode(op_resolve_base);
1326a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        instructions().append(dst->index());
1327a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        instructions().append(addConstant(property));
1328a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        instructions().append(true);
1329a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return dst;
1330a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
1331a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1332a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Global object is the base
1333a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<RegisterID> result = emitLoad(dst, JSValue(globalObject));
1334a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    emitOpcode(op_ensure_property_exists);
1335a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    instructions().append(dst->index());
1336a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    instructions().append(addConstant(property));
1337a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return result.get();
1338a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1339a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1340635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property)
13418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    size_t depth = 0;
13435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    int index = 0;
13445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    JSObject* globalObject = 0;
13456c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    bool requiresDynamicChecks = false;
13466c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (!findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject) || !globalObject || requiresDynamicChecks) {
13475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // We can't optimise at all :-(
13485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        emitOpcode(op_resolve_with_base);
13495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        instructions().append(baseDst->index());
13505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        instructions().append(propDst->index());
13515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        instructions().append(addConstant(property));
13525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return baseDst;
13535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
13545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
13555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    bool forceGlobalResolve = false;
13565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
13575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Global object is the base
13580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    emitLoad(baseDst, JSValue(globalObject));
13595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
13605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (index != missingSymbolMarker() && !forceGlobalResolve) {
13615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // Directly index the property lookup across multiple scopes.
13625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        emitGetScopedVar(propDst, depth, index, globalObject);
13635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return baseDst;
13645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
13655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
13665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if ENABLE(JIT)
13675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    m_codeBlock->addGlobalResolveInfo(instructions().size());
13685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#else
13695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    m_codeBlock->addGlobalResolveInstruction(instructions().size());
13705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif
13716c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    emitOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
13728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(propDst->index());
13738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(addConstant(property));
13745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    instructions().append(0);
13755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    instructions().append(0);
13766c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (requiresDynamicChecks)
13776c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        instructions().append(depth);
13788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return baseDst;
13798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid BytecodeGenerator::emitMethodCheck()
13825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
13835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    emitOpcode(op_method_check);
13845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
13855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1386635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
13878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1388635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if ENABLE(JIT)
13890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    m_codeBlock->addStructureStubInfo(StructureStubInfo(access_get_by_id));
1390635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#else
1391635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    m_codeBlock->addPropertyAccessInstruction(instructions().size());
1392635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif
13938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_get_by_id);
13958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(dst->index());
13968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(base->index());
13978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(addConstant(property));
13988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(0);
13998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(0);
14008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(0);
14018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(0);
14028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return dst;
14038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
14048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1405bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenRegisterID* BytecodeGenerator::emitGetArgumentsLength(RegisterID* dst, RegisterID* base)
1406bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{
1407bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    emitOpcode(op_get_arguments_length);
1408bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    instructions().append(dst->index());
1409bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    ASSERT(base->index() == m_codeBlock->argumentsRegister());
1410bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    instructions().append(base->index());
1411bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    instructions().append(addConstant(propertyNames().length));
1412bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return dst;
1413bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen}
1414bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
1415635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
14168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1417635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if ENABLE(JIT)
14180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    m_codeBlock->addStructureStubInfo(StructureStubInfo(access_put_by_id));
1419635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#else
1420635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    m_codeBlock->addPropertyAccessInstruction(instructions().size());
1421635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif
14228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_put_by_id);
14248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(base->index());
14258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(addConstant(property));
14268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(value->index());
14278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(0);
14288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(0);
14298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(0);
14308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(0);
1431e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    instructions().append(0);
1432e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    return value;
1433e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
1434e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
1435e458d70a0d18538346f41b503114c9ebe6b2ce12Leon ClarkeRegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value)
1436e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
1437e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(JIT)
1438e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    m_codeBlock->addStructureStubInfo(StructureStubInfo(access_put_by_id));
1439e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#else
1440e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    m_codeBlock->addPropertyAccessInstruction(instructions().size());
1441e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif
1442e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
1443e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    emitOpcode(op_put_by_id);
1444e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    instructions().append(base->index());
1445e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    instructions().append(addConstant(property));
1446e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    instructions().append(value->index());
1447e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    instructions().append(0);
1448e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    instructions().append(0);
1449e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    instructions().append(0);
1450e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    instructions().append(0);
1451e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    instructions().append(property != m_globalData->propertyNames->underscoreProto);
14528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return value;
14538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
14548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1455635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitPutGetter(RegisterID* base, const Identifier& property, RegisterID* value)
14568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
14578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_put_getter);
14588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(base->index());
14598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(addConstant(property));
14608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(value->index());
14618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return value;
14628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
14638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1464635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitPutSetter(RegisterID* base, const Identifier& property, RegisterID* value)
14658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
14668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_put_setter);
14678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(base->index());
14688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(addConstant(property));
14698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(value->index());
14708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return value;
14718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
14728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1473635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier& property)
14748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
14758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_del_by_id);
14768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(dst->index());
14778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(base->index());
14788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(addConstant(property));
14798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return dst;
14808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
14818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1482bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenRegisterID* BytecodeGenerator::emitGetArgumentByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
1483bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{
1484bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    emitOpcode(op_get_argument_by_val);
1485bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    instructions().append(dst->index());
1486bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    ASSERT(base->index() == m_codeBlock->argumentsRegister());
1487bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    instructions().append(base->index());
1488bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    instructions().append(property->index());
1489bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return dst;
1490bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen}
1491bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
1492635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
14938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1494cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    for (size_t i = m_forInContextStack.size(); i > 0; i--) {
1495cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        ForInContext& context = m_forInContextStack[i - 1];
1496cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        if (context.propertyRegister == property) {
1497cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            emitOpcode(op_get_by_pname);
1498cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            instructions().append(dst->index());
1499cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            instructions().append(base->index());
1500cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            instructions().append(property->index());
1501cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            instructions().append(context.expectedSubscriptRegister->index());
1502cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            instructions().append(context.iterRegister->index());
1503cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            instructions().append(context.indexRegister->index());
1504cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            return dst;
1505cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        }
1506cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    }
15078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_get_by_val);
15088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(dst->index());
15098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(base->index());
15108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(property->index());
15118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return dst;
15128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1514635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value)
15158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_put_by_val);
15178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(base->index());
15188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(property->index());
15198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(value->index());
15208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return value;
15218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1523635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
15248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_del_by_val);
15268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(dst->index());
15278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(base->index());
15288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(property->index());
15298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return dst;
15308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1532635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value)
15338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_put_by_index);
15358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(base->index());
15368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(index);
15378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(value->index());
15388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return value;
15398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1541635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitNewObject(RegisterID* dst)
15428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_new_object);
15448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(dst->index());
15458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return dst;
15468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1548635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements)
15498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<RefPtr<RegisterID>, 16> argv;
15518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (ElementNode* n = elements; n; n = n->next()) {
15528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (n->elision())
15538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
15548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        argv.append(newTemporary());
1555635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // op_new_array requires the initial values to be a sequential range of registers
1556635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        ASSERT(argv.size() == 1 || argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1);
15578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        emitNode(argv.last().get(), n->value());
15588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_new_array);
15608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(dst->index());
15618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(argv.size() ? argv[0]->index() : 0); // argv
15628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(argv.size()); // argc
15638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return dst;
15648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1566231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockRegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionBodyNode* function)
15678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1568bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return emitNewFunctionInternal(dst, m_codeBlock->addFunctionDecl(makeFunction(m_globalData, function)), false);
1569bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen}
1570231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1571bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenRegisterID* BytecodeGenerator::emitLazyNewFunction(RegisterID* dst, FunctionBodyNode* function)
1572bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{
1573bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    std::pair<FunctionOffsetMap::iterator, bool> ptr = m_functionOffsets.add(function, 0);
1574bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (ptr.second)
1575bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        ptr.first->second = m_codeBlock->addFunctionDecl(makeFunction(m_globalData, function));
1576bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    return emitNewFunctionInternal(dst, ptr.first->second, true);
1577bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen}
1578bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
1579bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenRegisterID* BytecodeGenerator::emitNewFunctionInternal(RegisterID* dst, unsigned index, bool doNullCheck)
1580bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{
1581a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    createActivationIfNecessary();
15828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_new_func);
15838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(dst->index());
1584231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    instructions().append(index);
1585bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    instructions().append(doNullCheck);
15868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return dst;
15878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15892bde8e466a4451c7319e3a072d118917957d6554Steve BlockRegisterID* BytecodeGenerator::emitNewRegExp(RegisterID* dst, PassRefPtr<RegExp> regExp)
15906c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{
15916c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    emitOpcode(op_new_regexp);
15926c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    instructions().append(dst->index());
15936c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    instructions().append(addRegExp(regExp));
15946c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    return dst;
15956c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen}
15966c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
1597635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExprNode* n)
15988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1599231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    FunctionBodyNode* function = n->body();
1600231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    unsigned index = m_codeBlock->addFunctionExpr(makeFunction(m_globalData, function));
1601a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1602a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    createActivationIfNecessary();
16038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_new_func_exp);
16048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(r0->index());
1605231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    instructions().append(index);
16068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return r0;
16078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
16088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1609545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset)
16108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1611545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return emitCall(op_call, dst, func, callArguments, divot, startOffset, endOffset);
16128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
16138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid BytecodeGenerator::createArgumentsIfNecessary()
16155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
1616e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (m_codeType != FunctionCode)
1617e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        return;
1618f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
1619f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!m_codeBlock->usesArguments())
1620f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return;
1621e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block
1622a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // If we're in strict mode we tear off the arguments on function
1623a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // entry, so there's no need to check if we need to create them
1624a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // now
1625a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (m_codeBlock->isStrictMode())
1626a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
1627a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1628e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    emitOpcode(op_create_arguments);
1629e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    instructions().append(m_codeBlock->argumentsRegister());
16305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
16315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1632a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid BytecodeGenerator::createActivationIfNecessary()
1633a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
1634a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (m_hasCreatedActivation)
1635a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
1636a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!m_codeBlock->needsFullScopeChain())
1637a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
1638a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    emitOpcode(op_create_activation);
1639a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    instructions().append(m_activationRegister->index());
1640a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
1641a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1642545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset)
16438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1644545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return emitCall(op_call_eval, dst, func, callArguments, divot, startOffset, endOffset);
16458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
16468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1647545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset)
16488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
16498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(opcodeID == op_call || opcodeID == op_call_eval);
16508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(func->refCount());
1651635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1652545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (m_shouldEmitProfileHooks)
1653545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        emitMove(callArguments.profileHookRegister(), func);
1654635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
16558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Generate code for arguments.
1656545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    unsigned argumentIndex = 0;
1657545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    for (ArgumentListNode* n = callArguments.argumentsNode()->m_listNode; n; n = n->m_next)
1658545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        emitNode(callArguments.argumentRegister(argumentIndex++), n);
16598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Reserve space for call frame.
16618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<RefPtr<RegisterID>, RegisterFile::CallFrameHeaderSize> callFrame;
16628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int i = 0; i < RegisterFile::CallFrameHeaderSize; ++i)
16638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        callFrame.append(newTemporary());
16648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_shouldEmitProfileHooks) {
16668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        emitOpcode(op_profile_will_call);
1667545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        instructions().append(callArguments.profileHookRegister()->index());
16688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitExpressionInfo(divot, startOffset, endOffset);
1671635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1672635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if ENABLE(JIT)
1673635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    m_codeBlock->addCallLinkInfo();
1674635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif
1675635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1676635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Emit call.
16778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(opcodeID);
1678635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    instructions().append(func->index()); // func
1679545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    instructions().append(callArguments.count()); // argCount
1680545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    instructions().append(callArguments.callFrame()); // registerOffset
1681e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (dst != ignoredResult()) {
1682e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        emitOpcode(op_call_put_result);
1683e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        instructions().append(dst->index()); // dst
1684e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    }
16858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_shouldEmitProfileHooks) {
16878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        emitOpcode(op_profile_did_call);
1688545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        instructions().append(callArguments.profileHookRegister()->index());
16898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return dst;
16928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
16938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
169428040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuRegisterID* BytecodeGenerator::emitLoadVarargs(RegisterID* argCountDst, RegisterID* thisRegister, RegisterID* arguments)
16955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
16965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(argCountDst->index() < arguments->index());
16975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    emitOpcode(op_load_varargs);
16985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    instructions().append(argCountDst->index());
16995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    instructions().append(arguments->index());
170028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    instructions().append(thisRegister->index() + RegisterFile::CallFrameHeaderSize); // initial registerOffset
17015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return argCountDst;
17025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
17035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
17045f1ab04193ad0130ca8204aadaceae083aca9881Feng QianRegisterID* BytecodeGenerator::emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* argCountRegister, unsigned divot, unsigned startOffset, unsigned endOffset)
17055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
17065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(func->refCount());
17075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(thisRegister->refCount());
17085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(dst != func);
17095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (m_shouldEmitProfileHooks) {
17105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        emitOpcode(op_profile_will_call);
17115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        instructions().append(func->index());
17125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
17135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
17145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    emitExpressionInfo(divot, startOffset, endOffset);
17155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
17165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Emit call.
17175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    emitOpcode(op_call_varargs);
17185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    instructions().append(func->index()); // func
17195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    instructions().append(argCountRegister->index()); // arg count
17205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    instructions().append(thisRegister->index() + RegisterFile::CallFrameHeaderSize); // initial registerOffset
1721e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (dst != ignoredResult()) {
1722e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        emitOpcode(op_call_put_result);
1723e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        instructions().append(dst->index()); // dst
1724e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    }
17255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (m_shouldEmitProfileHooks) {
17265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        emitOpcode(op_profile_did_call);
17275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        instructions().append(func->index());
17285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
17295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return dst;
17305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
17315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1732635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitReturn(RegisterID* src)
17338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1734635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (m_codeBlock->needsFullScopeChain()) {
17358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        emitOpcode(op_tear_off_activation);
1736e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        instructions().append(m_activationRegister->index());
1737e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        instructions().append(m_codeBlock->argumentsRegister());
1738a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else if (m_codeBlock->usesArguments() && m_codeBlock->m_numParameters > 1
1739a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch               && !m_codeBlock->isStrictMode()) { // If there are no named parameters, there's nothing to tear off, since extra / unnamed parameters get copied to the arguments object at construct time.
17408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        emitOpcode(op_tear_off_arguments);
1741e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        instructions().append(m_codeBlock->argumentsRegister());
1742e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    }
17438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1744e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    // Constructors use op_ret_object_or_this to check the result is an
1745e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    // object, unless we can trivially determine the check is not
1746e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    // necessary (currently, if the return value is 'this').
1747e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (isConstructor() && (src->index() != m_thisRegister.index())) {
1748e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        emitOpcode(op_ret_object_or_this);
1749e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        instructions().append(src->index());
1750e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        instructions().append(m_thisRegister.index());
1751e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        return src;
1752e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    }
17538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return emitUnaryNoDstOp(op_ret, src);
17548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1756635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitUnaryNoDstOp(OpcodeID opcodeID, RegisterID* src)
17578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1758635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    emitOpcode(opcodeID);
17598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(src->index());
17608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return src;
17618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1763545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset)
17648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
17658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(func->refCount());
17668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1767545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (m_shouldEmitProfileHooks)
1768545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        emitMove(callArguments.profileHookRegister(), func);
1769635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
17708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Generate code for arguments.
1771545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    unsigned argumentIndex = 0;
1772545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (ArgumentsNode* argumentsNode = callArguments.argumentsNode()) {
1773545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        for (ArgumentListNode* n = argumentsNode->m_listNode; n; n = n->m_next)
1774545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            emitNode(callArguments.argumentRegister(argumentIndex++), n);
17758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
17768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_shouldEmitProfileHooks) {
17788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        emitOpcode(op_profile_will_call);
1779545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        instructions().append(callArguments.profileHookRegister()->index());
17808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
17818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Reserve space for call frame.
17838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<RefPtr<RegisterID>, RegisterFile::CallFrameHeaderSize> callFrame;
17848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int i = 0; i < RegisterFile::CallFrameHeaderSize; ++i)
17858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        callFrame.append(newTemporary());
17868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitExpressionInfo(divot, startOffset, endOffset);
1788635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1789635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if ENABLE(JIT)
1790635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    m_codeBlock->addCallLinkInfo();
1791635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif
1792635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
17938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_construct);
1794635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    instructions().append(func->index()); // func
1795545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    instructions().append(callArguments.count()); // argCount
1796545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    instructions().append(callArguments.callFrame()); // registerOffset
1797e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    if (dst != ignoredResult()) {
1798e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        emitOpcode(op_call_put_result);
1799e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        instructions().append(dst->index()); // dst
1800e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    }
18018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_shouldEmitProfileHooks) {
18038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        emitOpcode(op_profile_did_call);
1804545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        instructions().append(callArguments.profileHookRegister()->index());
18058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
18068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return dst;
18088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18105f1ab04193ad0130ca8204aadaceae083aca9881Feng QianRegisterID* BytecodeGenerator::emitStrcat(RegisterID* dst, RegisterID* src, int count)
18115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
18125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    emitOpcode(op_strcat);
18135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    instructions().append(dst->index());
18145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    instructions().append(src->index());
18155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    instructions().append(count);
18165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
18175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return dst;
18185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
18195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
18205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid BytecodeGenerator::emitToPrimitive(RegisterID* dst, RegisterID* src)
18215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
18225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    emitOpcode(op_to_primitive);
18235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    instructions().append(dst->index());
18245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    instructions().append(src->index());
18255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
18265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1827635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitPushScope(RegisterID* scope)
18288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1829635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ASSERT(scope->isTemporary());
18308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ControlFlowContext context;
18318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    context.isFinallyBlock = false;
18328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_scopeContextStack.append(context);
18338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_dynamicScopeDepth++;
18348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return emitUnaryNoDstOp(op_push_scope, scope);
18368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1838635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::emitPopScope()
18398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
18408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_scopeContextStack.size());
18418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!m_scopeContextStack.last().isFinallyBlock);
18428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_pop_scope);
18448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_scopeContextStack.removeLast();
18468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_dynamicScopeDepth--;
18478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1849635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, int lastLine)
18508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
185121939df44de1705786c545cd1bf519d47250322dBen Murdoch#if ENABLE(DEBUG_WITH_BREAKPOINT)
185221939df44de1705786c545cd1bf519d47250322dBen Murdoch    if (debugHookID != DidReachBreakpoint)
185321939df44de1705786c545cd1bf519d47250322dBen Murdoch        return;
185421939df44de1705786c545cd1bf519d47250322dBen Murdoch#else
18558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_shouldEmitDebugHooks)
18568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
185721939df44de1705786c545cd1bf519d47250322dBen Murdoch#endif
18588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_debug);
18598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(debugHookID);
18608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(firstLine);
18618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(lastLine);
18628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1864635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::pushFinallyContext(Label* target, RegisterID* retAddrDst)
18658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
18668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ControlFlowContext scope;
18678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    scope.isFinallyBlock = true;
18688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FinallyContext context = { target, retAddrDst };
18698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    scope.finallyContext = context;
18708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_scopeContextStack.append(scope);
18718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_finallyDepth++;
18728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1874635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::popFinallyContext()
18758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
18768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_scopeContextStack.size());
18778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_scopeContextStack.last().isFinallyBlock);
18788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_finallyDepth > 0);
18798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_scopeContextStack.removeLast();
18808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_finallyDepth--;
18818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
18828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1883635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectLabelScope* BytecodeGenerator::breakTarget(const Identifier& name)
18848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
18858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Reclaim free label scopes.
18865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    //
18875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // The condition was previously coded as 'm_labelScopes.size() && !m_labelScopes.last().refCount()',
18885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // however sometimes this appears to lead to GCC going a little haywire and entering the loop with
18895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // size 0, leading to segfaulty badness.  We are yet to identify a valid cause within our code to
18905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // cause the GCC codegen to misbehave in this fashion, and as such the following refactoring of the
18915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // loop condition is a workaround.
18925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    while (m_labelScopes.size()) {
18935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if  (m_labelScopes.last().refCount())
18945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            break;
18958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_labelScopes.removeLast();
18965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
18978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_labelScopes.size())
18998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
19008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We special-case the following, which is a syntax error in Firefox:
19028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // label:
19038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    //     break;
19048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (name.isEmpty()) {
19058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
19068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            LabelScope* scope = &m_labelScopes[i];
19078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (scope->type() != LabelScope::NamedLabel) {
19088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                ASSERT(scope->breakTarget());
19098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return scope;
19108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
19118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
19128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
19138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
19148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
19168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        LabelScope* scope = &m_labelScopes[i];
19178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (scope->name() && *scope->name() == name) {
19188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(scope->breakTarget());
19198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return scope;
19208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
19218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
19228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
19238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
19248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1925635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectLabelScope* BytecodeGenerator::continueTarget(const Identifier& name)
19268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
19278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Reclaim free label scopes.
19288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (m_labelScopes.size() && !m_labelScopes.last().refCount())
19298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_labelScopes.removeLast();
19308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_labelScopes.size())
19328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
19338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (name.isEmpty()) {
19358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
19368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            LabelScope* scope = &m_labelScopes[i];
19378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (scope->type() == LabelScope::Loop) {
19388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                ASSERT(scope->continueTarget());
19398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return scope;
19408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
19418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
19428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
19438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
19448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Continue to the loop nested nearest to the label scope that matches
19468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 'name'.
19478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    LabelScope* result = 0;
19488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
19498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        LabelScope* scope = &m_labelScopes[i];
19508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (scope->type() == LabelScope::Loop) {
19518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(scope->continueTarget());
19528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            result = scope;
19538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
19548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (scope->name() && *scope->name() == name)
19558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return result; // may be 0
19568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
19578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
19588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
19598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1960635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<Label> BytecodeGenerator::emitComplexJumpScopes(Label* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope)
19618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
19628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (topScope > bottomScope) {
19638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // First we count the number of dynamic scopes we need to remove to get
19648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // to a finally block.
19658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int nNormalScopes = 0;
19668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (topScope > bottomScope) {
19678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (topScope->isFinallyBlock)
19688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
19698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ++nNormalScopes;
19708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            --topScope;
19718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
19728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (nNormalScopes) {
1974cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            size_t begin = instructions().size();
1975cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
19768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We need to remove a number of dynamic scopes to get to the next
19778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // finally block
19788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            emitOpcode(op_jmp_scopes);
19798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            instructions().append(nNormalScopes);
19808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // If topScope == bottomScope then there isn't actually a finally block
19828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // left to emit, so make the jmp_scopes jump directly to the target label
19838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (topScope == bottomScope) {
1984cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block                instructions().append(target->bind(begin, instructions().size()));
19858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return target;
19868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
19878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Otherwise we just use jmp_scopes to pop a group of scopes and go
19898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // to the next instruction
1990635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            RefPtr<Label> nextInsn = newLabel();
1991cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            instructions().append(nextInsn->bind(begin, instructions().size()));
19928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            emitLabel(nextInsn.get());
19938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
19948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
19955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        while (topScope > bottomScope && topScope->isFinallyBlock) {
19968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            emitJumpSubroutine(topScope->finallyContext.retAddrDst, topScope->finallyContext.finallyAddr);
19978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            --topScope;
19985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
19998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
20008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return emitJump(target);
20018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
20028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2003635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<Label> BytecodeGenerator::emitJumpScopes(Label* target, int targetScopeDepth)
20048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
20058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(scopeDepth() - targetScopeDepth >= 0);
2006635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ASSERT(target->isForward());
20078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
20088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    size_t scopeDelta = scopeDepth() - targetScopeDepth;
20098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(scopeDelta <= m_scopeContextStack.size());
20108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!scopeDelta)
20118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return emitJump(target);
20128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
20138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_finallyDepth)
20148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return emitComplexJumpScopes(target, &m_scopeContextStack.last(), &m_scopeContextStack.last() - scopeDelta);
20158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2016cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    size_t begin = instructions().size();
2017cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
20188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_jmp_scopes);
20198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(scopeDelta);
2020cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    instructions().append(target->bind(begin, instructions().size()));
20218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return target;
20228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
20238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2024cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve BlockRegisterID* BytecodeGenerator::emitGetPropertyNames(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, Label* breakTarget)
20258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2026cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    size_t begin = instructions().size();
2027cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
2028cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    emitOpcode(op_get_pnames);
2029cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    instructions().append(dst->index());
2030cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    instructions().append(base->index());
2031cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    instructions().append(i->index());
2032cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    instructions().append(size->index());
2033cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    instructions().append(breakTarget->bind(begin, instructions().size()));
2034cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    return dst;
2035cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block}
2036cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
2037cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve BlockRegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, RegisterID* iter, Label* target)
2038cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{
2039cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    size_t begin = instructions().size();
2040cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
20418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_next_pname);
20428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(dst->index());
2043cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    instructions().append(base->index());
2044cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    instructions().append(i->index());
2045cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    instructions().append(size->index());
20468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(iter->index());
2047cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    instructions().append(target->bind(begin, instructions().size()));
20488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return dst;
20498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
20508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2051635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitCatch(RegisterID* targetRegister, Label* start, Label* end)
20528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
205306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    m_usesExceptions = true;
2054635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if ENABLE(JIT)
2055cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() };
2056635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#else
2057cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth };
2058635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif
2059635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
2060635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    m_codeBlock->addExceptionHandler(info);
20618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_catch);
20628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(targetRegister->index());
20638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return targetRegister;
20648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
20658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
20666b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid BytecodeGenerator::emitThrowReferenceError(const UString& message)
20678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
20686b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    emitOpcode(op_throw_reference_error);
20696b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    instructions().append(addConstantValue(jsString(globalData(), message))->index());
20706b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner}
20716b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
2072635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<Label> BytecodeGenerator::emitJumpSubroutine(RegisterID* retAddrDst, Label* finally)
20738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2074cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    size_t begin = instructions().size();
2075cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
20768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_jsr);
20778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(retAddrDst->index());
2078cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    instructions().append(finally->bind(begin, instructions().size()));
20790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    emitLabel(newLabel().get()); // Record the fact that the next instruction is implicitly labeled, because op_sret will return to it.
20808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return finally;
20818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
20828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2083635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::emitSubroutineReturn(RegisterID* retAddrSrc)
20848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
20858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_sret);
20868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(retAddrSrc->index());
20878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
20888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2089231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid BytecodeGenerator::emitPushNewScope(RegisterID* dst, const Identifier& property, RegisterID* value)
20908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
20918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ControlFlowContext context;
20928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    context.isFinallyBlock = false;
20938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_scopeContextStack.append(context);
20948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_dynamicScopeDepth++;
20955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
20968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    emitOpcode(op_push_new_scope);
20978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(dst->index());
20988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(addConstant(property));
20998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(value->index());
21008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
21018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2102635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::beginSwitch(RegisterID* scrutineeRegister, SwitchInfo::SwitchType type)
21038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
21048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SwitchInfo info = { instructions().size(), type };
21058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch (type) {
21068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case SwitchInfo::SwitchImmediate:
21078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            emitOpcode(op_switch_imm);
21088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
21098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case SwitchInfo::SwitchCharacter:
21108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            emitOpcode(op_switch_char);
21118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
21128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case SwitchInfo::SwitchString:
21138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            emitOpcode(op_switch_string);
21148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
21158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        default:
21168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT_NOT_REACHED();
21178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
21188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(0); // place holder for table index
21208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(0); // place holder for default target
21218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    instructions().append(scrutineeRegister->index());
21228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_switchContextStack.append(info);
21238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
21248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic int32_t keyForImmediateSwitch(ExpressionNode* node, int32_t min, int32_t max)
21268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
21278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(max);
21288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(node->isNumber());
21298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double value = static_cast<NumberNode*>(node)->value();
21308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int32_t key = static_cast<int32_t>(value);
21318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(key == value);
21328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(key >= min);
21338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(key <= max);
21348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return key - min;
21358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
21368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2137635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void prepareJumpTableForImmediateSwitch(SimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, int32_t min, int32_t max)
21388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
21398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    jumpTable.min = min;
21408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    jumpTable.branchOffsets.resize(max - min + 1);
21418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    jumpTable.branchOffsets.fill(0);
21428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (uint32_t i = 0; i < clauseCount; ++i) {
21438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We're emitting this after the clause labels should have been fixed, so
21448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // the labels should not be "forward" references
2145635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        ASSERT(!labels[i]->isForward());
2146cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        jumpTable.add(keyForImmediateSwitch(nodes[i], min, max), labels[i]->bind(switchAddress, switchAddress + 3));
21478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
21488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
21498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic int32_t keyForCharacterSwitch(ExpressionNode* node, int32_t min, int32_t max)
21518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
21528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(max);
21538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(node->isString());
2154f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    StringImpl* clause = static_cast<StringNode*>(node)->value().impl();
2155692e5dbf12901edacf14812a6fae25462920af42Steve Block    ASSERT(clause->length() == 1);
21568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2157dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    int32_t key = clause->characters()[0];
21588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(key >= min);
21598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(key <= max);
21608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return key - min;
21618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
21628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2163635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void prepareJumpTableForCharacterSwitch(SimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, int32_t min, int32_t max)
21648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
21658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    jumpTable.min = min;
21668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    jumpTable.branchOffsets.resize(max - min + 1);
21678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    jumpTable.branchOffsets.fill(0);
21688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (uint32_t i = 0; i < clauseCount; ++i) {
21698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We're emitting this after the clause labels should have been fixed, so
21708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // the labels should not be "forward" references
2171635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        ASSERT(!labels[i]->isForward());
2172cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        jumpTable.add(keyForCharacterSwitch(nodes[i], min, max), labels[i]->bind(switchAddress, switchAddress + 3));
21738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
21748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
21758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2176635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void prepareJumpTableForStringSwitch(StringJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes)
21778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
21788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (uint32_t i = 0; i < clauseCount; ++i) {
21798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We're emitting this after the clause labels should have been fixed, so
21808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // the labels should not be "forward" references
2181635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        ASSERT(!labels[i]->isForward());
21828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(nodes[i]->isString());
2184f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        StringImpl* clause = static_cast<StringNode*>(nodes[i])->value().impl();
21858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        OffsetLocation location;
2186cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        location.branchOffset = labels[i]->bind(switchAddress, switchAddress + 3);
21878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        jumpTable.offsetTable.add(clause, location);
21888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
21898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
21908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2191635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::endSwitch(uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, Label* defaultLabel, int32_t min, int32_t max)
21928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
21938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SwitchInfo switchInfo = m_switchContextStack.last();
21948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_switchContextStack.removeLast();
21958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (switchInfo.switchType == SwitchInfo::SwitchImmediate) {
2196635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfImmediateSwitchJumpTables();
2197cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
21988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2199635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        SimpleJumpTable& jumpTable = m_codeBlock->addImmediateSwitchJumpTable();
2200cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        prepareJumpTableForImmediateSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max);
22018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (switchInfo.switchType == SwitchInfo::SwitchCharacter) {
2202635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfCharacterSwitchJumpTables();
2203cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
22048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2205635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        SimpleJumpTable& jumpTable = m_codeBlock->addCharacterSwitchJumpTable();
2206cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        prepareJumpTableForCharacterSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max);
22078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
22088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(switchInfo.switchType == SwitchInfo::SwitchString);
2209635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfStringSwitchJumpTables();
2210cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
22118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2212635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        StringJumpTable& jumpTable = m_codeBlock->addStringSwitchJumpTable();
2213cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        prepareJumpTableForStringSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes);
22148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
22158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
22168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2217635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitThrowExpressionTooDeepException()
2218635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
2219635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // It would be nice to do an even better job of identifying exactly where the expression is.
2220635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // And we could make the caller pass the node pointer in, if there was some way of getting
2221635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // that from an arbitrary node. However, calling emitExpressionInfo without any useful data
2222635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // is still good enough to get us an accurate line number.
222365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_expressionTooDeep = true;
22246b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    return newTemporary();
2225635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
2226635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
2227967717af5423377c967781471ee106e2bb4e11c8Ben Murdochvoid BytecodeGenerator::setIsNumericCompareFunction(bool isNumericCompareFunction)
2228967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{
2229967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    m_codeBlock->setIsNumericCompareFunction(isNumericCompareFunction);
2230967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch}
2231967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
2232967717af5423377c967781471ee106e2bb4e11c8Ben Murdochint BytecodeGenerator::argumentNumberFor(const Identifier& ident)
2233967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{
2234967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    int parameterCount = m_parameters.size(); // includes 'this'
2235967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    RegisterID* registerID = registerFor(ident);
2236967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    if (!registerID)
2237967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        return 0;
2238967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    int index = registerID->index() + RegisterFile::CallFrameHeaderSize + parameterCount;
2239967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    return (index > 0 && index < parameterCount) ? index : 0;
2240967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch}
2241967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
22428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace JSC
2243