Changeset 185083 in webkit
- Timestamp:
- Jun 1, 2015 4:22:22 PM (9 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r185067 r185083 1 2015-06-01 Mark Lam <mark.lam@apple.com> 2 3 Add the ability to tell between Catch and Finally blocks. 4 https://bugs.webkit.org/show_bug.cgi?id=145524 5 6 Reviewed by Michael Saboff. 7 8 ... and also SynthesizedFinally blocks too. A SynthesizedFinally block 9 is a finally block that is synthesized by the bytecode generator but 10 does not actually correspond to any exception handling construct at the 11 JS source code level. An example of this is the "for ... of" statement 12 where it needs to do some "final" clean up before passing on the 13 exception. 14 15 Manually tested by inspecting the bytecode dump of functions with 16 try-catch-finally blocks as well as for of statements which have 17 synthesized finally blocks. The bytecode dumps contains the exception 18 handlers table which has these blocks labelled with their newly added 19 types. No automatic test because this type info is not visible to JS 20 code. 21 22 * bytecode/CodeBlock.cpp: 23 (JSC::CodeBlock::dumpBytecode): 24 * bytecode/HandlerInfo.h: 25 (JSC::HandlerInfoBase::type): 26 (JSC::HandlerInfoBase::setType): 27 (JSC::HandlerInfoBase::typeName): 28 (JSC::HandlerInfoBase::isCatchHandler): 29 (JSC::UnlinkedHandlerInfo::UnlinkedHandlerInfo): 30 (JSC::HandlerInfo::initialize): 31 * bytecompiler/BytecodeGenerator.cpp: 32 (JSC::BytecodeGenerator::generate): 33 (JSC::BytecodeGenerator::pushTry): 34 (JSC::BytecodeGenerator::popTryAndEmitCatch): 35 (JSC::BytecodeGenerator::emitEnumeration): 36 * bytecompiler/BytecodeGenerator.h: 37 (JSC::BytecodeGenerator::emitThrow): 38 * bytecompiler/NodesCodegen.cpp: 39 (JSC::TryNode::emitBytecode): 40 1 41 2015-05-29 Geoffrey Garen <ggaren@apple.com> 2 42 -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r185063 r185083 656 656 do { 657 657 HandlerInfo& handler = m_rareData->m_exceptionHandlers[i]; 658 out.printf("\t %d: { start: [%4d] end: [%4d] target: [%4d] depth: [%4d] } \n",659 i + 1, handler.start, handler.end, handler.target, handler.scopeDepth );658 out.printf("\t %d: { start: [%4d] end: [%4d] target: [%4d] depth: [%4d] } %s\n", 659 i + 1, handler.start, handler.end, handler.target, handler.scopeDepth, handler.typeName()); 660 660 ++i; 661 661 } while (i < m_rareData->m_exceptionHandlers.size()); -
trunk/Source/JavaScriptCore/bytecode/HandlerInfo.h
r185063 r185083 31 31 namespace JSC { 32 32 33 enum class HandlerType { 34 Illegal = 0, 35 Catch = 1, 36 Finally = 2, 37 SynthesizedFinally = 3 38 }; 39 33 40 struct HandlerInfoBase { 41 HandlerType type() const { return static_cast<HandlerType>(typeBits); } 42 void setType(HandlerType type) { typeBits = static_cast<uint32_t>(type); } 43 44 const char* typeName() 45 { 46 switch (type()) { 47 case HandlerType::Catch: 48 return "catch"; 49 case HandlerType::Finally: 50 return "finally"; 51 case HandlerType::SynthesizedFinally: 52 return "synthesized finally"; 53 default: 54 ASSERT_NOT_REACHED(); 55 } 56 return nullptr; 57 } 58 59 bool isCatchHandler() const { return type() == HandlerType::Catch; } 60 34 61 uint32_t start; 35 62 uint32_t end; 36 63 uint32_t target; 37 uint32_t scopeDepth; 64 uint32_t scopeDepth : 30; 65 uint32_t typeBits : 2; // HandlerType 38 66 }; 39 67 40 68 struct UnlinkedHandlerInfo : public HandlerInfoBase { 41 UnlinkedHandlerInfo(uint32_t start, uint32_t end, uint32_t target, uint32_t scopeDepth )69 UnlinkedHandlerInfo(uint32_t start, uint32_t end, uint32_t target, uint32_t scopeDepth, HandlerType handlerType) 42 70 { 43 71 this->start = start; … … 45 73 this->target = target; 46 74 this->scopeDepth = scopeDepth; 75 setType(handlerType); 76 ASSERT(type() == handlerType); 47 77 } 48 78 }; … … 55 85 target = unlinkedInfo.target; 56 86 scopeDepth = unlinkedInfo.scopeDepth + nonLocalScopeDepth; 87 typeBits = unlinkedInfo.typeBits; 57 88 } 58 89 -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r185022 r185083 130 130 131 131 ASSERT(range.tryData->targetScopeDepth != UINT_MAX); 132 ASSERT(range.tryData->handlerType != HandlerType::Illegal); 132 133 UnlinkedHandlerInfo info(static_cast<uint32_t>(start), static_cast<uint32_t>(end), 133 static_cast<uint32_t>(range.tryData->target->bind()), range.tryData->targetScopeDepth); 134 static_cast<uint32_t>(range.tryData->target->bind()), range.tryData->targetScopeDepth, 135 range.tryData->handlerType); 134 136 m_codeBlock->addExceptionHandler(info); 135 137 } … … 2514 2516 tryData.target = newLabel(); 2515 2517 tryData.targetScopeDepth = UINT_MAX; 2518 tryData.handlerType = HandlerType::Illegal; 2516 2519 m_tryData.append(tryData); 2517 2520 TryData* result = &m_tryData.last(); … … 2526 2529 } 2527 2530 2528 RegisterID* BytecodeGenerator::popTryAndEmitCatch(TryData* tryData, RegisterID* targetRegister, Label* end )2531 RegisterID* BytecodeGenerator::popTryAndEmitCatch(TryData* tryData, RegisterID* targetRegister, Label* end, HandlerType handlerType) 2529 2532 { 2530 2533 m_usesExceptions = true; … … 2541 2544 emitLabel(tryRange.tryData->target.get()); 2542 2545 tryRange.tryData->targetScopeDepth = m_localScopeDepth; 2546 tryRange.tryData->handlerType = handlerType; 2543 2547 2544 2548 emitOpcode(op_catch); … … 2757 2761 { 2758 2762 RefPtr<Label> catchHere = emitLabel(newLabel().get()); 2759 RefPtr<RegisterID> exceptionRegister = popTryAndEmitCatch(tryData, newTemporary(), catchHere.get() );2763 RefPtr<RegisterID> exceptionRegister = popTryAndEmitCatch(tryData, newTemporary(), catchHere.get(), HandlerType::SynthesizedFinally); 2760 2764 RefPtr<Label> catchDone = newLabel(); 2761 2765 … … 2775 2779 2776 2780 // Absorb exception. 2777 popTryAndEmitCatch(returnCallTryData, newTemporary(), catchDone.get() );2781 popTryAndEmitCatch(returnCallTryData, newTemporary(), catchDone.get(), HandlerType::SynthesizedFinally); 2778 2782 emitThrow(exceptionRegister.get()); 2779 2783 } -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r184828 r185083 176 176 RefPtr<Label> target; 177 177 unsigned targetScopeDepth; 178 HandlerType handlerType; 178 179 }; 179 180 … … 553 554 TryData* pushTry(Label* start); 554 555 // End a try block. 'end' must have been emitted. 555 RegisterID* popTryAndEmitCatch(TryData*, RegisterID* targetRegister, Label* end );556 RegisterID* popTryAndEmitCatch(TryData*, RegisterID* targetRegister, Label* end, HandlerType); 556 557 557 558 void emitThrow(RegisterID* exc) -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r184859 r185083 2882 2882 // Uncaught exception path: the catch block. 2883 2883 RefPtr<Label> here = generator.emitLabel(generator.newLabel().get()); 2884 RefPtr<RegisterID> exceptionRegister = generator.popTryAndEmitCatch(tryData, generator.newTemporary(), here.get() );2884 RefPtr<RegisterID> exceptionRegister = generator.popTryAndEmitCatch(tryData, generator.newTemporary(), here.get(), HandlerType::Catch); 2885 2885 2886 2886 if (m_finallyBlock) { … … 2913 2913 2914 2914 // Uncaught exception path: invoke the finally block, then re-throw the exception. 2915 RefPtr<RegisterID> tempExceptionRegister = generator.popTryAndEmitCatch(tryData, generator.newTemporary(), preFinallyLabel.get() );2915 RefPtr<RegisterID> tempExceptionRegister = generator.popTryAndEmitCatch(tryData, generator.newTemporary(), preFinallyLabel.get(), HandlerType::Finally); 2916 2916 generator.emitProfileControlFlow(finallyStartOffset); 2917 2917 generator.emitNode(dst, m_finallyBlock);
Note: See TracChangeset
for help on using the changeset viewer.