Repository: bytedance/sonic (go)

Issue:
There is an panic at github.com/bytedance/sonic/internal/decoder/errors.(*MismatchTypeError).Error
There is an nil pointer panic in my prod env.

`runtime error: invalid memory address or nil pointer dereference
`
```
github.com/bytedance/sonic/internal/decoder/errors.(*MismatchTypeError).Error(0x2ff8980?)
	:1 +0x25
```
The code just like:

```
var sonicConfig = sonic.Config{
	EscapeHTML: true,
}.Froze()

err:=sonicConfig.Unmarshal(data, v)
if err!=nil{
  print(err.Error())
}
```
It panic when i call `err.Error()`

Pull request:
fix: corrupted mismatch type error in jit
Pin mismatch type error in `ST stack`, prevent it being collected by GC. Fixed #692 

Patch:
diff --git a/internal/decoder/jitdec/assembler_regabi_amd64.go b/internal/decoder/jitdec/assembler_regabi_amd64.go
index 3a2b718..8a43d86 100644
--- a/internal/decoder/jitdec/assembler_regabi_amd64.go
+++ b/internal/decoder/jitdec/assembler_regabi_amd64.go
@@ -385,7 +385,7 @@ func (self *_Assembler) prologue() {
 
 var (
     _REG_go = []obj.Addr { _ST, _VP, _IP, _IL, _IC }
-    _REG_rt = []obj.Addr { _ST, _VP, _IP, _IL, _IC, _IL }
+    _REG_rt = []obj.Addr { _ST, _VP, _IP, _IL, _IC }
 )
 
 func (self *_Assembler) save(r ...obj.Addr) {
@@ -492,9 +492,9 @@ func (self *_Assembler) type_error() {
 func (self *_Assembler) mismatch_error() {
     self.Link(_LB_mismatch_error)                     // _type_error:
     self.Emit("MOVQ", _VAR_et, _ET)                   // MOVQ _VAR_et, ET
-    self.Emit("MOVQ", _VAR_ic, _EP)                   // MOVQ _VAR_ic, EP
     self.Emit("MOVQ", _I_json_MismatchTypeError, _CX) // MOVQ _I_json_MismatchType, CX
     self.Emit("CMPQ", _ET, _CX)                       // CMPQ ET, CX
+    self.Emit("MOVQ", jit.Ptr(_ST, _EpOffset), _EP)   // MOVQ stack.Ep, EP
     self.Sjmp("JE"  , _LB_error)                      // JE _LB_error
     self.Emit("MOVQ", _ARG_sp, _AX)
     self.Emit("MOVQ", _ARG_sl, _BX)
@@ -1147,8 +1147,8 @@ func (self *_Assembler) decode_dynamic(vt obj.Addr, vp obj.Addr) {
     self.Emit("MOVQ", _I_json_MismatchTypeError, _CX) // MOVQ _I_json_MismatchTypeError, CX
     self.Emit("CMPQ", _ET, _CX)                 // CMPQ ET, CX
     self.Sjmp("JNE",  _LB_error)                // JNE  LB_error
-    self.Emit("MOVQ", _EP, _VAR_ic)             // MOVQ EP, VAR_ic
     self.Emit("MOVQ", _ET, _VAR_et)             // MOVQ ET, VAR_et
+    self.WriteRecNotAX(14, _EP, jit.Ptr(_ST, _EpOffset), false, false) // MOVQ EP, stack.Ep
     self.Link("_decode_dynamic_end_{n}")
 }
 
diff --git a/internal/decoder/jitdec/generic_regabi_amd64.go b/internal/decoder/jitdec/generic_regabi_amd64.go
index 2c21944..e6d5e3e 100644
--- a/internal/decoder/jitdec/generic_regabi_amd64.go
+++ b/internal/decoder/jitdec/generic_regabi_amd64.go
@@ -186,7 +186,6 @@ var (
     _T_slice   = jit.Type(reflect.TypeOf(([]interface{})(nil)))
     _T_string  = jit.Type(reflect.TypeOf(""))
     _T_number  = jit.Type(reflect.TypeOf(json.Number("")))
-    _T_miserr  = jit.Type(reflect.TypeOf(MismatchTypeError{}))
     _T_float64 = jit.Type(reflect.TypeOf(float64(0)))
 )
 
diff --git a/internal/decoder/jitdec/pools.go b/internal/decoder/jitdec/pools.go
index 37b7b7b..01868cb 100644
--- a/internal/decoder/jitdec/pools.go
+++ b/internal/decoder/jitdec/pools.go
@@ -36,6 +36,7 @@ const (
     _PtrBytes   = _PTR_SIZE / 8
     _FsmOffset  = (_MaxStack + 1) * _PtrBytes
     _DbufOffset = _FsmOffset + int64(unsafe.Sizeof(types.StateMachine{})) + types.MAX_RECURSE * _PtrBytes
+    _EpOffset   = _DbufOffset + _MaxDigitNums
     _StackSize  = unsafe.Sizeof(_Stack{})
 )
 
@@ -53,6 +54,7 @@ type _Stack struct {
     mm types.StateMachine
     vp [types.MAX_RECURSE]unsafe.Pointer
     dp [_MaxDigitNums]byte
+    ep unsafe.Pointer
 }
 
 type _Decoder func(


Test patch:
diff --git a/issue_test/issue692_test.go b/issue_test/issue692_test.go
new file mode 100644
index 0000000..39b0010
--- /dev/null
+++ b/issue_test/issue692_test.go
@@ -0,0 +1,47 @@
+// Copyright 2024 CloudWeGo Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package issue_test
+
+import (
+	"encoding/json"
+	"testing"
+
+	"github.com/bytedance/sonic"
+	"github.com/stretchr/testify/assert"
+)
+
+
+type A1 struct {
+	A *A1 `json:"a"`
+	B int `json:"b"`
+	C int `json:"c"`
+	D D `json:"d"`
+}
+
+type D int
+
+func (d *D) UnmarshalJSON(data []byte) error {
+	return nil
+}
+
+func TestMismatchErrorInRecusive(t *testing.T) {
+	data := `{"a":{"a": null, "b": "123"}, "c": 123, "d": {}}`
+	var obj1, obj2 A1
+	es := sonic.Unmarshal([]byte(data), &obj1)
+	ee := json.Unmarshal([]byte(data), &obj2)
+	assert.Equal(t, ee ==nil, es == nil, es)
+	assert.Equal(t, obj1, obj2)
+	println(es.Error())
+}
\ No newline at end of file
diff --git a/loader/loader_latest.go b/loader/loader_latest.go
index cc2d7ac..7143122 100644
--- a/loader/loader_latest.go
+++ b/loader/loader_latest.go
@@ -71,7 +71,7 @@ func (self Loader) LoadOne(text []byte, funcName string, frameSize int, argSize
     }
     
     if localPtrs != nil {
-        locals := rt .StackMapBuilder{}
+        locals := rt.StackMapBuilder{}
         for _, b := range localPtrs {
             locals.AddField(b)
         }