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