Repository: bytedance/sonic (go)

Issue:
Bugs when marshal nil interface{} that contains not-indirect values
**Describe the bug**

as title

**To Reproduce**

```
package issue_test

import (
	"testing"
	"github.com/bytedance/sonic"
)



func TestIssue755(t *testing.T) {
	tests := []interface{} {
		struct {
			Foo *int
		}{},
		struct {
			Foo func()
		}{},
		chan int(nil),
	}
	for _, v := range(tests) {
		assertMarshal(t, sonic.ConfigDefault, v)
	}
}
```

**Expected behavior**


**Screenshots**

```
Begin GC looping...
=== RUN   TestIssue755_
    common_test.go:37: 
            Error Trace:    /home/liuqiang.06/sonic/issue_test/common_test.go:37
                                        /home/liuqiang.06/sonic/issue_test/issue755_test.go:15
            Error:          Not equal: 
                            expected: []byte{0x7b, 0x22, 0x46, 0x6f, 0x6f, 0x22, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x7d}
                            actual  : []byte{0x6e, 0x75, 0x6c, 0x6c}
                        
                            Diff:
                            --- Expected
                            +++ Actual
                            @@ -1,3 +1,3 @@
                            -([]uint8) (len=12) {
                            - 00000000  7b 22 46 6f 6f 22 3a 6e  75 6c 6c 7d              |{"Foo":null}|
                            +([]uint8) (len=4) {
                            + 00000000  6e 75 6c 6c                                       |null|
                             }
            Test:           TestIssue755_
            Messages:       {Foo:<nil>}
--- FAIL: TestIssue755_ (0.00s)
FAIL
FAIL    github.com/bytedance/sonic/issue_test   0.021s
FAIL
```

**Sonic version:**

sonic v1.12.9



Pull request:
fix: bug when marshal nil interface{} that contains not-indirect value
#### What type of PR is this?
<!--
Add one of the following kinds:

build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
docs: Documentation only changes
feat: A new feature
optimize: A new optimization
fix: A bug fix
perf: A code change that improves performance
refactor: A code change that neither fixes a bug nor adds a feature
style: Changes that do not affect the meaning of the code (white space, formatting, missing semi-colons, etc)
test: Adding missing tests or correcting existing tests
chore: Changes to the build process or auxiliary tools and libraries such as documentation generation
-->
fix

#### Check the PR title.
<!--
The description of the title will be attached in Release Notes, 
so please describe it from user-oriented, what this PR does / why we need it.
Please check your PR title with the below requirements:
-->
- [x] This PR title match the format: \<type\>(optional scope): \<description\>
- [x] The description of this PR title is user-oriented and clear enough for others to understand.
- [x] Attach the PR updating the user documentation if the current PR requires user awareness at the usage level. [User docs repo](https://github.com/cloudwego/cloudwego.github.io)


#### (Optional) Translate the PR title into Chinese.

#### (Optional) More detailed description for this PR(en: English/zh: Chinese).
<!--
Provide more detailed info for review(e.g., it's recommended to provide perf data if this is a perf type PR).
-->
en:  
zh(optional):  修复marshal eface 时的一个bug，当eface 里面包含一个非 indirect value 时，marshal 结果与 encoding/json 不一致


#### (Optional) Which issue(s) this PR fixes:
<!--
Automatically closes linked issue when PR is merged.
Eg: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
-->
#755 

#### (optional) The PR that updates user documentation:
<!--
If the current PR requires user awareness at the usage level, please submit a PR to update user docs. [User docs repo](https://github.com/cloudwego/cloudwego.github.io)
-->

Patch:
diff --git a/.github/workflows/license-check.yml b/.github/workflows/license-check.yml
deleted file mode 100644
index 847cc3e..0000000
--- a/.github/workflows/license-check.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-name: License Check
-
-on: pull_request
-
-jobs:
-  build:
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v2
-
-      - name: Check License Header
-        uses: apache/skywalking-eyes/header@v0.4.0
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/internal/encoder/compiler.go b/internal/encoder/compiler.go
index 902fbc9..3975d90 100644
--- a/internal/encoder/compiler.go
+++ b/internal/encoder/compiler.go
@@ -626,16 +626,16 @@ func (self *Compiler) compileStructFieldQuoted(p *ir.Program, sp int, vt reflect
 }
 
 func (self *Compiler) compileInterface(p *ir.Program, vt reflect.Type) {
-	x := p.PC()
-	p.Add(ir.OP_is_nil_p1)
-
 	/* iface and efaces are different */
 	if vt.NumMethod() == 0 {
 		p.Add(ir.OP_eface)
-	} else {
-		p.Add(ir.OP_iface)
+		return
 	}
 
+	x := p.PC()
+	p.Add(ir.OP_is_nil_p1)
+	p.Add(ir.OP_iface)
+
 	/* the "null" value */
 	e := p.PC()
 	p.Add(ir.OP_goto)


Test patch:
diff --git a/issue_test/common_test.go b/issue_test/common_test.go
index 490c042..2824787 100644
--- a/issue_test/common_test.go
+++ b/issue_test/common_test.go
@@ -28,4 +28,11 @@ func assertUnmarshal(t *testing.T, api sonic.API, input []byte, newfn func() int
 	jerr := json.Unmarshal(input, jv)
 	assert.Equal(t, jv, sv)
 	assert.Equal(t, serr == nil, jerr == nil)
-}
\ No newline at end of file
+}
+
+func assertMarshal(t *testing.T, api sonic.API, v interface{}) {
+	sout, serr := api.Marshal(&v)
+	jout, jerr := json.Marshal(&v)
+	assert.Equal(t, jerr == nil, serr == nil, jerr)
+	assert.Equal(t, jout, sout, v)
+}
diff --git a/issue_test/issue755_test.go b/issue_test/issue755_test.go
new file mode 100644
index 0000000..e2364c8
--- /dev/null
+++ b/issue_test/issue755_test.go
@@ -0,0 +1,41 @@
+package issue_test
+
+import (
+	"testing"
+	"github.com/bytedance/sonic"
+)
+
+func TestIssue755_NilEfaceWithDirectValue(t *testing.T) {
+	tests := []interface{} {
+		struct {
+			Foo *int
+		}{},
+		struct {
+			Foo func()
+		}{},
+		chan int(nil),
+	}
+	for _, v := range(tests) {
+		assertMarshal(t, sonic.ConfigDefault, v)
+	}
+}
+
+type NilMarshaler struct {}
+
+func (n *NilMarshaler) MarshalJSON() ([]byte, error) {
+	if n == nil {
+		return []byte(`"my null value"`), nil
+	}
+	return []byte(`{}`), nil
+}
+
+func TestIssue755_MarshalIface(t *testing.T) {
+	tests := []interface{} {
+		&NilMarshaler{},
+		(*NilMarshaler)(nil),
+	}
+	for _, v := range(tests) {
+		assertMarshal(t, sonic.ConfigDefault, v)
+	}
+}
+