mirror of
https://github.com/taigrr/gopher-os
synced 2025-01-18 04:43:13 -08:00
Prevent early_fmt code from triggering Go's allocator
When converting strings to []byte so that they can be used with the tty io.Writer interface Go calls a runtime method called "stringtoslicebyte". If the input length exceeds a particular size then this method will allocate a new []byte and copy the data into it. This obviously causes our kernel to crash. To fix this, all early_fmt functions have been changed to iterate any string arguments and output them to the active TTY one byte at a time.
This commit is contained in:
parent
d7028cee00
commit
6d3c463ee8
@ -7,7 +7,7 @@ var (
|
|||||||
errWrongArgType = []byte("%!(WRONGTYPE)")
|
errWrongArgType = []byte("%!(WRONGTYPE)")
|
||||||
errNoVerb = []byte("%!(NOVERB)")
|
errNoVerb = []byte("%!(NOVERB)")
|
||||||
errExtraArg = []byte("%!(EXTRA)")
|
errExtraArg = []byte("%!(EXTRA)")
|
||||||
padding = []byte{' '}
|
padding = byte(' ')
|
||||||
trueValue = []byte("true")
|
trueValue = []byte("true")
|
||||||
falseValue = []byte("false")
|
falseValue = []byte("false")
|
||||||
)
|
)
|
||||||
@ -62,7 +62,9 @@ func Printf(format string, args ...interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if blockStart < blockEnd {
|
if blockStart < blockEnd {
|
||||||
hal.ActiveTerminal.Write([]byte(format[blockStart:blockEnd]))
|
for i := blockStart; i < blockEnd; i++ {
|
||||||
|
hal.ActiveTerminal.WriteByte(format[i])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan til we hit the format character
|
// Scan til we hit the format character
|
||||||
@ -109,7 +111,9 @@ func Printf(format string, args ...interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if blockStart != blockEnd {
|
if blockStart != blockEnd {
|
||||||
hal.ActiveTerminal.Write([]byte(format[blockStart:blockEnd]))
|
for i := blockStart; i < blockEnd; i++ {
|
||||||
|
hal.ActiveTerminal.WriteByte(format[i])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for unused args
|
// Check for unused args
|
||||||
@ -139,23 +143,25 @@ func fmtBool(v interface{}) {
|
|||||||
// padding specified by padLen. This function uses hal.ActiveTerminal for its
|
// padding specified by padLen. This function uses hal.ActiveTerminal for its
|
||||||
// output.
|
// output.
|
||||||
func fmtString(v interface{}, padLen int) {
|
func fmtString(v interface{}, padLen int) {
|
||||||
var sval []byte
|
|
||||||
|
|
||||||
switch castedVal := v.(type) {
|
switch castedVal := v.(type) {
|
||||||
case string:
|
case string:
|
||||||
sval = []byte(castedVal)
|
fmtRepeat(padding, padLen-len(castedVal))
|
||||||
|
for i := 0; i < len(castedVal); i++ {
|
||||||
|
hal.ActiveTerminal.WriteByte(castedVal[i])
|
||||||
|
}
|
||||||
case []byte:
|
case []byte:
|
||||||
sval = castedVal
|
fmtRepeat(padding, padLen-len(castedVal))
|
||||||
|
hal.ActiveTerminal.Write(castedVal)
|
||||||
default:
|
default:
|
||||||
hal.ActiveTerminal.Write(errWrongArgType)
|
hal.ActiveTerminal.Write(errWrongArgType)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for pad := padLen - len(sval); pad > 0; pad-- {
|
// fmtRepeat writes count bytes with value ch to the hal.ActiveTerminal.
|
||||||
hal.ActiveTerminal.Write(padding)
|
func fmtRepeat(ch byte, count int) {
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
hal.ActiveTerminal.WriteByte(ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
hal.ActiveTerminal.Write(sval)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fmtInt prints out a formatted version of v in the requested base, applying the
|
// fmtInt prints out a formatted version of v in the requested base, applying the
|
||||||
|
Loading…
x
Reference in New Issue
Block a user