Remove escaped optype

This commit is contained in:
Masaaki Goshima 2021-01-11 19:21:30 +09:00
parent 4cfb919183
commit 9c5f6ec0e6
6 changed files with 3837 additions and 12444 deletions

View File

@ -14,7 +14,6 @@ import (
type opType struct { type opType struct {
Op string Op string
Code string Code string
Escaped func() string
HeadToPtrHead func() string HeadToPtrHead func() string
HeadToNPtrHead func() string HeadToNPtrHead func() string
HeadToAnonymousHead func() string HeadToAnonymousHead func() string
@ -27,10 +26,6 @@ type opType struct {
FieldToStringTagField func() string FieldToStringTagField func() string
} }
func (t opType) IsEscaped() bool {
return t.Op != t.Escaped()
}
func (t opType) IsHeadToPtrHead() bool { func (t opType) IsHeadToPtrHead() bool {
return t.Op != t.HeadToPtrHead() return t.Op != t.HeadToPtrHead()
} }
@ -75,7 +70,6 @@ func createOpType(op, code string) opType {
return opType{ return opType{
Op: op, Op: op,
Code: code, Code: code,
Escaped: func() string { return op },
HeadToPtrHead: func() string { return op }, HeadToPtrHead: func() string { return op },
HeadToNPtrHead: func() string { return op }, HeadToNPtrHead: func() string { return op },
HeadToAnonymousHead: func() string { return op }, HeadToAnonymousHead: func() string { return op },
@ -158,31 +152,6 @@ func (t opType) codeType() codeType {
return codeOp return codeOp
} }
func (t opType) toEscaped() opType {
if strings.Index(t.String(), "Escaped") > 0 {
return t
}
if t.String() == "String" {
return opType(int(t) + 1)
}
fieldHeadIdx := strings.Index(t.String(), "Head")
if fieldHeadIdx > 0 && strings.Contains(t.String(), "Struct") {
const toEscapedHeadOffset = 36
return opType(int(t) + toEscapedHeadOffset)
}
fieldIdx := strings.Index(t.String(), "Field")
if fieldIdx > 0 && strings.Contains(t.String(), "Struct") {
const toEscapedFieldOffset = 3
return opType(int(t) + toEscapedFieldOffset)
}
if strings.Contains(t.String(), "StructEnd") {
const toEscapedEndOffset = 3
return opType(int(t) + toEscapedEndOffset)
}
return t
}
func (t opType) headToPtrHead() opType { func (t opType) headToPtrHead() opType {
if strings.Index(t.String(), "PtrHead") > 0 { if strings.Index(t.String(), "PtrHead") > 0 {
return t return t
@ -325,16 +294,16 @@ func (t opType) fieldToStringTagField() opType {
primitiveTypes := []string{ primitiveTypes := []string{
"int", "int8", "int16", "int32", "int64", "int", "int8", "int16", "int32", "int64",
"uint", "uint8", "uint16", "uint32", "uint64", "uint", "uint8", "uint16", "uint32", "uint64",
"float32", "float64", "bool", "string", "escapedString", "bytes", "float32", "float64", "bool", "string", "bytes",
"array", "map", "mapLoad", "slice", "struct", "MarshalJSON", "MarshalText", "recursive", "array", "map", "mapLoad", "slice", "struct", "MarshalJSON", "MarshalText", "recursive",
"intString", "int8String", "int16String", "int32String", "int64String", "intString", "int8String", "int16String", "int32String", "int64String",
"uintString", "uint8String", "uint16String", "uint32String", "uint64String", "uintString", "uint8String", "uint16String", "uint32String", "uint64String",
"intPtr", "int8Ptr", "int16Ptr", "int32Ptr", "int64Ptr", "intPtr", "int8Ptr", "int16Ptr", "int32Ptr", "int64Ptr",
"uintPtr", "uint8Ptr", "uint16Ptr", "uint32Ptr", "uint64Ptr", "uintPtr", "uint8Ptr", "uint16Ptr", "uint32Ptr", "uint64Ptr",
"float32Ptr", "float64Ptr", "boolPtr", "stringPtr", "escapedStringPtr", "bytesPtr", "float32Ptr", "float64Ptr", "boolPtr", "stringPtr", "bytesPtr",
"intNPtr", "int8NPtr", "int16NPtr", "int32NPtr", "int64NPtr", "intNPtr", "int8NPtr", "int16NPtr", "int32NPtr", "int64NPtr",
"uintNPtr", "uint8NPtr", "uint16NPtr", "uint32NPtr", "uint64NPtr", "uintNPtr", "uint8NPtr", "uint16NPtr", "uint32NPtr", "uint64NPtr",
"float32NPtr", "float64NPtr", "boolNPtr", "stringNPtr", "escapedStringNPtr", "bytesNPtr", "float32NPtr", "float64NPtr", "boolNPtr", "stringNPtr", "bytesNPtr",
} }
primitiveTypesUpper := []string{} primitiveTypesUpper := []string{}
for _, typ := range primitiveTypes { for _, typ := range primitiveTypes {
@ -364,289 +333,179 @@ func (t opType) fieldToStringTagField() opType {
} }
for _, typ := range primitiveTypesUpper { for _, typ := range primitiveTypesUpper {
typ := typ typ := typ
optype := createOpType(typ, "Op") opTypes = append(opTypes, createOpType(typ, "Op"))
switch typ {
case "String", "StringPtr", "StringNPtr":
optype.Escaped = func() string {
return fmt.Sprintf("Escaped%s", typ)
}
}
opTypes = append(opTypes, optype)
} }
for _, typ := range append(primitiveTypesUpper, "") { for _, typ := range append(primitiveTypesUpper, "") {
if typ == "EscapedString" || typ == "EscapedStringPtr" || typ == "EscapedStringNPtr" { for _, ptrOrNot := range []string{"", "Ptr", "NPtr"} {
continue for _, headType := range []string{"", "Anonymous"} {
} for _, opt := range []string{"", "OmitEmpty", "StringTag"} {
for _, escapedOrNot := range []string{"", "Escaped"} { for _, onlyOrNot := range []string{"", "Only"} {
for _, ptrOrNot := range []string{"", "Ptr", "NPtr"} { ptrOrNot := ptrOrNot
for _, headType := range []string{"", "Anonymous"} { headType := headType
for _, opt := range []string{"", "OmitEmpty", "StringTag"} { opt := opt
for _, onlyOrNot := range []string{"", "Only"} { typ := typ
escapedOrNot := escapedOrNot onlyOrNot := onlyOrNot
ptrOrNot := ptrOrNot
headType := headType
opt := opt
typ := typ
onlyOrNot := onlyOrNot
isEscaped := escapedOrNot != "" op := fmt.Sprintf(
isString := typ == "String" || typ == "StringPtr" || typ == "StringNPtr" "StructField%s%sHead%s%s%s",
ptrOrNot,
if isEscaped && isString { headType,
typ = "Escaped" + typ opt,
} typ,
onlyOrNot,
op := fmt.Sprintf( )
"Struct%sField%s%sHead%s%s%s", opTypes = append(opTypes, opType{
escapedOrNot, Op: op,
ptrOrNot, Code: "StructField",
headType, HeadToPtrHead: func() string {
opt, return fmt.Sprintf(
typ, "StructFieldPtr%sHead%s%s%s",
onlyOrNot, headType,
) opt,
opTypes = append(opTypes, opType{ typ,
Op: op, onlyOrNot,
Code: "StructField", )
Escaped: func() string { },
switch typ { HeadToNPtrHead: func() string {
case "String", "StringPtr", "StringNPtr": return fmt.Sprintf(
return fmt.Sprintf( "StructFieldNPtr%sHead%s%s%s",
"StructEscapedField%s%sHead%sEscaped%s%s", headType,
ptrOrNot, opt,
headType, typ,
opt, onlyOrNot,
typ, )
onlyOrNot, },
) HeadToAnonymousHead: func() string {
} return fmt.Sprintf(
return fmt.Sprintf( "StructField%sAnonymousHead%s%s%s",
"StructEscapedField%s%sHead%s%s%s", ptrOrNot,
ptrOrNot, opt,
headType, typ,
opt, onlyOrNot,
typ, )
onlyOrNot, },
) HeadToOmitEmptyHead: func() string {
}, return fmt.Sprintf(
HeadToPtrHead: func() string { "StructField%s%sHeadOmitEmpty%s%s",
return fmt.Sprintf( ptrOrNot,
"Struct%sFieldPtr%sHead%s%s%s", headType,
escapedOrNot, typ,
headType, onlyOrNot,
opt, )
typ, },
onlyOrNot, HeadToStringTagHead: func() string {
) return fmt.Sprintf(
}, "StructField%s%sHeadStringTag%s%s",
HeadToNPtrHead: func() string { ptrOrNot,
return fmt.Sprintf( headType,
"Struct%sFieldNPtr%sHead%s%s%s", typ,
escapedOrNot, onlyOrNot,
headType, )
opt, },
typ, HeadToOnlyHead: func() string {
onlyOrNot, switch typ {
) case "", "Array", "Map", "MapLoad", "Slice",
}, "Struct", "Recursive", "MarshalJSON", "MarshalText",
HeadToAnonymousHead: func() string { "IntString", "Int8String", "Int16String", "Int32String", "Int64String",
return fmt.Sprintf( "UintString", "Uint8String", "Uint16String", "Uint32String", "Uint64String":
"Struct%sField%sAnonymousHead%s%s%s", return op
escapedOrNot, }
ptrOrNot, return fmt.Sprintf(
opt, "StructField%s%sHead%s%sOnly",
typ, ptrOrNot,
onlyOrNot, headType,
) opt,
}, typ,
HeadToOmitEmptyHead: func() string { )
return fmt.Sprintf( },
"Struct%sField%s%sHeadOmitEmpty%s%s", PtrHeadToHead: func() string {
escapedOrNot, return fmt.Sprintf(
ptrOrNot, "StructField%sHead%s%s%s",
headType, headType,
typ, opt,
onlyOrNot, typ,
) onlyOrNot,
}, )
HeadToStringTagHead: func() string { },
return fmt.Sprintf( FieldToEnd: func() string { return op },
"Struct%sField%s%sHeadStringTag%s%s", FieldToOmitEmptyField: func() string { return op },
escapedOrNot, FieldToStringTagField: func() string { return op },
ptrOrNot, })
headType,
typ,
onlyOrNot,
)
},
HeadToOnlyHead: func() string {
switch typ {
case "", "Array", "Map", "MapLoad", "Slice",
"Struct", "Recursive", "MarshalJSON", "MarshalText",
"IntString", "Int8String", "Int16String", "Int32String", "Int64String",
"UintString", "Uint8String", "Uint16String", "Uint32String", "Uint64String":
return op
}
return fmt.Sprintf(
"Struct%sField%s%sHead%s%sOnly",
escapedOrNot,
ptrOrNot,
headType,
opt,
typ,
)
},
PtrHeadToHead: func() string {
return fmt.Sprintf(
"Struct%sField%sHead%s%s%s",
escapedOrNot,
headType,
opt,
typ,
onlyOrNot,
)
},
FieldToEnd: func() string { return op },
FieldToOmitEmptyField: func() string { return op },
FieldToStringTagField: func() string { return op },
})
}
} }
} }
} }
} }
} }
for _, typ := range append(primitiveTypesUpper, "") { for _, typ := range append(primitiveTypesUpper, "") {
if typ == "EscapedString" || typ == "EscapedStringPtr" || typ == "EscapedStringNPtr" { for _, opt := range []string{"", "OmitEmpty", "StringTag"} {
continue opt := opt
} typ := typ
for _, escapedOrNot := range []string{"", "Escaped"} {
for _, opt := range []string{"", "OmitEmpty", "StringTag"} {
escapedOrNot := escapedOrNot
opt := opt
typ := typ
isEscaped := escapedOrNot != "" op := fmt.Sprintf(
isString := typ == "String" || typ == "StringPtr" || typ == "StringNPtr" "StructField%s%s",
opt,
if isEscaped && isString { typ,
typ = "Escaped" + typ )
} opTypes = append(opTypes, opType{
Op: op,
op := fmt.Sprintf( Code: "StructField",
"Struct%sField%s%s", HeadToPtrHead: func() string { return op },
escapedOrNot, HeadToNPtrHead: func() string { return op },
opt, HeadToAnonymousHead: func() string { return op },
typ, HeadToOmitEmptyHead: func() string { return op },
) HeadToStringTagHead: func() string { return op },
opTypes = append(opTypes, opType{ HeadToOnlyHead: func() string { return op },
Op: op, PtrHeadToHead: func() string { return op },
Code: "StructField", FieldToEnd: func() string {
Escaped: func() string { switch typ {
switch typ { case "", "Array", "Map", "MapLoad", "Slice", "Struct", "Recursive":
case "String", "StringPtr", "StringNPtr": return op
return fmt.Sprintf( }
"StructEscapedField%sEscaped%s", return fmt.Sprintf(
opt, "StructEnd%s%s",
typ, opt,
) typ,
} )
return fmt.Sprintf( },
"StructEscapedField%s%s", FieldToOmitEmptyField: func() string {
opt, return fmt.Sprintf(
typ, "StructFieldOmitEmpty%s",
) typ,
}, )
HeadToPtrHead: func() string { return op }, },
HeadToNPtrHead: func() string { return op }, FieldToStringTagField: func() string {
HeadToAnonymousHead: func() string { return op }, return fmt.Sprintf(
HeadToOmitEmptyHead: func() string { return op }, "StructFieldStringTag%s",
HeadToStringTagHead: func() string { return op }, typ,
HeadToOnlyHead: func() string { return op }, )
PtrHeadToHead: func() string { return op }, },
FieldToEnd: func() string { })
switch typ {
case "", "Array", "Map", "MapLoad", "Slice", "Struct", "Recursive":
return op
}
return fmt.Sprintf(
"Struct%sEnd%s%s",
escapedOrNot,
opt,
typ,
)
},
FieldToOmitEmptyField: func() string {
return fmt.Sprintf(
"Struct%sFieldOmitEmpty%s",
escapedOrNot,
typ,
)
},
FieldToStringTagField: func() string {
return fmt.Sprintf(
"Struct%sFieldStringTag%s",
escapedOrNot,
typ,
)
},
})
}
} }
} }
for _, typ := range append(primitiveTypesUpper, "") { for _, typ := range append(primitiveTypesUpper, "") {
if typ == "EscapedString" || typ == "EscapedStringPtr" || typ == "EscapedStringNPtr" { for _, opt := range []string{"", "OmitEmpty", "StringTag"} {
continue opt := opt
} typ := typ
for _, escapedOrNot := range []string{"", "Escaped"} {
for _, opt := range []string{"", "OmitEmpty", "StringTag"} {
escapedOrNot := escapedOrNot
opt := opt
typ := typ
isEscaped := escapedOrNot != "" op := fmt.Sprintf(
isString := typ == "String" || typ == "StringPtr" || typ == "StringNPtr" "StructEnd%s%s",
opt,
if isEscaped && isString { typ,
typ = "Escaped" + typ )
} opTypes = append(opTypes, opType{
Op: op,
op := fmt.Sprintf( Code: "StructEnd",
"Struct%sEnd%s%s", HeadToPtrHead: func() string { return op },
escapedOrNot, HeadToNPtrHead: func() string { return op },
opt, HeadToAnonymousHead: func() string { return op },
typ, HeadToOmitEmptyHead: func() string { return op },
) HeadToStringTagHead: func() string { return op },
opTypes = append(opTypes, opType{ HeadToOnlyHead: func() string { return op },
Op: op, PtrHeadToHead: func() string { return op },
Code: "StructEnd", FieldToEnd: func() string { return op },
Escaped: func() string { FieldToOmitEmptyField: func() string { return op },
switch typ { FieldToStringTagField: func() string { return op },
case "String", "StringPtr", "StringNPtr": })
return fmt.Sprintf(
"StructEscapedEnd%sEscaped%s",
opt,
typ,
)
}
return fmt.Sprintf(
"StructEscapedEnd%s%s",
opt,
typ,
)
},
HeadToPtrHead: func() string { return op },
HeadToNPtrHead: func() string { return op },
HeadToAnonymousHead: func() string { return op },
HeadToOmitEmptyHead: func() string { return op },
HeadToStringTagHead: func() string { return op },
HeadToOnlyHead: func() string { return op },
PtrHeadToHead: func() string { return op },
FieldToEnd: func() string { return op },
FieldToOmitEmptyField: func() string { return op },
FieldToStringTagField: func() string { return op },
})
}
} }
} }
var b bytes.Buffer var b bytes.Buffer

View File

@ -42,9 +42,8 @@ const (
) )
type opcodeSet struct { type opcodeSet struct {
escapedCode *opcode code *opcode
code *opcode codeLength int
codeLength int
} }
func loadOpcodeMap() map[uintptr]*opcodeSet { func loadOpcodeMap() map[uintptr]*opcodeSet {
@ -198,13 +197,13 @@ func (e *Encoder) encode(header *interfaceHeader, isNil bool) ([]byte, error) {
if e.enabledIndent { if e.enabledIndent {
if e.enabledHTMLEscape { if e.enabledHTMLEscape {
return e.runEscapedIndent(ctx, b, codeSet.escapedCode) return e.runEscapedIndent(ctx, b, codeSet.code)
} else { } else {
return e.runIndent(ctx, b, codeSet.code) return e.runIndent(ctx, b, codeSet.code)
} }
} }
if e.enabledHTMLEscape { if e.enabledHTMLEscape {
return e.runEscaped(ctx, b, codeSet.escapedCode) return e.runEscaped(ctx, b, codeSet.code)
} }
return e.run(ctx, b, codeSet.code) return e.run(ctx, b, codeSet.code)
} }
@ -223,9 +222,8 @@ func (e *Encoder) encode(header *interfaceHeader, isNil bool) ([]byte, error) {
code = copyOpcode(code) code = copyOpcode(code)
codeLength := code.totalLength() codeLength := code.totalLength()
codeSet := &opcodeSet{ codeSet := &opcodeSet{
escapedCode: toEscaped(code), code: code,
code: code, codeLength: codeLength,
codeLength: codeLength,
} }
storeOpcodeSet(typeptr, codeSet, opcodeMap) storeOpcodeSet(typeptr, codeSet, opcodeMap)
@ -235,13 +233,13 @@ func (e *Encoder) encode(header *interfaceHeader, isNil bool) ([]byte, error) {
if e.enabledIndent { if e.enabledIndent {
if e.enabledHTMLEscape { if e.enabledHTMLEscape {
return e.runEscapedIndent(ctx, b, codeSet.escapedCode) return e.runEscapedIndent(ctx, b, codeSet.code)
} else { } else {
return e.runIndent(ctx, b, codeSet.code) return e.runIndent(ctx, b, codeSet.code)
} }
} }
if e.enabledHTMLEscape { if e.enabledHTMLEscape {
return e.runEscaped(ctx, b, codeSet.escapedCode) return e.runEscaped(ctx, b, codeSet.code)
} }
return e.run(ctx, b, codeSet.code) return e.run(ctx, b, codeSet.code)
} }

View File

@ -53,20 +53,6 @@ func copyOpcode(code *opcode) *opcode {
return code.copy(codeMap) return code.copy(codeMap)
} }
func toEscaped(c *opcode) *opcode {
c = copyOpcode(c)
for code := c; code.op != opEnd; {
code.op = code.op.toEscaped()
switch code.op.codeType() {
case codeArrayElem, codeSliceElem, codeMapKey:
code = code.end
default:
code = code.next
}
}
return c
}
func newOpCodeWithNext(ctx *encodeCompileContext, op opType, next *opcode) *opcode { func newOpCodeWithNext(ctx *encodeCompileContext, op opType, next *opcode) *opcode {
return &opcode{ return &opcode{
op: op, op: op,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff