<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[181466] trunk/Source/JavaScriptCore</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/181466">181466</a></dd>
<dt>Author</dt> <dd>rniwa@webkit.org</dd>
<dt>Date</dt> <dd>2015-03-12 18:11:15 -0700 (Thu, 12 Mar 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>"this" should be in TDZ until super is called in the constructor of a derived class
https://bugs.webkit.org/show_bug.cgi?id=142527
Reviewed by Mark Hahnenberg.
DFG and FTL implementations co-authored by Filip Pizlo.
In ES6 class syntax, "this" register must be in the "temporal dead zone" (TDZ) and throw ReferenceError until
super() is called inside the constructor of a derived class.
Added op_check_tdz, a new OP code, which throws a reference error when the first operand is an empty value
to all tiers of JIT and LLint. The op code throws in the slow path on the basis that a TDZ error should be
a programming error and not a part of the programs' normal control flow. In DFG, this op code is represented
by a no-op must-generate node CheckNotEmpty modeled after CheckCell.
Also made the constructor of a derived class assign the empty value to "this" register rather than undefined
so that ThisNode can emit the op_check_tdz to check the initialized-ness of "this" in such a constructor.
* bytecode/BytecodeList.json: Added op_check_tdz.
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset): Ditto.
(JSC::computeDefsForBytecodeOffset): Ditto.
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode): Ditto.
* bytecode/ExitKind.cpp:
(JSC::exitKindToString): Added TDZFailure.
* bytecode/ExitKind.h: Ditto.
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator): Assign the empty value to "this" register to indicate it's in TDZ.
(JSC::BytecodeGenerator::emitTDZCheck): Added.
(JSC::BytecodeGenerator::emitReturn): Emit the TDZ check since "this" can still be in TDZ if super() was never
called. e.g. class B extends A { constructor() { } }
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::ThisNode::emitBytecode): Always emit the TDZ check if we're inside the constructor of a derived class.
We can't omit this check even if the result was ignored per spec.
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): Previously, empty value could never appear
in a local variable. This is no longer true so generalize this code. Also added the support for CheckNotEmpty.
Like CheckCell, we phantomize this DFG node in the constant folding phase if the type of the operand is already
found to be not empty. Otherwise filter out SpecEmpty.
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock): Added op_check_tdz.
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel): op_check_tdz can be compiled and inlined.
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize): CheckNotEmpty doesn't read or write values.
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants): Convert CheckNotEmpty to a phantom if non-emptiness had already
been proven for the operand prior to this node.
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC): CheckNotEmpty does not trigger GC.
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode): CheckNotEmpty is a no-op in the fixup phase.
* dfg/DFGNodeType.h: CheckNotEmpty cannot be removed even if the result was ignored. See ThisNode::emitBytecode.
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate): CheckNotEmpty doesn't return any value.
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute): CheckNotEmpty doesn't load from heap so it's safe.
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile): Speculative the operand to be not empty. OSR exit if the speculation fails.
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile): Ditto.
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile): CheckNotEmpty can be compiled in FTL.
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode): Calls compileCheckNotEmpty for CheckNotEmpty.
(JSC::FTL::LowerDFGToLLVM::compileCheckNotEmpty): OSR exit with "TDZFailure" if the operand is not empty.
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass): Added op_check_tdz.
(JSC::JIT::privateCompileSlowCases): Ditto.
* jit/JIT.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_check_tdz): Implements op_check_tdz in Baseline JIT.
(JSC::JIT::emitSlow_op_check_tdz): Ditto.
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_check_tdz): Ditto.
(JSC::JIT::emitSlow_op_check_tdz): Ditto.
* llint/LowLevelInterpreter32_64.asm: Implements op_check_tdz in LLint.
* llint/LowLevelInterpreter64.asm: Ditto.
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL): Throws a reference error for op_check_tdz. Shared by LLint and Baseline JIT.
* runtime/CommonSlowPaths.h:
* tests/stress/class-syntax-no-loop-tdz.js: Added.
* tests/stress/class-syntax-no-tdz-in-catch.js: Added.
* tests/stress/class-syntax-no-tdz-in-conditional.js: Added.
* tests/stress/class-syntax-no-tdz-in-loop-no-inline-super.js: Added.
* tests/stress/class-syntax-no-tdz-in-loop.js: Added.
* tests/stress/class-syntax-no-tdz.js: Added.
* tests/stress/class-syntax-tdz-in-catch.js: Added.
* tests/stress/class-syntax-tdz-in-conditional.js: Added.
* tests/stress/class-syntax-tdz-in-loop.js: Added.
* tests/stress/class-syntax-tdz.js: Added.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeListjson">trunk/Source/JavaScriptCore/bytecode/BytecodeList.json</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeUseDefh">trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeExitKindcpp">trunk/Source/JavaScriptCore/bytecode/ExitKind.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeExitKindh">trunk/Source/JavaScriptCore/bytecode/ExitKind.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerNodesCodegencpp">trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCapabilitiescpp">trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDoesGCcpp">trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeTypeh">trunk/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSafeToExecuteh">trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITcpp">trunk/Source/JavaScriptCore/jit/JIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITh">trunk/Source/JavaScriptCore/jit/JIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOpcodescpp">trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOpcodes32_64cpp">trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonSlowPathsh">trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoretestsstressclasssyntaxnolooptdzjs">trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-loop-tdz.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressclasssyntaxnotdzincatchjs">trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-tdz-in-catch.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressclasssyntaxnotdzinconditionaljs">trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-tdz-in-conditional.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressclasssyntaxnotdzinloopnoinlinesuperjs">trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-tdz-in-loop-no-inline-super.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressclasssyntaxnotdzinloopjs">trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-tdz-in-loop.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressclasssyntaxnotdzjs">trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-tdz.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressclasssyntaxtdzincatchjs">trunk/Source/JavaScriptCore/tests/stress/class-syntax-tdz-in-catch.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressclasssyntaxtdzinconditionaljs">trunk/Source/JavaScriptCore/tests/stress/class-syntax-tdz-in-conditional.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressclasssyntaxtdzinloopjs">trunk/Source/JavaScriptCore/tests/stress/class-syntax-tdz-in-loop.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressclasssyntaxtdzjs">trunk/Source/JavaScriptCore/tests/stress/class-syntax-tdz.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -1,3 +1,99 @@
</span><ins>+2015-03-12 Ryosuke Niwa <rniwa@webkit.org>
+
+ "this" should be in TDZ until super is called in the constructor of a derived class
+ https://bugs.webkit.org/show_bug.cgi?id=142527
+
+ Reviewed by Mark Hahnenberg.
+
+ DFG and FTL implementations co-authored by Filip Pizlo.
+
+ In ES6 class syntax, "this" register must be in the "temporal dead zone" (TDZ) and throw ReferenceError until
+ super() is called inside the constructor of a derived class.
+
+ Added op_check_tdz, a new OP code, which throws a reference error when the first operand is an empty value
+ to all tiers of JIT and LLint. The op code throws in the slow path on the basis that a TDZ error should be
+ a programming error and not a part of the programs' normal control flow. In DFG, this op code is represented
+ by a no-op must-generate node CheckNotEmpty modeled after CheckCell.
+
+ Also made the constructor of a derived class assign the empty value to "this" register rather than undefined
+ so that ThisNode can emit the op_check_tdz to check the initialized-ness of "this" in such a constructor.
+
+ * bytecode/BytecodeList.json: Added op_check_tdz.
+ * bytecode/BytecodeUseDef.h:
+ (JSC::computeUsesForBytecodeOffset): Ditto.
+ (JSC::computeDefsForBytecodeOffset): Ditto.
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpBytecode): Ditto.
+ * bytecode/ExitKind.cpp:
+ (JSC::exitKindToString): Added TDZFailure.
+ * bytecode/ExitKind.h: Ditto.
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator): Assign the empty value to "this" register to indicate it's in TDZ.
+ (JSC::BytecodeGenerator::emitTDZCheck): Added.
+ (JSC::BytecodeGenerator::emitReturn): Emit the TDZ check since "this" can still be in TDZ if super() was never
+ called. e.g. class B extends A { constructor() { } }
+ * bytecompiler/BytecodeGenerator.h:
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ThisNode::emitBytecode): Always emit the TDZ check if we're inside the constructor of a derived class.
+ We can't omit this check even if the result was ignored per spec.
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): Previously, empty value could never appear
+ in a local variable. This is no longer true so generalize this code. Also added the support for CheckNotEmpty.
+ Like CheckCell, we phantomize this DFG node in the constant folding phase if the type of the operand is already
+ found to be not empty. Otherwise filter out SpecEmpty.
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock): Added op_check_tdz.
+ * dfg/DFGCapabilities.cpp:
+ (JSC::DFG::capabilityLevel): op_check_tdz can be compiled and inlined.
+ * dfg/DFGClobberize.h:
+ (JSC::DFG::clobberize): CheckNotEmpty doesn't read or write values.
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants): Convert CheckNotEmpty to a phantom if non-emptiness had already
+ been proven for the operand prior to this node.
+ * dfg/DFGDoesGC.cpp:
+ (JSC::DFG::doesGC): CheckNotEmpty does not trigger GC.
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode): CheckNotEmpty is a no-op in the fixup phase.
+ * dfg/DFGNodeType.h: CheckNotEmpty cannot be removed even if the result was ignored. See ThisNode::emitBytecode.
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate): CheckNotEmpty doesn't return any value.
+ * dfg/DFGSafeToExecute.h:
+ (JSC::DFG::safeToExecute): CheckNotEmpty doesn't load from heap so it's safe.
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile): Speculative the operand to be not empty. OSR exit if the speculation fails.
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile): Ditto.
+ * ftl/FTLCapabilities.cpp:
+ (JSC::FTL::canCompile): CheckNotEmpty can be compiled in FTL.
+ * ftl/FTLLowerDFGToLLVM.cpp:
+ (JSC::FTL::LowerDFGToLLVM::compileNode): Calls compileCheckNotEmpty for CheckNotEmpty.
+ (JSC::FTL::LowerDFGToLLVM::compileCheckNotEmpty): OSR exit with "TDZFailure" if the operand is not empty.
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass): Added op_check_tdz.
+ (JSC::JIT::privateCompileSlowCases): Ditto.
+ * jit/JIT.h:
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_check_tdz): Implements op_check_tdz in Baseline JIT.
+ (JSC::JIT::emitSlow_op_check_tdz): Ditto.
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_check_tdz): Ditto.
+ (JSC::JIT::emitSlow_op_check_tdz): Ditto.
+ * llint/LowLevelInterpreter32_64.asm: Implements op_check_tdz in LLint.
+ * llint/LowLevelInterpreter64.asm: Ditto.
+ * runtime/CommonSlowPaths.cpp:
+ (JSC::SLOW_PATH_DECL): Throws a reference error for op_check_tdz. Shared by LLint and Baseline JIT.
+ * runtime/CommonSlowPaths.h:
+ * tests/stress/class-syntax-no-loop-tdz.js: Added.
+ * tests/stress/class-syntax-no-tdz-in-catch.js: Added.
+ * tests/stress/class-syntax-no-tdz-in-conditional.js: Added.
+ * tests/stress/class-syntax-no-tdz-in-loop-no-inline-super.js: Added.
+ * tests/stress/class-syntax-no-tdz-in-loop.js: Added.
+ * tests/stress/class-syntax-no-tdz.js: Added.
+ * tests/stress/class-syntax-tdz-in-catch.js: Added.
+ * tests/stress/class-syntax-tdz-in-conditional.js: Added.
+ * tests/stress/class-syntax-tdz-in-loop.js: Added.
+ * tests/stress/class-syntax-tdz.js: Added.
+
</ins><span class="cx"> 2015-03-12 Yusuke Suzuki <utatane.tea@gmail.com>
</span><span class="cx">
</span><span class="cx"> Integrate MapData into JSMap and JSSet
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeListjson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeList.json (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -11,6 +11,7 @@
</span><span class="cx"> { "name" : "op_create_arguments", "length" : 3 },
</span><span class="cx"> { "name" : "op_create_this", "length" : 4 },
</span><span class="cx"> { "name" : "op_to_this", "length" : 4 },
</span><ins>+ { "name" : "op_check_tdz", "length" : 2 },
</ins><span class="cx"> { "name" : "op_new_object", "length" : 4 },
</span><span class="cx"> { "name" : "op_new_array", "length" : 5 },
</span><span class="cx"> { "name" : "op_new_array_with_size", "length" : 4 },
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeUseDefh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -56,6 +56,7 @@
</span><span class="cx"> return;
</span><span class="cx"> case op_get_scope:
</span><span class="cx"> case op_to_this:
</span><ins>+ case op_check_tdz:
</ins><span class="cx"> case op_pop_scope:
</span><span class="cx"> case op_profile_will_call:
</span><span class="cx"> case op_profile_did_call:
</span><span class="lines">@@ -364,6 +365,7 @@
</span><span class="cx"> case op_mov:
</span><span class="cx"> case op_new_object:
</span><span class="cx"> case op_to_this:
</span><ins>+ case op_check_tdz:
</ins><span class="cx"> case op_init_lazy_reg:
</span><span class="cx"> case op_get_scope:
</span><span class="cx"> case op_create_arguments:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -789,6 +789,11 @@
</span><span class="cx"> out.print(" ", (++it)->u.toThisStatus);
</span><span class="cx"> break;
</span><span class="cx"> }
</span><ins>+ case op_check_tdz: {
+ int r0 = (++it)->u.operand;
+ printLocationOpAndRegisterOperand(out, exec, location, it, "op_check_tdz", r0);
+ break;
+ }
</ins><span class="cx"> case op_new_object: {
</span><span class="cx"> int r0 = (++it)->u.operand;
</span><span class="cx"> unsigned inferredInlineCapacity = (++it)->u.operand;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeExitKindcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/ExitKind.cpp (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/ExitKind.cpp        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/bytecode/ExitKind.cpp        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -70,6 +70,8 @@
</span><span class="cx"> return "NotStringObject";
</span><span class="cx"> case VarargsOverflow:
</span><span class="cx"> return "VarargsOverflow";
</span><ins>+ case TDZFailure:
+ return "TDZFailure";
</ins><span class="cx"> case Uncountable:
</span><span class="cx"> return "Uncountable";
</span><span class="cx"> case UncountableInvalidation:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeExitKindh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/ExitKind.h (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/ExitKind.h        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/bytecode/ExitKind.h        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -47,6 +47,7 @@
</span><span class="cx"> ExoticObjectMode, // We exited because some exotic object that we were accessing was in an exotic mode (like Arguments with slow arguments).
</span><span class="cx"> NotStringObject, // We exited because we shouldn't have attempted to optimize string object access.
</span><span class="cx"> VarargsOverflow, // We exited because a varargs call passed more arguments than we expected.
</span><ins>+ TDZFailure, // We exited because we were in the TDZ and accessed the variable.
</ins><span class="cx"> Uncountable, // We exited for none of the above reasons, and we should not count it. Most uses of this should be viewed as a FIXME.
</span><span class="cx"> UncountableInvalidation, // We exited because the code block was invalidated; this means that we've already counted the reasons why the code block was invalidated.
</span><span class="cx"> WatchdogTimerFired, // We exited because we need to service the watchdog timer.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -404,7 +404,7 @@
</span><span class="cx"> if (constructorKindIsDerived()) {
</span><span class="cx"> m_newTargetRegister = addVar();
</span><span class="cx"> emitMove(m_newTargetRegister, &m_thisRegister);
</span><del>- emitLoad(&m_thisRegister, jsNull());
</del><ins>+ emitMove(&m_thisRegister, addConstantEmptyValue());
</ins><span class="cx"> } else
</span><span class="cx"> emitCreateThis(&m_thisRegister);
</span><span class="cx"> } else if (functionNode->usesThis() || codeBlock->usesEval()) {
</span><span class="lines">@@ -1556,6 +1556,12 @@
</span><span class="cx"> return dst;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void BytecodeGenerator::emitTDZCheck(RegisterID* target)
+{
+ emitOpcode(op_check_tdz);
+ instructions().append(target->index());
+}
+
</ins><span class="cx"> RegisterID* BytecodeGenerator::emitNewObject(RegisterID* dst)
</span><span class="cx"> {
</span><span class="cx"> size_t begin = instructions().size();
</span><span class="lines">@@ -1907,12 +1913,16 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> bool thisMightBeUninitialized = constructorKindIsDerived();
</span><del>- if (isConstructor() && (src->index() != m_thisRegister.index() || thisMightBeUninitialized)) {
</del><ins>+ bool srcIsThis = src->index() == m_thisRegister.index();
+ if (isConstructor() && (!srcIsThis || thisMightBeUninitialized)) {
</ins><span class="cx"> RefPtr<Label> isObjectOrUndefinedLabel = newLabel();
</span><span class="cx">
</span><ins>+ if (srcIsThis && thisMightBeUninitialized)
+ emitTDZCheck(src);
+
</ins><span class="cx"> emitJumpIfTrue(emitIsObject(newTemporary(), src), isObjectOrUndefinedLabel.get());
</span><span class="cx">
</span><del>- if (constructorKindIsDerived()) {
</del><ins>+ if (thisMightBeUninitialized) {
</ins><span class="cx"> emitJumpIfTrue(emitIsUndefined(newTemporary(), src), isObjectOrUndefinedLabel.get());
</span><span class="cx"> emitThrowTypeError("Cannot return a non-object type in the constructor of a derived class.");
</span><span class="cx"> } else
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -458,6 +458,7 @@
</span><span class="cx"> RegisterID* emitUnaryNoDstOp(OpcodeID, RegisterID* src);
</span><span class="cx">
</span><span class="cx"> RegisterID* emitCreateThis(RegisterID* dst);
</span><ins>+ void emitTDZCheck(RegisterID* target);
</ins><span class="cx"> RegisterID* emitNewObject(RegisterID* dst);
</span><span class="cx"> RegisterID* emitNewArray(RegisterID* dst, ElementNode*, unsigned length); // stops at first elision
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerNodesCodegencpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -144,6 +144,9 @@
</span><span class="cx">
</span><span class="cx"> RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
</span><span class="cx"> {
</span><ins>+ if (generator.constructorKindIsDerived())
+ generator.emitTDZCheck(generator.thisRegister());
+
</ins><span class="cx"> if (dst == generator.ignoredResult())
</span><span class="cx"> return 0;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -143,16 +143,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> case ExtractOSREntryLocal: {
</span><del>- if (!(node->unlinkedLocal().isArgument())
- && m_graph.m_lazyVars.get(node->unlinkedLocal().toLocal())) {
- // This is kind of pessimistic - we could know in some cases that the
- // DFG code at the point of the OSR had already initialized the lazy
- // variable. But maybe this is fine, since we're inserting OSR
- // entrypoints very early in the pipeline - so any lazy initializations
- // ought to be hoisted out anyway.
- forNode(node).makeBytecodeTop();
- } else
- forNode(node).makeHeapTop();
</del><ins>+ forNode(node).makeBytecodeTop();
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1865,11 +1856,21 @@
</span><span class="cx"> ASSERT(value);
</span><span class="cx"> break;
</span><span class="cx"> }
</span><del>-
</del><span class="cx"> filterByValue(node->child1(), *node->cellOperand());
</span><span class="cx"> break;
</span><span class="cx"> }
</span><ins>+
+ case CheckNotEmpty: {
+ AbstractValue& value = forNode(node->child1());
+ if (!(value.m_type & SpecEmpty)) {
+ m_state.setFoundConstants(true);
+ break;
+ }
</ins><span class="cx">
</span><ins>+ filter(value, ~SpecEmpty);
+ break;
+ }
+
</ins><span class="cx"> case CheckInBounds: {
</span><span class="cx"> JSValue left = forNode(node->child1()).value();
</span><span class="cx"> JSValue right = forNode(node->child2()).value();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -2822,6 +2822,12 @@
</span><span class="cx"> NEXT_OPCODE(op_mov);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ case op_check_tdz: {
+ Node* op = get(VirtualRegister(currentInstruction[1].u.operand));
+ addToGraph(CheckNotEmpty, op);
+ NEXT_OPCODE(op_check_tdz);
+ }
+
</ins><span class="cx"> case op_check_has_instance:
</span><span class="cx"> addToGraph(CheckHasInstance, get(VirtualRegister(currentInstruction[3].u.operand)));
</span><span class="cx"> NEXT_OPCODE(op_check_has_instance);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -99,6 +99,7 @@
</span><span class="cx"> case op_enter:
</span><span class="cx"> case op_touch_entry:
</span><span class="cx"> case op_to_this:
</span><ins>+ case op_check_tdz:
</ins><span class="cx"> case op_create_this:
</span><span class="cx"> case op_bitand:
</span><span class="cx"> case op_bitor:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -254,7 +254,11 @@
</span><span class="cx"> case CheckCell:
</span><span class="cx"> def(PureValue(CheckCell, AdjacencyList(AdjacencyList::Fixed, node->child1()), node->cellOperand()));
</span><span class="cx"> return;
</span><del>-
</del><ins>+
+ case CheckNotEmpty:
+ def(PureValue(CheckNotEmpty, AdjacencyList(AdjacencyList::Fixed, node->child1())));
+ return;
+
</ins><span class="cx"> case ConstantStoragePointer:
</span><span class="cx"> def(PureValue(node, node->storagePointer()));
</span><span class="cx"> return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -185,7 +185,15 @@
</span><span class="cx"> eliminated = true;
</span><span class="cx"> break;
</span><span class="cx"> }
</span><del>-
</del><ins>+
+ case CheckNotEmpty: {
+ if (m_state.forNode(node->child1()).m_type & SpecEmpty)
+ break;
+ node->convertToPhantom();
+ eliminated = true;
+ break;
+ }
+
</ins><span class="cx"> case CheckInBounds: {
</span><span class="cx"> JSValue left = m_state.forNode(node->child1()).value();
</span><span class="cx"> JSValue right = m_state.forNode(node->child2()).value();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -105,6 +105,7 @@
</span><span class="cx"> case PutGlobalVar:
</span><span class="cx"> case VarInjectionWatchpoint:
</span><span class="cx"> case CheckCell:
</span><ins>+ case CheckNotEmpty:
</ins><span class="cx"> case AllocationProfileWatchpoint:
</span><span class="cx"> case RegExpExec:
</span><span class="cx"> case RegExpTest:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -1269,6 +1269,7 @@
</span><span class="cx"> case CountExecution:
</span><span class="cx"> case ForceOSRExit:
</span><span class="cx"> case CheckBadCell:
</span><ins>+ case CheckNotEmpty:
</ins><span class="cx"> case CheckWatchdogTimer:
</span><span class="cx"> case Unreachable:
</span><span class="cx"> case ExtractOSREntryLocal:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -191,6 +191,7 @@
</span><span class="cx"> macro(NotifyWrite, NodeMustGenerate) \
</span><span class="cx"> macro(VarInjectionWatchpoint, NodeMustGenerate) \
</span><span class="cx"> macro(CheckCell, NodeMustGenerate) \
</span><ins>+ macro(CheckNotEmpty, NodeMustGenerate) \
</ins><span class="cx"> macro(CheckBadCell, NodeMustGenerate) \
</span><span class="cx"> macro(AllocationProfileWatchpoint, NodeMustGenerate) \
</span><span class="cx"> macro(CheckInBounds, NodeMustGenerate) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -626,6 +626,7 @@
</span><span class="cx"> case SetArgument:
</span><span class="cx"> case CheckStructure:
</span><span class="cx"> case CheckCell:
</span><ins>+ case CheckNotEmpty:
</ins><span class="cx"> case CheckBadCell:
</span><span class="cx"> case PutStructure:
</span><span class="cx"> case TearOffArguments:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -178,6 +178,7 @@
</span><span class="cx"> case VarInjectionWatchpoint:
</span><span class="cx"> case CheckCell:
</span><span class="cx"> case CheckBadCell:
</span><ins>+ case CheckNotEmpty:
</ins><span class="cx"> case AllocationProfileWatchpoint:
</span><span class="cx"> case RegExpExec:
</span><span class="cx"> case RegExpTest:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -3758,6 +3758,14 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ case CheckNotEmpty: {
+ JSValueOperand operand(this, node->child1());
+ GPRReg tagGPR = operand.tagGPR();
+ speculationCheck(TDZFailure, JSValueSource(), nullptr, m_jit.branch32(JITCompiler::Equal, tagGPR, TrustedImm32(JSValue::EmptyValueTag)));
+ noResult(node);
+ break;
+ }
+
</ins><span class="cx"> case GetExecutable: {
</span><span class="cx"> SpeculateCellOperand function(this, node->child1());
</span><span class="cx"> GPRTemporary result(this, Reuse, function);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -3842,7 +3842,15 @@
</span><span class="cx"> noResult(node);
</span><span class="cx"> break;
</span><span class="cx"> }
</span><del>-
</del><ins>+
+ case CheckNotEmpty: {
+ JSValueOperand operand(this, node->child1());
+ GPRReg gpr = operand.gpr();
+ speculationCheck(TDZFailure, JSValueSource(), nullptr, m_jit.branchTest64(JITCompiler::Zero, gpr));
+ noResult(node);
+ break;
+ }
+
</ins><span class="cx"> case GetExecutable: {
</span><span class="cx"> SpeculateCellOperand function(this, node->child1());
</span><span class="cx"> GPRTemporary result(this, Reuse, function);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -110,6 +110,7 @@
</span><span class="cx"> case StringCharAt:
</span><span class="cx"> case CheckCell:
</span><span class="cx"> case CheckBadCell:
</span><ins>+ case CheckNotEmpty:
</ins><span class="cx"> case StringCharCodeAt:
</span><span class="cx"> case AllocatePropertyStorage:
</span><span class="cx"> case ReallocatePropertyStorage:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -546,6 +546,9 @@
</span><span class="cx"> case CheckCell:
</span><span class="cx"> compileCheckCell();
</span><span class="cx"> break;
</span><ins>+ case CheckNotEmpty:
+ compileCheckNotEmpty();
+ break;
</ins><span class="cx"> case CheckBadCell:
</span><span class="cx"> compileCheckBadCell();
</span><span class="cx"> break;
</span><span class="lines">@@ -1862,7 +1865,12 @@
</span><span class="cx"> {
</span><span class="cx"> terminate(BadCell);
</span><span class="cx"> }
</span><del>-
</del><ins>+
+ void compileCheckNotEmpty()
+ {
+ speculate(TDZFailure, noValue(), nullptr, m_out.isZero64(lowJSValue(m_node->child1())));
+ }
+
</ins><span class="cx"> void compileGetExecutable()
</span><span class="cx"> {
</span><span class="cx"> LValue cell = lowCell(m_node->child1());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.cpp (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.cpp        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/jit/JIT.cpp        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -201,6 +201,7 @@
</span><span class="cx"> DEFINE_OP(op_construct)
</span><span class="cx"> DEFINE_OP(op_create_this)
</span><span class="cx"> DEFINE_OP(op_to_this)
</span><ins>+ DEFINE_OP(op_check_tdz)
</ins><span class="cx"> DEFINE_OP(op_init_lazy_reg)
</span><span class="cx"> DEFINE_OP(op_create_arguments)
</span><span class="cx"> DEFINE_OP(op_debug)
</span><span class="lines">@@ -375,6 +376,7 @@
</span><span class="cx"> DEFINE_SLOWCASE_OP(op_construct_varargs)
</span><span class="cx"> DEFINE_SLOWCASE_OP(op_construct)
</span><span class="cx"> DEFINE_SLOWCASE_OP(op_to_this)
</span><ins>+ DEFINE_SLOWCASE_OP(op_check_tdz)
</ins><span class="cx"> DEFINE_SLOWCASE_OP(op_create_this)
</span><span class="cx"> DEFINE_SLOWCASE_OP(op_div)
</span><span class="cx"> DEFINE_SLOWCASE_OP(op_eq)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.h (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.h        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/jit/JIT.h        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -468,6 +468,7 @@
</span><span class="cx"> void emit_op_construct(Instruction*);
</span><span class="cx"> void emit_op_create_this(Instruction*);
</span><span class="cx"> void emit_op_to_this(Instruction*);
</span><ins>+ void emit_op_check_tdz(Instruction*);
</ins><span class="cx"> void emit_op_create_arguments(Instruction*);
</span><span class="cx"> void emit_op_debug(Instruction*);
</span><span class="cx"> void emit_op_del_by_id(Instruction*);
</span><span class="lines">@@ -572,6 +573,7 @@
</span><span class="cx"> void emitSlow_op_construct(Instruction*, Vector<SlowCaseEntry>::iterator&);
</span><span class="cx"> void emitSlow_op_to_this(Instruction*, Vector<SlowCaseEntry>::iterator&);
</span><span class="cx"> void emitSlow_op_create_this(Instruction*, Vector<SlowCaseEntry>::iterator&);
</span><ins>+ void emitSlow_op_check_tdz(Instruction*, Vector<SlowCaseEntry>::iterator&);
</ins><span class="cx"> void emitSlow_op_div(Instruction*, Vector<SlowCaseEntry>::iterator&);
</span><span class="cx"> void emitSlow_op_eq(Instruction*, Vector<SlowCaseEntry>::iterator&);
</span><span class="cx"> void emitSlow_op_get_callee(Instruction*, Vector<SlowCaseEntry>::iterator&);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -756,6 +756,19 @@
</span><span class="cx"> slowPathCall.call();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void JIT::emit_op_check_tdz(Instruction* currentInstruction)
+{
+ emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
+ addSlowCase(branchTest64(Zero, regT0));
+}
+
+void JIT::emitSlow_op_check_tdz(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ linkSlowCase(iter);
+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_throw_tdz_error);
+ slowPathCall.call();
+}
+
</ins><span class="cx"> void JIT::emit_op_profile_will_call(Instruction* currentInstruction)
</span><span class="cx"> {
</span><span class="cx"> Jump profilerDone = branchTestPtr(Zero, AbsoluteAddress(m_vm->enabledProfilerAddress()));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodes32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -997,6 +997,19 @@
</span><span class="cx"> slowPathCall.call();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void JIT::emit_op_check_tdz(Instruction* currentInstruction)
+{
+ emitLoadTag(currentInstruction[1].u.operand, regT0);
+ addSlowCase(branch32(Equal, regT0, TrustedImm32(JSValue::EmptyValueTag)));
+}
+
+void JIT::emitSlow_op_check_tdz(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ linkSlowCase(iter);
+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_throw_tdz_error);
+ slowPathCall.call();
+}
+
</ins><span class="cx"> void JIT::emit_op_profile_will_call(Instruction* currentInstruction)
</span><span class="cx"> {
</span><span class="cx"> load32(m_vm->enabledProfilerAddress(), regT0);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -803,6 +803,16 @@
</span><span class="cx"> dispatch(4)
</span><span class="cx">
</span><span class="cx">
</span><ins>+_llint_op_check_tdz:
+ traceExecution()
+ loadpFromInstruction(1, t0)
+ bineq TagOffset[cfr, t0, 8], EmptyValueTag, .opNotTDZ
+ callSlowPath(_slow_path_throw_tdz_error)
+
+.opNotTDZ:
+ dispatch(2)
+
+
</ins><span class="cx"> _llint_op_mov:
</span><span class="cx"> traceExecution()
</span><span class="cx"> loadi 8[PC], t1
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -687,6 +687,17 @@
</span><span class="cx"> dispatch(4)
</span><span class="cx">
</span><span class="cx">
</span><ins>+_llint_op_check_tdz:
+ traceExecution()
+ loadpFromInstruction(1, t0)
+ loadq [cfr, t0, 8], t0
+ bqneq t0, ValueEmpty, .opNotTDZ
+ callSlowPath(_slow_path_throw_tdz_error)
+
+.opNotTDZ:
+ dispatch(2)
+
+
</ins><span class="cx"> _llint_op_mov:
</span><span class="cx"> traceExecution()
</span><span class="cx"> loadisFromInstruction(2, t1)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -257,6 +257,12 @@
</span><span class="cx"> RETURN(v1.toThis(exec, exec->codeBlock()->isStrictMode() ? StrictMode : NotStrictMode));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+SLOW_PATH_DECL(slow_path_throw_tdz_error)
+{
+ BEGIN();
+ THROW(createReferenceError(exec, "Cannot access uninitialized variable."));
+}
+
</ins><span class="cx"> SLOW_PATH_DECL(slow_path_not)
</span><span class="cx"> {
</span><span class="cx"> BEGIN();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonSlowPathsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h (181465 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h        2015-03-13 00:57:10 UTC (rev 181465)
+++ trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -187,6 +187,7 @@
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_enter);
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_get_callee);
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_to_this);
</span><ins>+SLOW_PATH_HIDDEN_DECL(slow_path_throw_tdz_error);
</ins><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_not);
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_eq);
</span><span class="cx"> SLOW_PATH_HIDDEN_DECL(slow_path_neq);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressclasssyntaxnolooptdzjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-loop-tdz.js (0 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-loop-tdz.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-loop-tdz.js        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+//@ skip
+
+class A {
+ constructor() { }
+}
+
+class B extends A {
+ constructor() {
+ for (var j = 0; j < 10; j++) {
+ if (!j)
+ super();
+ else
+ this;
+ }
+ }
+}
+
+noInline(B);
+
+for (var i = 0; i < 100000; ++i)
+ new B();
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressclasssyntaxnotdzincatchjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-tdz-in-catch.js (0 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-tdz-in-catch.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-tdz-in-catch.js        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+//@ skip
+
+class A {
+ constructor() { }
+}
+
+class B extends A {
+ constructor() {
+ try {
+ this;
+ } catch (e) {
+ super();
+ }
+ }
+}
+
+noInline(B);
+
+for (var i = 0; i < 100000; ++i)
+ new B();
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressclasssyntaxnotdzinconditionaljs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-tdz-in-conditional.js (0 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-tdz-in-conditional.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-tdz-in-conditional.js        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+//@ skip
+
+class A {
+ constructor() { }
+}
+
+class B extends A {
+ constructor(accessThisBeforeSuper) {
+ if (accessThisBeforeSuper)
+ this;
+ else
+ super();
+ }
+}
+
+noInline(B);
+
+for (var i = 0; i < 100000; ++i)
+ new B(false);
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressclasssyntaxnotdzinloopnoinlinesuperjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-tdz-in-loop-no-inline-super.js (0 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-tdz-in-loop-no-inline-super.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-tdz-in-loop-no-inline-super.js        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+//@ skip
+
+class A {
+ constructor() { }
+}
+
+noInline(A);
+
+class B extends A {
+ constructor() {
+ var values = [];
+ for (var j = 0; j < 100; j++) {
+ if (j == 1)
+ super();
+ else if (j > 2)
+ this;
+ else
+ values.push(i);
+ }
+ }
+}
+
+noInline(B);
+
+for (var i = 0; i < 100000; ++i)
+ new B();
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressclasssyntaxnotdzinloopjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-tdz-in-loop.js (0 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-tdz-in-loop.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-tdz-in-loop.js        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -0,0 +1,24 @@
</span><ins>+//@ skip
+
+class A {
+ constructor() { }
+}
+
+class B extends A {
+ constructor() {
+ var values = [];
+ for (var j = 0; j < 100; j++) {
+ if (j == 1)
+ super();
+ else if (j > 2)
+ this;
+ else
+ values.push(i);
+ }
+ }
+}
+
+noInline(B);
+
+for (var i = 0; i < 100000; ++i)
+ new B();
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressclasssyntaxnotdzjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-tdz.js (0 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-tdz.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/class-syntax-no-tdz.js        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+//@ skip
+
+class A {
+ constructor() { }
+}
+
+class B extends A {
+ constructor() {
+ super();
+ this;
+ }
+}
+
+noInline(B);
+
+for (var i = 0; i < 100000; ++i)
+ new B();
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressclasssyntaxtdzincatchjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/class-syntax-tdz-in-catch.js (0 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/class-syntax-tdz-in-catch.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/class-syntax-tdz-in-catch.js        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+//@ skip
+
+class A {
+ constructor() { }
+}
+
+class B extends A {
+ constructor() {
+ try {
+ this;
+ } catch (e) {
+ this;
+ super();
+ }
+ }
+}
+
+noInline(B);
+
+for (var i = 0; i < 100000; ++i) {
+ var exception = null;
+ try {
+ new B(false);
+ } catch (e) {
+ exception = e;
+ if (!(e instanceof ReferenceError))
+ throw "Exception thrown in iteration " + i + " was not a reference error";
+ }
+ if (!exception)
+ throw "Exception not thrown for an unitialized this at iteration " + i;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressclasssyntaxtdzinconditionaljs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/class-syntax-tdz-in-conditional.js (0 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/class-syntax-tdz-in-conditional.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/class-syntax-tdz-in-conditional.js        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -0,0 +1,29 @@
</span><ins>+//@ skip
+
+class A {
+ constructor() { }
+}
+
+class B extends A {
+ constructor(accessThisBeforeSuper) {
+ if (accessThisBeforeSuper)
+ this;
+ else {
+ this;
+ super();
+ }
+ }
+}
+
+noInline(B);
+
+for (var i = 0; i < 100000; ++i) {
+ var exception = null;
+ try {
+ new B(false);
+ } catch (e) {
+ exception = e;
+ }
+ if (!exception)
+ throw "Exception not thrown for an unitialized this at iteration " + i;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressclasssyntaxtdzinloopjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/class-syntax-tdz-in-loop.js (0 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/class-syntax-tdz-in-loop.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/class-syntax-tdz-in-loop.js        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+//@ skip
+
+class A {
+ constructor() { }
+}
+
+class B extends A {
+ constructor() {
+ for (var j = 0; j < 100; j++) {
+ if (j)
+ super();
+ else
+ this;
+ }
+ }
+}
+
+noInline(B);
+
+for (var i = 0; i < 100000; ++i) {
+ var exception = null;
+ try {
+ new B();
+ } catch (e) {
+ exception = e;
+ if (!(e instanceof ReferenceError))
+ throw "Exception thrown in iteration " + i + " was not a reference error";
+ }
+ if (!exception)
+ throw "Exception not thrown for an unitialized this at iteration " + i;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressclasssyntaxtdzjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/class-syntax-tdz.js (0 => 181466)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/class-syntax-tdz.js         (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/class-syntax-tdz.js        2015-03-13 01:11:15 UTC (rev 181466)
</span><span class="lines">@@ -0,0 +1,27 @@
</span><ins>+//@ skip
+
+class A {
+ constructor() { }
+}
+
+class B extends A {
+ constructor() {
+ this;
+ super();
+ }
+}
+
+noInline(B);
+
+for (var i = 0; i < 100000; ++i) {
+ var exception;
+ try {
+ new B();
+ } catch (e) {
+ exception = e;
+ if (!(e instanceof ReferenceError))
+ throw "Exception thrown in iteration " + i + " was not a reference error";
+ }
+ if (!exception)
+ throw "Exception not thrown for an unitialized this at iteration " + i;
+}
</ins></span></pre>
</div>
</div>
</body>
</html>