Skip to content

Commit

Permalink
bug fix as errors aren't hashable anymore, adding missing null for js…
Browse files Browse the repository at this point in the history
…on to object, reduced stack limit, see comment; improve Stack() implementation (a lot) (#185)
  • Loading branch information
ldemailly authored Aug 27, 2024
1 parent 4402e11 commit 251d268
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ flags:
-history file
history file to use (default "~/.grol_history")
-max-depth int
Maximum interpreter depth (default 249999)
Maximum interpreter depth (default 194999)
-max-history size
max history size, use 0 to disable. (default 99)
-max-save-len int
Expand Down
6 changes: 5 additions & 1 deletion eval/eval_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ import (

// Exported part of the eval package.

const DefaultMaxDepth = 250_000
// Approximate maximum depth of recursion to avoid:
// runtime: goroutine stack exceeds 1000000000-byte limit
// fatal error: stack overflow. Was 250k but adding a log
// in Error() makes it go over that (somehow).
const DefaultMaxDepth = 195_000

type State struct {
Out io.Writer
Expand Down
15 changes: 8 additions & 7 deletions eval/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,25 @@ import (

// Returns a stack array of the current stack.
func (s *State) Stack() []string {
stack := make([]string, 0, s.depth) // will be -1 because no name at toplevel but... it's fine.
e := s.env
for {
if e == nil {
break
}
if s.depth <= 1 {
return nil
}
stack := make([]string, 0, s.depth-1)
for e := s.env; e != nil; e = e.StackParent() {
n := e.Name()
if n != "" {
stack = append(stack, e.Name())
}
e = e.StackParent()
}
log.Debugf("Stack() len %d, depth %d returning %v", len(stack), s.depth, stack)
return stack
}

// Creates a new error object with the given message and stack.
func (s *State) Error(msg string) object.Error {
if log.LogDebug() {
log.LogVf("Error %q called", msg)
}
return object.Error{Value: msg, Stack: s.Stack()}
}

Expand Down
2 changes: 1 addition & 1 deletion examples/pi2.gr
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ f = func(i, n, prod) {
}
self(i+1, n, prod*(1-1./(2*i)))
}
n = 200_000
n = 194_990 // close to 195_000 default limit.
f(1, n, 1)
1 change: 1 addition & 0 deletions extensions/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ func initInternal(c *Config) error { //nolint:funlen,gocognit,gocyclo,maintidx /
return err
}
object.AddIdentifier("nil", object.NULL)
object.AddIdentifier("null", object.NULL)
object.AddIdentifier("NaN", object.Float{Value: math.NaN()})
object.AddIdentifier("Inf", object.Float{Value: math.Inf(0)}) // Works for both -Inf and +Inf (thanks to noop unary +).

Expand Down
4 changes: 3 additions & 1 deletion object/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strconv"
"strings"

"fortio.org/log"
"grol.io/grol/ast"
"grol.io/grol/token"
)
Expand Down Expand Up @@ -59,7 +60,7 @@ type Number interface {
// Hashable in tem of Go map for cache key.
func Hashable(o Object) bool {
switch o.Type() { //nolint:exhaustive // We have all the types that are hashable + default for the others.
case INTEGER, FLOAT, BOOLEAN, NIL, ERROR, STRING:
case INTEGER, FLOAT, BOOLEAN, NIL, STRING:
return true
case ARRAY:
if sa, ok := o.(SmallArray); ok {
Expand All @@ -80,6 +81,7 @@ func Hashable(o Object) bool {
return true
}
}
log.Debugf("Not hashable: %#v", o)
return false
}

Expand Down

0 comments on commit 251d268

Please sign in to comment.