mirror of https://github.com/status-im/op-geth.git
215 lines
5.5 KiB
Go
215 lines
5.5 KiB
Go
|
package otto
|
||
|
|
||
|
import (
|
||
|
"strconv"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
prototypeValueObject = interface{}(nil)
|
||
|
prototypeValueFunction = _functionObject{
|
||
|
call: _nativeCallFunction{"", func(_ FunctionCall) Value {
|
||
|
return UndefinedValue()
|
||
|
}},
|
||
|
}
|
||
|
prototypeValueString = _stringASCII("")
|
||
|
// TODO Make this just false?
|
||
|
prototypeValueBoolean = Value{
|
||
|
_valueType: valueBoolean,
|
||
|
value: false,
|
||
|
}
|
||
|
prototypeValueNumber = Value{
|
||
|
_valueType: valueNumber,
|
||
|
value: 0,
|
||
|
}
|
||
|
prototypeValueDate = _dateObject{
|
||
|
epoch: 0,
|
||
|
isNaN: false,
|
||
|
time: time.Unix(0, 0).UTC(),
|
||
|
value: Value{
|
||
|
_valueType: valueNumber,
|
||
|
value: 0,
|
||
|
},
|
||
|
}
|
||
|
prototypeValueRegExp = _regExpObject{
|
||
|
regularExpression: nil,
|
||
|
global: false,
|
||
|
ignoreCase: false,
|
||
|
multiline: false,
|
||
|
source: "",
|
||
|
flags: "",
|
||
|
}
|
||
|
)
|
||
|
|
||
|
func newContext() *_runtime {
|
||
|
|
||
|
self := &_runtime{}
|
||
|
|
||
|
self.GlobalEnvironment = self.newObjectEnvironment(nil, nil)
|
||
|
self.GlobalObject = self.GlobalEnvironment.Object
|
||
|
|
||
|
self.EnterGlobalExecutionContext()
|
||
|
|
||
|
_newContext(self)
|
||
|
|
||
|
self.eval = self.GlobalObject.property["eval"].value.(Value).value.(*_object)
|
||
|
self.GlobalObject.prototype = self.Global.ObjectPrototype
|
||
|
//self.parser = ast.NewParser()
|
||
|
|
||
|
return self
|
||
|
}
|
||
|
|
||
|
func (runtime *_runtime) newBaseObject() *_object {
|
||
|
self := newObject(runtime, "")
|
||
|
return self
|
||
|
}
|
||
|
|
||
|
func (runtime *_runtime) newClassObject(class string) *_object {
|
||
|
return newObject(runtime, class)
|
||
|
}
|
||
|
|
||
|
func (runtime *_runtime) newPrimitiveObject(class string, value Value) *_object {
|
||
|
self := runtime.newClassObject(class)
|
||
|
self.value = value
|
||
|
return self
|
||
|
}
|
||
|
|
||
|
func (self *_object) primitiveValue() Value {
|
||
|
switch value := self.value.(type) {
|
||
|
case Value:
|
||
|
return value
|
||
|
case _stringObject:
|
||
|
return toValue_string(value.String())
|
||
|
}
|
||
|
return Value{}
|
||
|
}
|
||
|
|
||
|
func (self *_object) hasPrimitive() bool {
|
||
|
switch self.value.(type) {
|
||
|
case Value, _stringObject:
|
||
|
return true
|
||
|
}
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
func (runtime *_runtime) newObject() *_object {
|
||
|
self := runtime.newClassObject("Object")
|
||
|
self.prototype = runtime.Global.ObjectPrototype
|
||
|
return self
|
||
|
}
|
||
|
|
||
|
func (runtime *_runtime) newArray(length uint32) *_object {
|
||
|
self := runtime.newArrayObject(length)
|
||
|
self.prototype = runtime.Global.ArrayPrototype
|
||
|
return self
|
||
|
}
|
||
|
|
||
|
func (runtime *_runtime) newArrayOf(valueArray []Value) *_object {
|
||
|
self := runtime.newArray(uint32(len(valueArray)))
|
||
|
for index, value := range valueArray {
|
||
|
if value.isEmpty() {
|
||
|
continue
|
||
|
}
|
||
|
self.defineProperty(strconv.FormatInt(int64(index), 10), value, 0111, false)
|
||
|
}
|
||
|
return self
|
||
|
}
|
||
|
|
||
|
func (runtime *_runtime) newString(value Value) *_object {
|
||
|
self := runtime.newStringObject(value)
|
||
|
self.prototype = runtime.Global.StringPrototype
|
||
|
return self
|
||
|
}
|
||
|
|
||
|
func (runtime *_runtime) newBoolean(value Value) *_object {
|
||
|
self := runtime.newBooleanObject(value)
|
||
|
self.prototype = runtime.Global.BooleanPrototype
|
||
|
return self
|
||
|
}
|
||
|
|
||
|
func (runtime *_runtime) newNumber(value Value) *_object {
|
||
|
self := runtime.newNumberObject(value)
|
||
|
self.prototype = runtime.Global.NumberPrototype
|
||
|
return self
|
||
|
}
|
||
|
|
||
|
func (runtime *_runtime) newRegExp(patternValue Value, flagsValue Value) *_object {
|
||
|
|
||
|
pattern := ""
|
||
|
flags := ""
|
||
|
if object := patternValue._object(); object != nil && object.class == "RegExp" {
|
||
|
if flagsValue.IsDefined() {
|
||
|
panic(newTypeError("Cannot supply flags when constructing one RegExp from another"))
|
||
|
}
|
||
|
regExp := object.regExpValue()
|
||
|
pattern = regExp.source
|
||
|
flags = regExp.flags
|
||
|
} else {
|
||
|
if patternValue.IsDefined() {
|
||
|
pattern = toString(patternValue)
|
||
|
}
|
||
|
if flagsValue.IsDefined() {
|
||
|
flags = toString(flagsValue)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return runtime._newRegExp(pattern, flags)
|
||
|
}
|
||
|
|
||
|
func (runtime *_runtime) _newRegExp(pattern string, flags string) *_object {
|
||
|
self := runtime.newRegExpObject(pattern, flags)
|
||
|
self.prototype = runtime.Global.RegExpPrototype
|
||
|
return self
|
||
|
}
|
||
|
|
||
|
// TODO Should (probably) be one argument, right? This is redundant
|
||
|
func (runtime *_runtime) newDate(epoch float64) *_object {
|
||
|
self := runtime.newDateObject(epoch)
|
||
|
self.prototype = runtime.Global.DatePrototype
|
||
|
return self
|
||
|
}
|
||
|
|
||
|
func (runtime *_runtime) newError(name string, message Value) *_object {
|
||
|
var self *_object
|
||
|
switch name {
|
||
|
case "EvalError":
|
||
|
return runtime.newEvalError(message)
|
||
|
case "TypeError":
|
||
|
return runtime.newTypeError(message)
|
||
|
case "RangeError":
|
||
|
return runtime.newRangeError(message)
|
||
|
case "ReferenceError":
|
||
|
return runtime.newReferenceError(message)
|
||
|
case "SyntaxError":
|
||
|
return runtime.newSyntaxError(message)
|
||
|
case "URIError":
|
||
|
return runtime.newURIError(message)
|
||
|
}
|
||
|
|
||
|
self = runtime.newErrorObject(message)
|
||
|
self.prototype = runtime.Global.ErrorPrototype
|
||
|
if name != "" {
|
||
|
self.defineProperty("name", toValue_string(name), 0111, false)
|
||
|
}
|
||
|
return self
|
||
|
}
|
||
|
|
||
|
func (runtime *_runtime) newNativeFunction(name string, _nativeFunction _nativeFunction) *_object {
|
||
|
self := runtime.newNativeFunctionObject(name, _nativeFunction, 0)
|
||
|
self.prototype = runtime.Global.FunctionPrototype
|
||
|
prototype := runtime.newObject()
|
||
|
self.defineProperty("prototype", toValue_object(prototype), 0100, false)
|
||
|
prototype.defineProperty("constructor", toValue_object(self), 0100, false)
|
||
|
return self
|
||
|
}
|
||
|
|
||
|
func (runtime *_runtime) newNodeFunction(node *_nodeFunctionLiteral, scopeEnvironment _environment) *_object {
|
||
|
// TODO Implement 13.2 fully
|
||
|
self := runtime.newNodeFunctionObject(node, scopeEnvironment)
|
||
|
self.prototype = runtime.Global.FunctionPrototype
|
||
|
prototype := runtime.newObject()
|
||
|
self.defineProperty("prototype", toValue_object(prototype), 0100, false)
|
||
|
prototype.defineProperty("constructor", toValue_object(self), 0101, false)
|
||
|
return self
|
||
|
}
|