Stack-based unmarshaler (#546)
* Benchmark script * Rewrite unmarshaler using the stack Instead of tracking the build chain using `target`s, use the stack instead. Working and most benchmarks look good, but regression on structs unmarshalling. ~60% slower on ReferenceFile/struct. * Shortcut to check if last node of iterator * Remove unecessary pointer allocation * Skip over unused keys without marking them as seen * Add some tests * Fix mktemp on macos
This commit is contained in:
@@ -6,35 +6,30 @@ import (
|
||||
)
|
||||
|
||||
func TestInvalidDatetimeMalformedNoLeads(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `no-leads = 1987-7-05T17:45:00Z`
|
||||
testgenInvalid(t, input)
|
||||
}
|
||||
|
||||
func TestInvalidDatetimeMalformedNoSecs(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `no-secs = 1987-07-05T17:45Z`
|
||||
testgenInvalid(t, input)
|
||||
}
|
||||
|
||||
func TestInvalidDatetimeMalformedNoT(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `no-t = 1987-07-0517:45:00Z`
|
||||
testgenInvalid(t, input)
|
||||
}
|
||||
|
||||
func TestInvalidDatetimeMalformedWithMilli(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `with-milli = 1987-07-5T17:45:00.12Z`
|
||||
testgenInvalid(t, input)
|
||||
}
|
||||
|
||||
func TestInvalidDuplicateKeyTable(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[fruit]
|
||||
type = "apple"
|
||||
@@ -45,7 +40,6 @@ apple = "yes"`
|
||||
}
|
||||
|
||||
func TestInvalidDuplicateKeys(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `dupe = false
|
||||
dupe = true`
|
||||
@@ -53,7 +47,6 @@ dupe = true`
|
||||
}
|
||||
|
||||
func TestInvalidDuplicateTables(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[a]
|
||||
[a]`
|
||||
@@ -61,21 +54,18 @@ func TestInvalidDuplicateTables(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInvalidEmptyImplicitTable(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[naughty..naughty]`
|
||||
testgenInvalid(t, input)
|
||||
}
|
||||
|
||||
func TestInvalidEmptyTable(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[]`
|
||||
testgenInvalid(t, input)
|
||||
}
|
||||
|
||||
func TestInvalidFloatNoLeadingZero(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `answer = .12345
|
||||
neganswer = -.12345`
|
||||
@@ -83,7 +73,6 @@ neganswer = -.12345`
|
||||
}
|
||||
|
||||
func TestInvalidFloatNoTrailingDigits(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `answer = 1.
|
||||
neganswer = -1.`
|
||||
@@ -91,21 +80,18 @@ neganswer = -1.`
|
||||
}
|
||||
|
||||
func TestInvalidKeyEmpty(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := ` = 1`
|
||||
testgenInvalid(t, input)
|
||||
}
|
||||
|
||||
func TestInvalidKeyHash(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `a# = 1`
|
||||
testgenInvalid(t, input)
|
||||
}
|
||||
|
||||
func TestInvalidKeyNewline(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `a
|
||||
= 1`
|
||||
@@ -113,28 +99,24 @@ func TestInvalidKeyNewline(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInvalidKeyOpenBracket(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[abc = 1`
|
||||
testgenInvalid(t, input)
|
||||
}
|
||||
|
||||
func TestInvalidKeySingleOpenBracket(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[`
|
||||
testgenInvalid(t, input)
|
||||
}
|
||||
|
||||
func TestInvalidKeySpace(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `a b = 1`
|
||||
testgenInvalid(t, input)
|
||||
}
|
||||
|
||||
func TestInvalidKeyStartBracket(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[a]
|
||||
[xyz = 5
|
||||
@@ -143,42 +125,36 @@ func TestInvalidKeyStartBracket(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInvalidKeyTwoEquals(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `key= = 1`
|
||||
testgenInvalid(t, input)
|
||||
}
|
||||
|
||||
func TestInvalidStringBadByteEscape(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `naughty = "\xAg"`
|
||||
testgenInvalid(t, input)
|
||||
}
|
||||
|
||||
func TestInvalidStringBadEscape(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `invalid-escape = "This string has a bad \a escape character."`
|
||||
testgenInvalid(t, input)
|
||||
}
|
||||
|
||||
func TestInvalidStringByteEscapes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `answer = "\x33"`
|
||||
testgenInvalid(t, input)
|
||||
}
|
||||
|
||||
func TestInvalidStringNoClose(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `no-ending-quote = "One time, at band camp`
|
||||
testgenInvalid(t, input)
|
||||
}
|
||||
|
||||
func TestInvalidTableArrayImplicit(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := "# This test is a bit tricky. It should fail because the first use of\n" +
|
||||
"# `[[albums.songs]]` without first declaring `albums` implies that `albums`\n" +
|
||||
@@ -198,7 +174,6 @@ func TestInvalidTableArrayImplicit(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInvalidTableArrayMalformedBracket(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[[albums]
|
||||
name = "Born to Run"`
|
||||
@@ -206,7 +181,6 @@ name = "Born to Run"`
|
||||
}
|
||||
|
||||
func TestInvalidTableArrayMalformedEmpty(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[[]]
|
||||
name = "Born to Run"`
|
||||
@@ -214,14 +188,12 @@ name = "Born to Run"`
|
||||
}
|
||||
|
||||
func TestInvalidTableEmpty(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[]`
|
||||
testgenInvalid(t, input)
|
||||
}
|
||||
|
||||
func TestInvalidTableNestedBracketsClose(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[a]b]
|
||||
zyx = 42`
|
||||
@@ -229,7 +201,6 @@ zyx = 42`
|
||||
}
|
||||
|
||||
func TestInvalidTableNestedBracketsOpen(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[a[b]
|
||||
zyx = 42`
|
||||
@@ -237,14 +208,12 @@ zyx = 42`
|
||||
}
|
||||
|
||||
func TestInvalidTableWhitespace(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[invalid key]`
|
||||
testgenInvalid(t, input)
|
||||
}
|
||||
|
||||
func TestInvalidTableWithPound(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[key#group]
|
||||
answer = 42`
|
||||
@@ -252,7 +221,6 @@ answer = 42`
|
||||
}
|
||||
|
||||
func TestInvalidTextAfterArrayEntries(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `array = [
|
||||
"Is there life after an array separator?", No
|
||||
@@ -262,28 +230,24 @@ func TestInvalidTextAfterArrayEntries(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInvalidTextAfterInteger(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `answer = 42 the ultimate answer?`
|
||||
testgenInvalid(t, input)
|
||||
}
|
||||
|
||||
func TestInvalidTextAfterString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `string = "Is there life after strings?" No.`
|
||||
testgenInvalid(t, input)
|
||||
}
|
||||
|
||||
func TestInvalidTextAfterTable(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[error] this shouldn't be here`
|
||||
testgenInvalid(t, input)
|
||||
}
|
||||
|
||||
func TestInvalidTextBeforeArraySeparator(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `array = [
|
||||
"Is there life before an array separator?" No,
|
||||
@@ -293,7 +257,6 @@ func TestInvalidTextBeforeArraySeparator(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInvalidTextInArray(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `array = [
|
||||
"Entry 1",
|
||||
@@ -304,7 +267,6 @@ func TestInvalidTextInArray(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidArrayEmpty(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `thevoid = [[[[[]]]]]`
|
||||
jsonRef := `{
|
||||
@@ -322,7 +284,6 @@ func TestValidArrayEmpty(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidArrayNospaces(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `ints = [1,2,3]`
|
||||
jsonRef := `{
|
||||
@@ -339,7 +300,6 @@ func TestValidArrayNospaces(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidArraysHetergeneous(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `mixed = [[1, 2], ["a", "b"], [1.1, 2.1]]`
|
||||
jsonRef := `{
|
||||
@@ -365,7 +325,6 @@ func TestValidArraysHetergeneous(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidArraysNested(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `nest = [["a"], ["b"]]`
|
||||
jsonRef := `{
|
||||
@@ -385,7 +344,6 @@ func TestValidArraysNested(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidArrays(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `ints = [1, 2, 3]
|
||||
floats = [1.1, 2.1, 3.1]
|
||||
@@ -433,7 +391,6 @@ dates = [
|
||||
}
|
||||
|
||||
func TestValidBool(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `t = true
|
||||
f = false`
|
||||
@@ -445,7 +402,6 @@ f = false`
|
||||
}
|
||||
|
||||
func TestValidCommentsEverywhere(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `# Top comment.
|
||||
# Top comment.
|
||||
@@ -487,7 +443,6 @@ more = [ # Comment
|
||||
}
|
||||
|
||||
func TestValidDatetime(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `bestdayever = 1987-07-05T17:45:00Z`
|
||||
jsonRef := `{
|
||||
@@ -497,7 +452,6 @@ func TestValidDatetime(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidEmpty(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := ``
|
||||
jsonRef := `{}`
|
||||
@@ -505,7 +459,6 @@ func TestValidEmpty(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidExample(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `best-day-ever = 1987-07-05T17:45:00Z
|
||||
|
||||
@@ -530,7 +483,6 @@ perfection = [6, 28, 496]`
|
||||
}
|
||||
|
||||
func TestValidFloat(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `pi = 3.14
|
||||
negpi = -3.14`
|
||||
@@ -542,7 +494,6 @@ negpi = -3.14`
|
||||
}
|
||||
|
||||
func TestValidImplicitAndExplicitAfter(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[a.b.c]
|
||||
answer = 42
|
||||
@@ -563,7 +514,6 @@ better = 43`
|
||||
}
|
||||
|
||||
func TestValidImplicitAndExplicitBefore(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[a]
|
||||
better = 43
|
||||
@@ -584,7 +534,6 @@ answer = 42`
|
||||
}
|
||||
|
||||
func TestValidImplicitGroups(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[a.b.c]
|
||||
answer = 42`
|
||||
@@ -601,7 +550,6 @@ answer = 42`
|
||||
}
|
||||
|
||||
func TestValidInteger(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `answer = 42
|
||||
neganswer = -42`
|
||||
@@ -613,7 +561,6 @@ neganswer = -42`
|
||||
}
|
||||
|
||||
func TestValidKeyEqualsNospace(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `answer=42`
|
||||
jsonRef := `{
|
||||
@@ -623,7 +570,6 @@ func TestValidKeyEqualsNospace(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidKeySpace(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `"a b" = 1`
|
||||
jsonRef := `{
|
||||
@@ -633,7 +579,6 @@ func TestValidKeySpace(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidKeySpecialChars(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := "\"~!@$^&*()_+-`1234567890[]|/?><.,;:'\" = 1\n"
|
||||
jsonRef := "{\n" +
|
||||
@@ -645,7 +590,6 @@ func TestValidKeySpecialChars(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidLongFloat(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `longpi = 3.141592653589793
|
||||
neglongpi = -3.141592653589793`
|
||||
@@ -657,7 +601,6 @@ neglongpi = -3.141592653589793`
|
||||
}
|
||||
|
||||
func TestValidLongInteger(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `answer = 9223372036854775807
|
||||
neganswer = -9223372036854775808`
|
||||
@@ -669,7 +612,6 @@ neganswer = -9223372036854775808`
|
||||
}
|
||||
|
||||
func TestValidMultilineString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `multiline_empty_one = """"""
|
||||
multiline_empty_two = """
|
||||
@@ -728,7 +670,6 @@ equivalent_three = """\
|
||||
}
|
||||
|
||||
func TestValidRawMultilineString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `oneline = '''This string has a ' quote character.'''
|
||||
firstnl = '''
|
||||
@@ -757,7 +698,6 @@ in it.'''`
|
||||
}
|
||||
|
||||
func TestValidRawString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `backspace = 'This string has a \b backspace character.'
|
||||
tab = 'This string has a \t tab character.'
|
||||
@@ -800,7 +740,6 @@ backslash = 'This string has a \\ backslash character.'`
|
||||
}
|
||||
|
||||
func TestValidStringEmpty(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `answer = ""`
|
||||
jsonRef := `{
|
||||
@@ -813,7 +752,6 @@ func TestValidStringEmpty(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidStringEscapes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `backspace = "This string has a \b backspace character."
|
||||
tab = "This string has a \t tab character."
|
||||
@@ -876,7 +814,6 @@ notunicode4 = "This string does not have a unicode \\\u0075 escape."`
|
||||
}
|
||||
|
||||
func TestValidStringSimple(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `answer = "You are not drinking enough whisky."`
|
||||
jsonRef := `{
|
||||
@@ -889,7 +826,6 @@ func TestValidStringSimple(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidStringWithPound(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `pound = "We see no # comments here."
|
||||
poundcomment = "But there are # some comments here." # Did I # mess you up?`
|
||||
@@ -904,7 +840,6 @@ poundcomment = "But there are # some comments here." # Did I # mess you up?`
|
||||
}
|
||||
|
||||
func TestValidTableArrayImplicit(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[[albums.songs]]
|
||||
name = "Glory Days"`
|
||||
@@ -919,7 +854,6 @@ name = "Glory Days"`
|
||||
}
|
||||
|
||||
func TestValidTableArrayMany(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[[people]]
|
||||
first_name = "Bruce"
|
||||
@@ -952,7 +886,6 @@ last_name = "Seger"`
|
||||
}
|
||||
|
||||
func TestValidTableArrayNest(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[[albums]]
|
||||
name = "Born to Run"
|
||||
@@ -993,7 +926,6 @@ name = "Born in the USA"
|
||||
}
|
||||
|
||||
func TestValidTableArrayOne(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[[people]]
|
||||
first_name = "Bruce"
|
||||
@@ -1010,7 +942,6 @@ last_name = "Springsteen"`
|
||||
}
|
||||
|
||||
func TestValidTableEmpty(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[a]`
|
||||
jsonRef := `{
|
||||
@@ -1020,7 +951,6 @@ func TestValidTableEmpty(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidTableSubEmpty(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `[a]
|
||||
[a.b]`
|
||||
@@ -1031,7 +961,6 @@ func TestValidTableSubEmpty(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidTableWhitespace(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `["valid key"]`
|
||||
jsonRef := `{
|
||||
@@ -1041,7 +970,6 @@ func TestValidTableWhitespace(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidTableWithPound(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `["key#group"]
|
||||
answer = 42`
|
||||
@@ -1054,7 +982,6 @@ answer = 42`
|
||||
}
|
||||
|
||||
func TestValidUnicodeEscape(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `answer4 = "\u03B4"
|
||||
answer8 = "\U000003B4"`
|
||||
@@ -1066,7 +993,6 @@ answer8 = "\U000003B4"`
|
||||
}
|
||||
|
||||
func TestValidUnicodeLiteral(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
input := `answer = "δ"`
|
||||
jsonRef := `{
|
||||
|
||||
Reference in New Issue
Block a user