https://bugs.webkit.org/show_bug.cgi?id=180970
Reviewed by Saam Barati.
JSTests:
* stress/regexp-syntax-error-invalid-flags.js: Added.
(shouldThrow):
Source/JavaScriptCore:
We should not check `isValid()` inside op_new_regexp.
This simplifies the semantics of NewRegexp node in DFG.
* bytecompiler/NodesCodegen.cpp:
(JSC::RegExpNode::emitBytecode):
* dfg/DFGMayExit.cpp:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileNewRegexp):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNewRegexp):
* jit/JITOperations.cpp:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@226209
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2017-12-19 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ [JSC] Do not check isValid() in op_new_regexp
+ https://bugs.webkit.org/show_bug.cgi?id=180970
+
+ Reviewed by Saam Barati.
+
+ * stress/regexp-syntax-error-invalid-flags.js: Added.
+ (shouldThrow):
+
2017-12-18 Guillaume Emont <guijemont@igalia.com>
Skip stress/call-apply-exponential-bytecode-size.js unless x86-64 or arm64
--- /dev/null
+function shouldThrow(func, errorMessage) {
+ var errorThrown = false;
+ var error = null;
+ try {
+ func();
+ } catch (e) {
+ errorThrown = true;
+ error = e;
+ }
+ if (!errorThrown)
+ throw new Error('not thrown');
+ if (String(error) !== errorMessage)
+ throw new Error(`bad error: ${String(error)}`);
+}
+
+function test()
+{
+ return /Hello/cocoa;
+}
+noInline(test);
+
+for (var i = 0; i < 1e4; ++i)
+ shouldThrow(test, `SyntaxError: Invalid regular expression: invalid flags`);
+2017-12-19 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ [JSC] Do not check isValid() in op_new_regexp
+ https://bugs.webkit.org/show_bug.cgi?id=180970
+
+ Reviewed by Saam Barati.
+
+ We should not check `isValid()` inside op_new_regexp.
+ This simplifies the semantics of NewRegexp node in DFG.
+
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::RegExpNode::emitBytecode):
+ * dfg/DFGMayExit.cpp:
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileNewRegexp):
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::compileNewRegexp):
+ * jit/JITOperations.cpp:
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+
2017-12-20 Saam Barati <sbarati@apple.com>
GetPropertyEnumerator in DFG/FTL should not unconditionally speculate cell
RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
if (dst == generator.ignoredResult())
- return 0;
- return generator.emitNewRegExp(generator.finalDestination(dst), RegExp::create(*generator.vm(), m_pattern.string(), regExpFlags(m_flags.string())));
+ return nullptr;
+ RegExp* regExp = RegExp::create(*generator.vm(), m_pattern.string(), regExpFlags(m_flags.string()));
+ if (regExp->isValid())
+ return generator.emitNewRegExp(generator.finalDestination(dst), regExp);
+ const char* messageCharacters = regExp->errorMessage();
+ const Identifier& message = generator.parserArena().identifierArena().makeIdentifier(generator.vm(), bitwise_cast<const LChar*>(messageCharacters), strlen(messageCharacters));
+ generator.emitThrowStaticError(ErrorType::SyntaxError, message);
+ return generator.emitLoad(generator.finalDestination(dst), jsUndefined());
}
// ------------------------------ ThisNode -------------------------------------
case NewAsyncFunction:
case NewAsyncGeneratorFunction:
case NewStringObject:
+ case NewRegexp:
case ToNumber:
result = ExitsForExceptions;
break;
void SpeculativeJIT::compileNewRegexp(Node* node)
{
RegExp* regexp = node->castOperand<RegExp*>();
-
- // FIXME: If the RegExp is invalid, we should emit a different bytecode.
- // https://bugs.webkit.org/show_bug.cgi?id=180970
- if (!regexp->isValid()) {
- flushRegisters();
- GPRFlushedCallResult result(this);
-
- callOperation(operationNewRegexp, result.gpr(), regexp);
- m_jit.exceptionCheck();
-
- cellResult(result.gpr(), node);
- return;
- }
+ ASSERT(regexp->isValid());
GPRTemporary result(this);
GPRTemporary scratch1(this);
{
FrozenValue* regexp = m_node->cellOperand();
ASSERT(regexp->cell()->inherits(vm(), RegExp::info()));
-
- // FIXME: If the RegExp is invalid, we should emit a different bytecode.
- // https://bugs.webkit.org/show_bug.cgi?id=180970
- if (!m_node->castOperand<RegExp*>()->isValid()) {
- LValue result = vmCall(
- pointerType(),
- m_out.operation(operationNewRegexp), m_callFrame,
- frozenPointer(regexp));
-
- setJSValue(result);
- return;
- }
+ ASSERT(m_node->castOperand<RegExp*>()->isValid());
LBasicBlock slowCase = m_out.newBlock();
LBasicBlock continuation = m_out.newBlock();
SuperSamplerScope superSamplerScope(false);
VM& vm = exec->vm();
NativeCallFrameTracer tracer(&vm, exec);
- auto scope = DECLARE_THROW_SCOPE(vm);
RegExp* regexp = static_cast<RegExp*>(regexpPtr);
-
- // FIXME: If the RegExp is invalid, we should emit a different bytecode.
- // https://bugs.webkit.org/show_bug.cgi?id=180970
- if (!regexp->isValid()) {
- throwException(exec, scope, createSyntaxError(exec, regexp->errorMessage()));
- return nullptr;
- }
-
+ ASSERT(regexp->isValid());
return RegExpObject::create(vm, exec->lexicalGlobalObject()->regExpStructure(), regexp);
}
{
LLINT_BEGIN();
RegExp* regExp = exec->codeBlock()->regexp(pc[2].u.operand);
-
- // FIXME: If the RegExp is invalid, we should emit a different bytecode.
- // https://bugs.webkit.org/show_bug.cgi?id=180970
- if (!regExp->isValid())
- LLINT_THROW(createSyntaxError(exec, regExp->errorMessage()));
+ ASSERT(regExp->isValid());
LLINT_RETURN(RegExpObject::create(vm, exec->lexicalGlobalObject()->regExpStructure(), regExp));
}