diff --git a/_demo/logdemo/log.go b/_demo/logdemo/log.go new file mode 100644 index 00000000..7f472f4a --- /dev/null +++ b/_demo/logdemo/log.go @@ -0,0 +1,9 @@ +package main + +import ( + "log" +) + +func main() { + log.Println("Hello") +} diff --git a/chore/nmdump/nmdump.go b/chore/nmdump/nmdump.go index cdb36554..c0a68042 100644 --- a/chore/nmdump/nmdump.go +++ b/chore/nmdump/nmdump.go @@ -26,7 +26,7 @@ import ( func main() { if len(os.Args) != 2 { - fmt.Fprintln(os.Stderr, "Usage: nmdump xxx.a") + fmt.Fprintln(os.Stderr, "Usage: nmdump libfile") return } diff --git a/internal/lib/runtime/extern.go b/internal/lib/runtime/extern.go new file mode 100644 index 00000000..07b91ef1 --- /dev/null +++ b/internal/lib/runtime/extern.go @@ -0,0 +1,9 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime + +func Caller(skip int) (pc uintptr, file string, line int, ok bool) { + panic("todo: runtime.Caller") +} diff --git a/internal/lib/runtime/runtime2.go b/internal/lib/runtime/runtime2.go new file mode 100644 index 00000000..f8c1b925 --- /dev/null +++ b/internal/lib/runtime/runtime2.go @@ -0,0 +1,13 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime + +// Layout of in-memory per-function information prepared by linker +// See https://golang.org/s/go12symtab. +// Keep in sync with linker (../cmd/link/internal/ld/pcln.go:/pclntab) +// and with package debug/gosym and with symtab.go in package runtime. +type _func struct { + unused [8]byte +} diff --git a/internal/lib/runtime/symtab.go b/internal/lib/runtime/symtab.go new file mode 100644 index 00000000..5ace3344 --- /dev/null +++ b/internal/lib/runtime/symtab.go @@ -0,0 +1,93 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime + +// Frames may be used to get function/file/line information for a +// slice of PC values returned by Callers. +type Frames struct { + // callers is a slice of PCs that have not yet been expanded to frames. + callers []uintptr + + // frames is a slice of Frames that have yet to be returned. + frames []Frame + frameStore [2]Frame +} + +// Frame is the information returned by Frames for each call frame. +type Frame struct { + // PC is the program counter for the location in this frame. + // For a frame that calls another frame, this will be the + // program counter of a call instruction. Because of inlining, + // multiple frames may have the same PC value, but different + // symbolic information. + PC uintptr + + // Func is the Func value of this call frame. This may be nil + // for non-Go code or fully inlined functions. + Func *Func + + // Function is the package path-qualified function name of + // this call frame. If non-empty, this string uniquely + // identifies a single function in the program. + // This may be the empty string if not known. + // If Func is not nil then Function == Func.Name(). + Function string + + // File and Line are the file name and line number of the + // location in this frame. For non-leaf frames, this will be + // the location of a call. These may be the empty string and + // zero, respectively, if not known. + File string + Line int + + // startLine is the line number of the beginning of the function in + // this frame. Specifically, it is the line number of the func keyword + // for Go functions. Note that //line directives can change the + // filename and/or line number arbitrarily within a function, meaning + // that the Line - startLine offset is not always meaningful. + // + // This may be zero if not known. + startLine int + + // Entry point program counter for the function; may be zero + // if not known. If Func is not nil then Entry == + // Func.Entry(). + Entry uintptr + + // The runtime's internal view of the function. This field + // is set (funcInfo.valid() returns true) only for Go functions, + // not for C functions. + funcInfo funcInfo +} + +func (ci *Frames) Next() (frame Frame, more bool) { + panic("todo: runtime.Frames.Next") +} + +// CallersFrames takes a slice of PC values returned by Callers and +// prepares to return function/file/line information. +// Do not change the slice until you are done with the Frames. +func CallersFrames(callers []uintptr) *Frames { + panic("todo: runtime.CallersFrames") +} + +// A Func represents a Go function in the running binary. +type Func struct { + opaque struct{} // unexported field to disallow conversions +} + +// moduledata records information about the layout of the executable +// image. It is written by the linker. Any changes here must be +// matched changes to the code in cmd/link/internal/ld/symtab.go:symtab. +// moduledata is stored in statically allocated non-pointer memory; +// none of the pointers here are visible to the garbage collector. +type moduledata struct { + unused [8]byte +} + +type funcInfo struct { + *_func + datap *moduledata +} diff --git a/internal/lib/sync/atomic/atomic.go b/internal/lib/sync/atomic/atomic.go index 11bef422..8d7bc8a3 100644 --- a/internal/lib/sync/atomic/atomic.go +++ b/internal/lib/sync/atomic/atomic.go @@ -16,7 +16,6 @@ package atomic -// llgo:skipall import ( "unsafe" ) diff --git a/internal/lib/sync/cond.go b/internal/lib/sync/cond.go new file mode 100644 index 00000000..a9daa017 --- /dev/null +++ b/internal/lib/sync/cond.go @@ -0,0 +1,18 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package sync + +// noCopy may be added to structs which must not be copied +// after the first use. +// +// See https://golang.org/issues/8005#issuecomment-190753527 +// for details. +// +// Note that it must not be embedded, due to the Lock and Unlock methods. +type noCopy struct{} + +// Lock is a no-op used by -copylocks checker from `go vet`. +func (*noCopy) Lock() {} +func (*noCopy) Unlock() {} diff --git a/internal/lib/sync/pool.go b/internal/lib/sync/pool.go new file mode 100644 index 00000000..98d5a11e --- /dev/null +++ b/internal/lib/sync/pool.go @@ -0,0 +1,29 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package sync + +import "unsafe" + +type Pool struct { + noCopy noCopy + + local unsafe.Pointer // local fixed-size per-P pool, actual type is [P]poolLocal + localSize uintptr // size of the local array + + victim unsafe.Pointer // local from previous cycle + victimSize uintptr // size of victims array + + // New optionally specifies a function to generate + // a value when Get would otherwise return nil. + // It may not be changed concurrently with calls to Get. + New func() any +} + +func (p *Pool) Put(x any) { +} + +func (p *Pool) Get() any { + return p.New() +} diff --git a/internal/lib/time/time.go b/internal/lib/time/time.go index 06b8262b..a941bee3 100644 --- a/internal/lib/time/time.go +++ b/internal/lib/time/time.go @@ -259,6 +259,12 @@ const ( daysPer4Years = 365*4 + 1 ) +// date computes the year, day of year, and when full=true, +// the month and day in which t occurs. +func (t Time) date(full bool) (year int, month Month, day int, yday int) { + return absDate(t.abs(), full) +} + // absDate is like date but operates on an absolute time. func absDate(abs uint64, full bool) (year int, month Month, day int, yday int) { // Split into time and day. @@ -426,6 +432,18 @@ func Now() Time { return Time{hasMonotonic | uint64(sec)<= March { - d++ // February 29 - } - - // Add in days before today. - d += uint64(day - 1) - - // Add in time elapsed today. - abs := d * secondsPerDay - abs += uint64(hour*secondsPerHour + min*secondsPerMinute + sec) - - unix := int64(abs) + (absoluteToInternal + internalToUnix) - - // Look for zone offset for expected time, so we can adjust to UTC. - // The lookup function expects UTC, so first we pass unix in the - // hope that it will not be too close to a zone transition, - // and then adjust if it is. - _, offset, start, end, _ := loc.lookup(unix) - if offset != 0 { - utc := unix - int64(offset) - // If utc is valid for the time zone we found, then we have the right offset. - // If not, we get the correct offset by looking up utc in the location. - if utc < start || utc >= end { - _, offset, _, _, _ = loc.lookup(utc) - } - unix -= int64(offset) - } - - t := unixTime(unix, int32(nsec)) - t.setLoc(loc) - return t +// Date returns the year, month, and day in which t occurs. +func (t Time) Date() (year int, month Month, day int) { + year, month, day, _ = t.date(true) + return } -/* TODO(xsw): // Year returns the year in which t occurs. func (t Time) Year() int { year, _, _, _ := t.date(false) @@ -586,7 +537,6 @@ func (t Time) Day() int { _, _, day, _ := t.date(true) return day } -*/ // Weekday returns the day of the week specified by t. func (t Time) Weekday() Weekday { @@ -666,11 +616,80 @@ func (t Time) Nanosecond() int { // YearDay returns the day of the year specified by t, in the range [1,365] for non-leap years, // and [1,366] in leap years. func (t Time) YearDay() int { - /* - _, _, _, yday := t.date(false) - return yday + 1 - */ - panic("todo: Time.YearDay") + _, _, _, yday := t.date(false) + return yday + 1 +} + +// Date returns the Time corresponding to +// +// yyyy-mm-dd hh:mm:ss + nsec nanoseconds +// +// in the appropriate zone for that time in the given location. +// +// The month, day, hour, min, sec, and nsec values may be outside +// their usual ranges and will be normalized during the conversion. +// For example, October 32 converts to November 1. +// +// A daylight savings time transition skips or repeats times. +// For example, in the United States, March 13, 2011 2:15am never occurred, +// while November 6, 2011 1:15am occurred twice. In such cases, the +// choice of time zone, and therefore the time, is not well-defined. +// Date returns a time that is correct in one of the two zones involved +// in the transition, but it does not guarantee which. +// +// Date panics if loc is nil. +func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time { + if loc == nil { + panic("time: missing Location in call to Date") + } + + // Normalize month, overflowing into year. + m := int(month) - 1 + year, m = norm(year, m, 12) + month = Month(m) + 1 + + // Normalize nsec, sec, min, hour, overflowing into day. + sec, nsec = norm(sec, nsec, 1e9) + min, sec = norm(min, sec, 60) + hour, min = norm(hour, min, 60) + day, hour = norm(day, hour, 24) + + // Compute days since the absolute epoch. + d := daysSinceEpoch(year) + + // Add in days before this month. + d += uint64(daysBefore[month-1]) + if isLeap(year) && month >= March { + d++ // February 29 + } + + // Add in days before today. + d += uint64(day - 1) + + // Add in time elapsed today. + abs := d * secondsPerDay + abs += uint64(hour*secondsPerHour + min*secondsPerMinute + sec) + + unix := int64(abs) + (absoluteToInternal + internalToUnix) + + // Look for zone offset for expected time, so we can adjust to UTC. + // The lookup function expects UTC, so first we pass unix in the + // hope that it will not be too close to a zone transition, + // and then adjust if it is. + _, offset, start, end, _ := loc.lookup(unix) + if offset != 0 { + utc := unix - int64(offset) + // If utc is valid for the time zone we found, then we have the right offset. + // If not, we get the correct offset by looking up utc in the location. + if utc < start || utc >= end { + _, offset, _, _, _ = loc.lookup(utc) + } + unix -= int64(offset) + } + + t := unixTime(unix, int32(nsec)) + t.setLoc(loc) + return t } func unixTime(sec int64, nsec int32) Time {