зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to mozilla-central. a=merge
This commit is contained in:
Коммит
2a6f3dde00
|
@ -2425,7 +2425,6 @@ struct StackMapGenerator {
|
|||
class BaseCompiler final : public BaseCompilerInterface {
|
||||
using Local = BaseStackFrame::Local;
|
||||
using LabelVector = Vector<NonAssertingLabel, 8, SystemAllocPolicy>;
|
||||
using MIRTypeVector = Vector<MIRType, 8, SystemAllocPolicy>;
|
||||
|
||||
// Bit set used for simple bounds check elimination. Capping this at 64
|
||||
// locals makes sense; even 32 locals would probably be OK in practice.
|
||||
|
@ -2546,17 +2545,6 @@ class BaseCompiler final : public BaseCompilerInterface {
|
|||
bceSafe_; // Locals that have been bounds checked and not updated since
|
||||
ValTypeVector SigD_;
|
||||
ValTypeVector SigF_;
|
||||
MIRTypeVector SigP_;
|
||||
MIRTypeVector SigPI_;
|
||||
MIRTypeVector SigPL_;
|
||||
MIRTypeVector SigPII_;
|
||||
MIRTypeVector SigPIRI_;
|
||||
MIRTypeVector SigPIII_;
|
||||
MIRTypeVector SigPIIL_;
|
||||
MIRTypeVector SigPIIR_;
|
||||
MIRTypeVector SigPILL_;
|
||||
MIRTypeVector SigPIIII_;
|
||||
MIRTypeVector SigPIIIII_;
|
||||
NonAssertingLabel returnLabel_;
|
||||
|
||||
LatentOp latentOp_; // Latent operation for branch (seen next)
|
||||
|
@ -6478,19 +6466,13 @@ class BaseCompiler final : public BaseCompilerInterface {
|
|||
// postbarrier call is active, so push a uintptr_t value.
|
||||
#ifdef JS_64BIT
|
||||
pushI64(RegI64(Register64(valueAddr)));
|
||||
if (!emitInstanceCall(bytecodeOffset, SigPL_, ExprType::Void,
|
||||
SymbolicAddress::PostBarrier,
|
||||
/*pushReturnedValue=*/false)) {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
pushI32(RegI32(valueAddr));
|
||||
if (!emitInstanceCall(bytecodeOffset, SigPI_, ExprType::Void,
|
||||
SymbolicAddress::PostBarrier,
|
||||
#endif
|
||||
if (!emitInstanceCall(bytecodeOffset, SASigPostBarrier,
|
||||
/*pushReturnedValue=*/false)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -6708,6 +6690,7 @@ class BaseCompiler final : public BaseCompilerInterface {
|
|||
|
||||
void doReturn(ExprType returnType, bool popStack);
|
||||
void pushReturnValueOfCall(const FunctionCall& call, ExprType type);
|
||||
void pushReturnValueOfCall(const FunctionCall& call, MIRType type);
|
||||
|
||||
void emitCompareI32(Assembler::Condition compareOp, ValType compareType);
|
||||
void emitCompareI64(Assembler::Condition compareOp, ValType compareType);
|
||||
|
@ -6824,8 +6807,7 @@ class BaseCompiler final : public BaseCompilerInterface {
|
|||
void emitReinterpretI64AsF64();
|
||||
void emitRound(RoundingMode roundingMode, ValType operandType);
|
||||
MOZ_MUST_USE bool emitInstanceCall(uint32_t lineOrBytecode,
|
||||
const MIRTypeVector& sig, ExprType retType,
|
||||
SymbolicAddress builtin,
|
||||
const SymbolicAddressSignature& builtin,
|
||||
bool pushReturnedValue = true);
|
||||
MOZ_MUST_USE bool emitMemoryGrow();
|
||||
MOZ_MUST_USE bool emitMemorySize();
|
||||
|
@ -8587,43 +8569,46 @@ bool BaseCompiler::emitCallArgs(const ValTypeVector& argTypes,
|
|||
}
|
||||
|
||||
void BaseCompiler::pushReturnValueOfCall(const FunctionCall& call,
|
||||
ExprType type) {
|
||||
switch (type.code()) {
|
||||
case ExprType::I32: {
|
||||
MIRType type) {
|
||||
switch (type) {
|
||||
case MIRType::Int32: {
|
||||
RegI32 rv = captureReturnedI32();
|
||||
pushI32(rv);
|
||||
break;
|
||||
}
|
||||
case ExprType::I64: {
|
||||
case MIRType::Int64: {
|
||||
RegI64 rv = captureReturnedI64();
|
||||
pushI64(rv);
|
||||
break;
|
||||
}
|
||||
case ExprType::F32: {
|
||||
case MIRType::Float32: {
|
||||
RegF32 rv = captureReturnedF32(call);
|
||||
pushF32(rv);
|
||||
break;
|
||||
}
|
||||
case ExprType::F64: {
|
||||
case MIRType::Double: {
|
||||
RegF64 rv = captureReturnedF64(call);
|
||||
pushF64(rv);
|
||||
break;
|
||||
}
|
||||
case ExprType::Ref:
|
||||
case ExprType::AnyRef: {
|
||||
case MIRType::RefOrNull: {
|
||||
RegPtr rv = captureReturnedRef();
|
||||
pushRef(rv);
|
||||
break;
|
||||
}
|
||||
case ExprType::NullRef:
|
||||
MOZ_CRASH("NullRef not expressible");
|
||||
default:
|
||||
// In particular, passing |type| == ExprType::Void to this function is
|
||||
// an error.
|
||||
// In particular, passing |type| as MIRType::Void or MIRType::Pointer to
|
||||
// this function is an error.
|
||||
MOZ_CRASH("Function return type");
|
||||
}
|
||||
}
|
||||
|
||||
void BaseCompiler::pushReturnValueOfCall(const FunctionCall& call,
|
||||
ExprType type) {
|
||||
MOZ_ASSERT(type.code() != ExprType::NullRef);
|
||||
pushReturnValueOfCall(call, ToMIRType(type));
|
||||
}
|
||||
|
||||
// For now, always sync() at the beginning of the call to easily save live
|
||||
// values.
|
||||
//
|
||||
|
@ -9730,25 +9715,25 @@ void BaseCompiler::emitCompareRef(Assembler::Condition compareOp,
|
|||
}
|
||||
|
||||
bool BaseCompiler::emitInstanceCall(uint32_t lineOrBytecode,
|
||||
const MIRTypeVector& sig, ExprType retType,
|
||||
SymbolicAddress builtin,
|
||||
const SymbolicAddressSignature& builtin,
|
||||
bool pushReturnedValue /*=true*/) {
|
||||
MOZ_ASSERT(sig[0] == MIRType::Pointer);
|
||||
const MIRType* argTypes = builtin.argTypes;
|
||||
MOZ_ASSERT(argTypes[0] == MIRType::Pointer);
|
||||
|
||||
sync();
|
||||
|
||||
uint32_t numArgs = sig.length() - 1 /* instance */;
|
||||
size_t stackSpace = stackConsumed(numArgs);
|
||||
uint32_t numNonInstanceArgs = builtin.numArgs - 1 /* instance */;
|
||||
size_t stackSpace = stackConsumed(numNonInstanceArgs);
|
||||
|
||||
FunctionCall baselineCall(lineOrBytecode);
|
||||
beginCall(baselineCall, UseABI::System, InterModule::True);
|
||||
|
||||
ABIArg instanceArg = reservePointerArgument(&baselineCall);
|
||||
|
||||
startCallArgs(StackArgAreaSizeUnaligned(sig), &baselineCall);
|
||||
for (uint32_t i = 1; i < sig.length(); i++) {
|
||||
startCallArgs(StackArgAreaSizeUnaligned(builtin), &baselineCall);
|
||||
for (uint32_t i = 1; i < builtin.numArgs; i++) {
|
||||
ValType t;
|
||||
switch (sig[i]) {
|
||||
switch (argTypes[i]) {
|
||||
case MIRType::Int32:
|
||||
t = ValType::I32;
|
||||
break;
|
||||
|
@ -9758,34 +9743,39 @@ bool BaseCompiler::emitInstanceCall(uint32_t lineOrBytecode,
|
|||
case MIRType::RefOrNull:
|
||||
t = ValType::AnyRef;
|
||||
break;
|
||||
case MIRType::Pointer:
|
||||
// Instance function args can now be uninterpreted pointers (eg, for
|
||||
// the cases PostBarrier and PostBarrierFilter) so we simply treat
|
||||
// them like the equivalently sized integer.
|
||||
t = sizeof(void*) == 4 ? ValType::I32 : ValType::I64;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unexpected type");
|
||||
}
|
||||
passArg(t, peek(numArgs - i), &baselineCall);
|
||||
passArg(t, peek(numNonInstanceArgs - i), &baselineCall);
|
||||
}
|
||||
CodeOffset raOffset =
|
||||
builtinInstanceMethodCall(builtin, instanceArg, baselineCall);
|
||||
builtinInstanceMethodCall(builtin.identity, instanceArg, baselineCall);
|
||||
if (!createStackMap("emitInstanceCall", raOffset)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
endCall(baselineCall, stackSpace);
|
||||
|
||||
popValueStackBy(numArgs);
|
||||
popValueStackBy(numNonInstanceArgs);
|
||||
|
||||
// Note, many clients of emitInstanceCall currently assume that pushing the
|
||||
// result here does not destroy ReturnReg.
|
||||
//
|
||||
// Furthermore, clients assume that even if retType == ExprType::Void, the
|
||||
// callee may have returned a status result and left it in ReturnReg for us
|
||||
// to find, and that that register will not be destroyed here (or above).
|
||||
// In this case the callee will have a C++ declaration stating that there is
|
||||
// a return value. Examples include memory and table operations that are
|
||||
// implemented as callouts.
|
||||
// Furthermore, clients assume that if builtin.retType != MIRType::None, the
|
||||
// callee will have returned a result and left it in ReturnReg for us to
|
||||
// find, and that that register will not be destroyed here (or above).
|
||||
|
||||
if (pushReturnedValue) {
|
||||
MOZ_ASSERT(retType != ExprType::Void);
|
||||
pushReturnValueOfCall(baselineCall, retType);
|
||||
// For the return type only, MIRType::None is used to indicate that the
|
||||
// call doesn't return a result, that is, returns a C/C++ "void".
|
||||
MOZ_ASSERT(builtin.retType != MIRType::None);
|
||||
pushReturnValueOfCall(baselineCall, builtin.retType);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -9802,8 +9792,7 @@ bool BaseCompiler::emitMemoryGrow() {
|
|||
return true;
|
||||
}
|
||||
|
||||
return emitInstanceCall(lineOrBytecode, SigPI_, ExprType::I32,
|
||||
SymbolicAddress::MemoryGrow);
|
||||
return emitInstanceCall(lineOrBytecode, SASigMemoryGrow);
|
||||
}
|
||||
|
||||
bool BaseCompiler::emitMemorySize() {
|
||||
|
@ -9817,8 +9806,7 @@ bool BaseCompiler::emitMemorySize() {
|
|||
return true;
|
||||
}
|
||||
|
||||
return emitInstanceCall(lineOrBytecode, SigP_, ExprType::I32,
|
||||
SymbolicAddress::MemorySize);
|
||||
return emitInstanceCall(lineOrBytecode, SASigMemorySize);
|
||||
}
|
||||
|
||||
bool BaseCompiler::emitRefNull() {
|
||||
|
@ -10132,14 +10120,12 @@ bool BaseCompiler::emitWait(ValType type, uint32_t byteSize) {
|
|||
// Returns -1 on trap, otherwise nonnegative result.
|
||||
switch (type.code()) {
|
||||
case ValType::I32:
|
||||
if (!emitInstanceCall(lineOrBytecode, SigPIIL_, ExprType::I32,
|
||||
SymbolicAddress::WaitI32)) {
|
||||
if (!emitInstanceCall(lineOrBytecode, SASigWaitI32)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case ValType::I64:
|
||||
if (!emitInstanceCall(lineOrBytecode, SigPILL_, ExprType::I32,
|
||||
SymbolicAddress::WaitI64)) {
|
||||
if (!emitInstanceCall(lineOrBytecode, SASigWaitI64)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
@ -10169,8 +10155,7 @@ bool BaseCompiler::emitWake() {
|
|||
}
|
||||
|
||||
// Returns -1 on trap, otherwise nonnegative result.
|
||||
if (!emitInstanceCall(lineOrBytecode, SigPII_, ExprType::I32,
|
||||
SymbolicAddress::Wake)) {
|
||||
if (!emitInstanceCall(lineOrBytecode, SASigWake)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -10202,16 +10187,14 @@ bool BaseCompiler::emitMemOrTableCopy(bool isMem) {
|
|||
if (isMem) {
|
||||
MOZ_ASSERT(srcMemOrTableIndex == 0);
|
||||
MOZ_ASSERT(dstMemOrTableIndex == 0);
|
||||
if (!emitInstanceCall(lineOrBytecode, SigPIII_, ExprType::I32,
|
||||
SymbolicAddress::MemCopy,
|
||||
if (!emitInstanceCall(lineOrBytecode, SASigMemCopy,
|
||||
/*pushReturnedValue=*/false)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
pushI32(dstMemOrTableIndex);
|
||||
pushI32(srcMemOrTableIndex);
|
||||
if (!emitInstanceCall(lineOrBytecode, SigPIIIII_, ExprType::I32,
|
||||
SymbolicAddress::TableCopy,
|
||||
if (!emitInstanceCall(lineOrBytecode, SASigTableCopy,
|
||||
/*pushReturnedValue=*/false)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -10241,10 +10224,9 @@ bool BaseCompiler::emitDataOrElemDrop(bool isData) {
|
|||
//
|
||||
// Returns -1 on trap, otherwise 0.
|
||||
pushI32(int32_t(segIndex));
|
||||
SymbolicAddress callee =
|
||||
isData ? SymbolicAddress::DataDrop : SymbolicAddress::ElemDrop;
|
||||
if (!emitInstanceCall(lineOrBytecode, SigPI_, ExprType::Void, callee,
|
||||
/*pushReturnedValue=*/false)) {
|
||||
const SymbolicAddressSignature& callee =
|
||||
isData ? SASigDataDrop : SASigElemDrop;
|
||||
if (!emitInstanceCall(lineOrBytecode, callee, /*pushReturnedValue=*/false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -10269,8 +10251,7 @@ bool BaseCompiler::emitMemFill() {
|
|||
}
|
||||
|
||||
// Returns -1 on trap, otherwise 0.
|
||||
if (!emitInstanceCall(lineOrBytecode, SigPIII_, ExprType::Void,
|
||||
SymbolicAddress::MemFill,
|
||||
if (!emitInstanceCall(lineOrBytecode, SASigMemFill,
|
||||
/*pushReturnedValue=*/false)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -10301,15 +10282,13 @@ bool BaseCompiler::emitMemOrTableInit(bool isMem) {
|
|||
// Returns -1 on trap, otherwise 0.
|
||||
pushI32(int32_t(segIndex));
|
||||
if (isMem) {
|
||||
if (!emitInstanceCall(lineOrBytecode, SigPIIII_, ExprType::Void,
|
||||
SymbolicAddress::MemInit,
|
||||
if (!emitInstanceCall(lineOrBytecode, SASigMemInit,
|
||||
/*pushReturnedValue=*/false)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
pushI32(dstTableIndex);
|
||||
if (!emitInstanceCall(lineOrBytecode, SigPIIIII_, ExprType::Void,
|
||||
SymbolicAddress::TableInit,
|
||||
if (!emitInstanceCall(lineOrBytecode, SASigTableInit,
|
||||
/*pushReturnedValue=*/false)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -10340,16 +10319,23 @@ bool BaseCompiler::emitTableGet() {
|
|||
// Returns nullptr for error, otherwise a pointer to a nonmoveable memory
|
||||
// location that holds the anyref value.
|
||||
pushI32(tableIndex);
|
||||
if (!emitInstanceCall(lineOrBytecode, SigPII_, ExprType::AnyRef,
|
||||
SymbolicAddress::TableGet)) {
|
||||
if (!emitInstanceCall(lineOrBytecode, SASigTableGet,
|
||||
/*pushReturnedValue=*/false)) {
|
||||
return false;
|
||||
}
|
||||
Label noTrap;
|
||||
masm.branchTestPtr(Assembler::NonZero, ReturnReg, ReturnReg, &noTrap);
|
||||
trap(Trap::ThrowReported);
|
||||
masm.bind(&noTrap);
|
||||
|
||||
masm.loadPtr(Address(ReturnReg, 0), ReturnReg);
|
||||
|
||||
// Push the resulting anyref back on the eval stack. NOTE: needRef() must
|
||||
// not kill the value in the register.
|
||||
RegPtr r = RegPtr(ReturnReg);
|
||||
needRef(r);
|
||||
pushRef(r);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -10369,8 +10355,7 @@ bool BaseCompiler::emitTableGrow() {
|
|||
//
|
||||
// infallible.
|
||||
pushI32(tableIndex);
|
||||
return emitInstanceCall(lineOrBytecode, SigPIRI_, ExprType::I32,
|
||||
SymbolicAddress::TableGrow);
|
||||
return emitInstanceCall(lineOrBytecode, SASigTableGrow);
|
||||
}
|
||||
|
||||
MOZ_MUST_USE
|
||||
|
@ -10388,8 +10373,7 @@ bool BaseCompiler::emitTableSet() {
|
|||
//
|
||||
// Returns -1 on range error, otherwise 0 (which is then ignored).
|
||||
pushI32(tableIndex);
|
||||
if (!emitInstanceCall(lineOrBytecode, SigPIRI_, ExprType::I32,
|
||||
SymbolicAddress::TableSet,
|
||||
if (!emitInstanceCall(lineOrBytecode, SASigTableSet,
|
||||
/*pushReturnedValue=*/false)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -10414,8 +10398,7 @@ bool BaseCompiler::emitTableSize() {
|
|||
//
|
||||
// infallible.
|
||||
pushI32(tableIndex);
|
||||
return emitInstanceCall(lineOrBytecode, SigPI_, ExprType::I32,
|
||||
SymbolicAddress::TableSize);
|
||||
return emitInstanceCall(lineOrBytecode, SASigTableSize);
|
||||
}
|
||||
|
||||
bool BaseCompiler::emitStructNew() {
|
||||
|
@ -10439,8 +10422,7 @@ bool BaseCompiler::emitStructNew() {
|
|||
const StructType& structType = env_.types[typeIndex].structType();
|
||||
|
||||
pushI32(structType.moduleIndex_);
|
||||
if (!emitInstanceCall(lineOrBytecode, SigPI_, ExprType::AnyRef,
|
||||
SymbolicAddress::StructNew)) {
|
||||
if (!emitInstanceCall(lineOrBytecode, SASigStructNew)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -10773,8 +10755,7 @@ bool BaseCompiler::emitStructNarrow() {
|
|||
pushI32(mustUnboxAnyref);
|
||||
pushI32(outputStruct.moduleIndex_);
|
||||
pushRef(rp);
|
||||
return emitInstanceCall(lineOrBytecode, SigPIIR_, ExprType::AnyRef,
|
||||
SymbolicAddress::StructNarrow);
|
||||
return emitInstanceCall(lineOrBytecode, SASigStructNarrow);
|
||||
}
|
||||
|
||||
bool BaseCompiler::emitBody() {
|
||||
|
@ -11852,54 +11833,6 @@ bool BaseCompiler::init() {
|
|||
if (!SigF_.append(ValType::F32)) {
|
||||
return false;
|
||||
}
|
||||
if (!SigP_.append(MIRType::Pointer)) {
|
||||
return false;
|
||||
}
|
||||
if (!SigPI_.append(MIRType::Pointer) || !SigPI_.append(MIRType::Int32)) {
|
||||
return false;
|
||||
}
|
||||
if (!SigPL_.append(MIRType::Pointer) || !SigPL_.append(MIRType::Int64)) {
|
||||
return false;
|
||||
}
|
||||
if (!SigPII_.append(MIRType::Pointer) || !SigPII_.append(MIRType::Int32) ||
|
||||
!SigPII_.append(MIRType::Int32)) {
|
||||
return false;
|
||||
}
|
||||
if (!SigPIRI_.append(MIRType::Pointer) || !SigPIRI_.append(MIRType::Int32) ||
|
||||
!SigPIRI_.append(MIRType::RefOrNull) ||
|
||||
!SigPIRI_.append(MIRType::Int32)) {
|
||||
return false;
|
||||
}
|
||||
if (!SigPIII_.append(MIRType::Pointer) || !SigPIII_.append(MIRType::Int32) ||
|
||||
!SigPIII_.append(MIRType::Int32) || !SigPIII_.append(MIRType::Int32)) {
|
||||
return false;
|
||||
}
|
||||
if (!SigPIIL_.append(MIRType::Pointer) || !SigPIIL_.append(MIRType::Int32) ||
|
||||
!SigPIIL_.append(MIRType::Int32) || !SigPIIL_.append(MIRType::Int64)) {
|
||||
return false;
|
||||
}
|
||||
if (!SigPIIR_.append(MIRType::Pointer) || !SigPIIR_.append(MIRType::Int32) ||
|
||||
!SigPIIR_.append(MIRType::Int32) ||
|
||||
!SigPIIR_.append(MIRType::RefOrNull)) {
|
||||
return false;
|
||||
}
|
||||
if (!SigPILL_.append(MIRType::Pointer) || !SigPILL_.append(MIRType::Int32) ||
|
||||
!SigPILL_.append(MIRType::Int64) || !SigPILL_.append(MIRType::Int64)) {
|
||||
return false;
|
||||
}
|
||||
if (!SigPIIII_.append(MIRType::Pointer) ||
|
||||
!SigPIIII_.append(MIRType::Int32) || !SigPIIII_.append(MIRType::Int32) ||
|
||||
!SigPIIII_.append(MIRType::Int32) || !SigPIIII_.append(MIRType::Int32)) {
|
||||
return false;
|
||||
}
|
||||
if (!SigPIIIII_.append(MIRType::Pointer) ||
|
||||
!SigPIIIII_.append(MIRType::Int32) ||
|
||||
!SigPIIIII_.append(MIRType::Int32) ||
|
||||
!SigPIIIII_.append(MIRType::Int32) ||
|
||||
!SigPIIIII_.append(MIRType::Int32) ||
|
||||
!SigPIIIII_.append(MIRType::Int32)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!fr.setupLocals(locals_, funcType().args(), env_.debugEnabled(),
|
||||
&localInfo_)) {
|
||||
|
|
|
@ -45,7 +45,153 @@ static const unsigned BUILTIN_THUNK_LIFO_SIZE = 64 * 1024;
|
|||
|
||||
// ============================================================================
|
||||
// WebAssembly builtin C++ functions called from wasm code to implement internal
|
||||
// wasm operations.
|
||||
// wasm operations: type descriptions.
|
||||
|
||||
// Some abbreviations, for the sake of conciseness.
|
||||
#define _F64 MIRType::Double
|
||||
#define _F32 MIRType::Float32
|
||||
#define _I32 MIRType::Int32
|
||||
#define _I64 MIRType::Int64
|
||||
#define _PTR MIRType::Pointer
|
||||
#define _RoN MIRType::RefOrNull
|
||||
#define _VOID MIRType::None
|
||||
#define _END MIRType::None
|
||||
|
||||
namespace js {
|
||||
namespace wasm {
|
||||
|
||||
const SymbolicAddressSignature SASigSinD = {
|
||||
SymbolicAddress::SinD, _F64, 1, { _F64, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigCosD = {
|
||||
SymbolicAddress::CosD, _F64, 1, { _F64, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigTanD = {
|
||||
SymbolicAddress::TanD, _F64, 1, { _F64, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigASinD = {
|
||||
SymbolicAddress::ASinD, _F64, 1, { _F64, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigACosD = {
|
||||
SymbolicAddress::ACosD, _F64, 1, { _F64, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigATanD = {
|
||||
SymbolicAddress::ATanD, _F64, 1, { _F64, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigCeilD = {
|
||||
SymbolicAddress::CeilD, _F64, 1, { _F64, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigCeilF = {
|
||||
SymbolicAddress::CeilF, _F32, 1, { _F32, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigFloorD = {
|
||||
SymbolicAddress::FloorD, _F64, 1, { _F64, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigFloorF = {
|
||||
SymbolicAddress::FloorF, _F32, 1, { _F32, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigTruncD = {
|
||||
SymbolicAddress::TruncD, _F64, 1, { _F64, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigTruncF = {
|
||||
SymbolicAddress::TruncF, _F32, 1, { _F32, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigNearbyIntD = {
|
||||
SymbolicAddress::NearbyIntD, _F64, 1, { _F64, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigNearbyIntF = {
|
||||
SymbolicAddress::NearbyIntF, _F32, 1, { _F32, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigExpD = {
|
||||
SymbolicAddress::ExpD, _F64, 1, { _F64, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigLogD = {
|
||||
SymbolicAddress::LogD, _F64, 1, { _F64, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigPowD = {
|
||||
SymbolicAddress::PowD, _F64, 2, { _F64, _F64, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigATan2D = {
|
||||
SymbolicAddress::ATan2D, _F64, 2, { _F64, _F64, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigMemoryGrow = {
|
||||
SymbolicAddress::MemoryGrow, _I32, 2, { _PTR, _I32, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigMemorySize = {
|
||||
SymbolicAddress::MemorySize, _I32, 1, { _PTR, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigWaitI32 = {
|
||||
SymbolicAddress::WaitI32, _I32, 4, { _PTR, _I32, _I32, _I64, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigWaitI64 = {
|
||||
SymbolicAddress::WaitI64, _I32, 4, { _PTR, _I32, _I64, _I64, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigWake = {
|
||||
SymbolicAddress::Wake, _I32, 3, { _PTR, _I32, _I32, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigMemCopy = {
|
||||
SymbolicAddress::MemCopy, _I32, 4, { _PTR, _I32, _I32, _I32, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigDataDrop = {
|
||||
SymbolicAddress::DataDrop, _I32, 2, { _PTR, _I32, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigMemFill = {
|
||||
SymbolicAddress::MemFill, _I32, 4, { _PTR, _I32, _I32, _I32, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigMemInit = {
|
||||
SymbolicAddress::MemInit, _I32, 5, { _PTR, _I32, _I32, _I32, _I32, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigTableCopy = {
|
||||
SymbolicAddress::TableCopy,
|
||||
_I32, 6, { _PTR, _I32, _I32, _I32, _I32, _I32, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigElemDrop = {
|
||||
SymbolicAddress::ElemDrop, _I32, 2, { _PTR, _I32, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigTableGet = {
|
||||
SymbolicAddress::TableGet, _PTR, 3, { _PTR, _I32, _I32, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigTableGrow = {
|
||||
SymbolicAddress::TableGrow, _I32, 4, { _PTR, _I32, _RoN, _I32, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigTableInit = {
|
||||
SymbolicAddress::TableInit,
|
||||
_I32, 6, { _PTR, _I32, _I32, _I32, _I32, _I32, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigTableSet = {
|
||||
SymbolicAddress::TableSet, _I32, 4, { _PTR, _I32, _RoN, _I32, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigTableSize = {
|
||||
SymbolicAddress::TableSize, _I32, 2, { _PTR, _I32, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigPostBarrier = {
|
||||
SymbolicAddress::PostBarrier, _VOID, 2, { _PTR, _PTR, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigPostBarrierFiltering = {
|
||||
SymbolicAddress::PostBarrierFiltering, _VOID, 2, { _PTR, _PTR, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigStructNew = {
|
||||
SymbolicAddress::StructNew, _RoN, 2, { _PTR, _I32, _END }
|
||||
};
|
||||
const SymbolicAddressSignature SASigStructNarrow = {
|
||||
SymbolicAddress::StructNarrow, _RoN, 4, { _PTR, _I32, _I32, _RoN, _END }
|
||||
};
|
||||
|
||||
} // namespace wasm
|
||||
} // namespace js
|
||||
|
||||
#undef _F64
|
||||
#undef _F32
|
||||
#undef _I32
|
||||
#undef _I64
|
||||
#undef _PTR
|
||||
#undef _RoN
|
||||
#undef _VOID
|
||||
#undef _END
|
||||
|
||||
// ============================================================================
|
||||
// WebAssembly builtin C++ functions called from wasm code to implement internal
|
||||
// wasm operations: implementations.
|
||||
|
||||
#if defined(JS_CODEGEN_ARM)
|
||||
extern "C" {
|
||||
|
|
|
@ -26,6 +26,48 @@ namespace wasm {
|
|||
|
||||
class WasmFrameIter;
|
||||
|
||||
// These provide argument type information for a subset of the SymbolicAddress
|
||||
// targets, for which type info is needed to generate correct stackmaps.
|
||||
|
||||
extern const SymbolicAddressSignature SASigSinD;
|
||||
extern const SymbolicAddressSignature SASigCosD;
|
||||
extern const SymbolicAddressSignature SASigTanD;
|
||||
extern const SymbolicAddressSignature SASigASinD;
|
||||
extern const SymbolicAddressSignature SASigACosD;
|
||||
extern const SymbolicAddressSignature SASigATanD;
|
||||
extern const SymbolicAddressSignature SASigCeilD;
|
||||
extern const SymbolicAddressSignature SASigCeilF;
|
||||
extern const SymbolicAddressSignature SASigFloorD;
|
||||
extern const SymbolicAddressSignature SASigFloorF;
|
||||
extern const SymbolicAddressSignature SASigTruncD;
|
||||
extern const SymbolicAddressSignature SASigTruncF;
|
||||
extern const SymbolicAddressSignature SASigNearbyIntD;
|
||||
extern const SymbolicAddressSignature SASigNearbyIntF;
|
||||
extern const SymbolicAddressSignature SASigExpD;
|
||||
extern const SymbolicAddressSignature SASigLogD;
|
||||
extern const SymbolicAddressSignature SASigPowD;
|
||||
extern const SymbolicAddressSignature SASigATan2D;
|
||||
extern const SymbolicAddressSignature SASigMemoryGrow;
|
||||
extern const SymbolicAddressSignature SASigMemorySize;
|
||||
extern const SymbolicAddressSignature SASigWaitI32;
|
||||
extern const SymbolicAddressSignature SASigWaitI64;
|
||||
extern const SymbolicAddressSignature SASigWake;
|
||||
extern const SymbolicAddressSignature SASigMemCopy;
|
||||
extern const SymbolicAddressSignature SASigDataDrop;
|
||||
extern const SymbolicAddressSignature SASigMemFill;
|
||||
extern const SymbolicAddressSignature SASigMemInit;
|
||||
extern const SymbolicAddressSignature SASigTableCopy;
|
||||
extern const SymbolicAddressSignature SASigElemDrop;
|
||||
extern const SymbolicAddressSignature SASigTableGet;
|
||||
extern const SymbolicAddressSignature SASigTableGrow;
|
||||
extern const SymbolicAddressSignature SASigTableInit;
|
||||
extern const SymbolicAddressSignature SASigTableSet;
|
||||
extern const SymbolicAddressSignature SASigTableSize;
|
||||
extern const SymbolicAddressSignature SASigPostBarrier;
|
||||
extern const SymbolicAddressSignature SASigPostBarrierFiltering;
|
||||
extern const SymbolicAddressSignature SASigStructNew;
|
||||
extern const SymbolicAddressSignature SASigStructNarrow;
|
||||
|
||||
// A SymbolicAddress that NeedsBuiltinThunk() will call through a thunk to the
|
||||
// C++ function. This will be true for all normal calls from normal wasm
|
||||
// function code. Only calls to C++ from other exits/thunks do not need a thunk.
|
||||
|
|
|
@ -47,6 +47,37 @@ static inline size_t StackArgAreaSizeUnaligned(const T& argTypes) {
|
|||
return i.stackBytesConsumedSoFar();
|
||||
}
|
||||
|
||||
static inline size_t StackArgAreaSizeUnaligned(
|
||||
const SymbolicAddressSignature& saSig) {
|
||||
// ABIArgIter::ABIArgIter wants the items to be iterated over to be
|
||||
// presented in some type that has methods length() and operator[]. So we
|
||||
// have to wrap up |saSig|'s array of types in this API-matching class.
|
||||
class MOZ_STACK_CLASS ItemsAndLength {
|
||||
const MIRType* items_;
|
||||
size_t length_;
|
||||
public:
|
||||
ItemsAndLength(const MIRType* items, size_t length)
|
||||
: items_(items), length_(length)
|
||||
{}
|
||||
size_t length() const { return length_; }
|
||||
MIRType operator[](size_t i) const { return items_[i]; }
|
||||
};
|
||||
|
||||
// Assert, at least crudely, that we're not accidentally going to run off
|
||||
// the end of the array of types, nor into undefined parts of it, while
|
||||
// iterating.
|
||||
MOZ_ASSERT(saSig.numArgs < sizeof(saSig.argTypes) / sizeof(saSig.argTypes[0]));
|
||||
MOZ_ASSERT(saSig.argTypes[saSig.numArgs] == MIRType::None/*the end marker*/);
|
||||
|
||||
ItemsAndLength itemsAndLength(saSig.argTypes, saSig.numArgs);
|
||||
|
||||
ABIArgIter<ItemsAndLength> i(itemsAndLength);
|
||||
while (!i.done()) {
|
||||
i++;
|
||||
}
|
||||
return i.stackBytesConsumedSoFar();
|
||||
}
|
||||
|
||||
static inline size_t AlignStackArgAreaSize(size_t unalignedSize) {
|
||||
return AlignBytes(unalignedSize, 16u);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "jit/CodeGenerator.h"
|
||||
|
||||
#include "wasm/WasmBaselineCompile.h"
|
||||
#include "wasm/WasmBuiltins.h"
|
||||
#include "wasm/WasmGenerator.h"
|
||||
#include "wasm/WasmOpIter.h"
|
||||
#include "wasm/WasmSignalHandlers.h"
|
||||
|
@ -986,12 +987,9 @@ class FunctionCompiler {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool passArg(MDefinition* argDef, ValType type, CallCompileState* call) {
|
||||
if (inDeadCode()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ABIArg arg = call->abi_.next(ToMIRType(type));
|
||||
// Do not call this directly. Call one of the passArg() variants instead.
|
||||
bool passArgWorker(MDefinition* argDef, MIRType type, CallCompileState* call) {
|
||||
ABIArg arg = call->abi_.next(type);
|
||||
switch (arg.kind()) {
|
||||
#ifdef JS_CODEGEN_REGISTER_PAIR
|
||||
case ABIArg::GPR_PAIR: {
|
||||
|
@ -1022,6 +1020,20 @@ class FunctionCompiler {
|
|||
MOZ_CRASH("Unknown ABIArg kind.");
|
||||
}
|
||||
|
||||
bool passArg(MDefinition* argDef, MIRType type, CallCompileState* call) {
|
||||
if (inDeadCode()) {
|
||||
return true;
|
||||
}
|
||||
return passArgWorker(argDef, type, call);
|
||||
}
|
||||
|
||||
bool passArg(MDefinition* argDef, ValType type, CallCompileState* call) {
|
||||
if (inDeadCode()) {
|
||||
return true;
|
||||
}
|
||||
return passArgWorker(argDef, ToMIRType(type), call);
|
||||
}
|
||||
|
||||
bool finishCall(CallCompileState* call) {
|
||||
if (inDeadCode()) {
|
||||
return true;
|
||||
|
@ -1126,8 +1138,8 @@ class FunctionCompiler {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool builtinCall(SymbolicAddress builtin, uint32_t lineOrBytecode,
|
||||
const CallCompileState& call, ValType ret,
|
||||
bool builtinCall(const SymbolicAddressSignature& builtin,
|
||||
uint32_t lineOrBytecode, const CallCompileState& call,
|
||||
MDefinition** def) {
|
||||
if (inDeadCode()) {
|
||||
*def = nullptr;
|
||||
|
@ -1135,9 +1147,9 @@ class FunctionCompiler {
|
|||
}
|
||||
|
||||
CallSiteDesc desc(lineOrBytecode, CallSiteDesc::Symbolic);
|
||||
auto callee = CalleeDesc::builtin(builtin);
|
||||
auto callee = CalleeDesc::builtin(builtin.identity);
|
||||
auto* ins =
|
||||
MWasmCall::New(alloc(), desc, callee, call.regArgs_, ToMIRType(ret));
|
||||
MWasmCall::New(alloc(), desc, callee, call.regArgs_, builtin.retType);
|
||||
if (!ins) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1147,9 +1159,9 @@ class FunctionCompiler {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool builtinInstanceMethodCall(SymbolicAddress builtin,
|
||||
bool builtinInstanceMethodCall(const SymbolicAddressSignature& builtin,
|
||||
uint32_t lineOrBytecode,
|
||||
const CallCompileState& call, MIRType ret,
|
||||
const CallCompileState& call,
|
||||
MDefinition** def) {
|
||||
if (inDeadCode()) {
|
||||
*def = nullptr;
|
||||
|
@ -1158,7 +1170,8 @@ class FunctionCompiler {
|
|||
|
||||
CallSiteDesc desc(lineOrBytecode, CallSiteDesc::Symbolic);
|
||||
auto* ins = MWasmCall::NewBuiltinInstanceMethodCall(
|
||||
alloc(), desc, builtin, call.instanceArg_, call.regArgs_, ret);
|
||||
alloc(), desc, builtin.identity, call.instanceArg_, call.regArgs_,
|
||||
builtin.retType);
|
||||
if (!ins) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1168,14 +1181,6 @@ class FunctionCompiler {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool builtinInstanceMethodCall(SymbolicAddress builtin,
|
||||
uint32_t lineOrBytecode,
|
||||
const CallCompileState& call, ValType ret,
|
||||
MDefinition** def) {
|
||||
return builtinInstanceMethodCall(builtin, lineOrBytecode, call,
|
||||
ToMIRType(ret), def);
|
||||
}
|
||||
|
||||
/*********************************************** Control flow generation */
|
||||
|
||||
inline bool inDeadCode() const { return curBlock_ == nullptr; }
|
||||
|
@ -2201,17 +2206,13 @@ static bool EmitSetGlobal(FunctionCompiler& f) {
|
|||
if (!f.passInstance(&args)) {
|
||||
return false;
|
||||
}
|
||||
// TODO: The argument type here is MIRType::Pointer, Julian's fix will take
|
||||
// care of this.
|
||||
if (!f.passArg(barrierAddr, ValType::AnyRef, &args)) {
|
||||
return false;
|
||||
}
|
||||
f.finishCall(&args);
|
||||
MDefinition* ret;
|
||||
// TODO: The return type here is void (ExprType::Void or MIRType::None),
|
||||
// Julian's fix will take care of this.
|
||||
if (!f.builtinInstanceMethodCall(SymbolicAddress::PostBarrierFiltering,
|
||||
lineOrBytecode, args, ValType::I32, &ret)) {
|
||||
if (!f.builtinInstanceMethodCall(SASigPostBarrierFiltering, lineOrBytecode,
|
||||
args, &ret)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -2591,21 +2592,22 @@ static bool TryInlineUnaryBuiltin(FunctionCompiler& f, SymbolicAddress callee,
|
|||
}
|
||||
|
||||
static bool EmitUnaryMathBuiltinCall(FunctionCompiler& f,
|
||||
SymbolicAddress callee,
|
||||
ValType operandType) {
|
||||
const SymbolicAddressSignature& callee) {
|
||||
MOZ_ASSERT(callee.numArgs == 1);
|
||||
|
||||
uint32_t lineOrBytecode = f.readCallSiteLineOrBytecode();
|
||||
|
||||
MDefinition* input;
|
||||
if (!f.iter().readUnary(operandType, &input)) {
|
||||
if (!f.iter().readUnary(ValType(callee.argTypes[0]), &input)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TryInlineUnaryBuiltin(f, callee, input)) {
|
||||
if (TryInlineUnaryBuiltin(f, callee.identity, input)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
CallCompileState call;
|
||||
if (!f.passArg(input, operandType, &call)) {
|
||||
if (!f.passArg(input, callee.argTypes[0], &call)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2614,7 +2616,7 @@ static bool EmitUnaryMathBuiltinCall(FunctionCompiler& f,
|
|||
}
|
||||
|
||||
MDefinition* def;
|
||||
if (!f.builtinCall(callee, lineOrBytecode, call, operandType, &def)) {
|
||||
if (!f.builtinCall(callee, lineOrBytecode, call, &def)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2623,22 +2625,25 @@ static bool EmitUnaryMathBuiltinCall(FunctionCompiler& f,
|
|||
}
|
||||
|
||||
static bool EmitBinaryMathBuiltinCall(FunctionCompiler& f,
|
||||
SymbolicAddress callee,
|
||||
ValType operandType) {
|
||||
const SymbolicAddressSignature& callee) {
|
||||
MOZ_ASSERT(callee.numArgs == 2);
|
||||
MOZ_ASSERT(callee.argTypes[0] == callee.argTypes[1]);
|
||||
|
||||
uint32_t lineOrBytecode = f.readCallSiteLineOrBytecode();
|
||||
|
||||
CallCompileState call;
|
||||
MDefinition* lhs;
|
||||
MDefinition* rhs;
|
||||
if (!f.iter().readBinary(operandType, &lhs, &rhs)) {
|
||||
// This call to readBinary assumes both operands have the same type.
|
||||
if (!f.iter().readBinary(ValType(callee.argTypes[0]), &lhs, &rhs)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!f.passArg(lhs, operandType, &call)) {
|
||||
if (!f.passArg(lhs, callee.argTypes[0], &call)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!f.passArg(rhs, operandType, &call)) {
|
||||
if (!f.passArg(rhs, callee.argTypes[1], &call)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2647,7 +2652,7 @@ static bool EmitBinaryMathBuiltinCall(FunctionCompiler& f,
|
|||
}
|
||||
|
||||
MDefinition* def;
|
||||
if (!f.builtinCall(callee, lineOrBytecode, call, operandType, &def)) {
|
||||
if (!f.builtinCall(callee, lineOrBytecode, call, &def)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2675,8 +2680,8 @@ static bool EmitMemoryGrow(FunctionCompiler& f) {
|
|||
f.finishCall(&args);
|
||||
|
||||
MDefinition* ret;
|
||||
if (!f.builtinInstanceMethodCall(SymbolicAddress::MemoryGrow, lineOrBytecode,
|
||||
args, ValType::I32, &ret)) {
|
||||
if (!f.builtinInstanceMethodCall(SASigMemoryGrow, lineOrBytecode, args,
|
||||
&ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2700,8 +2705,8 @@ static bool EmitMemorySize(FunctionCompiler& f) {
|
|||
f.finishCall(&args);
|
||||
|
||||
MDefinition* ret;
|
||||
if (!f.builtinInstanceMethodCall(SymbolicAddress::MemorySize,
|
||||
lineOrBytecode, args, ValType::I32, &ret)) {
|
||||
if (!f.builtinInstanceMethodCall(SASigMemorySize, lineOrBytecode, args,
|
||||
&ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2820,11 +2825,10 @@ static bool EmitWait(FunctionCompiler& f, ValType type, uint32_t byteSize) {
|
|||
return false;
|
||||
}
|
||||
|
||||
SymbolicAddress callee = type == ValType::I32 ? SymbolicAddress::WaitI32
|
||||
: SymbolicAddress::WaitI64;
|
||||
const SymbolicAddressSignature& callee =
|
||||
type == ValType::I32 ? SASigWaitI32 : SASigWaitI64;
|
||||
MDefinition* ret;
|
||||
if (!f.builtinInstanceMethodCall(callee, lineOrBytecode, args, ValType::I32,
|
||||
&ret)) {
|
||||
if (!f.builtinInstanceMethodCall(callee, lineOrBytecode, args, &ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2870,8 +2874,7 @@ static bool EmitWake(FunctionCompiler& f) {
|
|||
}
|
||||
|
||||
MDefinition* ret;
|
||||
if (!f.builtinInstanceMethodCall(SymbolicAddress::Wake, lineOrBytecode, args,
|
||||
ValType::I32, &ret)) {
|
||||
if (!f.builtinInstanceMethodCall(SASigWake, lineOrBytecode, args, &ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2952,11 +2955,9 @@ static bool EmitMemOrTableCopy(FunctionCompiler& f, bool isMem) {
|
|||
return false;
|
||||
}
|
||||
|
||||
SymbolicAddress callee =
|
||||
isMem ? SymbolicAddress::MemCopy : SymbolicAddress::TableCopy;
|
||||
const SymbolicAddressSignature& callee = isMem ? SASigMemCopy : SASigTableCopy;
|
||||
MDefinition* ret;
|
||||
if (!f.builtinInstanceMethodCall(callee, lineOrBytecode, args, ValType::I32,
|
||||
&ret)) {
|
||||
if (!f.builtinInstanceMethodCall(callee, lineOrBytecode, args, &ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2994,11 +2995,10 @@ static bool EmitDataOrElemDrop(FunctionCompiler& f, bool isData) {
|
|||
return false;
|
||||
}
|
||||
|
||||
SymbolicAddress callee =
|
||||
isData ? SymbolicAddress::DataDrop : SymbolicAddress::ElemDrop;
|
||||
const SymbolicAddressSignature& callee =
|
||||
isData ? SASigDataDrop : SASigElemDrop;
|
||||
MDefinition* ret;
|
||||
if (!f.builtinInstanceMethodCall(callee, lineOrBytecode, args, ValType::I32,
|
||||
&ret)) {
|
||||
if (!f.builtinInstanceMethodCall(callee, lineOrBytecode, args, &ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3041,8 +3041,7 @@ static bool EmitMemFill(FunctionCompiler& f) {
|
|||
}
|
||||
|
||||
MDefinition* ret;
|
||||
if (!f.builtinInstanceMethodCall(SymbolicAddress::MemFill, lineOrBytecode,
|
||||
args, ValType::I32, &ret)) {
|
||||
if (!f.builtinInstanceMethodCall(SASigMemFill, lineOrBytecode, args, &ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3100,11 +3099,9 @@ static bool EmitMemOrTableInit(FunctionCompiler& f, bool isMem) {
|
|||
return false;
|
||||
}
|
||||
|
||||
SymbolicAddress callee =
|
||||
isMem ? SymbolicAddress::MemInit : SymbolicAddress::TableInit;
|
||||
const SymbolicAddressSignature& callee = isMem ? SASigMemInit : SASigTableInit;
|
||||
MDefinition* ret;
|
||||
if (!f.builtinInstanceMethodCall(callee, lineOrBytecode, args, ValType::I32,
|
||||
&ret)) {
|
||||
if (!f.builtinInstanceMethodCall(callee, lineOrBytecode, args, &ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3158,8 +3155,8 @@ static bool EmitTableGet(FunctionCompiler& f) {
|
|||
// The return value here is either null, denoting an error, or a pointer to an
|
||||
// unmovable location containing a possibly-null ref.
|
||||
MDefinition* result;
|
||||
if (!f.builtinInstanceMethodCall(SymbolicAddress::TableGet, lineOrBytecode,
|
||||
args, MIRType::Pointer, &result)) {
|
||||
if (!f.builtinInstanceMethodCall(SASigTableGet, lineOrBytecode, args,
|
||||
&result)) {
|
||||
return false;
|
||||
}
|
||||
if (!f.checkPointerNullMeansFailedResult(result)) {
|
||||
|
@ -3216,8 +3213,8 @@ static bool EmitTableGrow(FunctionCompiler& f) {
|
|||
}
|
||||
|
||||
MDefinition* ret;
|
||||
if (!f.builtinInstanceMethodCall(SymbolicAddress::TableGrow, lineOrBytecode,
|
||||
args, ValType::I32, &ret)) {
|
||||
if (!f.builtinInstanceMethodCall(SASigTableGrow, lineOrBytecode, args,
|
||||
&ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3266,8 +3263,7 @@ static bool EmitTableSet(FunctionCompiler& f) {
|
|||
}
|
||||
|
||||
MDefinition* ret;
|
||||
if (!f.builtinInstanceMethodCall(SymbolicAddress::TableSet, lineOrBytecode,
|
||||
args, ValType::I32, &ret)) {
|
||||
if (!f.builtinInstanceMethodCall(SASigTableSet, lineOrBytecode, args, &ret)) {
|
||||
return false;
|
||||
}
|
||||
if (!f.checkI32NegativeMeansFailedResult(ret)) {
|
||||
|
@ -3307,8 +3303,8 @@ static bool EmitTableSize(FunctionCompiler& f) {
|
|||
}
|
||||
|
||||
MDefinition* ret;
|
||||
if (!f.builtinInstanceMethodCall(SymbolicAddress::TableSize, lineOrBytecode,
|
||||
args, ValType::I32, &ret)) {
|
||||
if (!f.builtinInstanceMethodCall(SASigTableSize, lineOrBytecode, args,
|
||||
&ret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3676,17 +3672,13 @@ static bool EmitBodyExprs(FunctionCompiler& f) {
|
|||
case uint16_t(Op::F32Neg):
|
||||
CHECK(EmitUnaryWithType<MWasmNeg>(f, ValType::F32, MIRType::Float32));
|
||||
case uint16_t(Op::F32Ceil):
|
||||
CHECK(
|
||||
EmitUnaryMathBuiltinCall(f, SymbolicAddress::CeilF, ValType::F32));
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SASigCeilF));
|
||||
case uint16_t(Op::F32Floor):
|
||||
CHECK(
|
||||
EmitUnaryMathBuiltinCall(f, SymbolicAddress::FloorF, ValType::F32));
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SASigFloorF));
|
||||
case uint16_t(Op::F32Trunc):
|
||||
CHECK(
|
||||
EmitUnaryMathBuiltinCall(f, SymbolicAddress::TruncF, ValType::F32));
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SASigTruncF));
|
||||
case uint16_t(Op::F32Nearest):
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SymbolicAddress::NearbyIntF,
|
||||
ValType::F32));
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SASigNearbyIntF));
|
||||
case uint16_t(Op::F32Sqrt):
|
||||
CHECK(EmitUnaryWithType<MSqrt>(f, ValType::F32, MIRType::Float32));
|
||||
case uint16_t(Op::F32Add):
|
||||
|
@ -3709,17 +3701,13 @@ static bool EmitBodyExprs(FunctionCompiler& f) {
|
|||
case uint16_t(Op::F64Neg):
|
||||
CHECK(EmitUnaryWithType<MWasmNeg>(f, ValType::F64, MIRType::Double));
|
||||
case uint16_t(Op::F64Ceil):
|
||||
CHECK(
|
||||
EmitUnaryMathBuiltinCall(f, SymbolicAddress::CeilD, ValType::F64));
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SASigCeilD));
|
||||
case uint16_t(Op::F64Floor):
|
||||
CHECK(
|
||||
EmitUnaryMathBuiltinCall(f, SymbolicAddress::FloorD, ValType::F64));
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SASigFloorD));
|
||||
case uint16_t(Op::F64Trunc):
|
||||
CHECK(
|
||||
EmitUnaryMathBuiltinCall(f, SymbolicAddress::TruncD, ValType::F64));
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SASigTruncD));
|
||||
case uint16_t(Op::F64Nearest):
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SymbolicAddress::NearbyIntD,
|
||||
ValType::F64));
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SASigNearbyIntD));
|
||||
case uint16_t(Op::F64Sqrt):
|
||||
CHECK(EmitUnaryWithType<MSqrt>(f, ValType::F64, MIRType::Double));
|
||||
case uint16_t(Op::F64Add):
|
||||
|
@ -4112,35 +4100,25 @@ static bool EmitBodyExprs(FunctionCompiler& f) {
|
|||
CHECK(EmitRem(f, ValType::F64, MIRType::Double,
|
||||
/* isUnsigned = */ false));
|
||||
case uint16_t(MozOp::F64Sin):
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SymbolicAddress::SinD,
|
||||
ValType::F64));
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SASigSinD));
|
||||
case uint16_t(MozOp::F64Cos):
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SymbolicAddress::CosD,
|
||||
ValType::F64));
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SASigCosD));
|
||||
case uint16_t(MozOp::F64Tan):
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SymbolicAddress::TanD,
|
||||
ValType::F64));
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SASigTanD));
|
||||
case uint16_t(MozOp::F64Asin):
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SymbolicAddress::ASinD,
|
||||
ValType::F64));
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SASigASinD));
|
||||
case uint16_t(MozOp::F64Acos):
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SymbolicAddress::ACosD,
|
||||
ValType::F64));
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SASigACosD));
|
||||
case uint16_t(MozOp::F64Atan):
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SymbolicAddress::ATanD,
|
||||
ValType::F64));
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SASigATanD));
|
||||
case uint16_t(MozOp::F64Exp):
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SymbolicAddress::ExpD,
|
||||
ValType::F64));
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SASigExpD));
|
||||
case uint16_t(MozOp::F64Log):
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SymbolicAddress::LogD,
|
||||
ValType::F64));
|
||||
CHECK(EmitUnaryMathBuiltinCall(f, SASigLogD));
|
||||
case uint16_t(MozOp::F64Pow):
|
||||
CHECK(EmitBinaryMathBuiltinCall(f, SymbolicAddress::PowD,
|
||||
ValType::F64));
|
||||
CHECK(EmitBinaryMathBuiltinCall(f, SASigPowD));
|
||||
case uint16_t(MozOp::F64Atan2):
|
||||
CHECK(EmitBinaryMathBuiltinCall(f, SymbolicAddress::ATan2D,
|
||||
ValType::F64));
|
||||
CHECK(EmitBinaryMathBuiltinCall(f, SASigATan2D));
|
||||
case uint16_t(MozOp::OldCallDirect):
|
||||
CHECK(EmitCall(f, /* asmJSFuncDef = */ true));
|
||||
case uint16_t(MozOp::OldCallIndirect):
|
||||
|
|
|
@ -396,6 +396,16 @@ class ValType {
|
|||
|
||||
explicit ValType(PackedTypeCode ptc) : tc_(ptc) { MOZ_ASSERT(isValidCode()); }
|
||||
|
||||
explicit ValType(jit::MIRType mty) {
|
||||
switch (mty) {
|
||||
case jit::MIRType::Int32: tc_ = PackTypeCode(TypeCode::I32); break;
|
||||
case jit::MIRType::Int64: tc_ = PackTypeCode(TypeCode::I64); break;
|
||||
case jit::MIRType::Float32: tc_ = PackTypeCode(TypeCode::F32); break;
|
||||
case jit::MIRType::Double: tc_ = PackTypeCode(TypeCode::F64); break;
|
||||
default: MOZ_CRASH("ValType(MIRType): unexpected type");
|
||||
}
|
||||
}
|
||||
|
||||
static ValType fromBitsUnsafe(uint32_t bits) {
|
||||
return ValType(PackedTypeCodeFromBits(bits));
|
||||
}
|
||||
|
@ -2091,6 +2101,40 @@ enum class SymbolicAddress {
|
|||
Limit
|
||||
};
|
||||
|
||||
// SymbolicAddressSignature carries type information for a function referred
|
||||
// to by a SymbolicAddress. In order that |argTypes| can be written out as a
|
||||
// static initialiser, it has to have fixed length. At present
|
||||
// SymbolicAddressType is used to describe functions with at most 6 arguments,
|
||||
// so |argTypes| has 7 entries in order to allow the last value to be
|
||||
// MIRType::None, in the hope of catching any accidental overruns of the
|
||||
// defined section of the array.
|
||||
|
||||
static constexpr size_t SymbolicAddressSignatureMaxArgs = 6;
|
||||
|
||||
struct SymbolicAddressSignature {
|
||||
// The SymbolicAddress that is described.
|
||||
const SymbolicAddress identity;
|
||||
// The return type, or MIRType::None to denote 'void'.
|
||||
const jit::MIRType retType;
|
||||
// The number of arguments, 0 .. SymbolicAddressSignatureMaxArgs only.
|
||||
const uint8_t numArgs;
|
||||
// The argument types; SymbolicAddressSignatureMaxArgs + 1 guard, which
|
||||
// should be MIRType::None.
|
||||
const jit::MIRType argTypes[SymbolicAddressSignatureMaxArgs + 1];
|
||||
};
|
||||
|
||||
// The 16 in this assertion is derived as follows: SymbolicAddress is probably
|
||||
// size-4 aligned-4, but it's at the start of the struct, so there's no
|
||||
// alignment hole before it. All other components (MIRType and uint8_t) are
|
||||
// size-1 aligned-1, and there are 8 in total, so it is reasonable to assume
|
||||
// that they also don't create any alignment holes. Hence it is also
|
||||
// reasonable to assume that the actual size is 1 * 4 + 8 * 1 == 12. The
|
||||
// worst-plausible-case rounding will take that up to 16. Hence, the
|
||||
// assertion uses 16.
|
||||
|
||||
static_assert(sizeof(SymbolicAddressSignature) <= 16,
|
||||
"SymbolicAddressSignature unexpectedly large");
|
||||
|
||||
bool IsRoundingFunction(SymbolicAddress callee, jit::RoundingMode* mode);
|
||||
|
||||
// Represents the resizable limits of memories and tables.
|
||||
|
|
|
@ -235,6 +235,9 @@ config = {
|
|||
"%(modules_dir)s",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--suite=crashtest",
|
||||
"--log-raw=%(raw_log_file)s",
|
||||
"--log-raw-level=%(log_raw_level)s",
|
||||
"--log-errorsummary=%(error_summary_file)s",
|
||||
"--log-tbpl-level=%(log_tbpl_level)s",
|
||||
"--deviceSerial=%(device_serial)s",
|
||||
],
|
||||
|
@ -268,6 +271,9 @@ config = {
|
|||
"--symbols-path=%(symbols_path)s",
|
||||
"--extra-profile-file=jsreftest/tests/user.js",
|
||||
"--suite=jstestbrowser",
|
||||
"--log-raw=%(raw_log_file)s",
|
||||
"--log-raw-level=%(log_raw_level)s",
|
||||
"--log-errorsummary=%(error_summary_file)s",
|
||||
"--log-tbpl-level=%(log_tbpl_level)s",
|
||||
"--deviceSerial=%(device_serial)s",
|
||||
],
|
||||
|
@ -304,6 +310,9 @@ config = {
|
|||
"--apk=%(installer_path)s",
|
||||
".",
|
||||
"--deviceSerial=%(device_serial)s",
|
||||
"--log-raw=%(raw_log_file)s",
|
||||
"--log-raw-level=%(log_raw_level)s",
|
||||
"--log-errorsummary=%(error_summary_file)s",
|
||||
],
|
||||
},
|
||||
"marionette": {
|
||||
|
@ -337,6 +346,7 @@ config = {
|
|||
"--utility-path=%(utility_path)s",
|
||||
"--deviceSerial=%(device_serial)s",
|
||||
"--log-raw=%(raw_log_file)s",
|
||||
"--log-raw-level=%(log_raw_level)s",
|
||||
],
|
||||
},
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
[playback-rate.https.html]
|
||||
[Zero current time is not affected by playbackRate set while the animation is in play-pending state.]
|
||||
expected: FAIL
|
||||
|
||||
[Non zero current time is not affected by playbackRate set while the animation is in play state.]
|
||||
expected: FAIL
|
||||
|
||||
[When playback rate is updated, the underlying effect is properly updated with the current time of its WorkletAnimation and produces correct visual result.]
|
||||
expected: FAIL
|
||||
|
||||
[Zero current time is not affected by playbackRate set while the animation is in idle state.]
|
||||
expected: FAIL
|
||||
|
||||
[The playback rate affects the rate of progress of the current time.]
|
||||
expected: FAIL
|
||||
|
||||
[The playback rate set before the animation started playing affects the rate of progress of the current time]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[worklet-animation-local-time-after-duration.https.html]
|
||||
expected: TIMEOUT
|
|
@ -0,0 +1,2 @@
|
|||
[worklet-animation-local-time-before-start.https.html]
|
||||
expected: TIMEOUT
|
|
@ -0,0 +1,2 @@
|
|||
[worklet-animation-pause-immediately.https.html]
|
||||
expected: TIMEOUT
|
|
@ -0,0 +1,2 @@
|
|||
[worklet-animation-pause-resume.https.html]
|
||||
expected: TIMEOUT
|
|
@ -0,0 +1,2 @@
|
|||
[worklet-animation-pause.https.html]
|
||||
expected: TIMEOUT
|
|
@ -0,0 +1,2 @@
|
|||
[worklet-animation-set-keyframes.https.html]
|
||||
expected: TIMEOUT
|
|
@ -0,0 +1,2 @@
|
|||
[worklet-animation-set-timing.https.html]
|
||||
expected: TIMEOUT
|
|
@ -5,6 +5,9 @@
|
|||
[navigator.clipboard.writeImageExperimental(Blob) succeeds]
|
||||
expected: FAIL
|
||||
|
||||
[navigator.clipboard.writeImageExperimental() fails (expect Blob)]
|
||||
[navigator.clipboard.write(Blob) succeeds]
|
||||
expected: FAIL
|
||||
|
||||
[navigator.clipboard.read() succeeds]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
[font-display-feature-policy-01.tentative.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,10 @@
|
|||
[font-display-feature-policy-02.tentative.html]
|
||||
expected:
|
||||
if not debug and not webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and not webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if not debug and not webrender and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and webrender and e10s and (os == "win") and (version == "10.0.17134") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if not debug and not webrender and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
|
|
@ -0,0 +1,5 @@
|
|||
[font-display-feature-policy-report-only.tentative.html]
|
||||
expected: TIMEOUT
|
||||
[font-display-late-swap Report Format]
|
||||
expected: NOTRUN
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[font-display-feature-policy-reporting.tentative.html]
|
||||
expected: TIMEOUT
|
||||
[font-display-late-swap Report Format]
|
||||
expected: NOTRUN
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[font-display-feature-policy.tentative.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,21 @@
|
|||
[start-edge-in-block-layout-direction.html]
|
||||
[Vertical-RL LTR.]
|
||||
expected:
|
||||
if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
|
||||
[Horizontal RTL.]
|
||||
expected:
|
||||
if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
|
||||
[Vertical-LR LTR.]
|
||||
expected:
|
||||
if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
|
||||
[Vertical-RL RTL.]
|
||||
expected:
|
||||
if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
|
||||
[Vertical-LR RTL.]
|
||||
expected:
|
||||
if not debug and not webrender and not e10s and (os == "android") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
|
|
@ -227,3 +227,48 @@
|
|||
["u+0-0000001" is invalid]
|
||||
expected: FAIL
|
||||
|
||||
["u+a" => "U+A"]
|
||||
expected: FAIL
|
||||
|
||||
["u+aaaa" => "U+AAAA"]
|
||||
expected: FAIL
|
||||
|
||||
["u+0" => "U+0"]
|
||||
expected: FAIL
|
||||
|
||||
["u+aaa" => "U+AAA"]
|
||||
expected: FAIL
|
||||
|
||||
["u+1e9a" => "U+1E9A"]
|
||||
expected: FAIL
|
||||
|
||||
["U+abc" => "U+ABC"]
|
||||
expected: FAIL
|
||||
|
||||
["u+aaaaa" => "U+AAAAA"]
|
||||
expected: FAIL
|
||||
|
||||
["u+AbC" => "U+ABC"]
|
||||
expected: FAIL
|
||||
|
||||
["U+ABC" => "U+ABC"]
|
||||
expected: FAIL
|
||||
|
||||
["u+1e-20" => "U+1E-20"]
|
||||
expected: FAIL
|
||||
|
||||
["u+1e3" => "U+1E3"]
|
||||
expected: FAIL
|
||||
|
||||
["u+0-1" => "U+0-1"]
|
||||
expected: FAIL
|
||||
|
||||
["u+ABC" => "U+ABC"]
|
||||
expected: FAIL
|
||||
|
||||
["u+aa" => "U+AA"]
|
||||
expected: FAIL
|
||||
|
||||
["u+abc" => "U+ABC"]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
[long_scroll_composited.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[backdrop-filter-border-radius.html]
|
||||
expected: FAIL
|
|
@ -0,0 +1,13 @@
|
|||
[XMLSerializer-serializeToString.html]
|
||||
[Check if generated prefixes match to "ns${index}".]
|
||||
expected: FAIL
|
||||
|
||||
[Check if "ns1" is generated even if the element already has xmlns:ns1.]
|
||||
expected: FAIL
|
||||
|
||||
[Check if attribute serialization takes into account of following xmlns:* attributes]
|
||||
expected: FAIL
|
||||
|
||||
[Check if attribute serialization takes into account of the same prefix declared in an ancestor element]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[image-TAO-wildcard.sub.html]
|
||||
[Cross-origin element with wildcard TAO is observed.]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
[observe-child-element.html]
|
||||
expected: TIMEOUT
|
||||
[Element from same-origin iframe is observable.]
|
||||
expected: TIMEOUT
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
[serial-report-only.https.html]
|
||||
[getPorts in serial report only mode]
|
||||
expected: FAIL
|
||||
|
||||
[requestPort in serial report only mode]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
[serial-reporting.https.html]
|
||||
[requestPort in serial reporting mode]
|
||||
expected: FAIL
|
||||
|
||||
[getPorts in serial reporting mode]
|
||||
expected: FAIL
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
[document_domain_setter_null.tentative.html]
|
||||
[No access when frame sets a `null` 'document.domain'.]
|
||||
expected: FAIL
|
||||
|
||||
[No access when parent sets a `null` 'document.domain'.]
|
||||
expected: FAIL
|
||||
|
||||
[No access when both sides set a `null` 'document.domain'.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
[window-open-noopener.html?_self]
|
||||
|
||||
[window-open-noopener.html?indexed]
|
||||
[noopener=1 means the same as noopener]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[window-open-noopener.html?_parent]
|
||||
|
||||
[window-open-noopener.html?_top]
|
|
@ -0,0 +1 @@
|
|||
leak-threshold: [gpu:51200]
|
|
@ -22,3 +22,32 @@
|
|||
|
||||
[getComputedStyle <th background>]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[attributes.sub.html?encoding=windows-1252]
|
||||
[getComputedStyle <tr background>]
|
||||
expected: FAIL
|
||||
|
||||
[getComputedStyle <td background>]
|
||||
expected: FAIL
|
||||
|
||||
[getComputedStyle <thead background>]
|
||||
expected: FAIL
|
||||
|
||||
[getComputedStyle <body background>]
|
||||
expected: FAIL
|
||||
|
||||
[getComputedStyle <tbody background>]
|
||||
expected: FAIL
|
||||
|
||||
[getComputedStyle <tfoot background>]
|
||||
expected: FAIL
|
||||
|
||||
[getComputedStyle <table background>]
|
||||
expected: FAIL
|
||||
|
||||
[getComputedStyle <th background>]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[attributes.sub.html?encoding=utf8]
|
||||
|
|
|
@ -23,3 +23,16 @@
|
|||
[hyperlink auditing <area ping>]
|
||||
expected: TIMEOUT
|
||||
|
||||
|
||||
[navigation.sub.html?encoding=windows-1252]
|
||||
expected:
|
||||
if not debug and e10s and (os == "linux") and (processor == "x86"): TIMEOUT
|
||||
if not debug and not asan and e10s and (os == "linux") and (processor == "x86_64"): TIMEOUT
|
||||
if not debug and (os == "win"): TIMEOUT
|
||||
if not debug and (os == "mac"): TIMEOUT
|
||||
[hyperlink auditing <a ping>]
|
||||
expected: TIMEOUT
|
||||
|
||||
[hyperlink auditing <area ping>]
|
||||
expected: TIMEOUT
|
||||
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
[string-compilation-base-url-external-classic.html]
|
||||
[inline-event-handlers-UA-code should successfully import]
|
||||
expected: FAIL
|
||||
|
||||
[reflected-inline-event-handlers should successfully import]
|
||||
expected: FAIL
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
[string-compilation-base-url-external-module.html]
|
||||
[inline-event-handlers-UA-code should successfully import]
|
||||
expected: FAIL
|
||||
|
||||
[reflected-inline-event-handlers should successfully import]
|
||||
expected: FAIL
|
||||
|
|
@ -1,7 +1,4 @@
|
|||
[string-compilation-nonce-classic.html]
|
||||
[setTimeout must inherit the nonce from the triggering script, thus execute]
|
||||
expected: FAIL
|
||||
|
||||
[inline event handlers triggered via UA code must inherit the nonce from the triggering script, thus execute]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
[string-compilation-nonce-module.html]
|
||||
[setTimeout must inherit the nonce from the triggering script, thus execute]
|
||||
expected: FAIL
|
||||
|
||||
[inline event handlers triggered via UA code must inherit the nonce from the triggering script, thus execute]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
[string-compilation-other-document.html]
|
||||
[inline event handlers triggered by JS should successfully import]
|
||||
expected: FAIL
|
||||
|
||||
[reflected inline event handlers should successfully import]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[child-display-none.tentative.html]
|
||||
expected: TIMEOUT
|
||||
[Child frame frozen]
|
||||
expected: TIMEOUT
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
[supported-longtask-types.any.html]
|
||||
[supportedEntryTypes contains 'longtask' and 'taskattribution'.]
|
||||
expected: FAIL
|
||||
|
||||
[supportedEntryTypes contains 'longtask' but not 'taskattribution'.]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[supported-longtask-types.any.worker.html]
|
||||
[supportedEntryTypes contains 'longtask' and 'taskattribution'.]
|
||||
expected: FAIL
|
||||
|
||||
[supportedEntryTypes contains 'longtask' but not 'taskattribution'.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[supported-longtask-types.window.html]
|
||||
[supportedEntryTypes contains 'longtask' but not 'taskattribution'.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[allowed.https.html]
|
||||
max-asserts: 2
|
|
@ -0,0 +1,2 @@
|
|||
[no-opt-in-allows.https.html]
|
||||
max-asserts: 2
|
|
@ -1,2 +1,2 @@
|
|||
local: 6153030f2e587bf87d8641038c687dce1fd3351a
|
||||
upstream: fab38653d3a4a8ce01db100fa049bdc72f4b8270
|
||||
local: e4bdf1e9a4d7125e27efdffec2ebdb7307a42137
|
||||
upstream: f8a1bfbe5454352d3f5b58845829968ff212519b
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
[supported_navigation_type.any.html]
|
||||
[supportedEntryTypes contains 'navigation'.]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[supported_navigation_type.any.worker.html]
|
||||
[supportedEntryTypes contains 'navigation'.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[supported_navigation_type.window.html]
|
||||
[supportedEntryTypes contains 'navigation'.]
|
||||
expected: FAIL
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
[supported-paint-type.any.html]
|
||||
[supportedEntryTypes contains 'paint'.]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[supported-paint-type.any.worker.html]
|
||||
[supportedEntryTypes contains 'paint'.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[supported-paint-type.window.html]
|
||||
[supportedEntryTypes contains 'paint'.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[payment-request-hasenrolledinstrument-method-protection.https.html]
|
||||
[Optionally, at the user agent's discretion, return a promise rejected with a "NotAllowedError" DOMException.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[payment-request-hasenrolledinstrument-method.https.html]
|
||||
[hasEnrolledInstrument() resolves to false for unsupported payment methods.]
|
||||
expected: FAIL
|
||||
|
|
@ -1,6 +1,9 @@
|
|||
[request-picture-in-picture-twice.html]
|
||||
disabled:
|
||||
if (os == "android"): https://bugzilla.mozilla.org/show_bug.cgi?id=1499003
|
||||
if os == "android": https://bugzilla.mozilla.org/show_bug.cgi?id=1499003
|
||||
[request Picture-in-Picture consumes user gesture]
|
||||
expected: FAIL
|
||||
|
||||
[request Picture-in-Picture does not require user gesture if document.pictureInPictureElement is set]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
[resource-reload-TAO.sub.html]
|
||||
expected: TIMEOUT
|
||||
[Test that TAO headers are reused on reloads.]
|
||||
expected: TIMEOUT
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[event-before-promise.html]
|
||||
[The 'change' event must fire before the [[orientationPendingPromise\]\] is resolved.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
[serial-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html]
|
||||
expected: TIMEOUT
|
||||
[Feature-Policy allow="serial" disallows cross-origin relocation.]
|
||||
expected: TIMEOUT
|
||||
|
||||
[Feature-Policy allow="serial" allows workers in same-origin relocation.]
|
||||
expected: TIMEOUT
|
||||
|
||||
[Feature-Policy allow="serial" allows same-origin relocation.]
|
||||
expected: TIMEOUT
|
||||
|
||||
[Feature-Policy allow="serial" disallows workers in cross-origin relocation.]
|
||||
expected: TIMEOUT
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
[serial-allowed-by-feature-policy-attribute.https.sub.html]
|
||||
expected: TIMEOUT
|
||||
[Feature policy "serial" can be enabled in a worker in same-origin iframe using allow="serial" attribute]
|
||||
expected: TIMEOUT
|
||||
|
||||
[Feature policy "serial" can be enabled in a worker in cross-origin iframe using allow="serial" attribute]
|
||||
expected: TIMEOUT
|
||||
|
||||
[Feature policy "serial" can be enabled in cross-origin iframe using allow="serial" attribute]
|
||||
expected: TIMEOUT
|
||||
|
||||
[Feature policy "serial" can be enabled in same-origin iframe using allow="serial" attribute]
|
||||
expected: TIMEOUT
|
||||
|
||||
[Inherited header feature policy allows dedicated workers.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
[serial-allowed-by-feature-policy.https.sub.html]
|
||||
expected: TIMEOUT
|
||||
[Feature-Policy header {"serial" : ["*"\]} allows cross-origin iframes.]
|
||||
expected: TIMEOUT
|
||||
|
||||
[Feature-Policy header {"serial" : ["*"\]} allows workers in cross-origin iframes.]
|
||||
expected: TIMEOUT
|
||||
|
||||
[Inherited header feature policy allows dedicated workers.]
|
||||
expected: FAIL
|
||||
|
||||
[Feature-Policy header {"serial" : ["*"\]} allows the top-level document.]
|
||||
expected: FAIL
|
||||
|
||||
[Feature-Policy header {"serial" : ["*"\]} allows same-origin iframes.]
|
||||
expected: TIMEOUT
|
||||
|
||||
[Feature-Policy header {"serial" : ["*"\]} allows workers in same-origin iframes.]
|
||||
expected: TIMEOUT
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
[serial-default-feature-policy.https.sub.html]
|
||||
expected: TIMEOUT
|
||||
[Default "serial" feature policy ["self"\] disallows cross-origin iframes.]
|
||||
expected: TIMEOUT
|
||||
|
||||
[Default "serial" feature policy ["self"\] allows same-origin iframes.]
|
||||
expected: TIMEOUT
|
||||
|
||||
[Default "serial" feature policy ["self"\] allows the top-level document.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
[serial-disabled-by-feature-policy.https.sub.html]
|
||||
expected: TIMEOUT
|
||||
[Feature-Policy header {"serial" : [\]} disallows cross-origin iframes.]
|
||||
expected: TIMEOUT
|
||||
|
||||
[Feature-Policy header {"serial" : [\]} disallows same-origin iframes.]
|
||||
expected: TIMEOUT
|
||||
|
||||
[Feature-Policy header {"serial" : [\]} disallows workers in cross-origin iframes.]
|
||||
expected: TIMEOUT
|
||||
|
||||
[Feature-Policy header {"serial" : [\]} disallows workers in same-origin iframes.]
|
||||
expected: TIMEOUT
|
||||
|
||||
[Inherited Feature-Policy header {"serial" : [\]} disallows dedicated workers.]
|
||||
expected: FAIL
|
||||
|
||||
[Feature-Policy header {"serial" : [\]} disallows getPorts in the top-level document.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,354 @@
|
|||
[async-iterator.any.serviceworker.html]
|
||||
[Async-iterating an empty but not closed/errored stream never executes the loop body and stalls the async function]
|
||||
expected: FAIL
|
||||
|
||||
[Calling return() twice rejects]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when manually calling return(); preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when returning inside loop body; preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[getIterator() throws if there's already a lock]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a push source]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a closed stream never executes the loop body, but works fine]
|
||||
expected: FAIL
|
||||
|
||||
[Acquiring a reader after exhaustively async-iterating a stream]
|
||||
expected: FAIL
|
||||
|
||||
[Async iterator instances should have the correct list of properties]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when returning inside loop body; preventCancel = false]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when manually calling return(); preventCancel = false]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when throwing inside loop body; preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when breaking inside loop body; preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when throwing inside loop body; preventCancel = false]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a pull source]
|
||||
expected: FAIL
|
||||
|
||||
[Acquiring a reader and reading the remaining chunks after partially async-iterating a stream with preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[Acquiring a reader after partially async-iterating a stream]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a partially consumed stream]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when breaking inside loop body; preventCancel = false]
|
||||
expected: FAIL
|
||||
|
||||
[calling return() while there are pending reads rejects]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a pull source manually]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating an errored stream throws]
|
||||
expected: FAIL
|
||||
|
||||
[next()'s fulfillment value has the right shape]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[async-iterator.any.sharedworker.html]
|
||||
[Async-iterating an empty but not closed/errored stream never executes the loop body and stalls the async function]
|
||||
expected: FAIL
|
||||
|
||||
[Calling return() twice rejects]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when manually calling return(); preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when returning inside loop body; preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[getIterator() throws if there's already a lock]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a push source]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a closed stream never executes the loop body, but works fine]
|
||||
expected: FAIL
|
||||
|
||||
[Acquiring a reader after exhaustively async-iterating a stream]
|
||||
expected: FAIL
|
||||
|
||||
[Async iterator instances should have the correct list of properties]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when returning inside loop body; preventCancel = false]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when manually calling return(); preventCancel = false]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when throwing inside loop body; preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when breaking inside loop body; preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when throwing inside loop body; preventCancel = false]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a pull source]
|
||||
expected: FAIL
|
||||
|
||||
[Acquiring a reader and reading the remaining chunks after partially async-iterating a stream with preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[Acquiring a reader after partially async-iterating a stream]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a partially consumed stream]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when breaking inside loop body; preventCancel = false]
|
||||
expected: FAIL
|
||||
|
||||
[calling return() while there are pending reads rejects]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a pull source manually]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating an errored stream throws]
|
||||
expected: FAIL
|
||||
|
||||
[next()'s fulfillment value has the right shape]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[async-iterator.any.worker.html]
|
||||
[Async-iterating an empty but not closed/errored stream never executes the loop body and stalls the async function]
|
||||
expected: FAIL
|
||||
|
||||
[Calling return() twice rejects]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when manually calling return(); preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when returning inside loop body; preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[getIterator() throws if there's already a lock]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a push source]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a closed stream never executes the loop body, but works fine]
|
||||
expected: FAIL
|
||||
|
||||
[Acquiring a reader after exhaustively async-iterating a stream]
|
||||
expected: FAIL
|
||||
|
||||
[Async iterator instances should have the correct list of properties]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when returning inside loop body; preventCancel = false]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when manually calling return(); preventCancel = false]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when throwing inside loop body; preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when breaking inside loop body; preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when throwing inside loop body; preventCancel = false]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a pull source]
|
||||
expected: FAIL
|
||||
|
||||
[Acquiring a reader and reading the remaining chunks after partially async-iterating a stream with preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[Acquiring a reader after partially async-iterating a stream]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a partially consumed stream]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when breaking inside loop body; preventCancel = false]
|
||||
expected: FAIL
|
||||
|
||||
[calling return() while there are pending reads rejects]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a pull source manually]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating an errored stream throws]
|
||||
expected: FAIL
|
||||
|
||||
[next()'s fulfillment value has the right shape]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[async-iterator.any.html]
|
||||
[Async-iterating an empty but not closed/errored stream never executes the loop body and stalls the async function]
|
||||
expected: FAIL
|
||||
|
||||
[Calling return() twice rejects]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when manually calling return(); preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when returning inside loop body; preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[getIterator() throws if there's already a lock]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a push source]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a closed stream never executes the loop body, but works fine]
|
||||
expected: FAIL
|
||||
|
||||
[Acquiring a reader after exhaustively async-iterating a stream]
|
||||
expected: FAIL
|
||||
|
||||
[Async iterator instances should have the correct list of properties]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when returning inside loop body; preventCancel = false]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when manually calling return(); preventCancel = false]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when throwing inside loop body; preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when breaking inside loop body; preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when throwing inside loop body; preventCancel = false]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a pull source]
|
||||
expected: FAIL
|
||||
|
||||
[Acquiring a reader and reading the remaining chunks after partially async-iterating a stream with preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[Acquiring a reader after partially async-iterating a stream]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a partially consumed stream]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when breaking inside loop body; preventCancel = false]
|
||||
expected: FAIL
|
||||
|
||||
[calling return() while there are pending reads rejects]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a pull source manually]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating an errored stream throws]
|
||||
expected: FAIL
|
||||
|
||||
[next()'s fulfillment value has the right shape]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[async-iterator.any.js]
|
||||
[Async-iterating an empty but not closed/errored stream never executes the loop body and stalls the async function]
|
||||
expected: FAIL
|
||||
|
||||
[Calling return() twice rejects]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when manually calling return(); preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when returning inside loop body; preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[getIterator() throws if there's already a lock]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a push source]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a closed stream never executes the loop body, but works fine]
|
||||
expected: FAIL
|
||||
|
||||
[Acquiring a reader after exhaustively async-iterating a stream]
|
||||
expected: FAIL
|
||||
|
||||
[Async iterator instances should have the correct list of properties]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when returning inside loop body; preventCancel = false]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when manually calling return(); preventCancel = false]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when throwing inside loop body; preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when breaking inside loop body; preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when throwing inside loop body; preventCancel = false]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a pull source]
|
||||
expected: FAIL
|
||||
|
||||
[Acquiring a reader and reading the remaining chunks after partially async-iterating a stream with preventCancel = true]
|
||||
expected: FAIL
|
||||
|
||||
[Acquiring a reader after partially async-iterating a stream]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a partially consumed stream]
|
||||
expected: FAIL
|
||||
|
||||
[Cancellation behavior when breaking inside loop body; preventCancel = false]
|
||||
expected: FAIL
|
||||
|
||||
[calling return() while there are pending reads rejects]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating a pull source manually]
|
||||
expected: FAIL
|
||||
|
||||
[Async-iterating an errored stream throws]
|
||||
expected: FAIL
|
||||
|
||||
[next()'s fulfillment value has the right shape]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
[brand-checks.any.worker.html]
|
||||
[ReadableStreamAsyncIteratorPrototype.return enforces a brand check]
|
||||
expected: FAIL
|
||||
|
||||
[ReadableStreamAsyncIteratorPrototype.next enforces a brand check]
|
||||
expected: FAIL
|
||||
|
||||
[Can get ReadableStreamAsyncIteratorPrototype object indirectly]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[brand-checks.any.serviceworker.html]
|
||||
[ReadableStreamAsyncIteratorPrototype.return enforces a brand check]
|
||||
expected: FAIL
|
||||
|
||||
[ReadableStreamAsyncIteratorPrototype.next enforces a brand check]
|
||||
expected: FAIL
|
||||
|
||||
[Can get ReadableStreamAsyncIteratorPrototype object indirectly]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[brand-checks.any.html]
|
||||
[ReadableStreamAsyncIteratorPrototype.return enforces a brand check]
|
||||
expected: FAIL
|
||||
|
||||
[ReadableStreamAsyncIteratorPrototype.next enforces a brand check]
|
||||
expected: FAIL
|
||||
|
||||
[Can get ReadableStreamAsyncIteratorPrototype object indirectly]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[brand-checks.any.sharedworker.html]
|
||||
[ReadableStreamAsyncIteratorPrototype.return enforces a brand check]
|
||||
expected: FAIL
|
||||
|
||||
[ReadableStreamAsyncIteratorPrototype.next enforces a brand check]
|
||||
expected: FAIL
|
||||
|
||||
[Can get ReadableStreamAsyncIteratorPrototype object indirectly]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[brand-checks.any.js]
|
||||
[ReadableStreamAsyncIteratorPrototype.return enforces a brand check]
|
||||
expected: FAIL
|
||||
|
||||
[ReadableStreamAsyncIteratorPrototype.next enforces a brand check]
|
||||
expected: FAIL
|
||||
|
||||
[Can get ReadableStreamAsyncIteratorPrototype object indirectly]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
[patched-global.any.serviceworker.html]
|
||||
[ReadableStream getIterator() should use the original values of getReader() and ReadableStreamDefaultReader methods]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[patched-global.any.sharedworker.html]
|
||||
[ReadableStream getIterator() should use the original values of getReader() and ReadableStreamDefaultReader methods]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[patched-global.any.worker.html]
|
||||
[ReadableStream getIterator() should use the original values of getReader() and ReadableStreamDefaultReader methods]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[patched-global.any.html]
|
||||
[ReadableStream getIterator() should use the original values of getReader() and ReadableStreamDefaultReader methods]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[patched-global.any.js]
|
||||
[ReadableStream getIterator() should use the original values of getReader() and ReadableStreamDefaultReader methods]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[auxclick_event.html]
|
||||
[auxclick event sequence received.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
[sub-sample-buffer-stitching.html]
|
||||
[# AUDIT TASK RUNNER FINISHED: 2 out of 2 tasks were failed.]
|
||||
expected: FAIL
|
||||
|
||||
[X Stitched sine-wave buffers at sample rate 44100 does not equal [0,0.06264832615852356,0.12505052983760834,0.18696144223213196,0.24813786149024963,0.308339387178421,0.36732956767082214,0.4248766303062439,0.4807544946670532,0.5347436666488647,0.5866319537162781,0.6362155675888062,0.683299720287323,0.7276993989944458,0.7692402005195618,0.8077588677406311...\] with an element-wise tolerance of {"absoluteThreshold":0.000090957,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[2003\]\t-9.6732087433338165e-2\t-9.6823699772357941e-2\t9.1612339019775391e-5\t9.4617680624852212e-4\t9.0957000000000003e-5\n\t[2004\]\t-3.4187544137239456e-2\t-3.4279607236385345e-2\t9.2063099145889282e-5\t2.6856520995424621e-3\t9.0957000000000003e-5\n\t[2005\]\t2.8491314500570297e-2\t2.8398986905813217e-2\t9.2327594757080078e-5\t3.2510876202481997e-3\t9.0957000000000003e-5\n\t[2006\]\t9.1058239340782166e-2\t9.0966261923313141e-2\t9.1977417469024658e-5\t1.0111157205356415e-3\t9.0957000000000003e-5\n\t[2007\]\t1.5326742827892303e-1\t1.5317615866661072e-1\t9.1269612312316895e-5\t5.9584737668585898e-4\t9.0957000000000003e-5\n\t...and 38045 more errors.\n\tMax AbsError of 2.0274701528251171e-3 at index of 44050.\n\t[44050\]\t-7.1237324737012386e-3\t-5.0962623208761215e-3\t2.0274701528251171e-3\t3.9783473164634225e-1\t9.0957000000000003e-5\n\tMax RelError of 5.5714977262789269e+1 at index of 30419.\n\t[30419\]\t-1.4247581129893661e-3\t-2.5121373255387880e-5\t1.3996367397339782e-3\t5.5714977262789269e+1\t9.0957000000000003e-5\n]
|
||||
expected: FAIL
|
||||
|
||||
[< [buffer-stitching-2\] 1 out of 3 assertions were failed.]
|
||||
expected: FAIL
|
||||
|
||||
[X SNR (56.56582705421649 dB) is not greater than or equal to 65.737. Got 56.56582705421649.]
|
||||
expected: FAIL
|
||||
|
||||
[< [buffer-stitching-1\] 2 out of 3 assertions were failed.]
|
||||
expected: FAIL
|
||||
|
||||
[X SNR (58.62182031202294 dB) is not greater than or equal to 85.586. Got 58.62182031202294.]
|
||||
expected: FAIL
|
||||
|
||||
[X SNR (56.565827273128384 dB) is not greater than or equal to 65.737. Got 56.565827273128384.]
|
||||
expected: FAIL
|
||||
|
||||
[X SNR (58.62182032943065 dB) is not greater than or equal to 85.586. Got 58.62182032943065.]
|
||||
expected: FAIL
|
||||
|
||||
[X Stitched sine-wave buffers at sample rate 43800 does not equal [0,0.06264832615852356,0.12505052983760834,0.18696144223213196,0.24813786149024963,0.308339387178421,0.36732956767082214,0.4248766303062439,0.4807544946670532,0.5347436666488647,0.5866319537162781,0.6362155675888062,0.683299720287323,0.7276993989944458,0.7692402005195618,0.8077588677406311...\] with an element-wise tolerance of {"absoluteThreshold":0.0038986,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[31\]\t9.2517089843750000e-1\t9.3139308691024780e-1\t6.2221884727478027e-3\t6.6805182046056925e-3\t3.8985999999999999e-3\n\t[270\]\t-9.3151855468750000e-1\t-9.3846446275711060e-1\t6.9459080696105957e-3\t7.4013543882143849e-3\t3.8985999999999999e-3\n\t[273\]\t-9.8104858398437500e-1\t-9.8648869991302490e-1\t5.4401159286499023e-3\t5.5146256912314735e-3\t3.8985999999999999e-3\n\t[421\]\t9.3499755859375000e-1\t9.5192760229110718e-1\t1.6930043697357178e-2\t1.7785011860786272e-2\t3.8985999999999999e-3\n\t[424\]\t9.7683715820312500e-1\t9.9241310358047485e-1\t1.5575945377349854e-2\t1.5695021882675898e-2\t3.8985999999999999e-3\n\t...and 535 more errors.\n\tMax AbsError of 4.4242441654205322e-2 at index of 43225.\n\t[43225\]\t9.4824218750000000e-1\t9.9248462915420532e-1\t4.4242441654205322e-2\t4.4577457780790718e-2\t3.8985999999999999e-3\n\tMax RelError of 4.4577457780790718e-2 at index of 43225.\n\t[43225\]\t9.4824218750000000e-1\t9.9248462915420532e-1\t4.4242441654205322e-2\t4.4577457780790718e-2\t3.8985999999999999e-3\n]
|
||||
expected: FAIL
|
||||
|
||||
[X SNR (58.62182025211463 dB) is not greater than or equal to 85.586. Got 58.62182025211463.]
|
||||
expected: FAIL
|
||||
|
||||
[< [buffer-stitching-2\] 2 out of 3 assertions were failed.]
|
||||
expected: FAIL
|
||||
|
||||
[X SNR (46.181437501508576 dB) is not greater than or equal to 65.737. Got 46.181437501508576.]
|
||||
expected: FAIL
|
||||
|
||||
[X SNR (56.56582707672834 dB) is not greater than or equal to 65.737. Got 56.56582707672834.]
|
||||
expected: FAIL
|
||||
|
||||
[X SNR (58.62182033056576 dB) is not greater than or equal to 85.586. Got 58.62182033056576.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
[sub-sample-scheduling.html]
|
||||
[X With playbackRate 0.25: output0[17\] is not equal to 0. Got 0.6892558932304382.]
|
||||
expected: FAIL
|
||||
|
||||
[X With playbackRate 0.25: output0[18\] is not close to 1.0499999999999998 within a relative error of 4.542e-8 (RelErr=0.07462642306373217). Got 0.971642255783081.]
|
||||
expected: FAIL
|
||||
|
||||
[X With playbackRate 4: output1[17\] is not equal to 0. Got -0.09868232905864716.]
|
||||
expected: FAIL
|
||||
|
||||
[X output0[3\] is not equal to 0. Got 1.]
|
||||
expected: FAIL
|
||||
|
||||
[X output0[0:33\]: Expected 0 for all values but found 1 unexpected values: \n\tIndex\tActual\n\t[33\]\t1]
|
||||
expected: FAIL
|
||||
|
||||
[< [sub-sample-grain\] 3 out of 16 assertions were failed.]
|
||||
expected: FAIL
|
||||
|
||||
[X output0[37\] should not be equal to 0. Got 0.]
|
||||
expected: FAIL
|
||||
|
||||
[X With playbackRate 4: output1[18\] is not close to 1.7999999999999972 within a relative error of 4.542e-8 (RelErr=0.05661286248101295). Got 1.9019031524658203.]
|
||||
expected: FAIL
|
||||
|
||||
[X output1[33\] should not be equal to 0. Got 0.]
|
||||
expected: FAIL
|
||||
|
||||
[X output0 expected to be equal to the array [0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1...\] but differs in 2 places:\n\tIndex\tActual\t\t\tExpected\n\t[3\]\t1.0000000000000000e+0\t0.0000000000000000e+0\n\t[37\]\t0.0000000000000000e+0\t1.0000000000000000e+0]
|
||||
expected: FAIL
|
||||
|
||||
[X output1[34:8190\] does not equal [1.100000023841858,2.0999999046325684,3.0999999046325684,4.099999904632568,5.099999904632568,6.099999904632568,7.099999904632568,8.100000381469727,9.100000381469727,10.100000381469727,11.100000381469727,12.100000381469727,13.100000381469727,14.100000381469727,15.100000381469727,16.100000381469727...\] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[0\]\t1.0000000000000000e+0\t1.1000000238418579e+0\t1.0000002384185791e-1\t9.0909110613105290e-2\t0.0000000000000000e+0\n\t[1\]\t2.0000000000000000e+0\t2.0999999046325684e+0\t9.9999904632568359e-2\t4.7619004368509764e-2\t0.0000000000000000e+0\n\t[2\]\t3.0000000000000000e+0\t3.0999999046325684e+0\t9.9999904632568359e-2\t3.2258034744817511e-2\t0.0000000000000000e+0\n\t[3\]\t4.0000000000000000e+0\t4.0999999046325684e+0\t9.9999904632568359e-2\t2.4390221209414906e-2\t0.0000000000000000e+0\n\t[4\]\t5.0000000000000000e+0\t5.0999999046325684e+0\t9.9999904632568359e-2\t1.9607824804414951e-2\t0.0000000000000000e+0\n\t...and 8152 more errors.\n\tMax AbsError of 1.0009765625000000e-1 at index of 2047.\n\t[2047\]\t2.0480000000000000e+3\t2.0481000976562500e+3\t1.0009765625000000e-1\t4.8873419987893697e-5\t0.0000000000000000e+0\n\tMax RelError of 9.0909110613105290e-2 at index of 0.\n]
|
||||
expected: FAIL
|
||||
|
||||
[# AUDIT TASK RUNNER FINISHED: 4 out of 4 tasks were failed.]
|
||||
expected: FAIL
|
||||
|
||||
[< [sub-sample accurate start with playbackRate\] 4 out of 5 assertions were failed.]
|
||||
expected: FAIL
|
||||
|
||||
[X output0[34:8190\] does not equal [1.899999976158142,2.9000000953674316,3.9000000953674316,4.900000095367432,5.900000095367432,6.900000095367432,7.900000095367432,8.899999618530273,9.899999618530273,10.899999618530273,11.899999618530273,12.899999618530273,13.899999618530273,14.899999618530273,15.899999618530273,16.899999618530273...\] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[0\]\t2.0000000000000000e+0\t1.8999999761581421e+0\t1.0000002384185791e-1\t5.2631592156154129e-2\t0.0000000000000000e+0\n\t[1\]\t3.0000000000000000e+0\t2.9000000953674316e+0\t9.9999904632568359e-2\t3.4482724601392921e-2\t0.0000000000000000e+0\n\t[2\]\t4.0000000000000000e+0\t3.9000000953674316e+0\t9.9999904632568359e-2\t2.5641000560833845e-2\t0.0000000000000000e+0\n\t[3\]\t5.0000000000000000e+0\t4.9000000953674316e+0\t9.9999904632568359e-2\t2.0408143405366560e-2\t0.0000000000000000e+0\n\t[4\]\t6.0000000000000000e+0\t5.9000000953674316e+0\t9.9999904632568359e-2\t1.6949136104436064e-2\t0.0000000000000000e+0\n\t...and 8152 more errors.\n\tMax AbsError of 1.0009765625000000e-1 at index of 2047.\n\t[2047\]\t2.0490000000000000e+3\t2.0488999023437500e+3\t1.0009765625000000e-1\t4.8854341852180105e-5\t0.0000000000000000e+0\n\tMax RelError of 5.2631592156154129e-2 at index of 0.\n]
|
||||
expected: FAIL
|
||||
|
||||
[< [sub-sample accurate start\] 3 out of 6 assertions were failed.]
|
||||
expected: FAIL
|
||||
|
||||
[< [sub-sample accurate stop\] 1 out of 9 assertions were failed.]
|
||||
expected: FAIL
|
||||
|
||||
[X With playbackRate 0.25: output0[17\] is not equal to 0. Got 0.73760986328125.]
|
||||
expected: FAIL
|
||||
|
||||
[X With playbackRate 0.25: output0[18\] is not close to 1.0499999999999998 within a relative error of 4.542e-8 (RelErr=0.11400204613095223). Got 0.9302978515625.]
|
||||
expected: FAIL
|
||||
|
||||
[X With playbackRate 4: output1[17\] is not equal to 0. Got 0.058258056640625.]
|
||||
expected: FAIL
|
||||
|
||||
[X With playbackRate 4: output1[18\] is not close to 1.7999999999999972 within a relative error of 4.542e-8 (RelErr=0.5584106445312493). Got 0.79486083984375.]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[RTCIceConnectionState-candidate-pair.https.html]
|
||||
expected: TIMEOUT
|
||||
[On ICE connected, getStats() contains a connected candidate-pair]
|
||||
expected: TIMEOUT
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
[RTCPeerConnection-iceConnectionState.html]
|
||||
[RTCPeerConnection-iceConnectionState.https.html]
|
||||
[connection with one data channel should eventually have connected connection state]
|
||||
expected: FAIL
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
[RTCPeerConnection-track-stats.https.html]
|
||||
expected: TIMEOUT
|
||||
[addTrack() without setLocalDescription() yields track stats]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -36,21 +37,25 @@
|
|||
expected: FAIL
|
||||
|
||||
[RTCRtpSender.getStats() contains only outbound-rtp and related stats]
|
||||
expected: FAIL
|
||||
expected: TIMEOUT
|
||||
|
||||
[RTCRtpReceiver.getStats() contains only inbound-rtp and related stats]
|
||||
expected: FAIL
|
||||
expected: NOTRUN
|
||||
|
||||
[RTCPeerConnection.getStats(track) throws InvalidAccessError when there are zero senders or receivers for the track]
|
||||
expected: FAIL
|
||||
expected: NOTRUN
|
||||
|
||||
[RTCPeerConnection.getStats(track) throws InvalidAccessError when there are multiple senders for the track]
|
||||
expected: FAIL
|
||||
expected: NOTRUN
|
||||
|
||||
[RTCPeerConnection.getStats(receivingTrack) is the same as RTCRtpReceiver.getStats()]
|
||||
disabled:
|
||||
if debug and not e10s and (os == "linux"): wpt-sync Bug 1453975
|
||||
expected: NOTRUN
|
||||
|
||||
[Media stream stats references track stats]
|
||||
expected: FAIL
|
||||
|
||||
[RTCPeerConnection.getStats(sendingTrack) is the same as RTCRtpSender.getStats()]
|
||||
expected: NOTRUN
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
[simplecall.https.html]
|
||||
max-asserts: 2
|
|
@ -0,0 +1,7 @@
|
|||
[xrSession_identity_referenceSpace.https.html]
|
||||
[Identity reference space provides correct poses for immersive sessions]
|
||||
expected: FAIL
|
||||
|
||||
[Identity reference space provides correct poses for inline sessions]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# People who've changed name:
|
||||
|
||||
# Sam Sneddon:
|
||||
Sam Sneddon <me@gsnedders.com>
|
||||
Sam Sneddon <me@gsnedders.com> <geoffers@gmail.com>
|
||||
|
||||
# Theresa O'Connor:
|
||||
Theresa O'Connor <eoconnor@apple.com>
|
||||
Theresa O'Connor <hober0@gmail.com>
|
|
@ -1,2 +1,5 @@
|
|||
# Prevent accidentially touching CSS submodules
|
||||
/css/tools/ @plinss @kojiishi @jgraham @gsnedders
|
||||
# Prevent accidentially touching CSS subtree
|
||||
/css/tools/apiclient/ @plinss @jgraham @gsnedders
|
||||
|
||||
# Prevent accidentally touching tools/third_party
|
||||
/tools/third_party/ @jgraham @gsnedders
|
||||
|
|
|
@ -30,3 +30,16 @@ function waitForAsyncAnimationFrames(count) {
|
|||
// AnimationWorklet.
|
||||
return waitForAnimationFrames(count + 1);
|
||||
}
|
||||
|
||||
async function waitForAnimationFrameWithCondition(condition) {
|
||||
do {
|
||||
await new Promise(window.requestAnimationFrame);
|
||||
} while (!condition())
|
||||
};
|
||||
|
||||
async function waitForDocumentTimelineAdvance() {
|
||||
const timeAtStart = document.timeline.currentTime;
|
||||
do {
|
||||
await new Promise(window.requestAnimationFrame);
|
||||
} while (timeAtStart === document.timeline.currentTime)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>The playback rate of a worklet animation</title>
|
||||
<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
// Presence of playback rate adds FP operations to calculating start_time
|
||||
// and current_time of animations. That's why it's needed to increase FP error
|
||||
// for comparing times in these tests.
|
||||
window.assert_times_equal = (actual, expected, description) => {
|
||||
assert_approx_equals(actual, expected, 0.002, description);
|
||||
};
|
||||
</script>
|
||||
<script src="/web-animations/testcommon.js"></script>
|
||||
<script src="common.js"></script>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
function InstantiateWorkletAnimation(test) {
|
||||
const DURATION = 10000; // ms
|
||||
const KEYFRAMES = { height : ['100px', '50px'] };
|
||||
return new WorkletAnimation('passthrough', new KeyframeEffect(createDiv(test),
|
||||
KEYFRAMES, DURATION), document.timeline);
|
||||
}
|
||||
|
||||
promise_test(async t => {
|
||||
await registerPassthroughAnimator();
|
||||
const animation = InstantiateWorkletAnimation(t);
|
||||
|
||||
animation.playbackRate = 0.5;
|
||||
animation.play();
|
||||
assert_equals(animation.currentTime, 0,
|
||||
'Zero current time is not affected by playbackRate.');
|
||||
}, 'Zero current time is not affected by playbackRate set while the animation is in idle state.');
|
||||
|
||||
promise_test(async t => {
|
||||
await registerPassthroughAnimator();
|
||||
const animation = InstantiateWorkletAnimation(t);
|
||||
|
||||
animation.play();
|
||||
animation.playbackRate = 0.5;
|
||||
assert_equals(animation.currentTime, 0,
|
||||
'Zero current time is not affected by playbackRate.');
|
||||
}, 'Zero current time is not affected by playbackRate set while the animation is in play-pending state.');
|
||||
|
||||
promise_test(async t => {
|
||||
await registerPassthroughAnimator();
|
||||
const animation = InstantiateWorkletAnimation(t);
|
||||
const playbackRate = 2;
|
||||
|
||||
animation.play();
|
||||
|
||||
await waitForNextFrame();
|
||||
|
||||
// Set playback rate while the animation is playing.
|
||||
const prevCurrentTime = animation.currentTime;
|
||||
animation.playbackRate = playbackRate;
|
||||
|
||||
assert_times_equal(animation.currentTime, prevCurrentTime,
|
||||
'The current time should stay unaffected by setting playback rate.');
|
||||
}, 'Non zero current time is not affected by playbackRate set while the animation is in play state.');
|
||||
|
||||
promise_test(async t => {
|
||||
await registerPassthroughAnimator();
|
||||
const animation = InstantiateWorkletAnimation(t);
|
||||
const playbackRate = 2;
|
||||
|
||||
animation.play();
|
||||
|
||||
await waitForNextFrame();
|
||||
|
||||
// Set playback rate while the animation is playing
|
||||
const prevCurrentTime = animation.currentTime;
|
||||
const prevTimelineTime = document.timeline.currentTime;
|
||||
animation.playbackRate = playbackRate;
|
||||
|
||||
// Play the animation some more.
|
||||
await waitForNextFrame();
|
||||
|
||||
const currentTime = animation.currentTime;
|
||||
const currentTimelineTime = document.timeline.currentTime;
|
||||
|
||||
assert_times_equal(currentTime - prevCurrentTime, (currentTimelineTime - prevTimelineTime) * playbackRate,
|
||||
'The current time should increase two times faster than timeline.');
|
||||
|
||||
}, 'The playback rate affects the rate of progress of the current time.');
|
||||
|
||||
promise_test(async t => {
|
||||
await registerPassthroughAnimator();
|
||||
const animation = InstantiateWorkletAnimation(t);;
|
||||
const playbackRate = 2;
|
||||
|
||||
// Set playback rate while the animation is in 'idle' state.
|
||||
animation.playbackRate = playbackRate;
|
||||
animation.play();
|
||||
const prevTimelineTime = document.timeline.currentTime;
|
||||
|
||||
await waitForNextFrame();
|
||||
|
||||
const currentTime = animation.currentTime;
|
||||
const timelineTime = document.timeline.currentTime;
|
||||
assert_times_equal(currentTime, (timelineTime - prevTimelineTime) * playbackRate,
|
||||
'The current time should increase two times faster than timeline.');
|
||||
}, 'The playback rate set before the animation started playing affects the ' +
|
||||
'rate of progress of the current time');
|
||||
|
||||
promise_test(async t => {
|
||||
await registerPassthroughAnimator();
|
||||
const timing = { duration: 100,
|
||||
easing: 'linear',
|
||||
fill: 'none',
|
||||
iterations: 1
|
||||
};
|
||||
const target = createDiv(t);
|
||||
const keyframeEffect = new KeyframeEffect(target, { opacity: [0, 1] }, timing);
|
||||
const animation = new WorkletAnimation('passthrough', keyframeEffect, document.timeline);
|
||||
const playbackRate = 2;
|
||||
|
||||
animation.play();
|
||||
animation.playbackRate = playbackRate;
|
||||
|
||||
await waitForNextFrame();
|
||||
|
||||
assert_times_equal(keyframeEffect.getComputedTiming().localTime, animation.currentTime,
|
||||
'When playback rate is set on WorkletAnimation, the underlying effect\'s timing should be properly updated.');
|
||||
|
||||
assert_approx_equals(Number(getComputedStyle(target).opacity),
|
||||
animation.currentTime / 100, 0.001,
|
||||
'When playback rate is set on WorkletAnimation, the underlying effect should produce correct visual result.');
|
||||
|
||||
}, 'When playback rate is updated, the underlying effect is properly updated ' +
|
||||
'with the current time of its WorkletAnimation and produces correct ' +
|
||||
'visual result.');
|
||||
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<style>
|
||||
#box {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
transform: translateY(100px);
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="box"></div>
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Reference for Animation Worklet local time set after duration</title>
|
||||
<style>
|
||||
#box {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: green;
|
||||
will-change: transform;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="box"></div>
|
|
@ -0,0 +1,41 @@
|
|||
<html class="reftest-wait">
|
||||
<title>Animation Worklet local time set after duration</title>
|
||||
<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
|
||||
<meta name="assert" content="If an effect doesn't have fill-mode specified, setting its local time beyond its duration makes the animation inactive.">
|
||||
<link rel="match" href="worklet-animation-local-time-after-duration-ref.html">
|
||||
|
||||
<script src="/web-animations/testcommon.js"></script>
|
||||
<script src="/common/reftest-wait.js"></script>
|
||||
<script src="common.js"></script>
|
||||
|
||||
<style>
|
||||
#box {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="box"></div>
|
||||
|
||||
<script>
|
||||
registerConstantLocalTimeAnimator(2000).then(() => {
|
||||
const box = document.getElementById('box');
|
||||
const effect = new KeyframeEffect(box,
|
||||
[
|
||||
{ transform: 'translateY(100px)' },
|
||||
{ transform: 'translateY(200px)' }
|
||||
], {
|
||||
duration: 1000,
|
||||
delay: 1000
|
||||
}
|
||||
);
|
||||
|
||||
const animation = new WorkletAnimation('constant_time', effect);
|
||||
animation.play();
|
||||
|
||||
waitForAsyncAnimationFrames(1).then(_ => {
|
||||
takeScreenshot();
|
||||
});
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Reference for Animation Worklet local time set before start</title>
|
||||
<style>
|
||||
#box {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: green;
|
||||
will-change: transform;
|
||||
transform: translateY(200px);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="box"></div>
|
|
@ -0,0 +1,41 @@
|
|||
<html class="reftest-wait">
|
||||
<title>Animation Worklet local time set before start</title>
|
||||
<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
|
||||
<meta name="assert" content="The local time should be trimmed by the duration, e.g. this is equivalent to effect.localTime = 0">
|
||||
<link rel="match" href="worklet-animation-local-time-before-start-ref.html">
|
||||
|
||||
<script src="/web-animations/testcommon.js"></script>
|
||||
<script src="/common/reftest-wait.js"></script>
|
||||
<script src="common.js"></script>
|
||||
|
||||
<style>
|
||||
#box {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="box"></div>
|
||||
|
||||
<script>
|
||||
registerConstantLocalTimeAnimator(-500).then(() => {
|
||||
const box = document.getElementById('box');
|
||||
const effect = new KeyframeEffect(box,
|
||||
[
|
||||
{ transform: 'translateY(200px)' },
|
||||
{ transform: 'translateY(0px)' }
|
||||
], {
|
||||
duration: 1000,
|
||||
fill: 'backwards'
|
||||
}
|
||||
);
|
||||
|
||||
const animation = new WorkletAnimation('constant_time', effect);
|
||||
animation.play();
|
||||
|
||||
waitForAsyncAnimationFrames(1).then(_ => {
|
||||
takeScreenshot();
|
||||
});
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<title>Verify that calling pause immediately after playing works as expected</title>
|
||||
<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
|
||||
<link rel="match" href="references/translated-box-ref.html">
|
||||
|
||||
<script src="/common/reftest-wait.js"></script>
|
||||
<script src="/web-animations/testcommon.js"></script>
|
||||
<script src="common.js"></script>
|
||||
<style>
|
||||
#box {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="box"></div>
|
||||
|
||||
<script>
|
||||
registerPassthroughAnimator().then(async _ => {
|
||||
const box = document.getElementById('box');
|
||||
const effect = new KeyframeEffect(box,
|
||||
{ transform: ['translateY(100px)', 'translateY(200px)'] },
|
||||
{ duration: 100, iterations: 1 }
|
||||
);
|
||||
|
||||
const animation = new WorkletAnimation('passthrough', effect);
|
||||
animation.play();
|
||||
// Immediately pausing animation should freeze the current time at 0.
|
||||
animation.pause();
|
||||
// Wait at least one frame to ensure a paused animation actually freezes.
|
||||
await waitForAsyncAnimationFrames(1);
|
||||
takeScreenshot();
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,40 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<title>Verify that calling pause immediately after playing works as expected</title>
|
||||
<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
|
||||
<link rel="match" href="references/translated-box-ref.html">
|
||||
|
||||
<script src="/common/reftest-wait.js"></script>
|
||||
<script src="common.js"></script>
|
||||
<style>
|
||||
#box {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="box"></div>
|
||||
|
||||
<script>
|
||||
registerPassthroughAnimator().then(async _ => {
|
||||
const duration = 18; // a bit longer than a frame
|
||||
const box = document.getElementById('box');
|
||||
const effect = new KeyframeEffect(box,
|
||||
{ transform: ['translateY(0px)', 'translateY(100px)'] },
|
||||
{ duration: duration, iterations: 1, fill: 'forwards'}
|
||||
);
|
||||
|
||||
const animation = new WorkletAnimation('passthrough', effect);
|
||||
// Immediately pausing animation should freeze the current time at 0.
|
||||
animation.pause();
|
||||
// Playing should cause animation to resume.
|
||||
animation.play();
|
||||
// Wait until we ensure animation has reached completion.
|
||||
await waitForAnimationFrameWithCondition( _ => {
|
||||
return animation.currentTime >= duration;
|
||||
});
|
||||
takeScreenshot();
|
||||
});
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,60 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Verify that currentTime and playState are correct when animation is paused</title>
|
||||
<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/web-animations/testcommon.js"></script>
|
||||
<script src="common.js"></script>
|
||||
|
||||
<div id="box"></div>
|
||||
|
||||
<script>
|
||||
|
||||
setup(setupAndRegisterTests, {explicit_done: true});
|
||||
|
||||
function createAnimation() {
|
||||
const box = document.getElementById('box');
|
||||
const effect = new KeyframeEffect(box,
|
||||
{ transform: ['translateY(100px)', 'translateY(200px)'] },
|
||||
{ duration: 100, iterations: 1 }
|
||||
);
|
||||
|
||||
return new WorkletAnimation('passthrough', effect);
|
||||
}
|
||||
|
||||
async function setupAndRegisterTests() {
|
||||
await registerPassthroughAnimator();
|
||||
|
||||
promise_test(async t => {
|
||||
const animation = createAnimation();
|
||||
animation.play();
|
||||
// Immediately pausing animation should freeze the current time at 0.
|
||||
animation.pause();
|
||||
assert_equals(animation.currentTime, 0);
|
||||
assert_equals(animation.playState, "paused");
|
||||
// Wait some time to ensure a paused animation actually freezes.
|
||||
await waitForNextFrame();
|
||||
assert_equals(animation.currentTime, 0);
|
||||
assert_equals(animation.playState, "paused");
|
||||
}, 'pausing an animation freezes its current time');
|
||||
|
||||
promise_test(async t => {
|
||||
const animation = createAnimation();
|
||||
animation.pause();
|
||||
animation.play();
|
||||
// Allow one async animation frame to pass so that animation is running.
|
||||
await waitForAsyncAnimationFrames(1);
|
||||
assert_equals(animation.playState, "running");
|
||||
// Allow time to advance so that we have a non-zero current time.
|
||||
await waitForDocumentTimelineAdvance();
|
||||
const timelineTime = document.timeline.currentTime;
|
||||
assert_greater_than(animation.currentTime, 0);
|
||||
assert_times_equal(animation.currentTime, (timelineTime - animation.startTime));
|
||||
}, 'playing a paused animation should resume it');
|
||||
|
||||
done();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Reference for Worklet Animation sets keyframes</title>
|
||||
<style>
|
||||
#box {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
transform: translateX(100px);
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="box"></div>
|
|
@ -0,0 +1,44 @@
|
|||
<html class="reftest-wait">
|
||||
<title>Worklet Animation sets keyframes</title>
|
||||
<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
|
||||
<meta name="assert" content="Can update the keyframes for an effect while the animation is running">
|
||||
<link rel="match" href="worklet-animation-set-keyframes-ref.html">
|
||||
|
||||
<script src="/web-animations/testcommon.js"></script>
|
||||
<script src="/common/reftest-wait.js"></script>
|
||||
<script src="common.js"></script>
|
||||
|
||||
<style>
|
||||
#box {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="box"></div>
|
||||
|
||||
<script>
|
||||
registerConstantLocalTimeAnimator(500).then(()=>{
|
||||
const keyframes_before = [
|
||||
{ transform: 'translateY(0)' },
|
||||
{ transform: 'translateY(200px)' }
|
||||
];
|
||||
const keyframes_after = [
|
||||
{ transform: 'translateX(0)' },
|
||||
{ transform: 'translateX(200px)' }
|
||||
];
|
||||
|
||||
const box = document.getElementById('box');
|
||||
const effect = new KeyframeEffect(box, keyframes_before, {duration: 1000});
|
||||
const animation = new WorkletAnimation('constant_time', effect);
|
||||
animation.play();
|
||||
|
||||
waitForAsyncAnimationFrames(1).then(_ => {
|
||||
effect.setKeyframes(keyframes_after);
|
||||
waitForAsyncAnimationFrames(1).then(_ => {
|
||||
takeScreenshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Reference for Worklet Animation sets timing</title>
|
||||
<style>
|
||||
#box {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
transform: translateX(50px);
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="box"></div>
|
|
@ -0,0 +1,46 @@
|
|||
<html class="reftest-wait">
|
||||
<title>Worklet Animation sets timing</title>
|
||||
<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
|
||||
<meta name="assert" content="Can update the timing for an effect while the animation is running">
|
||||
<link rel="match" href="worklet-animation-set-timing-ref.html">
|
||||
|
||||
<script src="/web-animations/testcommon.js"></script>
|
||||
<script src="/common/reftest-wait.js"></script>
|
||||
<script src="common.js"></script>
|
||||
|
||||
<style>
|
||||
#box {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="box"></div>
|
||||
|
||||
<script>
|
||||
registerConstantLocalTimeAnimator(500).then(()=>{
|
||||
const keyframes = [
|
||||
{ transform: 'translateX(0)' },
|
||||
{ transform: 'translateX(200px)' }
|
||||
];
|
||||
const options_before = {
|
||||
duration: 1000
|
||||
};
|
||||
const options_after = {
|
||||
duration: 2000
|
||||
};
|
||||
|
||||
const box = document.getElementById('box');
|
||||
const effect = new KeyframeEffect(box, keyframes, options_before);
|
||||
const animation = new WorkletAnimation('constant_time', effect);
|
||||
animation.play();
|
||||
|
||||
waitForAsyncAnimationFrames(1).then(_ => {
|
||||
effect.updateTiming(options_after);
|
||||
waitForAsyncAnimationFrames(1).then(_ => {
|
||||
takeScreenshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
|
@ -347,22 +347,9 @@ backgroundFetchTest(async (test, backgroundFetch) => {
|
|||
uniqueId(), ['resources/feature-name.txt', '/common/slow.py']);
|
||||
|
||||
const record = await registration.match('resources/feature-name.txt');
|
||||
|
||||
await new Promise(resolve => {
|
||||
const expectedResultText = 'Background Fetch';
|
||||
|
||||
registration.onprogress = async event => {
|
||||
if (event.target.downloaded < expectedResultText.length)
|
||||
return;
|
||||
|
||||
const response = await record.responseReady;
|
||||
|
||||
assert_true(response.url.includes('resources/feature-name.txt'));
|
||||
const completedResponseText = await response.text();
|
||||
assert_equals(completedResponseText, expectedResultText);
|
||||
|
||||
resolve();
|
||||
};
|
||||
});
|
||||
const response = await record.responseReady;
|
||||
assert_true(response.url.includes('resources/feature-name.txt'));
|
||||
const completedResponseText = await response.text();
|
||||
assert_equals(completedResponseText, 'Background Fetch');
|
||||
|
||||
}, 'Access to active fetches is supported.');
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
idl_test(
|
||||
['background-fetch'],
|
||||
['service-workers', 'dedicated-workers', 'dom'],
|
||||
['service-workers', 'html', 'dom'],
|
||||
idl_array => {
|
||||
const isServiceWorker = location.pathname.includes('.serviceworker.');
|
||||
if (isServiceWorker) {
|
||||
|
|
|
@ -11,28 +11,27 @@ test(() => {
|
|||
assert_equals(navigator.clipboard, navigator.clipboard);
|
||||
}, "navigator.clipboard exists");
|
||||
|
||||
/* clipboard.write() */
|
||||
/* clipboard.write(Blob/text) */
|
||||
|
||||
promise_test(async () => {
|
||||
const dt = new DataTransfer();
|
||||
dt.items.add("Howdy", "text/plain");
|
||||
await navigator.clipboard.write(dt);
|
||||
}, "navigator.clipboard.write(DataTransfer) succeeds");
|
||||
const blob = new Blob(["hello"], {type: 'text/plain'});
|
||||
await navigator.clipboard.write(blob);
|
||||
}, "navigator.clipboard.write(Blob) succeeds");
|
||||
|
||||
promise_test(async t => {
|
||||
await promise_rejects(t, new TypeError(),
|
||||
navigator.clipboard.write());
|
||||
}, "navigator.clipboard.write() fails (expect DataTransfer)");
|
||||
}, "navigator.clipboard.write() fails (expect Blob)");
|
||||
|
||||
promise_test(async t => {
|
||||
await promise_rejects(t, new TypeError(),
|
||||
navigator.clipboard.write(null));
|
||||
}, "navigator.clipboard.write(null) fails (expect DataTransfer)");
|
||||
}, "navigator.clipboard.write(null) fails (expect Blob)");
|
||||
|
||||
promise_test(async t => {
|
||||
await promise_rejects(t, new TypeError(),
|
||||
navigator.clipboard.write("Bad string"));
|
||||
}, "navigator.clipboard.write(DOMString) fails (expect DataTransfer)");
|
||||
}, "navigator.clipboard.write(DOMString) fails (expect Blob)");
|
||||
|
||||
|
||||
/* clipboard.writeText() */
|
||||
|
@ -46,27 +45,28 @@ promise_test(async t => {
|
|||
navigator.clipboard.writeText());
|
||||
}, "navigator.clipboard.writeText() fails (expect DOMString)");
|
||||
|
||||
/* clipboard.writeImageExperimental() */
|
||||
/* clipboard.write(Blob/image) */
|
||||
|
||||
promise_test(async () => {
|
||||
const fetched = await fetch(
|
||||
'http://localhost:8001/clipboard-apis/resources/greenbox.png');
|
||||
const image = await fetched.blob();
|
||||
|
||||
await navigator.clipboard.writeImageExperimental(image);
|
||||
await navigator.clipboard.write(image);
|
||||
}, "navigator.clipboard.writeImageExperimental(Blob) succeeds");
|
||||
|
||||
promise_test(async t => {
|
||||
await promise_rejects(t, new TypeError(),
|
||||
navigator.clipboard.writeImageExperimental());
|
||||
navigator.clipboard.write());
|
||||
}, "navigator.clipboard.writeImageExperimental() fails (expect Blob)");
|
||||
|
||||
|
||||
/* clipboard.read() */
|
||||
/* Blob/text or Blob/image clipboard.read() */
|
||||
|
||||
promise_test(async () => {
|
||||
const result = await navigator.clipboard.read();
|
||||
assert_true(result instanceof DataTransfer);
|
||||
assert_true(result instanceof Blob);
|
||||
assert_equals(typeof result, "object");
|
||||
}, "navigator.clipboard.read() succeeds");
|
||||
|
||||
|
||||
|
@ -77,11 +77,4 @@ promise_test(async () => {
|
|||
assert_equals(typeof result, "string");
|
||||
}, "navigator.clipboard.readText() succeeds");
|
||||
|
||||
/* clipboard.readImageExperimental() */
|
||||
|
||||
promise_test(async () => {
|
||||
const result = await navigator.clipboard.readImageExperimental();
|
||||
assert_equals(typeof result, "object");
|
||||
}, "navigator.clipboard.readImageExperimental() succeeds");
|
||||
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Async Clipboard write (Blob/text) -> read (Blob/text) tests</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
async function readWriteTest(textInput) {
|
||||
promise_test(async t => {
|
||||
const blobInput = new Blob([textInput], {type: 'text/plain'});
|
||||
|
||||
await navigator.clipboard.write(blobInput);
|
||||
const blobOutput = await navigator.clipboard.read();
|
||||
assert_equals(blobOutput.type, "text/plain");
|
||||
|
||||
const textOutput = await (new Response(blobOutput)).text();
|
||||
assert_equals(textOutput, textInput);
|
||||
}, "Verify write and read clipboard given text: " + textInput);
|
||||
}
|
||||
|
||||
readWriteTest("Clipboard write (Blob/text) -> read (Blob/text) test");
|
||||
readWriteTest("non-Latin1 text encoding test データ");
|
||||
</script>
|
||||
<p>
|
||||
Note: This is a manual test because it writes/reads to the shared system
|
||||
clipboard and thus cannot be run async with other tests that might interact
|
||||
with the clipboard.
|
||||
</p>
|
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Async Clipboard write (Blob/text) -> readText tests</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
async function readWriteTest(textInput) {
|
||||
promise_test(async t => {
|
||||
const blobInput = new Blob([textInput], {type: 'text/plain'});
|
||||
|
||||
await navigator.clipboard.write(blobInput);
|
||||
const textOutput = await navigator.clipboard.readText();
|
||||
|
||||
assert_equals(textOutput, textInput);
|
||||
}, "Verify write and read clipboard given text: " + textInput);
|
||||
}
|
||||
|
||||
readWriteTest("Clipboard write (Blob/text) -> read text test");
|
||||
readWriteTest("non-Latin1 text encoding test データ");
|
||||
</script>
|
||||
<p>
|
||||
Note: This is a manual test because it writes/reads to the shared system
|
||||
clipboard and thus cannot be run async with other tests that might interact
|
||||
with the clipboard.
|
||||
</p>
|
|
@ -1,25 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Async Clipboard write (dt/text) -> read (dt/text) tests</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
promise_test(async t => {
|
||||
const input = "Clipboard write (dt/text) -> read (dt/text) test data";
|
||||
const dt = new DataTransfer();
|
||||
dt.items.add(input, "text/plain");
|
||||
|
||||
await navigator.clipboard.write(dt);
|
||||
const output = await navigator.clipboard.read();
|
||||
|
||||
assert_equals(output.items.length, 1);
|
||||
const result_promise = new Promise(resolve => {
|
||||
output.items[0].getAsString(resolve);
|
||||
});
|
||||
const string_output = await result_promise;
|
||||
assert_equals(string_output, input);
|
||||
}, "Verify write and read clipboard (DataTransfer/text)");
|
||||
</script>
|
||||
Note: This is a manual test because it writes/reads to the shared system
|
||||
clipboard and thus cannot be run async with other tests that might interact
|
||||
with the clipboard.
|
|
@ -1,20 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Async Clipboard write (dt/text) -> readText tests</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
promise_test(async t => {
|
||||
const input = "Clipboard write (dt/text) -> readText test data";
|
||||
const dt = new DataTransfer();
|
||||
dt.items.add(input, "text/plain");
|
||||
|
||||
await navigator.clipboard.write(dt);
|
||||
const output = await navigator.clipboard.readText();
|
||||
|
||||
assert_equals(output, input);
|
||||
}, "Verify write and read clipboard (DataTransfer/text)");
|
||||
</script>
|
||||
Note: This is a manual test because it writes/reads to the shared system
|
||||
clipboard and thus cannot be run async with other tests that might interact
|
||||
with the clipboard.
|
|
@ -39,8 +39,10 @@ async function loadBlob(fileName) {
|
|||
promise_test(async t => {
|
||||
const input = await loadBlob('resources/greenbox.png');
|
||||
|
||||
await navigator.clipboard.writeImageExperimental(input);
|
||||
const output = await navigator.clipboard.readImageExperimental();
|
||||
assert_equals(input.type, "image/png");
|
||||
await navigator.clipboard.write(input);
|
||||
const output = await navigator.clipboard.read();
|
||||
assert_equals(output.type, "image/png");
|
||||
|
||||
document.getElementById('image-on-clipboard').src =
|
||||
window.URL.createObjectURL(output);
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Async Clipboard writeText -> read (Blob/text) tests</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
async function readWriteTest(textInput) {
|
||||
promise_test(async t => {
|
||||
await navigator.clipboard.writeText(textInput);
|
||||
const blobOutput = await navigator.clipboard.read();
|
||||
assert_equals(blobOutput.type, "text/plain");
|
||||
|
||||
const textOutput = await (new Response(blobOutput)).text();
|
||||
assert_equals(textOutput, textInput);
|
||||
}, "Verify write and read clipboard given text: " + textInput);
|
||||
}
|
||||
|
||||
readWriteTest("Clipboard write text -> read (Blob/text) test");
|
||||
readWriteTest("non-Latin1 text encoding test データ");
|
||||
</script>
|
||||
<p>
|
||||
Note: This is a manual test because it writes/reads to the shared system
|
||||
clipboard and thus cannot be run async with other tests that might interact
|
||||
with the clipboard.
|
||||
</p>
|
|
@ -1,23 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Async Clipboard writeText -> read (dt/text) tests</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
promise_test(async t => {
|
||||
const input = "Clipboard writeText -> read (dt/text) test data";
|
||||
|
||||
await navigator.clipboard.writeText(input);
|
||||
const output = await navigator.clipboard.read();
|
||||
|
||||
assert_equals(output.items.length, 1);
|
||||
const result_promise = new Promise(resolve => {
|
||||
output.items[0].getAsString(resolve);
|
||||
});
|
||||
const string_output = await result_promise;
|
||||
assert_equals(string_output, input);
|
||||
}, "Verify write and read clipboard (DOMString)");
|
||||
</script>
|
||||
Note: This is a manual test because it writes/reads to the shared system
|
||||
clipboard and thus cannot be run async with other tests that might interact
|
||||
with the clipboard.
|
|
@ -4,15 +4,20 @@
|
|||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
promise_test(async t => {
|
||||
const input = "Clipboard writeText -> readText test data";
|
||||
async function readWriteTest(textInput) {
|
||||
promise_test(async t => {
|
||||
await navigator.clipboard.writeText(textInput);
|
||||
const textOutput = await navigator.clipboard.readText();
|
||||
|
||||
await navigator.clipboard.writeText(input);
|
||||
const output = await navigator.clipboard.readText();
|
||||
assert_equals(textOutput, textInput);
|
||||
}, "Verify write and read clipboard given text: " + textInput);
|
||||
}
|
||||
|
||||
assert_equals(output, input);
|
||||
}, "Verify write and read clipboard (DOMString)");
|
||||
readWriteTest("Clipboard write text -> read text test");
|
||||
readWriteTest("non-Latin1 text encoding test データ");
|
||||
</script>
|
||||
Note: This is a manual test because it writes/reads to the shared system
|
||||
clipboard and thus cannot be run async with other tests that might interact
|
||||
with the clipboard.
|
||||
<p>
|
||||
Note: This is a manual test because it writes/reads to the shared system
|
||||
clipboard and thus cannot be run async with other tests that might interact
|
||||
with the clipboard.
|
||||
</p>
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Filler text below is green reference</title>
|
||||
<link rel="author" title="Geoffrey Sneddon" href="mailto:me@gsnedders.com"/>
|
||||
<style>
|
||||
.green { color: green; }
|
||||
</style>
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>No red visible, filler text, reference</title>
|
||||
<link rel="author" title="Geoffrey Sneddon" href="mailto:me@gsnedders.com"/>
|
||||
</head>
|
||||
<body>
|
||||
<p>Test passes if there is no red visible on the page.</p>
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче