~ubuntu-branches/ubuntu/karmic/webkit/karmic-proposed

« back to all changes in this revision

Viewing changes to JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Gustavo Noronha Silva
  • Date: 2009-05-15 18:30:58 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20090515183058-50q5exjo9b1kxy9s
Tags: 1.1.7-1
* New upstream release
* debian/libwebkit-1.0-2.symbols:
- updated with the new symbols in 1.1.7
* debian/libwebkit-dev.install, debian/libwebkit-dev.links,
  debian/rules:
- Build, and ship gtk-doc documentation (Closes: #526683)
* debian/copyright:
- updated.

Show diffs side-by-side

added added

removed removed

Lines of Context:
262
262
        m_nextGlobalIndex -= symbolTable->size();
263
263
 
264
264
        for (size_t i = 0; i < functionStack.size(); ++i) {
265
 
            FuncDeclNode* funcDecl = functionStack[i].get();
 
265
            FuncDeclNode* funcDecl = functionStack[i];
266
266
            globalObject->removeDirect(funcDecl->m_ident); // Make sure our new function is not shadowed by an old property.
267
267
            emitNewFunction(addGlobalVar(funcDecl->m_ident, false), funcDecl);
268
268
        }
269
269
 
270
270
        Vector<RegisterID*, 32> newVars;
271
271
        for (size_t i = 0; i < varStack.size(); ++i)
272
 
            if (!globalObject->hasProperty(exec, varStack[i].first))
273
 
                newVars.append(addGlobalVar(varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant));
 
272
            if (!globalObject->hasProperty(exec, *varStack[i].first))
 
273
                newVars.append(addGlobalVar(*varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant));
274
274
 
275
275
        allocateConstants(programNode->neededConstants());
276
276
 
278
278
            emitLoad(newVars[i], jsUndefined());
279
279
    } else {
280
280
        for (size_t i = 0; i < functionStack.size(); ++i) {
281
 
            FuncDeclNode* funcDecl = functionStack[i].get();
 
281
            FuncDeclNode* funcDecl = functionStack[i];
282
282
            globalObject->putWithAttributes(exec, funcDecl->m_ident, funcDecl->makeFunction(exec, scopeChain.node()), DontDelete);
283
283
        }
284
284
        for (size_t i = 0; i < varStack.size(); ++i) {
285
 
            if (globalObject->hasProperty(exec, varStack[i].first))
 
285
            if (globalObject->hasProperty(exec, *varStack[i].first))
286
286
                continue;
287
287
            int attributes = DontDelete;
288
288
            if (varStack[i].second & DeclarationStacks::IsConstant)
289
289
                attributes |= ReadOnly;
290
 
            globalObject->putWithAttributes(exec, varStack[i].first, jsUndefined(), attributes);
 
290
            globalObject->putWithAttributes(exec, *varStack[i].first, jsUndefined(), attributes);
291
291
        }
292
292
 
293
293
        allocateConstants(programNode->neededConstants());
332
332
    } else
333
333
        emitOpcode(op_enter);
334
334
 
335
 
    if (usesArguments)
336
 
        emitOpcode(op_create_arguments);
 
335
     if (usesArguments)
 
336
        emitOpcode(op_init_arguments);
337
337
 
338
338
    const DeclarationStacks::FunctionStack& functionStack = functionBody->functionStack();
339
339
    for (size_t i = 0; i < functionStack.size(); ++i) {
340
 
        FuncDeclNode* funcDecl = functionStack[i].get();
 
340
        FuncDeclNode* funcDecl = functionStack[i];
341
341
        const Identifier& ident = funcDecl->m_ident;
342
342
        m_functions.add(ident.ustring().rep());
343
343
        emitNewFunction(addVar(ident, false), funcDecl);
345
345
 
346
346
    const DeclarationStacks::VarStack& varStack = functionBody->varStack();
347
347
    for (size_t i = 0; i < varStack.size(); ++i)
348
 
        addVar(varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant);
 
348
        addVar(*varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant);
349
349
 
350
350
    const Identifier* parameters = functionBody->parameters();
351
351
    size_t parameterCount = functionBody->parameterCount();
428
428
    if (entry.isNull())
429
429
        return 0;
430
430
 
 
431
    if (ident == propertyNames().arguments)
 
432
        createArgumentsIfNecessary();
 
433
 
 
434
    return &registerFor(entry.getIndex());
 
435
}
 
436
 
 
437
bool BytecodeGenerator::willResolveToArguments(const Identifier& ident)
 
438
{
 
439
    if (ident != propertyNames().arguments)
 
440
        return false;
 
441
    
 
442
    if (!shouldOptimizeLocals())
 
443
        return false;
 
444
    
 
445
    SymbolTableEntry entry = symbolTable().get(ident.ustring().rep());
 
446
    if (entry.isNull())
 
447
        return false;
 
448
    
 
449
    if (m_codeBlock->usesArguments() && m_codeType == FunctionCode)
 
450
        return true;
 
451
    
 
452
    return false;
 
453
}
 
454
 
 
455
RegisterID* BytecodeGenerator::uncheckedRegisterForArguments()
 
456
{
 
457
    ASSERT(willResolveToArguments(propertyNames().arguments));
 
458
 
 
459
    SymbolTableEntry entry = symbolTable().get(propertyNames().arguments.ustring().rep());
 
460
    ASSERT(!entry.isNull());
431
461
    return &registerFor(entry.getIndex());
432
462
}
433
463
 
652
682
            instructions().append(target->offsetFrom(instructions().size()));
653
683
            return target;
654
684
        }
 
685
    } else if (m_lastOpcodeID == op_lesseq) {
 
686
        int dstIndex;
 
687
        int src1Index;
 
688
        int src2Index;
 
689
 
 
690
        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
 
691
 
 
692
        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
 
693
            rewindBinaryOp();
 
694
            emitOpcode(op_jnlesseq);
 
695
            instructions().append(src1Index);
 
696
            instructions().append(src2Index);
 
697
            instructions().append(target->offsetFrom(instructions().size()));
 
698
            return target;
 
699
        }
655
700
    } else if (m_lastOpcodeID == op_not) {
656
701
        int dstIndex;
657
702
        int srcIndex;
739
784
    return result.first->second;
740
785
}
741
786
 
742
 
RegisterID* BytecodeGenerator::addConstant(JSValuePtr v)
 
787
RegisterID* BytecodeGenerator::addConstant(JSValue v)
743
788
{
744
 
    pair<JSValueMap::iterator, bool> result = m_jsValueMap.add(JSValuePtr::encode(v), m_nextConstantIndex);
 
789
    pair<JSValueMap::iterator, bool> result = m_jsValueMap.add(JSValue::encode(v), m_nextConstantIndex);
745
790
    if (result.second) {
746
791
        RegisterID& constant = m_calleeRegisters[m_nextConstantIndex];
747
792
        
748
793
        ++m_nextConstantIndex;
749
794
 
750
 
        m_codeBlock->addConstantRegister(JSValuePtr(v));
 
795
        m_codeBlock->addConstantRegister(JSValue(v));
751
796
        return &constant;
752
797
    }
753
798
 
754
799
    return &registerFor(result.first->second);
755
800
}
756
801
 
757
 
unsigned BytecodeGenerator::addUnexpectedConstant(JSValuePtr v)
 
802
unsigned BytecodeGenerator::addUnexpectedConstant(JSValue v)
758
803
{
759
804
    return m_codeBlock->addUnexpectedConstant(v);
760
805
}
846
891
        if (src1->index() == dstIndex
847
892
            && src1->isTemporary()
848
893
            && m_codeBlock->isConstantRegisterIndex(src2->index())
849
 
            && m_codeBlock->constantRegister(src2->index() - m_codeBlock->m_numVars).jsValue(m_scopeChain->globalObject()->globalExec()).isString()) {
850
 
            const UString& value = asString(m_codeBlock->constantRegister(src2->index() - m_codeBlock->m_numVars).jsValue(m_scopeChain->globalObject()->globalExec()))->value();
 
894
            && m_codeBlock->constantRegister(src2->index() - m_codeBlock->m_numVars).jsValue().isString()) {
 
895
            const UString& value = asString(m_codeBlock->constantRegister(src2->index() - m_codeBlock->m_numVars).jsValue())->value();
851
896
            if (value == "undefined") {
852
897
                rewindUnaryOp();
853
898
                emitOpcode(op_is_undefined);
911
956
    // Later we can do the extra work to handle that like the other cases.
912
957
    if (number == HashTraits<double>::emptyValue() || HashTraits<double>::isDeletedValue(number))
913
958
        return emitLoad(dst, jsNumber(globalData(), number));
914
 
    JSValuePtr& valueInMap = m_numberMap.add(number, noValue()).first->second;
 
959
    JSValue& valueInMap = m_numberMap.add(number, JSValue()).first->second;
915
960
    if (!valueInMap)
916
961
        valueInMap = jsNumber(globalData(), number);
917
962
    return emitLoad(dst, valueInMap);
922
967
    JSString*& stringInMap = m_stringMap.add(identifier.ustring().rep(), 0).first->second;
923
968
    if (!stringInMap)
924
969
        stringInMap = jsOwnedString(globalData(), identifier.ustring());
925
 
    return emitLoad(dst, JSValuePtr(stringInMap));
 
970
    return emitLoad(dst, JSValue(stringInMap));
926
971
}
927
972
 
928
 
RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValuePtr v)
 
973
RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValue v)
929
974
{
930
975
    RegisterID* constantID = addConstant(v);
931
976
    if (dst)
1069
1114
    return dst;
1070
1115
}
1071
1116
 
1072
 
RegisterID* BytecodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, int index, JSValuePtr globalObject)
 
1117
RegisterID* BytecodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, int index, JSValue globalObject)
1073
1118
{
1074
1119
    if (globalObject) {
1075
1120
        emitOpcode(op_get_global_var);
1086
1131
    return dst;
1087
1132
}
1088
1133
 
1089
 
RegisterID* BytecodeGenerator::emitPutScopedVar(size_t depth, int index, RegisterID* value, JSValuePtr globalObject)
 
1134
RegisterID* BytecodeGenerator::emitPutScopedVar(size_t depth, int index, RegisterID* value, JSValue globalObject)
1090
1135
{
1091
1136
    if (globalObject) {
1092
1137
        emitOpcode(op_put_global_var);
1331
1376
    return emitCall(op_call, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);
1332
1377
}
1333
1378
 
 
1379
void BytecodeGenerator::createArgumentsIfNecessary()
 
1380
{
 
1381
    if (m_codeBlock->usesArguments() && m_codeType == FunctionCode)
 
1382
        emitOpcode(op_create_arguments);
 
1383
}
 
1384
 
1334
1385
RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
1335
1386
{
 
1387
    createArgumentsIfNecessary();
1336
1388
    return emitCall(op_call_eval, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);
1337
1389
}
1338
1390
 
1359
1411
    // Generate code for arguments.
1360
1412
    Vector<RefPtr<RegisterID>, 16> argv;
1361
1413
    argv.append(thisRegister);
1362
 
    for (ArgumentListNode* n = argumentsNode->m_listNode.get(); n; n = n->m_next.get()) {
 
1414
    for (ArgumentListNode* n = argumentsNode->m_listNode; n; n = n->m_next) {
1363
1415
        argv.append(newTemporary());
1364
1416
        // op_call requires the arguments to be a sequential range of registers
1365
1417
        ASSERT(argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1);
1482
1534
    // Generate code for arguments.
1483
1535
    Vector<RefPtr<RegisterID>, 16> argv;
1484
1536
    argv.append(newTemporary()); // reserve space for "this"
1485
 
    for (ArgumentListNode* n = argumentsNode ? argumentsNode->m_listNode.get() : 0; n; n = n->m_next.get()) {
 
1537
    for (ArgumentListNode* n = argumentsNode ? argumentsNode->m_listNode : 0; n; n = n->m_next) {
1486
1538
        argv.append(newTemporary());
1487
1539
        // op_construct requires the arguments to be a sequential range of registers
1488
1540
        ASSERT(argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1);
1533
1585
    return dst;
1534
1586
}
1535
1587
 
 
1588
RegisterID* BytecodeGenerator::emitStrcat(RegisterID* dst, RegisterID* src, int count)
 
1589
{
 
1590
    emitOpcode(op_strcat);
 
1591
    instructions().append(dst->index());
 
1592
    instructions().append(src->index());
 
1593
    instructions().append(count);
 
1594
 
 
1595
    return dst;
 
1596
}
 
1597
 
 
1598
void BytecodeGenerator::emitToPrimitive(RegisterID* dst, RegisterID* src)
 
1599
{
 
1600
    emitOpcode(op_to_primitive);
 
1601
    instructions().append(dst->index());
 
1602
    instructions().append(src->index());
 
1603
}
 
1604
 
1536
1605
RegisterID* BytecodeGenerator::emitPushScope(RegisterID* scope)
1537
1606
{
1538
1607
    ASSERT(scope->isTemporary());
1540
1609
    context.isFinallyBlock = false;
1541
1610
    m_scopeContextStack.append(context);
1542
1611
    m_dynamicScopeDepth++;
 
1612
    createArgumentsIfNecessary();
1543
1613
 
1544
1614
    return emitUnaryNoDstOp(op_push_scope, scope);
1545
1615
}
1694
1764
            emitLabel(nextInsn.get());
1695
1765
        }
1696
1766
 
1697
 
        // To get here there must be at least one finally block present
1698
 
        do {
1699
 
            ASSERT(topScope->isFinallyBlock);
 
1767
        while (topScope > bottomScope && topScope->isFinallyBlock) {
1700
1768
            emitJumpSubroutine(topScope->finallyContext.retAddrDst, topScope->finallyContext.finallyAddr);
1701
1769
            --topScope;
1702
 
            if (!topScope->isFinallyBlock)
1703
 
                break;
1704
 
        } while (topScope > bottomScope);
 
1770
        }
1705
1771
    }
1706
1772
    return emitJump(target);
1707
1773
}
1748
1814
    return targetRegister;
1749
1815
}
1750
1816
 
1751
 
RegisterID* BytecodeGenerator::emitNewError(RegisterID* dst, ErrorType type, JSValuePtr message)
 
1817
RegisterID* BytecodeGenerator::emitNewError(RegisterID* dst, ErrorType type, JSValue message)
1752
1818
{
1753
1819
    emitOpcode(op_new_error);
1754
1820
    instructions().append(dst->index());
1771
1837
    instructions().append(retAddrSrc->index());
1772
1838
}
1773
1839
 
1774
 
void BytecodeGenerator::emitPushNewScope(RegisterID* dst, Identifier& property, RegisterID* value)
 
1840
void BytecodeGenerator::emitPushNewScope(RegisterID* dst, const Identifier& property, RegisterID* value)
1775
1841
{
1776
1842
    ControlFlowContext context;
1777
1843
    context.isFinallyBlock = false;
1778
1844
    m_scopeContextStack.append(context);
1779
1845
    m_dynamicScopeDepth++;
1780
1846
    
 
1847
    createArgumentsIfNecessary();
 
1848
 
1781
1849
    emitOpcode(op_push_new_scope);
1782
1850
    instructions().append(dst->index());
1783
1851
    instructions().append(addConstant(property));
1813
1881
    ASSERT(node->isNumber());
1814
1882
    double value = static_cast<NumberNode*>(node)->value();
1815
1883
    int32_t key = static_cast<int32_t>(value);
1816
 
    ASSERT(JSValuePtr::makeInt32Fast(key) && (JSValuePtr::makeInt32Fast(key).getInt32Fast() == value));
 
1884
    ASSERT(JSValue::makeInt32Fast(key) && (JSValue::makeInt32Fast(key).getInt32Fast() == value));
1817
1885
    ASSERT(key == value);
1818
1886
    ASSERT(key >= min);
1819
1887
    ASSERT(key <= max);