Cleanup and ability to run all but a couple of the spec tests

This commit is contained in:
Chad Retz 2017-04-15 01:15:45 -05:00
parent 9a1090c439
commit b37bc44c50
4 changed files with 43 additions and 147 deletions

View File

@ -114,11 +114,17 @@ open class InsnReworker {
}
if (count == 0) return inject(stackManips.size)
var countSoFar = 0
var foundUnconditionalJump = false
for ((amountChanged, insnIndex) in stackManips.asReversed()) {
countSoFar += amountChanged
if (!foundUnconditionalJump) foundUnconditionalJump = insns[insnIndex].let { insn ->
insn is Node.Instr.Br || insn is Node.Instr.BrTable ||
insn is Node.Instr.Unreachable || insn is Node.Instr.Return
}
if (countSoFar == count) return inject(insnIndex)
}
throw CompileErr.StackInjectionMismatch(count, insn)
// Only consider it a failure if we didn't hit any unconditional jumps
if (!foundUnconditionalJump) throw CompileErr.StackInjectionMismatch(count, insn)
}
// Go over each insn, determining where to inject

View File

@ -17,6 +17,12 @@ class SpecTestUnit(val name: String, val wast: String, val expectedOutput: Strin
val shouldFail get() = name.endsWith(".fail")
val skipRunReason get() = when (name) {
"br_table" -> "Table issues on jump"
"switch" -> "Table issues on jumps (ref 'argument switch')"
else -> null
}
val defaultMaxMemPages get() = when (name) {
"nop"-> 20
"resizing" -> 830
@ -24,6 +30,31 @@ class SpecTestUnit(val name: String, val wast: String, val expectedOutput: Strin
else -> 1
}
fun isWarningInsteadOfError(t: Throwable) = when (name) {
// NaN bit patterns can be off
"float_literals" -> isNanMismatch(t)
"float_exprs" -> isNanMismatch(t)
// We don't hold table capacity right now
// TODO: Figure out how we want to store/retrieve table capacity. Right now
// a table is an array, so there is only size not capacity. Since we want to
// stay w/ the stdlib of the JVM, the best option may be to store the capacity
// as a separate int value and query it or pass it around via import as
// necessary. I guess I could use a vector, but it's not worth it just for
// capacity since you lose speed.
"imports" -> t is ScriptAssertionError && (t.assertion as? Script.Cmd.Assertion.Unlinkable).let {
it != null && it.failure == "maximum size larger than declared" &&
it.module.imports.singleOrNull()?.kind is Node.Import.Kind.Table
}
else -> false
}
private fun isNanMismatch(t: Throwable) = t is ScriptAssertionError && (
t.assertion is Script.Cmd.Assertion.ReturnNan ||
(t.assertion is Script.Cmd.Assertion.Return && (t.assertion as Script.Cmd.Assertion.Return).let {
(it.action as? Script.Cmd.Action.Invoke)?.string?.contains("nan") ?: false
})
)
val parseResult: StrToSExpr.ParseResult.Success by lazy {
StrToSExpr.parse(wast).let {
when (it) {
@ -37,150 +68,7 @@ class SpecTestUnit(val name: String, val wast: String, val expectedOutput: Strin
val script: Script by lazy { SExprToAst.toScript(SExpr.Multi(ast)) }
fun isWarningInsteadOfError(t: Throwable) = testsWithErrorToWarningPredicates[name]?.invoke(t) ?: false
companion object {
/*
TODO: We are going down in order. One's we have not yet handled:
- br_table.wast - Table issues on jumps
- linking.wast - Not handling tables yet
- return.wast - Not handling tables yet
- switch.wast - Table issues on jumps (ref "argument switch")
- typecheck.wast - Not handling tables yet
- unreachable.wast - Not handling tables yet
*/
val knownGoodTests = arrayOf(
"address.wast",
"address-offset-range.fail.wast",
"binary.wast",
"block.wast",
"block-end-label-mismatch.fail.wast",
"block-end-label-superfluous.wast",
"br.wast",
"br_if.wast",
"break-drop.wast",
"call.wast",
"call_indirect.wast",
"comments.wast",
"conversions.wast",
"custom_section.wast",
"endianness.wast",
"exports.wast",
"f32.load32.fail.wast",
"f32.load64.fail.wast",
"f32.store32.fail.wast",
"f32.store64.fail.wast",
"f32.wast",
"f32_cmp.wast",
"f64.load32.fail.wast",
"f64.load64.fail.wast",
"f64.store32.fail.wast",
"f64.store64.fail.wast",
"f64.wast",
"f64_cmp.wast",
"fac.wast",
"float_exprs.wast",
"float_literals.wast",
"float_memory.wast",
"float_misc.wast",
"forward.wast",
"func_ptrs.wast",
"func-local-after-body.fail.wast",
"func-local-before-param.fail.wast",
"func-local-before-result.fail.wast",
"func-param-after-body.fail.wast",
"func-result-after-body.fail.wast",
"func-result-before-param.fail.wast",
"func.wast",
"get_local.wast",
"globals.wast",
"i32.load32_s.fail.wast",
"i32.load32_u.fail.wast",
"i32.load64_s.fail.wast",
"i32.load64_u.fail.wast",
"i32.store32.fail.wast",
"i32.store64.fail.wast",
"i32.wast",
"i64.load64_s.fail.wast",
"i64.load64_u.fail.wast",
"i64.store64.fail.wast",
"i64.wast",
"if.wast",
"if-else-end-label-mismatch.fail.wast",
"if-else-end-label-superfluous.fail.wast",
"if-else-label-mismatch.fail.wast",
"if-else-label-superfluous.fail.wast",
"if-end-label-mismatch.fail.wast",
"if-end-label-superfluous.fail.wast",
"import-after-func.fail.wast",
"import-after-global.fail.wast",
"import-after-memory.fail.wast",
"import-after-table.fail.wast",
"imports.wast",
"int_exprs.wast",
"int_literals.wast",
"labels.wast",
"left-to-right.wast",
"linking.wast",
"load-align-0.fail.wast",
"load-align-odd.fail.wast",
"loop.wast",
"loop-end-label-mismatch.fail.wast",
"loop-end-label-superfluous.fail.wast",
"memory.wast",
"memory_redundancy.wast",
"memory_trap.wast",
"names.wast",
"nop.wast",
"of_string-overflow-hex-u32.fail.wast",
"of_string-overflow-hex-u64.fail.wast",
"of_string-overflow-s32.fail.wast",
"of_string-overflow-s64.fail.wast",
"of_string-overflow-u32.fail.wast",
"of_string-overflow-u64.fail.wast",
"resizing.wast",
"select.wast",
"set_local.wast",
"skip-stack-guard-page.wast",
"stack.wast",
"start.wast",
"store-align-0.fail.wast",
"store-align-odd.fail.wast",
"store_retval.wast",
"tee_local.wast",
"traps.wast",
"unreached-invalid.wast",
"unwind.wast"
)
val testsWithErrorToWarningPredicates: Map<String, (Throwable) -> Boolean> = mapOf(
// NaN bit patterns can be off
"float_literals" to this::isNanMismatch,
"float_exprs" to this::isNanMismatch,
// We don't hold table capacity right now
// TODO: Figure out how we want to store/retrieve table capacity. Right now
// a table is an array, so there is only size not capacity. Since we want to
// stay w/ the stdlib of the JVM, the best option may be to store the capacity
// as a separate int value and query it or pass it around via import as
// necessary. I guess I could use a vector, but it's not worth it just for
// capacity since you lose speed.
"imports" to { t: Throwable ->
t is ScriptAssertionError && (t.assertion as? Script.Cmd.Assertion.Unlinkable).let {
it != null && it.failure == "maximum size larger than declared" &&
it.module.imports.singleOrNull()?.kind is Node.Import.Kind.Table
}
}
)
fun isNanMismatch(t: Throwable) = t is ScriptAssertionError && (
t.assertion is Script.Cmd.Assertion.ReturnNan ||
(t.assertion is Script.Cmd.Assertion.Return && (t.assertion as Script.Cmd.Assertion.Return).let {
(it.action as? Script.Cmd.Action.Invoke)?.string?.contains("nan") ?: false
})
)
val unitsPath = "/spec/test/core"
val allUnits by lazy { loadFromResourcePath("/local-spec") + loadFromResourcePath(unitsPath) }
@ -193,9 +81,7 @@ class SpecTestUnit(val name: String, val wast: String, val expectedOutput: Strin
fs.use { fs ->
val path = fs?.getPath(basePath) ?: Paths.get(uri)
val testWastFiles = Files.walk(path, 1).
filter { it.toString().endsWith(".wast") }.
// TODO: remove this when they all succeed
filter { knownGoodTests.contains(it.fileName.toString()) }
filter { it.toString().endsWith(".wast") }
return testWastFiles.map {
val name = it.fileName.toString().substringBeforeLast(".wast")
SpecTestUnit(

View File

@ -4,6 +4,7 @@ import asmble.SpecTestUnit
import asmble.io.AstToSExpr
import asmble.io.SExprToStr
import asmble.util.Logger
import org.junit.Assume
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
@ -17,6 +18,8 @@ class RunTest(val unit: SpecTestUnit) : Logger by Logger.Print(Logger.Level.INFO
@Test
fun testRun() {
unit.skipRunReason?.let { Assume.assumeTrue("Skipping ${unit.name}, reason: $it", false) }
val ex = try { run(); null } catch (e: Throwable) { e }
if (unit.shouldFail) {
assertNotNull(ex, "Expected failure, but succeeded")

View File

@ -0,0 +1 @@
;; TODO: test w/ emscripten compiled code