Diff
Modified: trunk/JSTests/ChangeLog (260489 => 260490)
--- trunk/JSTests/ChangeLog 2020-04-22 02:35:57 UTC (rev 260489)
+++ trunk/JSTests/ChangeLog 2020-04-22 02:54:28 UTC (rev 260490)
@@ -1,3 +1,15 @@
+2020-04-21 Yusuke Suzuki <[email protected]>
+
+ [JSC] SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq should expect AnyBigIntUse
+ https://bugs.webkit.org/show_bug.cgi?id=210832
+
+ Reviewed by Mark Lam.
+
+ * stress/heap-and-32-bigint-eq.js: Added.
+ (shouldBe):
+ * stress/heap-and-32-bigint-stricteq.js: Added.
+ (shouldBe):
+
2020-04-21 Alexey Shvayka <[email protected]>
constructObjectFromPropertyDescriptor() is incorrect with partial descriptors
Added: trunk/JSTests/stress/heap-and-32-bigint-eq.js (0 => 260490)
--- trunk/JSTests/stress/heap-and-32-bigint-eq.js (rev 0)
+++ trunk/JSTests/stress/heap-and-32-bigint-eq.js 2020-04-22 02:54:28 UTC (rev 260490)
@@ -0,0 +1,12 @@
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+if (typeof createBigInt32 !== 'undefined') {
+ for (var i = -100000; i < 100000; ++i) {
+ var bigInt32 = createBigInt32(String(i));
+ var heapBigInt = createHeapBigInt(String(i));
+ shouldBe(bigInt32 == heapBigInt, true);
+ }
+}
Added: trunk/JSTests/stress/heap-and-32-bigint-stricteq.js (0 => 260490)
--- trunk/JSTests/stress/heap-and-32-bigint-stricteq.js (rev 0)
+++ trunk/JSTests/stress/heap-and-32-bigint-stricteq.js 2020-04-22 02:54:28 UTC (rev 260490)
@@ -0,0 +1,12 @@
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+if (typeof createBigInt32 !== 'undefined') {
+ for (var i = -100000; i < 100000; ++i) {
+ var bigInt32 = createBigInt32(String(i));
+ var heapBigInt = createHeapBigInt(String(i));
+ shouldBe(bigInt32 === heapBigInt, true);
+ }
+}
Modified: trunk/Source/_javascript_Core/ChangeLog (260489 => 260490)
--- trunk/Source/_javascript_Core/ChangeLog 2020-04-22 02:35:57 UTC (rev 260489)
+++ trunk/Source/_javascript_Core/ChangeLog 2020-04-22 02:54:28 UTC (rev 260490)
@@ -1,5 +1,29 @@
2020-04-21 Yusuke Suzuki <[email protected]>
+ [JSC] SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq should expect AnyBigIntUse
+ https://bugs.webkit.org/show_bug.cgi?id=210832
+
+ Reviewed by Mark Lam.
+
+ SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq will get AnyBigIntUse now. We should use ManualOperandSpeculation
+ and speculate function to perform speculation check.
+
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq):
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq):
+ * jsc.cpp:
+ (functionCreateHeapBigInt):
+ (functionCreateBigInt32):
+ * runtime/BigIntConstructor.cpp:
+ (JSC::toBigInt):
+ (JSC::callBigIntConstructor):
+ * runtime/BigIntConstructor.h:
+ * runtime/JSBigInt.h:
+
+2020-04-21 Yusuke Suzuki <[email protected]>
+
Canonicalize JSBigInt generated by structured-cloning by calling rightTrim
https://bugs.webkit.org/show_bug.cgi?id=210816
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (260489 => 260490)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2020-04-22 02:35:57 UTC (rev 260489)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2020-04-22 02:54:28 UTC (rev 260490)
@@ -1184,7 +1184,7 @@
cellResult(resultGPR, node);
}
-bool SpeculativeJIT::nonSpeculativeStrictEq(Node* node, bool invert)
+bool SpeculativeJIT::genericJSValueStrictEq(Node* node, bool invert)
{
unsigned branchIndexInBlock = detectPeepHoleBranch();
if (branchIndexInBlock != UINT_MAX) {
@@ -1200,7 +1200,7 @@
return true;
}
- nonSpeculativeNonPeepholeStrictEq(node, invert);
+ genericJSValueNonPeepholeStrictEq(node, invert);
return false;
}
@@ -6522,7 +6522,7 @@
}
ASSERT(node->isBinaryUseKind(UntypedUse) || node->isBinaryUseKind(AnyBigIntUse));
- return nonSpeculativeStrictEq(node);
+ return genericJSValueStrictEq(node);
}
void SpeculativeJIT::compileBooleanCompare(Node* node, MacroAssembler::RelationalCondition condition)
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (260489 => 260490)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2020-04-22 02:35:57 UTC (rev 260489)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2020-04-22 02:54:28 UTC (rev 260490)
@@ -746,8 +746,8 @@
void nonSpeculativeNonPeepholeCompare(Node*, MacroAssembler::RelationalCondition, S_JITOperation_GJJ helperFunction);
void nonSpeculativePeepholeStrictEq(Node*, Node* branchNode, bool invert = false);
- void nonSpeculativeNonPeepholeStrictEq(Node*, bool invert = false);
- bool nonSpeculativeStrictEq(Node*, bool invert = false);
+ void genericJSValueNonPeepholeStrictEq(Node*, bool invert = false);
+ bool genericJSValueStrictEq(Node*, bool invert = false);
void compileInstanceOfForCells(Node*, JSValueRegs valueGPR, JSValueRegs prototypeGPR, GPRReg resultGPT, GPRReg scratchGPR, GPRReg scratch2GPR, JITCompiler::Jump slowCase = JITCompiler::Jump());
void compileInstanceOf(Node*);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (260489 => 260490)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2020-04-22 02:35:57 UTC (rev 260489)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2020-04-22 02:54:28 UTC (rev 260490)
@@ -397,8 +397,10 @@
notTaken = tmp;
}
- JSValueOperand arg1(this, node->child1());
- JSValueOperand arg2(this, node->child2());
+ JSValueOperand arg1(this, node->child1(), ManualOperandSpeculation);
+ JSValueOperand arg2(this, node->child2(), ManualOperandSpeculation);
+ speculate(node, node->child1());
+ speculate(node, node->child2());
GPRReg arg1PayloadGPR = arg1.payloadGPR();
GPRReg arg2PayloadGPR = arg2.payloadGPR();
JSValueRegs arg1Regs = arg1.jsValueRegs();
@@ -435,10 +437,12 @@
jump(notTaken);
}
-void SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq(Node* node, bool invert)
+void SpeculativeJIT::genericJSValueNonPeepholeStrictEq(Node* node, bool invert)
{
- JSValueOperand arg1(this, node->child1());
- JSValueOperand arg2(this, node->child2());
+ JSValueOperand arg1(this, node->child1(), ManualOperandSpeculation);
+ JSValueOperand arg2(this, node->child2(), ManualOperandSpeculation);
+ speculate(node, node->child1());
+ speculate(node, node->child2());
GPRReg arg1PayloadGPR = arg1.payloadGPR();
GPRReg arg2PayloadGPR = arg2.payloadGPR();
JSValueRegs arg1Regs = arg1.jsValueRegs();
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (260489 => 260490)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2020-04-22 02:35:57 UTC (rev 260489)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2020-04-22 02:54:28 UTC (rev 260490)
@@ -419,11 +419,13 @@
jump(notTaken);
}
-void SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq(Node* node, bool invert)
+void SpeculativeJIT::genericJSValueNonPeepholeStrictEq(Node* node, bool invert)
{
// FIXME: some of this code should be shareable with nonSpeculativePeepholeStrictEq
- JSValueOperand arg1(this, node->child1());
- JSValueOperand arg2(this, node->child2());
+ JSValueOperand arg1(this, node->child1(), ManualOperandSpeculation);
+ JSValueOperand arg2(this, node->child2(), ManualOperandSpeculation);
+ speculate(node, node->child1());
+ speculate(node, node->child2());
JSValueRegs arg1Regs = arg1.jsValueRegs();
JSValueRegs arg2Regs = arg2.jsValueRegs();
GPRReg arg1GPR = arg1.gpr();
Modified: trunk/Source/_javascript_Core/jsc.cpp (260489 => 260490)
--- trunk/Source/_javascript_Core/jsc.cpp 2020-04-22 02:35:57 UTC (rev 260489)
+++ trunk/Source/_javascript_Core/jsc.cpp 2020-04-22 02:54:28 UTC (rev 260490)
@@ -24,6 +24,7 @@
#include "ArrayBuffer.h"
#include "ArrayPrototype.h"
+#include "BigIntConstructor.h"
#include "BuiltinNames.h"
#include "ButterflyInlines.h"
#include "BytecodeCacheError.h"
@@ -270,6 +271,8 @@
static EncodedJSValue JSC_HOST_CALL functionCreateGlobalObject(JSGlobalObject*, CallFrame*);
+static EncodedJSValue JSC_HOST_CALL functionCreateHeapBigInt(JSGlobalObject*, CallFrame*);
+static EncodedJSValue JSC_HOST_CALL functionCreateBigInt32(JSGlobalObject*, CallFrame*);
static EncodedJSValue JSC_HOST_CALL functionPrintStdOut(JSGlobalObject*, CallFrame*);
static EncodedJSValue JSC_HOST_CALL functionPrintStdErr(JSGlobalObject*, CallFrame*);
@@ -541,6 +544,10 @@
addFunction(vm, "hasCustomProperties", functionHasCustomProperties, 0);
addFunction(vm, "createGlobalObject", functionCreateGlobalObject, 0);
+ addFunction(vm, "createHeapBigInt", functionCreateHeapBigInt, 1);
+#if USE(BIGINT32)
+ addFunction(vm, "createBigInt32", functionCreateBigInt32, 1);
+#endif
addFunction(vm, "dumpTypesForAllVariables", functionDumpTypesForAllVariables , 0);
@@ -2244,6 +2251,53 @@
return JSValue::encode(GlobalObject::create(vm, GlobalObject::createStructure(vm, jsNull()), Vector<String>()));
}
+EncodedJSValue JSC_HOST_CALL functionCreateHeapBigInt(JSGlobalObject* globalObject, CallFrame* callFrame)
+{
+ VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ JSValue argument = callFrame->argument(0);
+ JSValue bigInt = toBigInt(globalObject, argument);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+#if USE(BIGINT32)
+ if (bigInt.isHeapBigInt())
+ return JSValue::encode(bigInt);
+ ASSERT(bigInt.isBigInt32());
+ int32_t value = bigInt.bigInt32AsInt32();
+ return JSValue::encode(JSBigInt::createFrom(vm, value));
+#else
+ return JSValue::encode(bigInt);
+#endif
+}
+
+#if USE(BIGINT32)
+EncodedJSValue JSC_HOST_CALL functionCreateBigInt32(JSGlobalObject* globalObject, CallFrame* callFrame)
+{
+ VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ JSValue argument = callFrame->argument(0);
+ JSValue bigIntValue = toBigInt(globalObject, argument);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ if (bigIntValue.isBigInt32())
+ return JSValue::encode(bigIntValue);
+ ASSERT(bigIntValue.isHeapBigInt());
+ JSBigInt* bigInt = jsCast<JSBigInt*>(bigIntValue);
+ if (!bigInt->length())
+ return JSValue::encode(JSValue(JSValue::JSBigInt32, 0));
+ if (bigInt->length() == 1) {
+ JSBigInt::Digit digit = bigInt->digit(0);
+ if (bigInt->sign()) {
+ if (digit <= static_cast<uint64_t>(-static_cast<int64_t>(INT32_MIN)))
+ return JSValue::encode(JSValue(JSValue::JSBigInt32, static_cast<int32_t>(-static_cast<int64_t>(digit))));
+ } else {
+ if (digit <= INT32_MAX)
+ return JSValue::encode(JSValue(JSValue::JSBigInt32, static_cast<int32_t>(digit)));
+ }
+ }
+ throwTypeError(globalObject, scope, "Out of range of BigInt32"_s);
+ return { };
+}
+#endif
+
EncodedJSValue JSC_HOST_CALL functionCheckModuleSyntax(JSGlobalObject* globalObject, CallFrame* callFrame)
{
VM& vm = globalObject->vm();
Modified: trunk/Source/_javascript_Core/runtime/BigIntConstructor.cpp (260489 => 260490)
--- trunk/Source/_javascript_Core/runtime/BigIntConstructor.cpp 2020-04-22 02:35:57 UTC (rev 260489)
+++ trunk/Source/_javascript_Core/runtime/BigIntConstructor.cpp 2020-04-22 02:54:28 UTC (rev 260490)
@@ -75,31 +75,33 @@
// ------------------------------ Functions ---------------------------
-static EncodedJSValue toBigInt(JSGlobalObject* globalObject, JSValue argument)
+JSValue toBigInt(JSGlobalObject* globalObject, JSValue argument)
{
ASSERT(argument.isPrimitive());
VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
if (argument.isBigInt())
- return JSValue::encode(argument);
+ return argument;
if (argument.isBoolean()) {
#if USE(BIGINT32)
- return JSValue::encode(JSValue(JSValue::JSBigInt32, argument.asBoolean()));
+ return JSValue(JSValue::JSBigInt32, argument.asBoolean());
#else
- return JSValue::encode(JSBigInt::createFrom(vm, argument.asBoolean()));
+ return JSBigInt::createFrom(vm, argument.asBoolean());
#endif
}
if (argument.isString()) {
+ scope.release();
return toStringView(globalObject, argument, [&] (StringView view) {
- return JSValue::encode(JSBigInt::parseInt(globalObject, view));
+ return JSBigInt::parseInt(globalObject, view);
});
}
ASSERT(argument.isUndefinedOrNull() || argument.isNumber() || argument.isSymbol());
- auto scope = DECLARE_THROW_SCOPE(vm);
- return throwVMTypeError(globalObject, scope, "Invalid argument type in ToBigInt operation"_s);
+ throwTypeError(globalObject, scope, "Invalid argument type in ToBigInt operation"_s);
+ return jsUndefined();
}
static EncodedJSValue JSC_HOST_CALL callBigIntConstructor(JSGlobalObject* globalObject, CallFrame* callFrame)
@@ -129,9 +131,7 @@
return JSValue::encode(JSBigInt::makeHeapBigIntOrBigInt32(vm, static_cast<int64_t>(primitive.asDouble())));
}
- EncodedJSValue result = toBigInt(globalObject, primitive);
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
- return result;
+ RELEASE_AND_RETURN(scope, JSValue::encode(toBigInt(globalObject, primitive)));
}
EncodedJSValue JSC_HOST_CALL bigIntConstructorFuncAsUintN(JSGlobalObject*, CallFrame*)
Modified: trunk/Source/_javascript_Core/runtime/BigIntConstructor.h (260489 => 260490)
--- trunk/Source/_javascript_Core/runtime/BigIntConstructor.h 2020-04-22 02:35:57 UTC (rev 260489)
+++ trunk/Source/_javascript_Core/runtime/BigIntConstructor.h 2020-04-22 02:54:28 UTC (rev 260490)
@@ -58,4 +58,6 @@
};
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(BigIntConstructor, InternalFunction);
+JS_EXPORT_PRIVATE JSValue toBigInt(JSGlobalObject*, JSValue);
+
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/JSBigInt.h (260489 => 260490)
--- trunk/Source/_javascript_Core/runtime/JSBigInt.h 2020-04-22 02:35:57 UTC (rev 260489)
+++ trunk/Source/_javascript_Core/runtime/JSBigInt.h 2020-04-22 02:54:28 UTC (rev 260490)
@@ -63,7 +63,7 @@
JS_EXPORT_PRIVATE static JSBigInt* tryCreateWithLength(JSGlobalObject*, unsigned length);
static JSBigInt* createWithLengthUnchecked(VM&, unsigned length);
- static JSBigInt* createFrom(VM&, int32_t value);
+ JS_EXPORT_PRIVATE static JSBigInt* createFrom(VM&, int32_t value);
static JSBigInt* createFrom(VM&, uint32_t value);
static JSBigInt* createFrom(VM&, int64_t value);
static JSBigInt* createFrom(VM&, bool value);