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