Skip to content

Commit cae96e7

Browse files
committed
vm: implement CALL_FUNCTION*, fast locals and make function calling work properly
* Add Localsplus to frame to implement the fastlocals * Implemente LOAD_FAST, DELETE_FAST and STORE_FAST properly * Implement CALL_FUNCTION, CALL_FUNCTION_VAR, CALL_FUNCTION_KW, CALL_FUNCTION_VAR_KW * Rename py.Run* to py.VmRun* - external callers should be calling vm.Run
1 parent 7f90811 commit cae96e7

File tree

9 files changed

+516
-141
lines changed

9 files changed

+516
-141
lines changed

py/frame.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ type Frame struct {
6262
// Executing byte // whether the frame is still executing
6363
Blockstack []TryBlock // for try and loop blocks
6464
Block *TryBlock // pointer to current block or nil
65-
// Localsplus []Object // locals+stack, dynamically sized
65+
Localsplus []Object // LocalVars + CellAndFreeVars
6666
}
6767

6868
var FrameType = NewType("frame", "Represents a stack frame")
@@ -78,10 +78,9 @@ func NewFrame(globals, locals StringDict, code *Code, closure Tuple) *Frame {
7878
ncells := len(code.Cellvars)
7979
nfrees := len(code.Freevars)
8080
varsize := nlocals + ncells + nfrees
81-
size := varsize + int(code.Stacksize)
8281
// Allocate the stack, locals, cells and frees in a contigious block of memory
83-
allocation := make([]Object, varsize, size)
84-
localVars := allocation[0:nlocals]
82+
allocation := make([]Object, varsize)
83+
localVars := allocation[:nlocals]
8584
//cellVars := allocation[nlocals : nlocals+ncells]
8685
//freeVars := allocation[nlocals+ncells : varsize]
8786
cellAndFreeVars := allocation[nlocals:varsize]
@@ -93,6 +92,7 @@ func NewFrame(globals, locals StringDict, code *Code, closure Tuple) *Frame {
9392
LocalVars: localVars,
9493
CellAndFreeVars: cellAndFreeVars,
9594
Builtins: Builtins.Globals,
95+
Localsplus: allocation,
9696
Stack: make([]Object, 0, code.Stacksize),
9797
}
9898
}

py/function.go

Lines changed: 1 addition & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@
1111
// executed so far.
1212
package py
1313

14-
import (
15-
"fmt"
16-
)
17-
1814
// A python Function object
1915
type Function struct {
2016
Code *Code // A code object, the __code__ attribute
@@ -87,48 +83,9 @@ func NewFunction(code *Code, globals StringDict, qualname string) *Function {
8783
}
8884
}
8985

90-
// Setup locals for calling the function with the given arguments
91-
func (f *Function) LocalsForCall(args Tuple) StringDict {
92-
// fmt.Printf("call f %#v with %v\n", f, args)
93-
max := int(f.Code.Argcount)
94-
min := max - len(f.Defaults)
95-
if len(args) > max || len(args) < min {
96-
if min == max {
97-
panic(ExceptionNewf(TypeError, "%s() takes %d positional arguments but %d were given", f.Name, max, len(args)))
98-
} else {
99-
panic(ExceptionNewf(TypeError, "%s() takes from %d to %d positional arguments but %d were given", f.Name, min, max, len(args)))
100-
}
101-
}
102-
103-
// FIXME not sure this is right!
104-
// Copy the args into the local variables
105-
locals := NewStringDict()
106-
for i := range args {
107-
locals[f.Code.Varnames[i]] = args[i]
108-
}
109-
for i := len(args); i < max; i++ {
110-
locals[f.Code.Varnames[i]] = f.Defaults[i-min]
111-
}
112-
// fmt.Printf("locals = %v\n", locals)
113-
return locals
114-
}
115-
116-
// Call the function with the given arguments
117-
func (f *Function) LocalsForCallWithKeywords(args Tuple, kwargs StringDict) StringDict {
118-
locals := NewStringDict()
119-
fmt.Printf("FIXME LocalsForCallWithKeywords NOT IMPLEMENTED\n")
120-
return locals
121-
}
122-
12386
// Call a function
12487
func (f *Function) M__call__(args Tuple, kwargs StringDict) Object {
125-
var locals StringDict
126-
if kwargs != nil {
127-
locals = f.LocalsForCallWithKeywords(args, kwargs)
128-
} else {
129-
locals = f.LocalsForCall(args)
130-
}
131-
result, err := Run(f.Globals, locals, f.Code, f.Closure)
88+
result, err := VmEvalCodeEx(f.Code, f.Globals, NewStringDict(), args, kwargs, f.Defaults, f.KwDefaults, f.Closure)
13289
if err != nil {
13390
// Propagate the error
13491
panic(err)

py/generator.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func (it *Generator) Send(arg Object) Object {
8989
it.Frame.Stack = append(it.Frame.Stack, arg)
9090
}
9191
it.Running = true
92-
res, err := RunFrame(it.Frame)
92+
res, err := VmRunFrame(it.Frame)
9393
it.Running = false
9494
if err != nil {
9595
// Propagate the error

py/import.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ func ImportModuleLevelObject(name string, globals, locals StringDict, fromlist T
116116
panic(ExceptionNewf(ImportError, "Compile didn't return code object"))
117117
}
118118
module := NewModule(name, "", nil, nil)
119-
_, err = Run(module.Globals, module.Globals, code, nil)
119+
_, err = VmRun(module.Globals, module.Globals, code, nil)
120120
if err != nil {
121121
panic(err)
122122
}

py/py.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ type IGetDict interface {
1313

1414
// Some well known objects
1515
var (
16-
// See vm/eval.go - set to avoid circular import
17-
Run func(globals, locals StringDict, code *Code, closure Tuple) (res Object, err error)
18-
RunFrame func(frame *Frame) (res Object, err error)
16+
// Set in vm/eval.go - to avoid circular import
17+
VmRun func(globals, locals StringDict, code *Code, closure Tuple) (res Object, err error)
18+
VmRunFrame func(frame *Frame) (res Object, err error)
19+
VmEvalCodeEx func(co *Code, globals, locals StringDict, args []Object, kws StringDict, defs []Object, kwdefs StringDict, closure Tuple) (retval Object, err error)
20+
1921
// See compile/compile.go - set to avoid circular import
2022
Compile func(str, filename, mode string, flags int, dont_inherit bool) (Object, error)
2123
)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy