Update goja and fix console.[log|error]

This commit is contained in:
Guillaume Ballet 2019-11-20 22:12:07 +01:00
parent c003b9e321
commit f857b8076b
13 changed files with 82 additions and 86 deletions

View file

@ -71,6 +71,7 @@ type Console struct {
histPath string // Absolute path to the console scrollback history
history []string // Scroll history maintained by the console
printer io.Writer // Output writer to serialize any display strings to
runtime *goja.Runtime // The javascript runtime
}
// New initializes a JavaScript interpreted runtime environment and sets defaults
@ -86,10 +87,15 @@ func New(config Config) (*Console, error) {
if config.Printer == nil {
config.Printer = colorable.NewColorableStdout()
}
// Create the JS runtime
runtime := goja.New()
// Initialize the console and return
console := &Console{
runtime: runtime,
client: config.Client,
jsre: jsre.New(config.DocRoot, config.Printer),
jsre: jsre.New(config.DocRoot, config.Printer, runtime),
prompt: config.Prompt,
prompter: config.Prompter,
printer: config.Printer,
@ -108,18 +114,25 @@ func New(config Config) (*Console, error) {
// the console's JavaScript namespaces based on the exposed modules.
func (c *Console) init(preload []string) error {
// Initialize the JavaScript <-> Go RPC bridge
runtime := goja.New()
bridge := newBridge(c.client, c.prompter, c.printer, runtime)
c.jsre.Set("jeth", struct{}{})
c.jsre.Set("console", struct{}{})
bridge := newBridge(c.client, c.prompter, c.printer, c.runtime)
c.jsre.Run("jeth = {};")
c.jsre.Run("console = {};")
jethObj := c.jsre.Get("jeth").ToObject(runtime)
jethObj.Set("send", bridge.Send)
jethObj.Set("sendAsync", bridge.Send)
jethObj := c.jsre.Get("jeth").ToObject(c.runtime)
if err := jethObj.Set("send", bridge.Send); err != nil {
panic(err)
}
if err := jethObj.Set("sendAsync", bridge.Send); err != nil {
panic(err)
}
consoleObj := c.jsre.Get("console").ToObject(runtime)
consoleObj.Set("log", c.consoleOutput)
consoleObj.Set("error", c.consoleOutput)
consoleObj := c.runtime.Get("console").ToObject(c.runtime)
if err := consoleObj.Set("log", c.consoleOutput); err != nil {
panic(err)
}
if err := consoleObj.Set("error", c.consoleOutput); err != nil {
panic(err)
}
// Load all the internal utility JavaScript libraries
if err := c.jsre.Compile("bignumber.js", string(jsre.BignumberJs)); err != nil {
@ -150,7 +163,7 @@ func (c *Console) init(preload []string) error {
return fmt.Errorf("%s.js: %v", api, err)
}
flatten += fmt.Sprintf("var %s = web3.%s; ", api, api)
} else if obj, err := c.jsre.Run("web3." + api); err == nil && obj.ToObject(runtime) != nil {
} else if obj, err := c.jsre.Run("web3." + api); err == nil && obj.ToObject(c.runtime) != nil {
// Enable web3.js built-in extension if available.
flatten += fmt.Sprintf("var %s = web3.%s; ", api, api)
}
@ -173,7 +186,7 @@ func (c *Console) init(preload []string) error {
// original web3 callbacks. These will be called by the jeth.* methods after
// they got the password from the user and send the original web3 request to
// the backend.
if obj := personal.ToObject(runtime); obj != nil { // make sure the personal api is enabled over the interface
if obj := personal.ToObject(c.runtime); obj != nil { // make sure the personal api is enabled over the interface
if _, err = c.jsre.Run(`jeth.openWallet = personal.openWallet;`); err != nil {
return fmt.Errorf("personal.openWallet: %v", err)
}
@ -197,7 +210,7 @@ func (c *Console) init(preload []string) error {
if admin == nil {
return fmt.Errorf("Could not find admin")
}
if obj := admin.ToObject(runtime); obj != nil { // make sure the admin api is enabled over the interface
if obj := admin.ToObject(c.runtime); obj != nil { // make sure the admin api is enabled over the interface
obj.Set("sleepBlocks", bridge.SleepBlocks)
obj.Set("sleep", bridge.Sleep)
obj.Set("clearHistory", c.clearHistory)

View file

@ -68,13 +68,14 @@ type evalReq struct {
}
// runtime must be stopped with Stop() after use and cannot be used after stopping
func New(assetPath string, output io.Writer) *JSRE {
func New(assetPath string, output io.Writer, vm *goja.Runtime) *JSRE {
re := &JSRE{
assetPath: assetPath,
output: output,
closed: make(chan struct{}),
evalQueue: make(chan *evalReq),
stopEventLoop: make(chan bool),
vm: vm,
}
go re.runEventLoop()
re.Set("loadScript", re.loadScript)
@ -106,7 +107,6 @@ func randomSource() *rand.Rand {
func (re *JSRE) runEventLoop() {
defer close(re.closed)
re.vm = goja.New()
r := randomSource()
re.vm.SetRandSource(r.Float64)

View file

@ -22,10 +22,6 @@ func (a *arrayObject) init() {
a._put("length", &a.lengthProp)
}
func (a *arrayObject) getLength() Value {
return intToValue(a.length)
}
func (a *arrayObject) _setLengthInt(l int64, throw bool) bool {
if l >= 0 && l <= math.MaxUint32 {
ret := true
@ -57,7 +53,7 @@ func (a *arrayObject) _setLengthInt(l int64, throw bool) bool {
a.values = ar
} else {
ar := a.values[l:len(a.values)]
for i, _ := range ar {
for i := range ar {
ar[i] = nil
}
a.values = a.values[:l]

View file

@ -27,10 +27,6 @@ func (a *sparseArrayObject) init() {
a._put("length", &a.lengthProp)
}
func (a *sparseArrayObject) getLength() Value {
return intToValue(a.length)
}
func (a *sparseArrayObject) findIdx(idx int64) int {
return sort.Search(len(a.items), func(i int) bool {
return a.items[i].idx >= idx
@ -64,7 +60,7 @@ func (a *sparseArrayObject) _setLengthInt(l int64, throw bool) bool {
idx := a.findIdx(l)
aa := a.items[idx:]
for i, _ := range aa {
for i := range aa {
aa[i].value = nil
}
a.items = a.items[:idx]

View file

@ -278,7 +278,7 @@ func (c *compiler) compile(in *ast.Program) {
}
c.p.code = append(c.p.code, code...)
for i, _ := range c.p.srcMap {
for i := range c.p.srcMap {
c.p.srcMap[i].pc += len(c.scope.names)
}

View file

@ -770,11 +770,6 @@ func (e *compiledFunctionLiteral) emitGetter(putOnStack bool) {
needCallee = true
}
}
lenBefore := len(e.c.scope.names)
namesBefore := make([]string, 0, lenBefore)
for key, _ := range e.c.scope.names {
namesBefore = append(namesBefore, key)
}
maxPreambleLen := 2
e.c.p.code = make([]instruction, maxPreambleLen)
if needCallee {
@ -801,7 +796,7 @@ func (e *compiledFunctionLiteral) emitGetter(putOnStack bool) {
e.c.p.code = e.c.p.code[maxPreambleLen-1:]
}
e.c.convertFunctionToStashless(e.c.p.code, paramsCount)
for i, _ := range e.c.p.srcMap {
for i := range e.c.p.srcMap {
e.c.p.srcMap[i].pc -= maxPreambleLen - l
}
} else {
@ -842,7 +837,7 @@ func (e *compiledFunctionLiteral) emitGetter(putOnStack bool) {
copy(code[l:], e.c.p.code[maxPreambleLen:])
e.c.p.code = code
for i, _ := range e.c.p.srcMap {
for i := range e.c.p.srcMap {
e.c.p.srcMap[i].pc += l - maxPreambleLen
}
}

View file

@ -22,8 +22,6 @@ type dateObject struct {
var (
dateLayoutList = []string{
"2006-01-02T15:04:05.000Z0700",
"2006-01-02T15:04:05.000",
"2006-01-02T15:04:05Z0700",
"2006-01-02T15:04:05",
"2006-01-02",
@ -46,18 +44,12 @@ var (
"2006T15:04:05",
"2006-01T15:04:05",
"2006T15:04:05.000",
"2006-01T15:04:05.000",
"2006T15:04Z0700",
"2006-01T15:04Z0700",
"2006-01-02T15:04Z0700",
"2006T15:04:05Z0700",
"2006-01T15:04:05Z0700",
"2006T15:04:05.000Z0700",
"2006-01T15:04:05.000Z0700",
}
)

View file

@ -1,8 +1,6 @@
package goja
import (
"reflect"
)
import "reflect"
type baseFuncObject struct {
baseObject

View file

@ -18,7 +18,7 @@ type FieldNameMapper interface {
// If this method returns "" the field becomes hidden.
FieldName(t reflect.Type, f reflect.StructField) string
// FieldName returns a JavaScript name for the given method in the given type.
// MethodName returns a JavaScript name for the given method in the given type.
// If this method returns "" the method becomes hidden.
MethodName(t reflect.Type, m reflect.Method) string
}
@ -216,9 +216,8 @@ func (r *Runtime) checkHostObjectPropertyDescr(name string, descr propertyDescr,
}
func (o *objectGoReflect) defineOwnProperty(n Value, descr propertyDescr, throw bool) bool {
name := n.String()
if ast.IsExported(name) {
if o.value.Kind() == reflect.Struct {
name := n.String()
if v := o._getField(name); v.IsValid() {
if !o.val.runtime.checkHostObjectPropertyDescr(name, descr, throw) {
return false
@ -236,15 +235,11 @@ func (o *objectGoReflect) defineOwnProperty(n Value, descr propertyDescr, throw
return true
}
}
}
return o.baseObject.defineOwnProperty(n, descr, throw)
}
func (o *objectGoReflect) _has(name string) bool {
if !ast.IsExported(name) {
return false
}
if o.value.Kind() == reflect.Struct {
if v := o._getField(name); v.IsValid() {
return true
@ -508,7 +503,7 @@ func (r *Runtime) typeInfo(t reflect.Type) (info *reflectTypeInfo) {
return
}
// Sets a custom field name mapper for Go types. It can be called at any time, however
// SetFieldNameMapper sets a custom field name mapper for Go types. It can be called at any time, however
// the mapping for any given value is fixed at the point of creation.
// Setting this to nil restores the default behaviour which is all exported fields and methods are mapped to their
// original unchanged names.

View file

@ -974,7 +974,7 @@ func (r *Runtime) ToValue(i interface{}) Value {
case int64:
return intToValue(i)
case uint:
if int64(i) <= math.MaxInt64 {
if uint64(i) <= math.MaxInt64 {
return intToValue(int64(i))
} else {
return floatToValue(float64(i))
@ -995,6 +995,9 @@ func (r *Runtime) ToValue(i interface{}) Value {
case float64:
return floatToValue(i)
case map[string]interface{}:
if i == nil {
return _null
}
obj := &Object{runtime: r}
m := &objectGoMapSimple{
baseObject: baseObject{
@ -1007,6 +1010,9 @@ func (r *Runtime) ToValue(i interface{}) Value {
m.init()
return obj
case []interface{}:
if i == nil {
return _null
}
obj := &Object{runtime: r}
a := &objectGoSlice{
baseObject: baseObject{
@ -1018,6 +1024,9 @@ func (r *Runtime) ToValue(i interface{}) Value {
a.init()
return obj
case *[]interface{}:
if i == nil {
return _null
}
obj := &Object{runtime: r}
a := &objectGoSlice{
baseObject: baseObject{

View file

@ -436,7 +436,7 @@ func (p *valueProperty) get(this Value) Value {
}
return _undefined
}
call, r := p.getterFunc.self.assertCallable()
call, _ := p.getterFunc.self.assertCallable()
return call(FunctionCall{
This: this,
})

View file

@ -2,7 +2,6 @@ package goja
import (
"fmt"
"log"
"math"
"runtime"
"strconv"
@ -364,11 +363,14 @@ func (vm *vm) try(f func()) (ex *Exception) {
case *Exception:
ex = x1
default:
/*
if vm.prg != nil {
vm.prg.dumpCode(log.Printf)
}
//log.Print("Stack: ", string(debug.Stack()))
log.Print("Stack: ", string(debug.Stack()))
panic(fmt.Errorf("Panic at %d: %v", vm.pc, x))
*/
panic(x)
}
ex.stack = vm.captureStack(ex.stack, ctxOffset)
}

6
vendor/vendor.json vendored
View file

@ -75,10 +75,10 @@
"revisionTime": "2018-06-25T18:44:42Z"
},
{
"checksumSHA1": "h5A0DLu0ZXvpW1F0Lh2oNOlKWf0=",
"checksumSHA1": "2oeluLsV3EQS1b0kjmgLc/i2d7E=",
"path": "github.com/dop251/goja",
"revision": "cc13d3ec34f7c6e4e73dddbfe0a7e868cd3b5c93",
"revisionTime": "2019-06-21T10:59:25Z"
"revision": "aa89e6a4c7339be720f99bae0a56a8f6055b5b3e",
"revisionTime": "2019-09-12T22:33:29Z"
},
{
"checksumSHA1": "zYnPsNAVm1/ViwCkN++dX2JQhBo=",