Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (226268 => 226269)
--- trunk/Source/_javascript_Core/ChangeLog 2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-12-22 19:51:03 UTC (rev 226269)
@@ -1,3 +1,57 @@
+2017-12-22 Yusuke Suzuki <[email protected]>
+
+ [DFG] Cleaning up and unifying 32bit code more
+ https://bugs.webkit.org/show_bug.cgi?id=181124
+
+ Reviewed by Mark Lam.
+
+ This patch unifies DFG 32bit code into 64bit code more. In this patch, we move RegExp DFG nodes
+ from 32bit / 64bit code to the common code. We change some RegExp operations to returning JSCell*
+ instead of EncodedJSValue. This simplifies DFG implementation.
+
+ And we also move HasGenericProperty since we now have JSValueRegsFlushedCallResult. ToPrimive,
+ LogShadowChickenPrologue, and LogShadowChickenTail are almost the same in 32bit and 64bit.
+ Thus, it is unified easily.
+
+ And we also move some GPRFlushedCallResult from the original places to the places just after
+ `flushRegisters()` not to spill unnecessary registers.
+
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileRegExpExec):
+ (JSC::DFG::SpeculativeJIT::compileRegExpTest):
+ (JSC::DFG::SpeculativeJIT::compileStringReplace):
+ (JSC::DFG::SpeculativeJIT::compileHasGenericProperty):
+ (JSC::DFG::SpeculativeJIT::compileToPrimitive):
+ (JSC::DFG::SpeculativeJIT::compileLogShadowChickenPrologue):
+ (JSC::DFG::SpeculativeJIT::compileLogShadowChickenTail):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::emitCall):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ (JSC::DFG::SpeculativeJIT::speculateDoubleRepAnyInt):
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::compileStringReplace):
+ * jit/JITOperations.cpp:
+ * jit/JITOperations.h:
+ * runtime/StringPrototype.cpp:
+ (JSC::jsSpliceSubstrings):
+ (JSC::jsSpliceSubstringsWithSeparators):
+ (JSC::removeUsingRegExpSearch):
+ (JSC::replaceUsingRegExpSearch):
+ (JSC::operationStringProtoFuncReplaceRegExpEmptyStr):
+ (JSC::operationStringProtoFuncReplaceRegExpString):
+ (JSC::replaceUsingStringSearch):
+ (JSC::replace):
+ (JSC::stringProtoFuncReplaceUsingRegExp):
+ (JSC::stringProtoFuncReplaceUsingStringSearch):
+ (JSC::operationStringProtoFuncReplaceGeneric):
+ * runtime/StringPrototype.h:
+
2017-12-22 Michael Catanzaro <[email protected]>
[GTK] Duplicated symbols in libjavascriptcoregtk and libwebkit2gtk can cause crashes in production builds
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (226268 => 226269)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2017-12-22 19:51:03 UTC (rev 226269)
@@ -55,6 +55,7 @@
#include "JSGlobalObjectFunctions.h"
#include "JSLexicalEnvironment.h"
#include "JSMap.h"
+#include "JSPropertyNameEnumerator.h"
#include "JSSet.h"
#include "ObjectConstructor.h"
#include "Operations.h"
@@ -1800,6 +1801,20 @@
return reinterpret_cast<char*>(asObject(cell)->ensureArrayStorage(vm));
}
+EncodedJSValue JIT_OPERATION operationHasGenericProperty(ExecState* exec, EncodedJSValue encodedBaseValue, JSCell* propertyName)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+ JSValue baseValue = JSValue::decode(encodedBaseValue);
+ if (baseValue.isUndefinedOrNull())
+ return JSValue::encode(jsBoolean(false));
+
+ JSObject* base = baseValue.toObject(exec);
+ if (!base)
+ return JSValue::encode(JSValue());
+ return JSValue::encode(jsBoolean(base->hasPropertyGeneric(exec, asString(propertyName)->toIdentifier(exec), PropertySlot::InternalMethodType::GetOwnProperty)));
+}
+
EncodedJSValue JIT_OPERATION operationHasIndexedPropertyByInt(ExecState* exec, JSCell* baseCell, int32_t subscript, int32_t internalMethodType)
{
VM& vm = exec->vm();
@@ -1812,6 +1827,43 @@
return JSValue::encode(jsBoolean(object->hasPropertyGeneric(exec, subscript, static_cast<PropertySlot::InternalMethodType>(internalMethodType))));
}
+JSCell* JIT_OPERATION operationGetPropertyEnumerator(ExecState* exec, EncodedJSValue encodedBase)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ JSValue base = JSValue::decode(encodedBase);
+ if (base.isUndefinedOrNull())
+ return JSPropertyNameEnumerator::create(vm);
+
+ JSObject* baseObject = base.toObject(exec);
+ RETURN_IF_EXCEPTION(scope, { });
+
+ scope.release();
+ return propertyNameEnumerator(exec, baseObject);
+}
+
+JSCell* JIT_OPERATION operationGetPropertyEnumeratorCell(ExecState* exec, JSCell* cell)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ JSObject* base = cell->toObject(exec, exec->lexicalGlobalObject());
+ RETURN_IF_EXCEPTION(scope, { });
+
+ scope.release();
+ return propertyNameEnumerator(exec, base);
+}
+
+JSCell* JIT_OPERATION operationToIndexString(ExecState* exec, int32_t index)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+ return jsString(exec, Identifier::from(exec, index).string());
+}
+
StringImpl* JIT_OPERATION operationResolveRope(ExecState* exec, JSString* string)
{
VM& vm = exec->vm();
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.h (226268 => 226269)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.h 2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.h 2017-12-22 19:51:03 UTC (rev 226269)
@@ -80,7 +80,11 @@
EncodedJSValue JIT_OPERATION operationGetByValWithThis(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
EncodedJSValue JIT_OPERATION operationGetPrototypeOf(ExecState*, EncodedJSValue) WTF_INTERNAL;
EncodedJSValue JIT_OPERATION operationGetPrototypeOfObject(ExecState*, JSObject*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationHasGenericProperty(ExecState*, EncodedJSValue, JSCell*);
EncodedJSValue JIT_OPERATION operationHasIndexedPropertyByInt(ExecState*, JSCell*, int32_t, int32_t);
+JSCell* JIT_OPERATION operationGetPropertyEnumerator(ExecState*, EncodedJSValue);
+JSCell* JIT_OPERATION operationGetPropertyEnumeratorCell(ExecState*, JSCell*);
+JSCell* JIT_OPERATION operationToIndexString(ExecState*, int32_t);
char* JIT_OPERATION operationNewArray(ExecState*, Structure*, void*, size_t) WTF_INTERNAL;
char* JIT_OPERATION operationNewEmptyArray(ExecState*, Structure*) WTF_INTERNAL;
char* JIT_OPERATION operationNewArrayWithSize(ExecState*, Structure*, int32_t, Butterfly*) WTF_INTERNAL;
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (226268 => 226269)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2017-12-22 19:51:03 UTC (rev 226269)
@@ -10423,6 +10423,195 @@
noResult(node);
}
+void SpeculativeJIT::compileRegExpExec(Node* node)
+{
+ bool sample = false;
+ if (sample)
+ m_jit.incrementSuperSamplerCount();
+
+ SpeculateCellOperand globalObject(this, node->child1());
+ GPRReg globalObjectGPR = globalObject.gpr();
+
+ if (node->child2().useKind() == RegExpObjectUse) {
+ if (node->child3().useKind() == StringUse) {
+ SpeculateCellOperand base(this, node->child2());
+ SpeculateCellOperand argument(this, node->child3());
+ GPRReg baseGPR = base.gpr();
+ GPRReg argumentGPR = argument.gpr();
+ speculateRegExpObject(node->child2(), baseGPR);
+ speculateString(node->child3(), argumentGPR);
+
+ flushRegisters();
+ JSValueRegsFlushedCallResult result(this);
+ JSValueRegs resultRegs = result.regs();
+ callOperation(operationRegExpExecString, resultRegs, globalObjectGPR, baseGPR, argumentGPR);
+ m_jit.exceptionCheck();
+
+ jsValueResult(resultRegs, node);
+
+ if (sample)
+ m_jit.decrementSuperSamplerCount();
+ return;
+ }
+
+ SpeculateCellOperand base(this, node->child2());
+ JSValueOperand argument(this, node->child3());
+ GPRReg baseGPR = base.gpr();
+ JSValueRegs argumentRegs = argument.jsValueRegs();
+ speculateRegExpObject(node->child2(), baseGPR);
+
+ flushRegisters();
+ JSValueRegsFlushedCallResult result(this);
+ JSValueRegs resultRegs = result.regs();
+ callOperation(operationRegExpExec, resultRegs, globalObjectGPR, baseGPR, argumentRegs);
+ m_jit.exceptionCheck();
+
+ jsValueResult(resultRegs, node);
+
+ if (sample)
+ m_jit.decrementSuperSamplerCount();
+ return;
+ }
+
+ JSValueOperand base(this, node->child2());
+ JSValueOperand argument(this, node->child3());
+ JSValueRegs baseRegs = base.jsValueRegs();
+ JSValueRegs argumentRegs = argument.jsValueRegs();
+
+ flushRegisters();
+ JSValueRegsFlushedCallResult result(this);
+ JSValueRegs resultRegs = result.regs();
+ callOperation(operationRegExpExecGeneric, resultRegs, globalObjectGPR, baseRegs, argumentRegs);
+ m_jit.exceptionCheck();
+
+ jsValueResult(resultRegs, node);
+
+ if (sample)
+ m_jit.decrementSuperSamplerCount();
+}
+
+void SpeculativeJIT::compileRegExpTest(Node* node)
+{
+ SpeculateCellOperand globalObject(this, node->child1());
+ GPRReg globalObjectGPR = globalObject.gpr();
+
+ if (node->child2().useKind() == RegExpObjectUse) {
+ if (node->child3().useKind() == StringUse) {
+ SpeculateCellOperand base(this, node->child2());
+ SpeculateCellOperand argument(this, node->child3());
+ GPRReg baseGPR = base.gpr();
+ GPRReg argumentGPR = argument.gpr();
+ speculateRegExpObject(node->child2(), baseGPR);
+ speculateString(node->child3(), argumentGPR);
+
+ flushRegisters();
+ GPRFlushedCallResult result(this);
+ callOperation(operationRegExpTestString, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
+ m_jit.exceptionCheck();
+
+ unblessedBooleanResult(result.gpr(), node);
+ return;
+ }
+
+ SpeculateCellOperand base(this, node->child2());
+ JSValueOperand argument(this, node->child3());
+ GPRReg baseGPR = base.gpr();
+ JSValueRegs argumentRegs = argument.jsValueRegs();
+ speculateRegExpObject(node->child2(), baseGPR);
+
+ flushRegisters();
+ GPRFlushedCallResult result(this);
+ callOperation(operationRegExpTest, result.gpr(), globalObjectGPR, baseGPR, argumentRegs);
+ m_jit.exceptionCheck();
+
+ unblessedBooleanResult(result.gpr(), node);
+ return;
+ }
+
+ JSValueOperand base(this, node->child2());
+ JSValueOperand argument(this, node->child3());
+ JSValueRegs baseRegs = base.jsValueRegs();
+ JSValueRegs argumentRegs = argument.jsValueRegs();
+
+ flushRegisters();
+ GPRFlushedCallResult result(this);
+ callOperation(operationRegExpTestGeneric, result.gpr(), globalObjectGPR, baseRegs, argumentRegs);
+ m_jit.exceptionCheck();
+
+ unblessedBooleanResult(result.gpr(), node);
+}
+
+void SpeculativeJIT::compileStringReplace(Node* node)
+{
+ ASSERT(node->op() == StringReplace || node->op() == StringReplaceRegExp);
+ bool sample = false;
+ if (sample)
+ m_jit.incrementSuperSamplerCount();
+
+ if (node->child1().useKind() == StringUse
+ && node->child2().useKind() == RegExpObjectUse
+ && node->child3().useKind() == StringUse) {
+ if (JSString* replace = node->child3()->dynamicCastConstant<JSString*>(*m_jit.vm())) {
+ if (!replace->length()) {
+ SpeculateCellOperand string(this, node->child1());
+ SpeculateCellOperand regExp(this, node->child2());
+ GPRReg stringGPR = string.gpr();
+ GPRReg regExpGPR = regExp.gpr();
+ speculateString(node->child1(), stringGPR);
+ speculateRegExpObject(node->child2(), regExpGPR);
+
+ flushRegisters();
+ GPRFlushedCallResult result(this);
+ callOperation(operationStringProtoFuncReplaceRegExpEmptyStr, result.gpr(), stringGPR, regExpGPR);
+ m_jit.exceptionCheck();
+ cellResult(result.gpr(), node);
+ if (sample)
+ m_jit.decrementSuperSamplerCount();
+ return;
+ }
+ }
+
+ SpeculateCellOperand string(this, node->child1());
+ SpeculateCellOperand regExp(this, node->child2());
+ SpeculateCellOperand replace(this, node->child3());
+ GPRReg stringGPR = string.gpr();
+ GPRReg regExpGPR = regExp.gpr();
+ GPRReg replaceGPR = replace.gpr();
+ speculateString(node->child1(), stringGPR);
+ speculateRegExpObject(node->child2(), regExpGPR);
+ speculateString(node->child3(), replaceGPR);
+
+ flushRegisters();
+ GPRFlushedCallResult result(this);
+ callOperation(operationStringProtoFuncReplaceRegExpString, result.gpr(), stringGPR, regExpGPR, replaceGPR);
+ m_jit.exceptionCheck();
+ cellResult(result.gpr(), node);
+ if (sample)
+ m_jit.decrementSuperSamplerCount();
+ return;
+ }
+
+ // If we fixed up the edge of child2, we inserted a Check(@child2, String).
+ OperandSpeculationMode child2SpeculationMode = AutomaticOperandSpeculation;
+ if (node->child2().useKind() == StringUse)
+ child2SpeculationMode = ManualOperandSpeculation;
+
+ JSValueOperand string(this, node->child1());
+ JSValueOperand search(this, node->child2(), child2SpeculationMode);
+ JSValueOperand replace(this, node->child3());
+ JSValueRegs stringRegs = string.jsValueRegs();
+ JSValueRegs searchRegs = search.jsValueRegs();
+ JSValueRegs replaceRegs = replace.jsValueRegs();
+
+ flushRegisters();
+ GPRFlushedCallResult result(this);
+ callOperation(operationStringProtoFuncReplaceGeneric, result.gpr(), stringRegs, searchRegs, replaceRegs);
+ m_jit.exceptionCheck();
+ cellResult(result.gpr(), node);
+ if (sample)
+ m_jit.decrementSuperSamplerCount();
+}
+
void SpeculativeJIT::compileLazyJSConstant(Node* node)
{
JSValueRegsTemporary result(this);
@@ -10905,6 +11094,22 @@
int32Result(resultGPR, node);
}
+void SpeculativeJIT::compileHasGenericProperty(Node* node)
+{
+ JSValueOperand base(this, node->child1());
+ SpeculateCellOperand property(this, node->child2());
+
+ JSValueRegs baseRegs = base.jsValueRegs();
+ GPRReg propertyGPR = property.gpr();
+
+ flushRegisters();
+ JSValueRegsFlushedCallResult result(this);
+ JSValueRegs resultRegs = result.regs();
+ callOperation(operationHasGenericProperty, resultRegs, baseRegs, propertyGPR);
+ m_jit.exceptionCheck();
+ blessedBooleanResult(resultRegs.payloadGPR(), node);
+}
+
void SpeculativeJIT::compileToIndexString(Node* node)
{
SpeculateInt32Operand index(this, node->child1());
@@ -11227,6 +11432,74 @@
cellResult(resultGPR, node);
}
+void SpeculativeJIT::compileToPrimitive(Node* node)
+{
+ DFG_ASSERT(m_jit.graph(), node, node->child1().useKind() == UntypedUse);
+ JSValueOperand argument(this, node->child1());
+ JSValueRegsTemporary result(this, Reuse, argument);
+
+ JSValueRegs argumentRegs = argument.jsValueRegs();
+ JSValueRegs resultRegs = result.regs();
+
+ argument.use();
+
+ MacroAssembler::Jump alreadyPrimitive = m_jit.branchIfNotCell(argumentRegs);
+ MacroAssembler::Jump notPrimitive = m_jit.branchIfObject(argumentRegs.payloadGPR());
+
+ alreadyPrimitive.link(&m_jit);
+ m_jit.moveValueRegs(argumentRegs, resultRegs);
+
+ addSlowPathGenerator(slowPathCall(notPrimitive, this, operationToPrimitive, resultRegs, argumentRegs));
+
+ jsValueResult(resultRegs, node, DataFormatJS, UseChildrenCalledExplicitly);
+}
+
+void SpeculativeJIT::compileLogShadowChickenPrologue(Node* node)
+{
+ flushRegisters();
+ prepareForExternalCall();
+ m_jit.emitStoreCodeOrigin(node->origin.semantic);
+
+ GPRTemporary scratch1(this, GPRInfo::nonArgGPR0); // This must be a non-argument GPR.
+ GPRReg scratch1Reg = scratch1.gpr();
+ GPRTemporary scratch2(this);
+ GPRReg scratch2Reg = scratch2.gpr();
+ GPRTemporary shadowPacket(this);
+ GPRReg shadowPacketReg = shadowPacket.gpr();
+
+ m_jit.ensureShadowChickenPacket(*m_jit.vm(), shadowPacketReg, scratch1Reg, scratch2Reg);
+
+ SpeculateCellOperand scope(this, node->child1());
+ GPRReg scopeReg = scope.gpr();
+
+ m_jit.logShadowChickenProloguePacket(shadowPacketReg, scratch1Reg, scopeReg);
+ noResult(node);
+}
+
+void SpeculativeJIT::compileLogShadowChickenTail(Node* node)
+{
+ flushRegisters();
+ prepareForExternalCall();
+ CallSiteIndex callSiteIndex = m_jit.emitStoreCodeOrigin(node->origin.semantic);
+
+ GPRTemporary scratch1(this, GPRInfo::nonArgGPR0); // This must be a non-argument GPR.
+ GPRReg scratch1Reg = scratch1.gpr();
+ GPRTemporary scratch2(this);
+ GPRReg scratch2Reg = scratch2.gpr();
+ GPRTemporary shadowPacket(this);
+ GPRReg shadowPacketReg = shadowPacket.gpr();
+
+ m_jit.ensureShadowChickenPacket(*m_jit.vm(), shadowPacketReg, scratch1Reg, scratch2Reg);
+
+ JSValueOperand thisValue(this, node->child1());
+ JSValueRegs thisRegs = thisValue.jsValueRegs();
+ SpeculateCellOperand scope(this, node->child2());
+ GPRReg scopeReg = scope.gpr();
+
+ m_jit.logShadowChickenTailPacket(shadowPacketReg, thisRegs, scopeReg, m_jit.codeBlock(), callSiteIndex);
+ noResult(node);
+}
+
void SpeculativeJIT::compileSetAdd(Node* node)
{
SpeculateCellOperand set(this, node->child1());
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (226268 => 226269)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2017-12-22 19:51:03 UTC (rev 226269)
@@ -1347,18 +1347,6 @@
return appendCallSetResult(operation, result);
}
- JITCompiler::Call callOperation(J_JITOperation_EGReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
- {
- m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
- return appendCallSetResult(operation, result);
- }
-
- JITCompiler::Call callOperation(J_JITOperation_EGReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
- {
- m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
- return appendCallSetResult(operation, result);
- }
-
JITCompiler::Call callOperation(V_JITOperation_EWs operation, WatchpointSet* watchpointSet)
{
m_jit.setupArgumentsWithExecState(TrustedImmPtr(watchpointSet));
@@ -1570,12 +1558,22 @@
m_jit.setupArgumentsWithExecState(arg1, arg2);
return appendCallSetResult(operation, result);
}
- JITCompiler::Call callOperation(J_JITOperation_EJssReo operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+ JITCompiler::Call callOperation(J_JITOperation_EGReoJ operation, JSValueRegs result, GPRReg arg1, GPRReg arg2, JSValueRegs arg3)
{
+ m_jit.setupArgumentsWithExecState(arg1, arg2, arg3.payloadGPR());
+ return appendCallSetResult(operation, result.payloadGPR());
+ }
+ JITCompiler::Call callOperation(J_JITOperation_EGReoJss operation, JSValueRegs result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+ {
+ m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
+ return appendCallSetResult(operation, result.payloadGPR());
+ }
+ JITCompiler::Call callOperation(C_JITOperation_EJssReo operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+ {
m_jit.setupArgumentsWithExecState(arg1, arg2);
return appendCallSetResult(operation, result);
}
- JITCompiler::Call callOperation(J_JITOperation_EJssReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+ JITCompiler::Call callOperation(C_JITOperation_EJssReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
{
m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
return appendCallSetResult(operation, result);
@@ -1826,14 +1824,14 @@
{
return callOperation(operation, result, arg1.gpr(), arg2.gpr());
}
- JITCompiler::Call callOperation(S_JITOperation_EGJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+ JITCompiler::Call callOperation(S_JITOperation_EGJJ operation, GPRReg result, GPRReg arg1, JSValueRegs arg2, JSValueRegs arg3)
{
- m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
+ m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg3.payloadGPR());
return appendCallSetResult(operation, result);
}
- JITCompiler::Call callOperation(S_JITOperation_EGReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+ JITCompiler::Call callOperation(S_JITOperation_EGReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, JSValueRegs arg3)
{
- m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
+ m_jit.setupArgumentsWithExecState(arg1, arg2, arg3.payloadGPR());
return appendCallSetResult(operation, result);
}
JITCompiler::Call callOperation(S_JITOperation_EGReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
@@ -1872,10 +1870,10 @@
m_jit.setupArgumentsWithExecState(arg1, arg2);
return appendCallSetResult(operation, result);
}
- JITCompiler::Call callOperation(J_JITOperation_EGJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+ JITCompiler::Call callOperation(J_JITOperation_EGJJ operation, JSValueRegs result, GPRReg arg1, JSValueRegs arg2, JSValueRegs arg3)
{
- m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
- return appendCallSetResult(operation, result);
+ m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg3.payloadGPR());
+ return appendCallSetResult(operation, result.payloadGPR());
}
JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, int32_t imm)
{
@@ -2247,15 +2245,15 @@
m_jit.setupArgumentsWithExecState(arg1, arg2);
return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR());
}
- JITCompiler::Call callOperation(J_JITOperation_EJssReo operation, JSValueRegs result, GPRReg arg1, GPRReg arg2)
+ JITCompiler::Call callOperation(C_JITOperation_EJssReo operation, GPRReg result, GPRReg arg1, GPRReg arg2)
{
m_jit.setupArgumentsWithExecState(arg1, arg2);
- return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR());
+ return appendCallSetResult(operation, result);
}
- JITCompiler::Call callOperation(J_JITOperation_EJssReoJss operation, JSValueRegs result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+ JITCompiler::Call callOperation(C_JITOperation_EJssReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
{
m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
- return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR());
+ return appendCallSetResult(operation, result);
}
JITCompiler::Call callOperation(J_JITOperation_EPS operation, JSValueRegs result, void* pointer, size_t size)
{
@@ -3051,7 +3049,9 @@
void compileArrayIndexOf(Node*);
void compileArrayPush(Node*);
void compileNotifyWrite(Node*);
- bool compileRegExpExec(Node*);
+ void compileRegExpExec(Node*);
+ void compileRegExpTest(Node*);
+ void compileStringReplace(Node*);
void compileIsObjectOrNull(Node*);
void compileIsFunction(Node*);
void compileTypeOf(Node*);
@@ -3078,6 +3078,7 @@
void compileThrow(Node*);
void compileThrowStaticError(Node*);
void compileGetEnumerableLength(Node*);
+ void compileHasGenericProperty(Node*);
void compileToIndexString(Node*);
void compilePutByIdWithThis(Node*);
void compileHasStructureProperty(Node*);
@@ -3092,6 +3093,9 @@
void compileNewTypedArray(Node*);
void compileCreateThis(Node*);
void compileNewObject(Node*);
+ void compileToPrimitive(Node*);
+ void compileLogShadowChickenPrologue(Node*);
+ void compileLogShadowChickenTail(Node*);
void moveTrueTo(GPRReg);
void moveFalseTo(GPRReg);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (226268 => 226269)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2017-12-22 19:51:03 UTC (rev 226269)
@@ -987,14 +987,12 @@
info->setUpCall(callType, node->origin.semantic, calleePayloadGPR);
auto setResultAndResetStack = [&] () {
- GPRFlushedCallResult resultPayload(this);
- GPRFlushedCallResult2 resultTag(this);
- GPRReg resultPayloadGPR = resultPayload.gpr();
- GPRReg resultTagGPR = resultTag.gpr();
-
- m_jit.setupResults(resultPayloadGPR, resultTagGPR);
+ JSValueRegsFlushedCallResult result(this);
+ JSValueRegs resultRegs = result.regs();
- jsValueResult(resultTagGPR, resultPayloadGPR, node, DataFormatJS, UseChildrenCalledExplicitly);
+ m_jit.setupResults(resultRegs);
+
+ jsValueResult(resultRegs, node, DataFormatJS, UseChildrenCalledExplicitly);
// After the calls are done, we need to reestablish our stack
// pointer. We rely on this for varargs calls, calls with arity
// mismatch (the callframe is slided) and tail calls.
@@ -2590,12 +2588,12 @@
JSValueRegs propertyRegs = property.jsValueRegs();
flushRegisters();
- GPRFlushedCallResult2 resultTag(this);
- GPRFlushedCallResult resultPayload(this);
- callOperation(operationGetByValCell, JSValueRegs(resultTag.gpr(), resultPayload.gpr()), baseGPR, propertyRegs);
+ JSValueRegsFlushedCallResult result(this);
+ JSValueRegs resultRegs = result.regs();
+ callOperation(operationGetByValCell, resultRegs, baseGPR, propertyRegs);
m_jit.exceptionCheck();
- jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
+ jsValueResult(resultRegs, node);
break;
}
case Array::Int32:
@@ -2852,16 +2850,13 @@
JSValueOperand subscript(this, node->child3());
JSValueRegs subscriptRegs = subscript.jsValueRegs();
- GPRFlushedCallResult resultPayload(this);
- GPRFlushedCallResult2 resultTag(this);
- GPRReg resultPayloadGPR = resultPayload.gpr();
- GPRReg resultTagGPR = resultTag.gpr();
-
flushRegisters();
- callOperation(operationGetByValWithThis, JSValueRegs(resultTagGPR, resultPayloadGPR), baseRegs, thisValueRegs, subscriptRegs);
+ JSValueRegsFlushedCallResult result(this);
+ JSValueRegs resultRegs = result.regs();
+ callOperation(operationGetByValWithThis, resultRegs, baseRegs, thisValueRegs, subscriptRegs);
m_jit.exceptionCheck();
- jsValueResult(resultTagGPR, resultPayloadGPR, node);
+ jsValueResult(resultRegs, node);
break;
}
@@ -3164,183 +3159,18 @@
}
case RegExpExec: {
- SpeculateCellOperand globalObject(this, node->child1());
- GPRReg globalObjectGPR = globalObject.gpr();
-
- if (node->child2().useKind() == RegExpObjectUse) {
- if (node->child3().useKind() == StringUse) {
- SpeculateCellOperand base(this, node->child2());
- SpeculateCellOperand argument(this, node->child3());
- GPRReg baseGPR = base.gpr();
- GPRReg argumentGPR = argument.gpr();
- speculateRegExpObject(node->child2(), baseGPR);
- speculateString(node->child3(), argumentGPR);
-
- flushRegisters();
- GPRFlushedCallResult2 resultTag(this);
- GPRFlushedCallResult resultPayload(this);
- callOperation(
- operationRegExpExecString, JSValueRegs(resultTag.gpr(), resultPayload.gpr()),
- globalObjectGPR, baseGPR, argumentGPR);
- m_jit.exceptionCheck();
-
- jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
- break;
- }
-
- SpeculateCellOperand base(this, node->child2());
- JSValueOperand argument(this, node->child3());
- GPRReg baseGPR = base.gpr();
- JSValueRegs argumentRegs = argument.jsValueRegs();
- speculateRegExpObject(node->child2(), baseGPR);
-
- flushRegisters();
- GPRFlushedCallResult2 resultTag(this);
- GPRFlushedCallResult resultPayload(this);
- callOperation(
- operationRegExpExec, JSValueRegs(resultTag.gpr(), resultPayload.gpr()), globalObjectGPR, baseGPR, argumentRegs);
- m_jit.exceptionCheck();
-
- jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
- break;
- }
-
- JSValueOperand base(this, node->child2());
- JSValueOperand argument(this, node->child3());
- JSValueRegs baseRegs = base.jsValueRegs();
- JSValueRegs argumentRegs = argument.jsValueRegs();
-
- flushRegisters();
- GPRFlushedCallResult2 resultTag(this);
- GPRFlushedCallResult resultPayload(this);
- callOperation(
- operationRegExpExecGeneric, JSValueRegs(resultTag.gpr(), resultPayload.gpr()), globalObjectGPR, baseRegs, argumentRegs);
- m_jit.exceptionCheck();
-
- jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
+ compileRegExpExec(node);
break;
}
case RegExpTest: {
- SpeculateCellOperand globalObject(this, node->child1());
- GPRReg globalObjectGPR = globalObject.gpr();
-
- if (node->child2().useKind() == RegExpObjectUse) {
- if (node->child3().useKind() == StringUse) {
- SpeculateCellOperand base(this, node->child2());
- SpeculateCellOperand argument(this, node->child3());
- GPRReg baseGPR = base.gpr();
- GPRReg argumentGPR = argument.gpr();
- speculateRegExpObject(node->child2(), baseGPR);
- speculateString(node->child3(), argumentGPR);
-
- flushRegisters();
- GPRFlushedCallResult result(this);
- callOperation(
- operationRegExpTestString, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
- m_jit.exceptionCheck();
-
- booleanResult(result.gpr(), node);
- break;
- }
-
- SpeculateCellOperand base(this, node->child2());
- JSValueOperand argument(this, node->child3());
- GPRReg baseGPR = base.gpr();
- JSValueRegs argumentRegs = argument.jsValueRegs();
- speculateRegExpObject(node->child2(), baseGPR);
-
- flushRegisters();
- GPRFlushedCallResult result(this);
- callOperation(
- operationRegExpTest, result.gpr(), globalObjectGPR, baseGPR, argumentRegs);
- m_jit.exceptionCheck();
-
- booleanResult(result.gpr(), node);
- break;
- }
-
- JSValueOperand base(this, node->child2());
- JSValueOperand argument(this, node->child3());
- JSValueRegs baseRegs = base.jsValueRegs();
- JSValueRegs argumentRegs = argument.jsValueRegs();
-
- flushRegisters();
- GPRFlushedCallResult result(this);
- callOperation(
- operationRegExpTestGeneric, result.gpr(), globalObjectGPR, baseRegs, argumentRegs);
- m_jit.exceptionCheck();
-
- booleanResult(result.gpr(), node);
+ compileRegExpTest(node);
break;
}
case StringReplace:
case StringReplaceRegExp: {
- if (node->child1().useKind() == StringUse
- && node->child2().useKind() == RegExpObjectUse
- && node->child3().useKind() == StringUse) {
- if (JSString* replace = node->child3()->dynamicCastConstant<JSString*>(*m_jit.vm())) {
- if (!replace->length()) {
- SpeculateCellOperand string(this, node->child1());
- SpeculateCellOperand regExp(this, node->child2());
- GPRReg stringGPR = string.gpr();
- GPRReg regExpGPR = regExp.gpr();
- speculateString(node->child1(), stringGPR);
- speculateRegExpObject(node->child2(), regExpGPR);
-
- flushRegisters();
- GPRFlushedCallResult2 resultTag(this);
- GPRFlushedCallResult resultPayload(this);
- callOperation(
- operationStringProtoFuncReplaceRegExpEmptyStr, JSValueRegs(resultTag.gpr(), resultPayload.gpr()), stringGPR, regExpGPR);
- m_jit.exceptionCheck();
- cellResult(resultPayload.gpr(), node);
- break;
- }
- }
-
- SpeculateCellOperand string(this, node->child1());
- SpeculateCellOperand regExp(this, node->child2());
- SpeculateCellOperand replace(this, node->child3());
- GPRReg stringGPR = string.gpr();
- GPRReg regExpGPR = regExp.gpr();
- GPRReg replaceGPR = replace.gpr();
- speculateString(node->child1(), stringGPR);
- speculateRegExpObject(node->child2(), regExpGPR);
- speculateString(node->child3(), replaceGPR);
-
- flushRegisters();
- GPRFlushedCallResult2 resultTag(this);
- GPRFlushedCallResult resultPayload(this);
- callOperation(
- operationStringProtoFuncReplaceRegExpString, JSValueRegs(resultTag.gpr(), resultPayload.gpr()),
- stringGPR, regExpGPR, replaceGPR);
- m_jit.exceptionCheck();
- cellResult(resultPayload.gpr(), node);
- break;
- }
-
- // If we fixed up the edge of child2, we inserted a Check(@child2, String).
- OperandSpeculationMode child2SpeculationMode = AutomaticOperandSpeculation;
- if (node->child2().useKind() == StringUse)
- child2SpeculationMode = ManualOperandSpeculation;
-
- JSValueOperand string(this, node->child1());
- JSValueOperand search(this, node->child2(), child2SpeculationMode);
- JSValueOperand replace(this, node->child3());
- JSValueRegs stringRegs = string.jsValueRegs();
- JSValueRegs searchRegs = search.jsValueRegs();
- JSValueRegs replaceRegs = replace.jsValueRegs();
-
- flushRegisters();
- GPRFlushedCallResult2 resultTag(this);
- GPRFlushedCallResult resultPayload(this);
- callOperation(
- operationStringProtoFuncReplaceGeneric, JSValueRegs(resultTag.gpr(), resultPayload.gpr()),
- stringRegs, searchRegs, replaceRegs);
- m_jit.exceptionCheck();
- cellResult(resultPayload.gpr(), node);
+ compileStringReplace(node);
break;
}
@@ -3615,31 +3445,7 @@
}
case ToPrimitive: {
- RELEASE_ASSERT(node->child1().useKind() == UntypedUse);
- JSValueOperand argument(this, node->child1());
- GPRTemporary resultTag(this, Reuse, argument, TagWord);
- GPRTemporary resultPayload(this, Reuse, argument, PayloadWord);
-
- GPRReg argumentTagGPR = argument.tagGPR();
- GPRReg argumentPayloadGPR = argument.payloadGPR();
- GPRReg resultTagGPR = resultTag.gpr();
- GPRReg resultPayloadGPR = resultPayload.gpr();
-
- argument.use();
-
- MacroAssembler::Jump alreadyPrimitive = m_jit.branchIfNotCell(argument.jsValueRegs());
- MacroAssembler::Jump notPrimitive = m_jit.branchIfObject(argumentPayloadGPR);
-
- alreadyPrimitive.link(&m_jit);
- m_jit.move(argumentTagGPR, resultTagGPR);
- m_jit.move(argumentPayloadGPR, resultPayloadGPR);
-
- addSlowPathGenerator(
- slowPathCall(
- notPrimitive, this, operationToPrimitive,
- JSValueRegs(resultTagGPR, resultPayloadGPR), JSValueRegs(argumentTagGPR, argumentPayloadGPR)));
-
- jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
+ compileToPrimitive(node);
break;
}
@@ -4635,10 +4441,9 @@
JSValueRegs inputRegs = input.jsValueRegs();
+ flushRegisters();
GPRFlushedCallResult result(this);
GPRReg resultGPR = result.gpr();
-
- flushRegisters();
callOperation(operationMapHash, resultGPR, inputRegs);
m_jit.exceptionCheck();
int32Result(resultGPR, node);
@@ -4654,12 +4459,10 @@
SpeculateCellOperand map(this, node->child1());
JSValueOperand key(this, node->child2());
SpeculateInt32Operand hash(this, node->child3());
- GPRFlushedCallResult result(this);
GPRReg mapGPR = map.gpr();
JSValueRegs keyRegs = key.jsValueRegs();
GPRReg hashGPR = hash.gpr();
- GPRReg resultGPR = result.gpr();
if (node->child1().useKind() == MapObjectUse)
speculateMapObject(node->child1(), mapGPR);
@@ -4669,6 +4472,8 @@
RELEASE_ASSERT_NOT_REACHED();
flushRegisters();
+ GPRFlushedCallResult result(this);
+ GPRReg resultGPR = result.gpr();
if (node->child1().useKind() == MapObjectUse)
callOperation(operationJSMapFindBucket, resultGPR, mapGPR, keyRegs, hashGPR);
else
@@ -4990,18 +4795,7 @@
break;
}
case HasGenericProperty: {
- JSValueOperand base(this, node->child1());
- SpeculateCellOperand property(this, node->child2());
- GPRFlushedCallResult resultPayload(this);
- GPRFlushedCallResult2 resultTag(this);
- JSValueRegs baseRegs = base.jsValueRegs();
- GPRReg resultPayloadGPR = resultPayload.gpr();
- GPRReg resultTagGPR = resultTag.gpr();
-
- flushRegisters();
- callOperation(operationHasGenericProperty, JSValueRegs(resultTagGPR, resultPayloadGPR), baseRegs, property.gpr());
- m_jit.exceptionCheck();
- booleanResult(resultPayloadGPR, node);
+ compileHasGenericProperty(node);
break;
}
case HasStructureProperty: {
@@ -5086,27 +4880,23 @@
GPRReg propertyGPR = property.gpr();
#if CPU(X86)
- GPRFlushedCallResult resultPayload(this);
- GPRFlushedCallResult2 resultTag(this);
GPRTemporary scratch(this);
- GPRReg resultTagGPR = resultTag.gpr();
- GPRReg resultPayloadGPR = resultPayload.gpr();
GPRReg scratchGPR = scratch.gpr();
// Not enough registers on X86 for this code, so always use the slow path.
flushRegisters();
+ JSValueRegsFlushedCallResult result(this);
+ JSValueRegs resultRegs = result.regs();
m_jit.move(MacroAssembler::TrustedImm32(JSValue::CellTag), scratchGPR);
- callOperation(operationGetByValCell, JSValueRegs(resultTagGPR, resultPayloadGPR), baseGPR, JSValueRegs(scratchGPR, propertyGPR));
+ callOperation(operationGetByValCell, resultRegs, baseGPR, JSValueRegs(scratchGPR, propertyGPR));
m_jit.exceptionCheck();
#else
- GPRTemporary resultPayload(this);
- GPRTemporary resultTag(this);
GPRTemporary scratch(this);
+ JSValueRegsFlushedCallResult result(this);
- GPRReg resultTagGPR = resultTag.gpr();
- GPRReg resultPayloadGPR = resultPayload.gpr();
GPRReg scratchGPR = scratch.gpr();
+ JSValueRegs resultRegs = result.regs();
Edge& indexEdge = m_jit.graph().varArgChild(node, 2);
Edge& enumeratorEdge = m_jit.graph().varArgChild(node, 3);
@@ -5135,8 +4925,8 @@
m_jit.move(indexGPR, scratchGPR);
m_jit.signExtend32ToPtr(scratchGPR, scratchGPR);
- m_jit.load32(MacroAssembler::BaseIndex(baseGPR, scratchGPR, MacroAssembler::TimesEight, JSObject::offsetOfInlineStorage() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTagGPR);
- m_jit.load32(MacroAssembler::BaseIndex(baseGPR, scratchGPR, MacroAssembler::TimesEight, JSObject::offsetOfInlineStorage() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayloadGPR);
+ m_jit.load32(MacroAssembler::BaseIndex(baseGPR, scratchGPR, MacroAssembler::TimesEight, JSObject::offsetOfInlineStorage() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultRegs.tagGPR());
+ m_jit.load32(MacroAssembler::BaseIndex(baseGPR, scratchGPR, MacroAssembler::TimesEight, JSObject::offsetOfInlineStorage() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultRegs.payloadGPR());
MacroAssembler::Jump done = m_jit.jump();
@@ -5146,19 +4936,19 @@
m_jit.sub32(MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedInlineCapacityOffset()), scratchGPR);
m_jit.neg32(scratchGPR);
m_jit.signExtend32ToPtr(scratchGPR, scratchGPR);
- // We use resultPayloadGPR as a temporary here. We have to make sure clobber it after getting the
- // value out of indexGPR and enumeratorGPR because resultPayloadGPR could reuse either of those registers.
- m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), resultPayloadGPR);
+ // We use resultRegs.payloadGPR() as a temporary here. We have to make sure clobber it after getting the
+ // value out of indexGPR and enumeratorGPR because resultRegs.payloadGPR() could reuse either of those registers.
+ m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), resultRegs.payloadGPR());
int32_t offsetOfFirstProperty = static_cast<int32_t>(offsetInButterfly(firstOutOfLineOffset)) * sizeof(EncodedJSValue);
- m_jit.load32(MacroAssembler::BaseIndex(resultPayloadGPR, scratchGPR, MacroAssembler::TimesEight, offsetOfFirstProperty + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTagGPR);
- m_jit.load32(MacroAssembler::BaseIndex(resultPayloadGPR, scratchGPR, MacroAssembler::TimesEight, offsetOfFirstProperty + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayloadGPR);
+ m_jit.load32(MacroAssembler::BaseIndex(resultRegs.payloadGPR(), scratchGPR, MacroAssembler::TimesEight, offsetOfFirstProperty + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultRegs.tagGPR());
+ m_jit.load32(MacroAssembler::BaseIndex(resultRegs.payloadGPR(), scratchGPR, MacroAssembler::TimesEight, offsetOfFirstProperty + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultRegs.payloadGPR());
done.link(&m_jit);
- addSlowPathGenerator(slowPathCall(slowPath, this, operationGetByValCell, JSValueRegs(resultTagGPR, resultPayloadGPR), baseGPR, propertyGPR));
+ addSlowPathGenerator(slowPathCall(slowPath, this, operationGetByValCell, resultRegs, baseGPR, propertyGPR));
#endif
- jsValueResult(resultTagGPR, resultPayloadGPR, node);
+ jsValueResult(resultRegs, node);
break;
}
case GetPropertyEnumerator: {
@@ -5232,48 +5022,12 @@
}
case LogShadowChickenPrologue: {
- flushRegisters();
- prepareForExternalCall();
- m_jit.emitStoreCodeOrigin(node->origin.semantic);
-
- GPRTemporary scratch1(this, GPRInfo::nonArgGPR0); // This must be a non-argument GPR.
- GPRReg scratch1Reg = scratch1.gpr();
- GPRTemporary shadowPacket(this);
- GPRReg shadowPacketReg = shadowPacket.gpr();
- GPRTemporary scratch2(this);
- GPRReg scratch2Reg = scratch2.gpr();
-
- m_jit.ensureShadowChickenPacket(*m_jit.vm(), shadowPacketReg, scratch1Reg, scratch2Reg);
-
- SpeculateCellOperand scope(this, node->child1());
- GPRReg scopeReg = scope.gpr();
-
- m_jit.logShadowChickenProloguePacket(shadowPacketReg, scratch1Reg, scopeReg);
- noResult(node);
+ compileLogShadowChickenPrologue(node);
break;
}
case LogShadowChickenTail: {
- flushRegisters();
- prepareForExternalCall();
- CallSiteIndex callSiteIndex = m_jit.emitStoreCodeOrigin(node->origin.semantic);
-
- GPRTemporary scratch1(this, GPRInfo::nonArgGPR0); // This must be a non-argument GPR.
- GPRReg scratch1Reg = scratch1.gpr();
- GPRTemporary shadowPacket(this);
- GPRReg shadowPacketReg = shadowPacket.gpr();
- GPRTemporary scratch2(this);
- GPRReg scratch2Reg = scratch2.gpr();
-
- m_jit.ensureShadowChickenPacket(*m_jit.vm(), shadowPacketReg, scratch1Reg, scratch2Reg);
-
- JSValueOperand thisValue(this, node->child1());
- JSValueRegs thisRegs = thisValue.jsValueRegs();
- SpeculateCellOperand scope(this, node->child2());
- GPRReg scopeReg = scope.gpr();
-
- m_jit.logShadowChickenTailPacket(shadowPacketReg, thisRegs, scopeReg, m_jit.codeBlock(), callSiteIndex);
- noResult(node);
+ compileLogShadowChickenTail(node);
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (226268 => 226269)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2017-12-22 19:51:03 UTC (rev 226269)
@@ -2446,11 +2446,9 @@
SpeculateDoubleOperand value(this, node->child1());
FPRReg valueFPR = value.fpr();
+ flushRegisters();
GPRFlushedCallResult result(this);
GPRReg resultGPR = result.gpr();
-
- flushRegisters();
-
callOperation(operationConvertDoubleToInt52, resultGPR, valueFPR);
DFG_TYPE_CHECK_WITH_EXIT_KIND(Int52Overflow,
@@ -2934,10 +2932,9 @@
JSValueOperand subscript(this, node->child3());
GPRReg subscriptGPR = subscript.gpr();
+ flushRegisters();
GPRFlushedCallResult result(this);
GPRReg resultGPR = result.gpr();
-
- flushRegisters();
callOperation(operationGetByValWithThis, resultGPR, baseGPR, thisValueGPR, subscriptGPR);
m_jit.exceptionCheck();
@@ -3255,10 +3252,9 @@
argGPRs[i] = args[i]->gpr();
}
+ flushRegisters();
GPRFlushedCallResult result(this);
resultGPR = result.gpr();
-
- flushRegisters();
callSlowPath();
m_jit.exceptionCheck();
@@ -3404,9 +3400,9 @@
if (node->child1().useKind() != Int32Use) {
JSValueOperand operand(this, node->child1());
GPRReg operandGPR = operand.gpr();
+ flushRegisters();
GPRFlushedCallResult result(this);
GPRReg resultGPR = result.gpr();
- flushRegisters();
callOperation(operationAtomicsIsLockFree, resultGPR, operandGPR);
m_jit.exceptionCheck();
jsValueResult(resultGPR, node);
@@ -3429,199 +3425,18 @@
}
case RegExpExec: {
- bool sample = false;
-
- if (sample)
- m_jit.incrementSuperSamplerCount();
-
- SpeculateCellOperand globalObject(this, node->child1());
- GPRReg globalObjectGPR = globalObject.gpr();
-
- if (node->child2().useKind() == RegExpObjectUse) {
- if (node->child3().useKind() == StringUse) {
- SpeculateCellOperand base(this, node->child2());
- SpeculateCellOperand argument(this, node->child3());
- GPRReg baseGPR = base.gpr();
- GPRReg argumentGPR = argument.gpr();
- speculateRegExpObject(node->child2(), baseGPR);
- speculateString(node->child3(), argumentGPR);
-
- flushRegisters();
- GPRFlushedCallResult result(this);
- callOperation(operationRegExpExecString, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
- m_jit.exceptionCheck();
-
- jsValueResult(result.gpr(), node);
-
- if (sample)
- m_jit.decrementSuperSamplerCount();
- break;
- }
-
- SpeculateCellOperand base(this, node->child2());
- JSValueOperand argument(this, node->child3());
- GPRReg baseGPR = base.gpr();
- GPRReg argumentGPR = argument.gpr();
- speculateRegExpObject(node->child2(), baseGPR);
-
- flushRegisters();
- GPRFlushedCallResult result(this);
- callOperation(operationRegExpExec, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
- m_jit.exceptionCheck();
-
- jsValueResult(result.gpr(), node);
-
- if (sample)
- m_jit.decrementSuperSamplerCount();
- break;
- }
-
- JSValueOperand base(this, node->child2());
- JSValueOperand argument(this, node->child3());
- GPRReg baseGPR = base.gpr();
- GPRReg argumentGPR = argument.gpr();
-
- flushRegisters();
- GPRFlushedCallResult result(this);
- callOperation(operationRegExpExecGeneric, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
- m_jit.exceptionCheck();
-
- jsValueResult(result.gpr(), node);
-
- if (sample)
- m_jit.decrementSuperSamplerCount();
+ compileRegExpExec(node);
break;
}
case RegExpTest: {
- SpeculateCellOperand globalObject(this, node->child1());
- GPRReg globalObjectGPR = globalObject.gpr();
-
- if (node->child2().useKind() == RegExpObjectUse) {
- if (node->child3().useKind() == StringUse) {
- SpeculateCellOperand base(this, node->child2());
- SpeculateCellOperand argument(this, node->child3());
- GPRReg baseGPR = base.gpr();
- GPRReg argumentGPR = argument.gpr();
- speculateRegExpObject(node->child2(), baseGPR);
- speculateString(node->child3(), argumentGPR);
-
- flushRegisters();
- GPRFlushedCallResult result(this);
- callOperation(operationRegExpTestString, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
- m_jit.exceptionCheck();
-
- m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
- jsValueResult(result.gpr(), node);
- break;
- }
-
- SpeculateCellOperand base(this, node->child2());
- JSValueOperand argument(this, node->child3());
- GPRReg baseGPR = base.gpr();
- GPRReg argumentGPR = argument.gpr();
- speculateRegExpObject(node->child2(), baseGPR);
-
- flushRegisters();
- GPRFlushedCallResult result(this);
- callOperation(operationRegExpTest, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
- m_jit.exceptionCheck();
-
- m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
- jsValueResult(result.gpr(), node);
- break;
- }
-
- JSValueOperand base(this, node->child2());
- JSValueOperand argument(this, node->child3());
- GPRReg baseGPR = base.gpr();
- GPRReg argumentGPR = argument.gpr();
-
- flushRegisters();
- GPRFlushedCallResult result(this);
- callOperation(operationRegExpTestGeneric, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
- m_jit.exceptionCheck();
-
- m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
- jsValueResult(result.gpr(), node, DataFormatJSBoolean);
+ compileRegExpTest(node);
break;
}
case StringReplace:
case StringReplaceRegExp: {
- bool sample = false;
-
- if (sample)
- m_jit.incrementSuperSamplerCount();
-
- if (node->child1().useKind() == StringUse
- && node->child2().useKind() == RegExpObjectUse
- && node->child3().useKind() == StringUse) {
- if (JSString* replace = node->child3()->dynamicCastConstant<JSString*>(*m_jit.vm())) {
- if (!replace->length()) {
- SpeculateCellOperand string(this, node->child1());
- SpeculateCellOperand regExp(this, node->child2());
- GPRReg stringGPR = string.gpr();
- GPRReg regExpGPR = regExp.gpr();
- speculateString(node->child1(), stringGPR);
- speculateRegExpObject(node->child2(), regExpGPR);
-
- flushRegisters();
- GPRFlushedCallResult result(this);
- callOperation(
- operationStringProtoFuncReplaceRegExpEmptyStr, result.gpr(), stringGPR,
- regExpGPR);
- m_jit.exceptionCheck();
- cellResult(result.gpr(), node);
- if (sample)
- m_jit.decrementSuperSamplerCount();
- break;
- }
- }
-
- SpeculateCellOperand string(this, node->child1());
- SpeculateCellOperand regExp(this, node->child2());
- SpeculateCellOperand replace(this, node->child3());
- GPRReg stringGPR = string.gpr();
- GPRReg regExpGPR = regExp.gpr();
- GPRReg replaceGPR = replace.gpr();
- speculateString(node->child1(), stringGPR);
- speculateRegExpObject(node->child2(), regExpGPR);
- speculateString(node->child3(), replaceGPR);
-
- flushRegisters();
- GPRFlushedCallResult result(this);
- callOperation(
- operationStringProtoFuncReplaceRegExpString, result.gpr(), stringGPR, regExpGPR,
- replaceGPR);
- m_jit.exceptionCheck();
- cellResult(result.gpr(), node);
- if (sample)
- m_jit.decrementSuperSamplerCount();
- break;
- }
-
- // If we fixed up the edge of child2, we inserted a Check(@child2, String).
- OperandSpeculationMode child2SpeculationMode = AutomaticOperandSpeculation;
- if (node->child2().useKind() == StringUse)
- child2SpeculationMode = ManualOperandSpeculation;
-
- JSValueOperand string(this, node->child1());
- JSValueOperand search(this, node->child2(), child2SpeculationMode);
- JSValueOperand replace(this, node->child3());
- GPRReg stringGPR = string.gpr();
- GPRReg searchGPR = search.gpr();
- GPRReg replaceGPR = replace.gpr();
-
- flushRegisters();
- GPRFlushedCallResult result(this);
- callOperation(
- operationStringProtoFuncReplaceGeneric, result.gpr(), stringGPR, searchGPR,
- replaceGPR);
- m_jit.exceptionCheck();
- cellResult(result.gpr(), node);
- if (sample)
- m_jit.decrementSuperSamplerCount();
+ compileStringReplace(node);
break;
}
@@ -3845,25 +3660,7 @@
}
case ToPrimitive: {
- DFG_ASSERT(m_jit.graph(), node, node->child1().useKind() == UntypedUse);
- JSValueOperand argument(this, node->child1());
- GPRTemporary result(this, Reuse, argument);
-
- GPRReg argumentGPR = argument.gpr();
- GPRReg resultGPR = result.gpr();
-
- argument.use();
-
- MacroAssembler::Jump alreadyPrimitive = m_jit.branchIfNotCell(JSValueRegs(argumentGPR));
- MacroAssembler::Jump notPrimitive = m_jit.branchIfObject(argumentGPR);
-
- alreadyPrimitive.link(&m_jit);
- m_jit.move(argumentGPR, resultGPR);
-
- addSlowPathGenerator(
- slowPathCall(notPrimitive, this, operationToPrimitive, resultGPR, argumentGPR));
-
- jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
+ compileToPrimitive(node);
break;
}
@@ -5452,18 +5249,7 @@
break;
}
case HasGenericProperty: {
- JSValueOperand base(this, node->child1());
- SpeculateCellOperand property(this, node->child2());
-
- JSValueRegs baseRegs = base.jsValueRegs();
- GPRReg propertyGPR = property.gpr();
-
- flushRegisters();
- GPRFlushedCallResult result(this);
- GPRReg resultGPR = result.gpr();
- callOperation(operationHasGenericProperty, resultGPR, baseRegs, propertyGPR);
- m_jit.exceptionCheck();
- jsValueResult(resultGPR, node, DataFormatJSBoolean);
+ compileHasGenericProperty(node);
break;
}
case HasStructureProperty: {
@@ -5701,48 +5487,12 @@
}
case LogShadowChickenPrologue: {
- flushRegisters();
- prepareForExternalCall();
- m_jit.emitStoreCodeOrigin(node->origin.semantic);
-
- GPRTemporary scratch1(this, GPRInfo::nonArgGPR0); // This must be a non-argument GPR.
- GPRReg scratch1Reg = scratch1.gpr();
- GPRTemporary scratch2(this);
- GPRReg scratch2Reg = scratch2.gpr();
- GPRTemporary shadowPacket(this);
- GPRReg shadowPacketReg = shadowPacket.gpr();
-
- m_jit.ensureShadowChickenPacket(*m_jit.vm(), shadowPacketReg, scratch1Reg, scratch2Reg);
-
- SpeculateCellOperand scope(this, node->child1());
- GPRReg scopeReg = scope.gpr();
-
- m_jit.logShadowChickenProloguePacket(shadowPacketReg, scratch1Reg, scopeReg);
- noResult(node);
+ compileLogShadowChickenPrologue(node);
break;
}
case LogShadowChickenTail: {
- flushRegisters();
- prepareForExternalCall();
- CallSiteIndex callSiteIndex = m_jit.emitStoreCodeOrigin(node->origin.semantic);
-
- GPRTemporary scratch1(this, GPRInfo::nonArgGPR0); // This must be a non-argument GPR.
- GPRReg scratch1Reg = scratch1.gpr();
- GPRTemporary scratch2(this);
- GPRReg scratch2Reg = scratch2.gpr();
- GPRTemporary shadowPacket(this);
- GPRReg shadowPacketReg = shadowPacket.gpr();
-
- m_jit.ensureShadowChickenPacket(*m_jit.vm(), shadowPacketReg, scratch1Reg, scratch2Reg);
-
- JSValueOperand thisValue(this, node->child1());
- JSValueRegs thisRegs = JSValueRegs(thisValue.gpr());
- SpeculateCellOperand scope(this, node->child2());
- GPRReg scopeReg = scope.gpr();
-
- m_jit.logShadowChickenTailPacket(shadowPacketReg, thisRegs, scopeReg, m_jit.codeBlock(), callSiteIndex);
- noResult(node);
+ compileLogShadowChickenTail(node);
break;
}
@@ -5975,11 +5725,9 @@
SpeculateDoubleOperand value(this, edge);
FPRReg valueFPR = value.fpr();
+ flushRegisters();
GPRFlushedCallResult result(this);
GPRReg resultGPR = result.gpr();
-
- flushRegisters();
-
callOperation(operationConvertDoubleToInt52, resultGPR, valueFPR);
DFG_TYPE_CHECK(
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (226268 => 226269)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2017-12-22 19:51:03 UTC (rev 226269)
@@ -10320,7 +10320,7 @@
LValue regExp = lowRegExpObject(m_node->child2());
LValue result = vmCall(
- Int64, m_out.operation(operationStringProtoFuncReplaceRegExpEmptyStr),
+ pointerType(), m_out.operation(operationStringProtoFuncReplaceRegExpEmptyStr),
m_callFrame, string, regExp);
setJSValue(result);
@@ -10333,7 +10333,7 @@
LValue replace = lowString(m_node->child3());
LValue result = vmCall(
- Int64, m_out.operation(operationStringProtoFuncReplaceRegExpString),
+ pointerType(), m_out.operation(operationStringProtoFuncReplaceRegExpString),
m_callFrame, string, regExp, replace);
setJSValue(result);
@@ -10347,7 +10347,7 @@
search = lowJSValue(m_node->child2());
LValue result = vmCall(
- Int64, m_out.operation(operationStringProtoFuncReplaceGeneric), m_callFrame,
+ pointerType(), m_out.operation(operationStringProtoFuncReplaceGeneric), m_callFrame,
lowJSValue(m_node->child1()), search,
lowJSValue(m_node->child3()));
Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (226268 => 226269)
--- trunk/Source/_javascript_Core/jit/JITOperations.cpp 2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp 2017-12-22 19:51:03 UTC (rev 226269)
@@ -58,7 +58,6 @@
#include "JSGeneratorFunction.h"
#include "JSGlobalObjectFunctions.h"
#include "JSLexicalEnvironment.h"
-#include "JSPropertyNameEnumerator.h"
#include "JSWithScope.h"
#include "ModuleProgramCodeBlock.h"
#include "ObjectConstructor.h"
@@ -2372,66 +2371,6 @@
#endif // COMPILER(GCC_OR_CLANG)
}
-EncodedJSValue JIT_OPERATION operationHasGenericProperty(ExecState* exec, EncodedJSValue encodedBaseValue, JSCell* propertyName)
-{
- VM& vm = exec->vm();
- NativeCallFrameTracer tracer(&vm, exec);
- JSValue baseValue = JSValue::decode(encodedBaseValue);
- if (baseValue.isUndefinedOrNull())
- return JSValue::encode(jsBoolean(false));
-
- JSObject* base = baseValue.toObject(exec);
- if (!base)
- return JSValue::encode(JSValue());
- return JSValue::encode(jsBoolean(base->hasPropertyGeneric(exec, asString(propertyName)->toIdentifier(exec), PropertySlot::InternalMethodType::GetOwnProperty)));
-}
-
-JSCell* JIT_OPERATION operationGetPropertyEnumeratorCell(ExecState* exec, JSCell* cell)
-{
- VM& vm = exec->vm();
- NativeCallFrameTracer tracer(&vm, exec);
- auto scope = DECLARE_THROW_SCOPE(vm);
-
- JSObject* base = cell->toObject(exec, exec->lexicalGlobalObject());
- RETURN_IF_EXCEPTION(scope, { });
-
- scope.release();
- return propertyNameEnumerator(exec, base);
-}
-
-JSCell* JIT_OPERATION operationGetPropertyEnumerator(ExecState* exec, EncodedJSValue encodedBase)
-{
- VM& vm = exec->vm();
- NativeCallFrameTracer tracer(&vm, exec);
- auto scope = DECLARE_THROW_SCOPE(vm);
-
- JSValue base = JSValue::decode(encodedBase);
- if (base.isUndefinedOrNull())
- return JSPropertyNameEnumerator::create(vm);
-
- JSObject* baseObject = base.toObject(exec);
- RETURN_IF_EXCEPTION(scope, { });
-
- scope.release();
- return propertyNameEnumerator(exec, baseObject);
-}
-
-EncodedJSValue JIT_OPERATION operationNextEnumeratorPname(ExecState* exec, JSCell* enumeratorCell, int32_t index)
-{
- VM& vm = exec->vm();
- NativeCallFrameTracer tracer(&vm, exec);
- JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(enumeratorCell);
- JSString* propertyName = enumerator->propertyNameAtIndex(index);
- return JSValue::encode(propertyName ? propertyName : jsNull());
-}
-
-JSCell* JIT_OPERATION operationToIndexString(ExecState* exec, int32_t index)
-{
- VM& vm = exec->vm();
- NativeCallFrameTracer tracer(&vm, exec);
- return jsString(exec, Identifier::from(exec, index).string());
-}
-
ALWAYS_INLINE static EncodedJSValue unprofiledAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
{
VM* vm = &exec->vm();
Modified: trunk/Source/_javascript_Core/jit/JITOperations.h (226268 => 226269)
--- trunk/Source/_javascript_Core/jit/JITOperations.h 2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/jit/JITOperations.h 2017-12-22 19:51:03 UTC (rev 226269)
@@ -220,6 +220,8 @@
typedef JSCell* (JIT_OPERATION *C_JITOperation_ECJZ)(ExecState*, JSCell*, EncodedJSValue, int32_t);
typedef JSCell* (JIT_OPERATION *C_JITOperation_ECJ)(ExecState*, JSCell*, EncodedJSValue);
typedef JSCell* (JIT_OPERATION *C_JITOperation_ECO)(ExecState*, JSCell*, JSObject*);
+typedef JSCell* (JIT_OPERATION *C_JITOperation_EJssReo)(ExecState*, JSString*, RegExpObject*);
+typedef JSCell* (JIT_OPERATION *C_JITOperation_EJssReoJss)(ExecState*, JSString*, RegExpObject*, JSString*);
typedef double (JIT_OPERATION *D_JITOperation_D)(double);
typedef double (JIT_OPERATION *D_JITOperation_G)(JSGlobalObject*);
typedef double (JIT_OPERATION *D_JITOperation_DD)(double, double);
@@ -460,12 +462,6 @@
int32_t JIT_OPERATION operationCheckIfExceptionIsUncatchableAndNotifyProfiler(ExecState*);
int32_t JIT_OPERATION operationInstanceOfCustom(ExecState*, EncodedJSValue encodedValue, JSObject* constructor, EncodedJSValue encodedHasInstance) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationHasGenericProperty(ExecState*, EncodedJSValue, JSCell*);
-JSCell* JIT_OPERATION operationGetPropertyEnumeratorCell(ExecState*, JSCell*);
-JSCell* JIT_OPERATION operationGetPropertyEnumerator(ExecState*, EncodedJSValue);
-EncodedJSValue JIT_OPERATION operationNextEnumeratorPname(ExecState*, JSCell*, int32_t);
-JSCell* JIT_OPERATION operationToIndexString(ExecState*, int32_t);
-
EncodedJSValue JIT_OPERATION operationValueAdd(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
EncodedJSValue JIT_OPERATION operationValueAddProfiled(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*) WTF_INTERNAL;
EncodedJSValue JIT_OPERATION operationValueAddProfiledOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC*) WTF_INTERNAL;
Modified: trunk/Source/_javascript_Core/runtime/StringPrototype.cpp (226268 => 226269)
--- trunk/Source/_javascript_Core/runtime/StringPrototype.cpp 2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/runtime/StringPrototype.cpp 2017-12-22 19:51:03 UTC (rev 226269)
@@ -307,7 +307,7 @@
int length;
};
-static ALWAYS_INLINE JSValue jsSpliceSubstrings(ExecState* exec, JSString* sourceVal, const String& source, const StringRange* substringRanges, int rangeCount)
+static ALWAYS_INLINE JSString* jsSpliceSubstrings(ExecState* exec, JSString* sourceVal, const String& source, const StringRange* substringRanges, int rangeCount)
{
VM& vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
@@ -334,8 +334,10 @@
LChar* buffer;
const LChar* sourceData = source.characters8();
auto impl = StringImpl::tryCreateUninitialized(totalLength, buffer);
- if (!impl)
- return throwOutOfMemoryError(exec, scope);
+ if (!impl) {
+ throwOutOfMemoryError(exec, scope);
+ return nullptr;
+ }
int bufferPos = 0;
for (int i = 0; i < rangeCount; i++) {
@@ -353,8 +355,10 @@
const UChar* sourceData = source.characters16();
auto impl = StringImpl::tryCreateUninitialized(totalLength, buffer);
- if (!impl)
- return throwOutOfMemoryError(exec, scope);
+ if (!impl) {
+ throwOutOfMemoryError(exec, scope);
+ return nullptr;
+ }
int bufferPos = 0;
for (int i = 0; i < rangeCount; i++) {
@@ -368,7 +372,7 @@
return jsString(exec, WTFMove(impl));
}
-static ALWAYS_INLINE JSValue jsSpliceSubstringsWithSeparators(ExecState* exec, JSString* sourceVal, const String& source, const StringRange* substringRanges, int rangeCount, const String* separators, int separatorCount)
+static ALWAYS_INLINE JSString* jsSpliceSubstringsWithSeparators(ExecState* exec, JSString* sourceVal, const String& source, const StringRange* substringRanges, int rangeCount, const String* separators, int separatorCount)
{
VM& vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
@@ -393,8 +397,10 @@
if (separators[i].length() && !separators[i].is8Bit())
allSeparators8Bit = false;
}
- if (totalLength.hasOverflowed())
- return throwOutOfMemoryError(exec, scope);
+ if (totalLength.hasOverflowed()) {
+ throwOutOfMemoryError(exec, scope);
+ return nullptr;
+ }
if (!totalLength)
return jsEmptyString(exec);
@@ -404,8 +410,10 @@
const LChar* sourceData = source.characters8();
auto impl = StringImpl::tryCreateUninitialized(totalLength.unsafeGet(), buffer);
- if (!impl)
- return throwOutOfMemoryError(exec, scope);
+ if (!impl) {
+ throwOutOfMemoryError(exec, scope);
+ return nullptr;
+ }
int maxCount = std::max(rangeCount, separatorCount);
int bufferPos = 0;
@@ -430,8 +438,10 @@
UChar* buffer;
auto impl = StringImpl::tryCreateUninitialized(totalLength.unsafeGet(), buffer);
- if (!impl)
- return throwOutOfMemoryError(exec, scope);
+ if (!impl) {
+ throwOutOfMemoryError(exec, scope);
+ return nullptr;
+ }
int maxCount = std::max(rangeCount, separatorCount);
int bufferPos = 0;
@@ -463,10 +473,10 @@
#define OUT_OF_MEMORY(exec__, scope__) \
do { \
throwOutOfMemoryError(exec__, scope__); \
- return encodedJSValue(); \
+ return nullptr; \
} while (false)
-static ALWAYS_INLINE EncodedJSValue removeUsingRegExpSearch(VM& vm, ExecState* exec, JSString* string, const String& source, RegExp* regExp)
+static ALWAYS_INLINE JSString* removeUsingRegExpSearch(VM& vm, ExecState* exec, JSString* string, const String& source, RegExp* regExp)
{
auto scope = DECLARE_THROW_SCOPE(vm);
SuperSamplerScope superSamplerScope(false);
@@ -499,7 +509,7 @@
}
if (!lastIndex)
- return JSValue::encode(string);
+ return string;
if (static_cast<unsigned>(lastIndex) < sourceLen) {
if (UNLIKELY(!sourceRanges.tryConstructAndAppend(lastIndex, sourceLen - lastIndex)))
@@ -506,10 +516,10 @@
OUT_OF_MEMORY(exec, scope);
}
scope.release();
- return JSValue::encode(jsSpliceSubstrings(exec, string, source, sourceRanges.data(), sourceRanges.size()));
+ return jsSpliceSubstrings(exec, string, source, sourceRanges.data(), sourceRanges.size());
}
-static ALWAYS_INLINE EncodedJSValue replaceUsingRegExpSearch(
+static ALWAYS_INLINE JSString* replaceUsingRegExpSearch(
VM& vm, ExecState* exec, JSString* string, JSValue searchValue, CallData& callData,
CallType callType, String& replacementString, JSValue replaceValue)
{
@@ -517,7 +527,7 @@
const String& source = string->value(exec);
unsigned sourceLen = source.length();
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ RETURN_IF_EXCEPTION(scope, nullptr);
RegExpObject* regExpObject = asRegExpObject(searchValue);
RegExp* regExp = regExpObject->regExp();
bool global = regExp->global();
@@ -526,7 +536,7 @@
if (global) {
// ES5.1 15.5.4.10 step 8.a.
regExpObject->setLastIndex(exec, 0);
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ RETURN_IF_EXCEPTION(scope, nullptr);
if (callType == CallType::None && !replacementString.length()) {
scope.release();
@@ -550,7 +560,7 @@
int argCount = regExp->numSubpatterns() + 1 + 2;
JSFunction* func = jsCast<JSFunction*>(replaceValue);
CachedCall cachedCall(exec, func, argCount);
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ RETURN_IF_EXCEPTION(scope, nullptr);
if (source.is8Bit()) {
while (true) {
int* ovector;
@@ -599,13 +609,13 @@
cachedCall.setThis(jsUndefined());
if (UNLIKELY(cachedCall.hasOverflowedArguments())) {
throwOutOfMemoryError(exec, scope);
- return encodedJSValue();
+ return nullptr;
}
JSValue jsResult = cachedCall.call();
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ RETURN_IF_EXCEPTION(scope, nullptr);
replacements.append(jsResult.toWTFString(exec));
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ RETURN_IF_EXCEPTION(scope, nullptr);
lastIndex = result.end;
startPosition = lastIndex;
@@ -665,13 +675,13 @@
cachedCall.setThis(jsUndefined());
if (UNLIKELY(cachedCall.hasOverflowedArguments())) {
throwOutOfMemoryError(exec, scope);
- return encodedJSValue();
+ return nullptr;
}
JSValue jsResult = cachedCall.call();
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ RETURN_IF_EXCEPTION(scope, nullptr);
replacements.append(jsResult.toWTFString(exec));
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ RETURN_IF_EXCEPTION(scope, nullptr);
lastIndex = result.end;
startPosition = lastIndex;
@@ -730,15 +740,15 @@
args.append(groups);
if (UNLIKELY(args.hasOverflowed())) {
throwOutOfMemoryError(exec, scope);
- return encodedJSValue();
+ return nullptr;
}
JSValue replacement = call(exec, replaceValue, callType, callData, jsUndefined(), args);
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ RETURN_IF_EXCEPTION(scope, nullptr);
String replacementString = replacement.toWTFString(exec);
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ RETURN_IF_EXCEPTION(scope, nullptr);
replacements.append(replacementString);
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ RETURN_IF_EXCEPTION(scope, nullptr);
} else {
int replLen = replacementString.length();
if (lastIndex < result.start || replLen) {
@@ -765,7 +775,7 @@
}
if (!lastIndex && replacements.isEmpty())
- return JSValue::encode(string);
+ return string;
if (static_cast<unsigned>(lastIndex) < sourceLen) {
if (UNLIKELY(!sourceRanges.tryConstructAndAppend(lastIndex, sourceLen - lastIndex)))
@@ -772,10 +782,10 @@
OUT_OF_MEMORY(exec, scope);
}
scope.release();
- return JSValue::encode(jsSpliceSubstringsWithSeparators(exec, string, source, sourceRanges.data(), sourceRanges.size(), replacements.data(), replacements.size()));
+ return jsSpliceSubstringsWithSeparators(exec, string, source, sourceRanges.data(), sourceRanges.size(), replacements.data(), replacements.size());
}
-EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceRegExpEmptyStr(
+JSCell* JIT_OPERATION operationStringProtoFuncReplaceRegExpEmptyStr(
ExecState* exec, JSString* thisValue, RegExpObject* searchValue)
{
VM& vm = exec->vm();
@@ -786,7 +796,7 @@
if (regExp->global()) {
// ES5.1 15.5.4.10 step 8.a.
searchValue->setLastIndex(exec, 0);
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ RETURN_IF_EXCEPTION(scope, nullptr);
scope.release();
return removeUsingRegExpSearch(vm, exec, thisValue, thisValue->value(exec), regExp);
}
@@ -798,7 +808,7 @@
vm, exec, thisValue, searchValue, callData, CallType::None, replacementString, JSValue());
}
-EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceRegExpString(
+JSCell* JIT_OPERATION operationStringProtoFuncReplaceRegExpString(
ExecState* exec, JSString* thisValue, RegExpObject* searchValue, JSString* replaceString)
{
VM& vm = exec->vm();
@@ -810,7 +820,7 @@
vm, exec, thisValue, searchValue, callData, CallType::None, replacementString, replaceString);
}
-static ALWAYS_INLINE EncodedJSValue replaceUsingRegExpSearch(VM& vm, ExecState* exec, JSString* string, JSValue searchValue, JSValue replaceValue)
+static ALWAYS_INLINE JSString* replaceUsingRegExpSearch(VM& vm, ExecState* exec, JSString* string, JSValue searchValue, JSValue replaceValue)
{
auto scope = DECLARE_THROW_SCOPE(vm);
@@ -819,7 +829,7 @@
CallType callType = getCallData(replaceValue, callData);
if (callType == CallType::None) {
replacementString = replaceValue.toWTFString(exec);
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ RETURN_IF_EXCEPTION(scope, nullptr);
}
scope.release();
@@ -827,19 +837,19 @@
vm, exec, string, searchValue, callData, callType, replacementString, replaceValue);
}
-static ALWAYS_INLINE EncodedJSValue replaceUsingStringSearch(VM& vm, ExecState* exec, JSString* jsString, JSValue searchValue, JSValue replaceValue)
+static ALWAYS_INLINE JSString* replaceUsingStringSearch(VM& vm, ExecState* exec, JSString* jsString, JSValue searchValue, JSValue replaceValue)
{
auto scope = DECLARE_THROW_SCOPE(vm);
const String& string = jsString->value(exec);
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ RETURN_IF_EXCEPTION(scope, nullptr);
String searchString = searchValue.toWTFString(exec);
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ RETURN_IF_EXCEPTION(scope, nullptr);
size_t matchStart = string.find(searchString);
if (matchStart == notFound)
- return JSValue::encode(jsString);
+ return jsString;
CallData callData;
CallType callType = getCallData(replaceValue, callData);
@@ -850,11 +860,11 @@
args.append(jsString);
ASSERT(!args.hasOverflowed());
replaceValue = call(exec, replaceValue, callType, callData, jsUndefined(), args);
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ RETURN_IF_EXCEPTION(scope, nullptr);
}
String replaceString = replaceValue.toWTFString(exec);
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ RETURN_IF_EXCEPTION(scope, nullptr);
StringImpl* stringImpl = string.impl();
String leftPart(StringImpl::createSubstringSharingImpl(*stringImpl, 0, matchStart));
@@ -866,7 +876,7 @@
size_t leftLength = stringImpl->length() - matchEnd;
String rightPart(StringImpl::createSubstringSharingImpl(*stringImpl, matchEnd, leftLength));
scope.release();
- return JSValue::encode(JSC::jsString(exec, leftPart, middlePart, rightPart));
+ return JSC::jsString(exec, leftPart, middlePart, rightPart);
}
static inline bool checkObjectCoercible(JSValue thisValue)
@@ -936,7 +946,7 @@
return JSValue::encode(repeatCharacter(*exec, character, repeatCount));
}
-ALWAYS_INLINE EncodedJSValue replace(
+ALWAYS_INLINE JSString* replace(
VM& vm, ExecState* exec, JSString* string, JSValue searchValue, JSValue replaceValue)
{
if (searchValue.inherits(vm, RegExpObject::info()))
@@ -944,15 +954,17 @@
return replaceUsingStringSearch(vm, exec, string, searchValue, replaceValue);
}
-ALWAYS_INLINE EncodedJSValue replace(
+ALWAYS_INLINE JSString* replace(
VM& vm, ExecState* exec, JSValue thisValue, JSValue searchValue, JSValue replaceValue)
{
auto scope = DECLARE_THROW_SCOPE(vm);
- if (!checkObjectCoercible(thisValue))
- return throwVMTypeError(exec, scope);
+ if (!checkObjectCoercible(thisValue)) {
+ throwVMTypeError(exec, scope);
+ return nullptr;
+ }
JSString* string = thisValue.toString(exec);
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ RETURN_IF_EXCEPTION(scope, nullptr);
scope.release();
return replace(vm, exec, string, searchValue, replaceValue);
}
@@ -970,7 +982,7 @@
return JSValue::encode(jsUndefined());
scope.release();
- return replaceUsingRegExpSearch(vm, exec, string, searchValue, exec->argument(1));
+ return JSValue::encode(replaceUsingRegExpSearch(vm, exec, string, searchValue, exec->argument(1)));
}
EncodedJSValue JSC_HOST_CALL stringProtoFuncReplaceUsingStringSearch(ExecState* exec)
@@ -982,10 +994,10 @@
RETURN_IF_EXCEPTION(scope, encodedJSValue());
scope.release();
- return replaceUsingStringSearch(vm, exec, string, exec->argument(0), exec->argument(1));
+ return JSValue::encode(replaceUsingStringSearch(vm, exec, string, exec->argument(0), exec->argument(1)));
}
-EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceGeneric(
+JSCell* JIT_OPERATION operationStringProtoFuncReplaceGeneric(
ExecState* exec, EncodedJSValue thisValue, EncodedJSValue searchValue,
EncodedJSValue replaceValue)
{
Modified: trunk/Source/_javascript_Core/runtime/StringPrototype.h (226268 => 226269)
--- trunk/Source/_javascript_Core/runtime/StringPrototype.h 2017-12-22 18:12:53 UTC (rev 226268)
+++ trunk/Source/_javascript_Core/runtime/StringPrototype.h 2017-12-22 19:51:03 UTC (rev 226269)
@@ -50,13 +50,13 @@
void finishCreation(VM&, JSGlobalObject*, JSString*);
};
-EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceGeneric(
+JSCell* JIT_OPERATION operationStringProtoFuncReplaceGeneric(
ExecState*, EncodedJSValue thisValue, EncodedJSValue searchValue, EncodedJSValue replaceValue);
-EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceRegExpEmptyStr(
+JSCell* JIT_OPERATION operationStringProtoFuncReplaceRegExpEmptyStr(
ExecState*, JSString* thisValue, RegExpObject* searchValue);
-EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceRegExpString(
+JSCell* JIT_OPERATION operationStringProtoFuncReplaceRegExpString(
ExecState*, JSString* thisValue, RegExpObject* searchValue, JSString* replaceValue);
String substituteBackreferences(const String& replacement, StringView source, const int* ovector, RegExp* reg);