diff --git a/internal/cmd/generator/vm.go.tmpl b/internal/cmd/generator/vm.go.tmpl index f45a593..70a45e4 100644 --- a/internal/cmd/generator/vm.go.tmpl +++ b/internal/cmd/generator/vm.go.tmpl @@ -403,11 +403,12 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b break } b = appendStructHead(ctx, b) - mapCtx := encoder.NewMapContext(mlen) + unorderedMap := (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 + mapCtx := encoder.NewMapContext(mlen, unorderedMap) mapiterinit(code.Type, uptr, &mapCtx.Iter) store(ctxptr, code.Idx, uintptr(unsafe.Pointer(mapCtx))) ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(mapCtx)) - if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + if unorderedMap { b = appendMapKeyIndent(ctx, code.Next, b) } else { mapCtx.Start = len(b) diff --git a/internal/encoder/decode_rune.go b/internal/encoder/decode_rune.go index 1087f0b..35c959d 100644 --- a/internal/encoder/decode_rune.go +++ b/internal/encoder/decode_rune.go @@ -44,13 +44,6 @@ var first = [256]uint8{ s5, s6, s6, s6, s7, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xF0-0xFF } -// acceptRange gives the range of valid values for the second byte in a UTF-8 -// sequence. -type acceptRange struct { - lo uint8 // lowest value for second byte. - hi uint8 // highest value for second byte. -} - const ( lineSep = byte(168) //'\u2028' paragraphSep = byte(169) //'\u2029' @@ -80,25 +73,31 @@ func decodeRuneInString(s string) (decodeRuneState, int) { return validUTF8State, 1 } sz := int(x & 7) - var accept acceptRange - switch x >> 4 { - case 0: - accept = acceptRange{locb, hicb} - case 1: - accept = acceptRange{0xA0, hicb} - case 2: - accept = acceptRange{locb, 0x9F} - case 3: - accept = acceptRange{0x90, hicb} - case 4: - accept = acceptRange{locb, 0x8F} - } if n < sz { return runeErrorState, 1 } s1 := s[1] - if s1 < accept.lo || accept.hi < s1 { - return runeErrorState, 1 + switch x >> 4 { + case 0: + if s1 < locb || hicb < s1 { + return runeErrorState, 1 + } + case 1: + if s1 < 0xA0 || hicb < s1 { + return runeErrorState, 1 + } + case 2: + if s1 < locb || 0x9F < s1 { + return runeErrorState, 1 + } + case 3: + if s1 < 0x90 || hicb < s1 { + return runeErrorState, 1 + } + case 4: + if s1 < locb || 0x8F < s1 { + return runeErrorState, 1 + } } if sz <= 2 { return validUTF8State, 2 diff --git a/internal/encoder/encoder.go b/internal/encoder/encoder.go index 4ba3158..d210ec4 100644 --- a/internal/encoder/encoder.go +++ b/internal/encoder/encoder.go @@ -275,12 +275,14 @@ var mapContextPool = sync.Pool{ }, } -func NewMapContext(mapLen int) *MapContext { +func NewMapContext(mapLen int, unorderedMap bool) *MapContext { ctx := mapContextPool.Get().(*MapContext) - if len(ctx.Slice.Items) < mapLen { - ctx.Slice.Items = make([]MapItem, mapLen) - } else { - ctx.Slice.Items = ctx.Slice.Items[:mapLen] + if !unorderedMap { + if len(ctx.Slice.Items) < mapLen { + ctx.Slice.Items = make([]MapItem, mapLen) + } else { + ctx.Slice.Items = ctx.Slice.Items[:mapLen] + } } ctx.Buf = ctx.Buf[:0] ctx.Iter = mapIter{} diff --git a/internal/encoder/vm/vm.go b/internal/encoder/vm/vm.go index f45a593..70a45e4 100644 --- a/internal/encoder/vm/vm.go +++ b/internal/encoder/vm/vm.go @@ -403,11 +403,12 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b break } b = appendStructHead(ctx, b) - mapCtx := encoder.NewMapContext(mlen) + unorderedMap := (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 + mapCtx := encoder.NewMapContext(mlen, unorderedMap) mapiterinit(code.Type, uptr, &mapCtx.Iter) store(ctxptr, code.Idx, uintptr(unsafe.Pointer(mapCtx))) ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(mapCtx)) - if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + if unorderedMap { b = appendMapKeyIndent(ctx, code.Next, b) } else { mapCtx.Start = len(b) diff --git a/internal/encoder/vm_color/vm.go b/internal/encoder/vm_color/vm.go index 4a2e3c7..6461bb5 100644 --- a/internal/encoder/vm_color/vm.go +++ b/internal/encoder/vm_color/vm.go @@ -403,11 +403,12 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b break } b = appendStructHead(ctx, b) - mapCtx := encoder.NewMapContext(mlen) + unorderedMap := (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 + mapCtx := encoder.NewMapContext(mlen, unorderedMap) mapiterinit(code.Type, uptr, &mapCtx.Iter) store(ctxptr, code.Idx, uintptr(unsafe.Pointer(mapCtx))) ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(mapCtx)) - if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + if unorderedMap { b = appendMapKeyIndent(ctx, code.Next, b) } else { mapCtx.Start = len(b) diff --git a/internal/encoder/vm_color_indent/vm.go b/internal/encoder/vm_color_indent/vm.go index a9fb725..c428fbe 100644 --- a/internal/encoder/vm_color_indent/vm.go +++ b/internal/encoder/vm_color_indent/vm.go @@ -403,11 +403,12 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b break } b = appendStructHead(ctx, b) - mapCtx := encoder.NewMapContext(mlen) + unorderedMap := (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 + mapCtx := encoder.NewMapContext(mlen, unorderedMap) mapiterinit(code.Type, uptr, &mapCtx.Iter) store(ctxptr, code.Idx, uintptr(unsafe.Pointer(mapCtx))) ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(mapCtx)) - if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + if unorderedMap { b = appendMapKeyIndent(ctx, code.Next, b) } else { mapCtx.Start = len(b) diff --git a/internal/encoder/vm_indent/vm.go b/internal/encoder/vm_indent/vm.go index a023472..90ae850 100644 --- a/internal/encoder/vm_indent/vm.go +++ b/internal/encoder/vm_indent/vm.go @@ -403,11 +403,12 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]b break } b = appendStructHead(ctx, b) - mapCtx := encoder.NewMapContext(mlen) + unorderedMap := (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 + mapCtx := encoder.NewMapContext(mlen, unorderedMap) mapiterinit(code.Type, uptr, &mapCtx.Iter) store(ctxptr, code.Idx, uintptr(unsafe.Pointer(mapCtx))) ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(mapCtx)) - if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + if unorderedMap { b = appendMapKeyIndent(ctx, code.Next, b) } else { mapCtx.Start = len(b)