Changeset 36604 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Sep 17, 2008, 11:20:42 PM (17 years ago)
Author:
[email protected]
Message:

2008-09-17 Cameron Zwarich <[email protected]>

Reviewed by Maciej Stachowiak.

Bug 20876: REGRESSION (r36417, r36427): fast/js/exception-expression-offset.html fails
<https://bugs.webkit.org/show_bug.cgi?id=20876>

r36417 and r36427 caused an get_by_id opcode to be emitted before the
instanceof and construct opcodes, in order to enable inline caching of
the prototype property. Unfortunately, this regressed some tests dealing
with exceptions thrown by 'instanceof' and the 'new' operator. We fix
these problems by detecting whether an "is not an object" exception is
thrown before op_instanceof or op_construct, and emit the proper
exception in those cases.

  • VM/CodeGenerator.cpp: (JSC::CodeGenerator::emitConstruct):
  • VM/CodeGenerator.h:
  • VM/ExceptionHelpers.cpp: (JSC::createInvalidParamError): (JSC::createNotAConstructorError): (JSC::createNotAnObjectError):
  • VM/ExceptionHelpers.h:
  • VM/Machine.cpp: (JSC::Machine::getOpcode): (JSC::Machine::privateExecute):
  • VM/Machine.h:
  • kjs/nodes.cpp: (JSC::NewExprNode::emitCode): (JSC::InstanceOfNode::emitCode):
Location:
trunk/JavaScriptCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r36581 r36604  
     12008-09-17  Cameron Zwarich  <[email protected]>
     2
     3        Reviewed by Maciej Stachowiak.
     4
     5        Bug 20876: REGRESSION (r36417, r36427): fast/js/exception-expression-offset.html fails
     6        <https://bugs.webkit.org/show_bug.cgi?id=20876>
     7
     8        r36417 and r36427 caused an get_by_id opcode to be emitted before the
     9        instanceof and construct opcodes, in order to enable inline caching of
     10        the prototype property. Unfortunately, this regressed some tests dealing
     11        with exceptions thrown by 'instanceof' and the 'new' operator. We fix
     12        these problems by detecting whether an "is not an object" exception is
     13        thrown before op_instanceof or op_construct, and emit the proper
     14        exception in those cases.
     15
     16        * VM/CodeGenerator.cpp:
     17        (JSC::CodeGenerator::emitConstruct):
     18        * VM/CodeGenerator.h:
     19        * VM/ExceptionHelpers.cpp:
     20        (JSC::createInvalidParamError):
     21        (JSC::createNotAConstructorError):
     22        (JSC::createNotAnObjectError):
     23        * VM/ExceptionHelpers.h:
     24        * VM/Machine.cpp:
     25        (JSC::Machine::getOpcode):
     26        (JSC::Machine::privateExecute):
     27        * VM/Machine.h:
     28        * kjs/nodes.cpp:
     29        (JSC::NewExprNode::emitCode):
     30        (JSC::InstanceOfNode::emitCode):
     31
    1322008-09-17  Gavin Barraclough  <[email protected]>
    233
  • trunk/JavaScriptCore/VM/CodeGenerator.cpp

    r36528 r36604  
    11101110}
    11111111
    1112 RegisterID* CodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, ArgumentsNode* argumentsNode)
     1112RegisterID* CodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
    11131113{
    11141114    ASSERT(func->refCount());
     
    11301130    }
    11311131
     1132    emitExpressionInfo(divot, startOffset, endOffset);
    11321133    emitGetById(funcProto.get(), func, globalExec()->propertyNames().prototype);
    11331134
     1135    emitExpressionInfo(divot, startOffset, endOffset);
    11341136    emitOpcode(op_construct);
    11351137    instructions().append(dst->index());
  • trunk/JavaScriptCore/VM/CodeGenerator.h

    r36417 r36604  
    281281        RegisterID* emitEnd(RegisterID* src) { return emitUnaryNoDstOp(op_end, src); }
    282282
    283         RegisterID* emitConstruct(RegisterID* dst, RegisterID* func, ArgumentsNode*);
     283        RegisterID* emitConstruct(RegisterID* dst, RegisterID* func, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
    284284
    285285        PassRefPtr<LabelID> emitLabel(LabelID*);
  • trunk/JavaScriptCore/VM/ExceptionHelpers.cpp

    r36263 r36604  
    3232#include "CodeBlock.h"
    3333#include "ExecState.h"
    34 #include "nodes.h"
    3534#include "JSObject.h"
    3635#include "JSNotAnObject.h"
     36#include "Machine.h"
     37#include "nodes.h"
    3738
    3839namespace JSC {
     
    148149}
    149150
    150 JSValue* createInvalidParamError(ExecState* exec, const char* op, JSValue* value, const Instruction* vPC, CodeBlock* codeBlock)
     151JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue* value, const Instruction* vPC, CodeBlock* codeBlock)
    151152{
    152153    UString message = "not a valid argument for '";
     
    166167}
    167168
    168 JSValue* createNotAConstructorError(ExecState* exec, JSValue* value, const Instruction* vPC, CodeBlock* codeBlock)
     169JSObject* createNotAConstructorError(ExecState* exec, JSValue* value, const Instruction* vPC, CodeBlock* codeBlock)
    169170{
    170171    int startOffset = 0;
     
    208209JSObject* createNotAnObjectError(ExecState* exec, JSNotAnObjectErrorStub* error, const Instruction* vPC, CodeBlock* codeBlock)
    209210{
     211    if (vPC[8].u.opcode == Machine::getOpcode(op_instanceof))
     212        return createInvalidParamError(exec, "instanceof", error->isNull() ? jsNull() : jsUndefined(), vPC, codeBlock);
     213    if (vPC[8].u.opcode == Machine::getOpcode(op_construct))
     214        return createNotAConstructorError(exec, error->isNull() ? jsNull() : jsUndefined(), vPC, codeBlock);
     215
    210216    int startOffset = 0;
    211217    int endOffset = 0;
  • trunk/JavaScriptCore/VM/ExceptionHelpers.h

    r36263 r36604  
    4343    JSValue* createUndefinedVariableError(ExecState*, const Identifier&, const Instruction*, CodeBlock*);
    4444    JSNotAnObjectErrorStub* createNotAnObjectErrorStub(ExecState*, bool isNull);
    45     JSValue* createInvalidParamError(ExecState*, const char* op, JSValue*, const Instruction*, CodeBlock*);
    46     JSValue* createNotAConstructorError(ExecState*, JSValue*, const Instruction*, CodeBlock*);
     45    JSObject* createInvalidParamError(ExecState*, const char* op, JSValue*, const Instruction*, CodeBlock*);
     46    JSObject* createNotAConstructorError(ExecState*, JSValue*, const Instruction*, CodeBlock*);
    4747    JSValue* createNotAFunctionError(ExecState*, JSValue*, const Instruction*, CodeBlock*);
    4848    JSObject* createNotAnObjectError(ExecState*, JSNotAnObjectErrorStub*, const Instruction*, CodeBlock*);
  • trunk/JavaScriptCore/VM/Machine.cpp

    r36581 r36604  
    476476    exceptionValue = createUndefinedVariableError(exec, ident, vPC, codeBlock);
    477477    return false;
     478}
     479
     480#if HAVE(COMPUTED_GOTO)
     481Opcode Machine::s_opcodeTable[numOpcodeIDs];
     482#endif
     483
     484Opcode Machine::getOpcode(OpcodeID id)
     485{
     486    #if HAVE(COMPUTED_GOTO)
     487        return s_opcodeTable[id];
     488    #else
     489        return id;
     490    #endif
    478491}
    479492
     
    13881401    if (flag == InitializeAndReturn) {
    13891402        #if HAVE(COMPUTED_GOTO)
    1390             #define ADD_OPCODE(id) m_opcodeTable[id] = &&id;
     1403            #define ADD_OPCODE(id) s_opcodeTable[id] = &&id;
    13911404                FOR_EACH_OPCODE_ID(ADD_OPCODE);
    13921405            #undef ADD_OPCODE
  • trunk/JavaScriptCore/VM/Machine.h

    r36581 r36604  
    7575        RegisterFile& registerFile() { return m_registerFile; }
    7676       
    77         Opcode getOpcode(OpcodeID id)
    78         {
    79             #if HAVE(COMPUTED_GOTO)
    80                 return m_opcodeTable[id];
    81             #else
    82                 return id;
    83             #endif
    84         }
     77        static Opcode getOpcode(OpcodeID id);
    8578
    8679        OpcodeID getOpcodeID(Opcode opcode)
     
    300293
    301294#if HAVE(COMPUTED_GOTO)
    302         Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
     295        static Opcode s_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
    303296        HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
    304297#endif
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r36528 r36604  
    408408{
    409409    RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
    410     generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    411     return generator.emitConstruct(generator.finalDestination(dst, r0.get()), r0.get(), m_args.get());
     410    return generator.emitConstruct(generator.finalDestination(dst, r0.get()), r0.get(), m_args.get(), m_divot, m_startOffset, m_endOffset);
    412411}
    413412
     
    799798    RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
    800799    RefPtr<RegisterID> src2 = generator.emitNode(m_expr2.get());
     800
     801    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    801802    RegisterID* src2Prototype = generator.emitGetById(generator.newTemporary(), src2.get(), generator.globalExec()->propertyNames().prototype);
     803
    802804    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    803805    return generator.emitInstanceOf(generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), src2Prototype);
Note: See TracChangeset for help on using the changeset viewer.