Skip to content

Commit

Permalink
fix runtime patch, addressing #4 (comment)
Browse files Browse the repository at this point in the history
  • Loading branch information
xhd2015 committed Mar 25, 2024
1 parent a90c6ef commit c5d2615
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 31 deletions.
17 changes: 13 additions & 4 deletions cmd/xgo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,18 @@ func main() {

err := handleBuild(cmd, args)
if err != nil {
logDebug("finished with error: %v", err)
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
var errMsg string
var exitCode int = 1
if e, ok := err.(*exec.ExitError); ok {
errMsg = string(e.Stderr)
exitCode = e.ExitCode()
} else {
errMsg = e.Error()

}
logDebug("finished with error: %s", errMsg)
fmt.Fprintf(os.Stderr, "%v\n", errMsg)
os.Exit(exitCode)
}
logDebug("finished successfully")
}
Expand Down Expand Up @@ -264,7 +273,7 @@ func handleBuild(cmd string, args []string) error {
}
// patch go runtime and compiler
logDebug("patch compiler at: %s", instrumentGoroot)
err = patchRuntimeAndCompiler(instrumentGoroot, realXgoSrc, goVersion, syncWithLink || setupDev || buildCompiler, revisionChanged)
err = patchRuntimeAndCompiler(goroot, instrumentGoroot, realXgoSrc, goVersion, syncWithLink || setupDev || buildCompiler, revisionChanged)
if err != nil {
return err
}
Expand Down
70 changes: 47 additions & 23 deletions cmd/xgo/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import (

// assume go 1.20
// the patch should be idempotent
func patchRuntimeAndCompiler(goroot string, xgoSrc string, goVersion *goinfo.GoVersion, syncWithLink bool, revisionChanged bool) error {
// the origGoroot is used to generate runtime defs, see https://github.com/xhd2015/xgo/issues/4#issuecomment-2017880791
func patchRuntimeAndCompiler(origGoroot string, goroot string, xgoSrc string, goVersion *goinfo.GoVersion, syncWithLink bool, revisionChanged bool) error {
if goroot == "" {
return fmt.Errorf("requires goroot")
}
Expand All @@ -39,7 +40,7 @@ func patchRuntimeAndCompiler(goroot string, xgoSrc string, goVersion *goinfo.GoV
}

// compiler
err = patchCompiler(goroot, goVersion, xgoSrc, revisionChanged, syncWithLink)
err = patchCompiler(origGoroot, goroot, goVersion, xgoSrc, revisionChanged, syncWithLink)
if err != nil {
return err
}
Expand Down Expand Up @@ -170,25 +171,26 @@ func importCompileInternalPatch(goroot string, xgoSrc string, forceReset bool, s
return nil
}

func patchRuntimeDef(goRoot string, goVersion *goinfo.GoVersion) error {
err := prepareRuntimeDefs(goRoot, goVersion)
func patchRuntimeDef(origGoroot string, goroot string, goVersion *goinfo.GoVersion) error {
err := prepareRuntimeDefs(origGoroot, goVersion)
if err != nil {
return err
}

// run mkbuiltin
cmd := exec.Command(filepath.Join(goRoot, "bin", "go"), "run", "mkbuiltin.go")
cmd := exec.Command(filepath.Join(origGoroot, "bin", "go"), "run", "mkbuiltin.go")
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout

dir := "src/cmd/compile/internal/typecheck"
if goVersion.Major == 1 && goVersion.Minor <= 16 {
dir = "src/cmd/compile/internal/gc"
var dirs []string
if goVersion.Major > 1 || (goVersion.Major == 1 && goVersion.Minor > 16) {
dirs = []string{goroot, "src", "cmd", "compile", "internal", "typecheck"}
} else {
dirs = []string{goroot, "src", "cmd", "compile", "internal", "gc"}
}
cmd.Dir = filepath.Join(goRoot, dir)

cmd.Dir = filepath.Join(dirs...)
cmd.Env = os.Environ()
cmd.Env, err = patchEnvWithGoroot(cmd.Env, goRoot)
cmd.Env, err = patchEnvWithGoroot(cmd.Env, origGoroot)
if err != nil {
return err
}
Expand All @@ -202,15 +204,16 @@ func patchRuntimeDef(goRoot string, goVersion *goinfo.GoVersion) error {
}

func prepareRuntimeDefs(goRoot string, goVersion *goinfo.GoVersion) error {
runtimeDefFile := "src/cmd/compile/internal/typecheck/_builtin/runtime.go"
runtimeDefFiles := []string{"src", "cmd", "compile", "internal", "typecheck", "_builtin", "runtime.go"}
if goVersion.Major == 1 && goVersion.Minor <= 19 {
if goVersion.Minor > 16 {
// in go1.19 and below, builtin has no _ prefix
runtimeDefFile = "src/cmd/compile/internal/typecheck/builtin/runtime.go"
runtimeDefFiles = []string{"src", "cmd", "compile", "internal", "typecheck", "builtin", "runtime.go"}
} else {
runtimeDefFile = "src/cmd/compile/internal/gc/builtin/runtime.go"
runtimeDefFiles = []string{"src", "cmd", "compile", "internal", "gc", "builtin", "runtime.go"}
}
}
runtimeDefFile := filepath.Join(runtimeDefFiles...)
fullFile := filepath.Join(goRoot, runtimeDefFile)

extraDef := patch.RuntimeExtraDef
Expand All @@ -224,7 +227,7 @@ func prepareRuntimeDefs(goRoot string, goVersion *goinfo.GoVersion) error {
})
}

func patchCompiler(goroot string, goVersion *goinfo.GoVersion, xgoSrc string, forceReset bool, syncWithLink bool) error {
func patchCompiler(origGoroot string, goroot string, goVersion *goinfo.GoVersion, xgoSrc string, forceReset bool, syncWithLink bool) error {
// copy compiler internal dependencies
err := importCompileInternalPatch(goroot, xgoSrc, forceReset, syncWithLink)
if err != nil {
Expand All @@ -236,7 +239,7 @@ func patchCompiler(goroot string, goVersion *goinfo.GoVersion, xgoSrc string, fo
}

if runtimeDefUpdated {
err = patchRuntimeDef(goroot, goVersion)
err = patchRuntimeDef(origGoroot, goroot, goVersion)
if err != nil {
return err
}
Expand Down Expand Up @@ -281,8 +284,13 @@ func addRuntimeFunctions(goroot string, goVersion *goinfo.GoVersion, xgoSrc stri
if err != nil {
return false, err
}
const buildIgnore = "//go:build ignore"

content = bytes.Replace(content, []byte("//go:build ignore\n"), nil, 1)
// buggy: content = bytes.Replace(content, []byte("//go:build ignore\n"), nil, 1)
content, err = replaceMarkerNewline(content, []byte(buildIgnore))
if err != nil {
return false, fmt.Errorf("file %s: %w", filepath.Base(dstFile), err)
}

// the func.entry is a field, not a function
if goVersion.Major == 1 && goVersion.Minor <= 17 {
Expand All @@ -304,13 +312,28 @@ func addRuntimeFunctions(goroot string, goVersion *goinfo.GoVersion, xgoSrc stri
return true, ioutil.WriteFile(dstFile, content, 0755)
}

// content = bytes.Replace(content, []byte("//go:build ignore\n"), nil, 1)
func replaceMarkerNewline(content []byte, marker []byte) ([]byte, error) {
idx := bytes.Index(content, marker)
if idx < 0 {
return nil, fmt.Errorf("missing %s", string(marker))
}
idx += len(marker)
if idx < len(content) && content[idx] == '\r' {
idx++
}
if idx < len(content) && content[idx] == '\n' {
idx++
}
return content[idx:], nil
}
func patchCompilerNoder(goroot string, goVersion *goinfo.GoVersion) error {
file := "src/cmd/compile/internal/noder/noder.go"
files := []string{"src", "cmd", "compile", "internal", "noder", "noder.go"}
var noderFiles string
if goVersion.Major == 1 {
minor := goVersion.Minor
if minor == 16 {
file = "src/cmd/compile/internal/gc/noder.go"
files = []string{"src", "cmd", "compile", "internal", "gc", "noder.go"}
noderFiles = patch.NoderFiles_1_17
} else if minor == 17 {
noderFiles = patch.NoderFiles_1_17
Expand All @@ -329,6 +352,7 @@ func patchCompilerNoder(goroot string, goVersion *goinfo.GoVersion) error {
if noderFiles == "" {
return fmt.Errorf("unsupported: %v", goVersion)
}
file := filepath.Join(files...)
return editFile(filepath.Join(goroot, file), func(content string) (string, error) {
content = addCodeAfterImports(content,
"/*<begin file_autogen_import>*/", "/*<end file_autogen_import>*/",
Expand Down Expand Up @@ -360,8 +384,8 @@ func patchCompilerNoder(goroot string, goVersion *goinfo.GoVersion) error {
}

func poatchIRGenericGen(goroot string, goVersion *goinfo.GoVersion) error {
file := "src/cmd/compile/internal/noder/irgen.go"
return editFile(filepath.Join(goroot, file), func(content string) (string, error) {
file := filepath.Join(goroot, "src", "cmd", "compile", "internal", "noder", "irgen.go")
return editFile(file, func(content string) (string, error) {
imports := []string{
`xgo_patch "cmd/compile/internal/xgo_rewrite_internal/patch"`,
}
Expand All @@ -385,7 +409,7 @@ func poatchIRGenericGen(goroot string, goVersion *goinfo.GoVersion) error {
}

func patchGcMain(goroot string, goVersion *goinfo.GoVersion) error {
file := "src/cmd/compile/internal/gc/main.go"
file := filepath.Join(goroot, "src", "cmd", "compile", "internal", "gc", "main.go")
go116AndUnder := goVersion.Major == 1 && goVersion.Minor <= 16
go117 := goVersion.Major == 1 && goVersion.Minor == 17
go118 := goVersion.Major == 1 && goVersion.Minor == 18
Expand All @@ -395,7 +419,7 @@ func patchGcMain(goroot string, goVersion *goinfo.GoVersion) error {
go121 := goVersion.Major == 1 && goVersion.Minor == 21
go122 := goVersion.Major == 1 && goVersion.Minor == 22

return editFile(filepath.Join(goroot, file), func(content string) (string, error) {
return editFile(file, func(content string) (string, error) {
imports := []string{
`xgo_patch "cmd/compile/internal/xgo_rewrite_internal/patch"`,
`xgo_record "cmd/compile/internal/xgo_rewrite_internal/patch/record"`,
Expand Down
4 changes: 2 additions & 2 deletions cmd/xgo/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package main
import "fmt"

const VERSION = "1.0.6"
const REVISION = "f33f74e62755baf725f5f05e87bbf25c21af2951+1"
const NUMBER = 103
const REVISION = "a90c6ef098ea021488a507ab255b738b8712c3be+1"
const NUMBER = 104

func getRevision() string {
return fmt.Sprintf("%s %s BUILD_%d", VERSION, REVISION, NUMBER)
Expand Down
4 changes: 2 additions & 2 deletions runtime/core/version.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package core

const VERSION = "1.0.5"
const REVISION = "f33f74e62755baf725f5f05e87bbf25c21af2951+1"
const NUMBER = 103
const REVISION = "a90c6ef098ea021488a507ab255b738b8712c3be+1"
const NUMBER = 104

0 comments on commit c5d2615

Please sign in to comment.