1
0
mirror of https://github.com/robertkrimen/otto synced 2025-10-26 20:28:49 +08:00

make call stacks aware of native functions

* add stackFramesToPop argument to error factories
* put native functions in their own stack frames
* add tests for native stack frames
* amend Context functionality to account for native frames
This commit is contained in:
deoxxa
2015-11-28 09:27:56 +11:00
parent 3a69c44018
commit 668c95f04e
11 changed files with 352 additions and 60 deletions

40
otto.go
View File

@@ -383,7 +383,7 @@ func (self Otto) SetStackDepthLimit(limit int) {
// MakeCustomError creates a new Error object with the given name and message,
// returning it as a Value.
func (self Otto) MakeCustomError(name, message string) Value {
return self.runtime.toValue(self.runtime.newError(name, self.runtime.toValue(message)))
return self.runtime.toValue(self.runtime.newError(name, self.runtime.toValue(message), 0))
}
// MakeRangeError creates a new RangeError object with the given message,
@@ -416,8 +416,23 @@ type Context struct {
Stacktrace []string
}
// Context returns the current execution context of the vm
func (self Otto) Context() (ctx Context) {
// Context returns the current execution context of the vm, traversing up to
// ten stack frames, and skipping any innermost native function stack frames.
func (self Otto) Context() Context {
return self.ContextSkip(10, true)
}
// ContextLimit returns the current execution context of the vm, with a
// specific limit on the number of stack frames to traverse, skipping any
// innermost native function stack frames.
func (self Otto) ContextLimit(limit int) Context {
return self.ContextSkip(limit, true)
}
// ContextSkip returns the current execution context of the vm, with a
// specific limit on the number of stack frames to traverse, optionally
// skipping any innermost native function stack frames.
func (self Otto) ContextSkip(limit int, skipNative bool) (ctx Context) {
// Ensure we are operating in a scope
if self.runtime.scope == nil {
self.runtime.enterGlobalScope()
@@ -427,14 +442,24 @@ func (self Otto) Context() (ctx Context) {
scope := self.runtime.scope
frame := scope.frame
for skipNative && frame.native && scope.outer != nil {
scope = scope.outer
frame = scope.frame
}
// Get location information
ctx.Filename = "<unknown>"
ctx.Callee = frame.callee
if frame.file != nil {
switch {
case frame.native:
ctx.Filename = frame.nativeFile
ctx.Line = frame.nativeLine
ctx.Column = 0
case frame.file != nil:
ctx.Filename = "<anonymous>"
p := frame.file.Position(file.Idx(frame.offset))
if p != nil {
if p := frame.file.Position(file.Idx(frame.offset)); p != nil {
ctx.Line = p.Line
ctx.Column = p.Column
@@ -448,10 +473,9 @@ func (self Otto) Context() (ctx Context) {
ctx.This = toValue_object(scope.this)
// Build stacktrace (up to 10 levels deep)
limit := 10
ctx.Symbols = make(map[string]Value)
ctx.Stacktrace = append(ctx.Stacktrace, frame.location())
for limit > 0 {
for limit != 0 {
// Get variables
stash := scope.lexical
for {