~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

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