Browse Source

Slight functions refactoring

Dmitry Panov 8 years ago
parent
commit
6416a5b5ab
3 changed files with 248 additions and 255 deletions
  1. 226 0
      func.go
  2. 0 239
      object.go
  3. 22 16
      runtime.go

+ 226 - 0
func.go

@@ -0,0 +1,226 @@
+package goja
+
+import "reflect"
+
+type baseFuncObject struct {
+	baseObject
+
+	nameProp, lenProp valueProperty
+}
+
+type funcObject struct {
+	baseFuncObject
+
+	stash *stash
+	prg   *Program
+	src   string
+}
+
+type nativeFuncObject struct {
+	baseFuncObject
+
+	f         func(FunctionCall) Value
+	construct func(args []Value) *Object
+}
+
+type boundFuncObject struct {
+	nativeFuncObject
+}
+
+func (f *nativeFuncObject) export() interface{} {
+	return f.f
+}
+
+func (f *nativeFuncObject) exportType() reflect.Type {
+	return reflect.TypeOf(f.f)
+}
+
+func (f *funcObject) getPropStr(name string) Value {
+	switch name {
+	case "prototype":
+		if _, exists := f.values["prototype"]; !exists {
+			return f.addPrototype()
+		}
+	}
+
+	return f.baseObject.getPropStr(name)
+}
+
+func (f *funcObject) addPrototype() Value {
+	proto := f.val.runtime.NewObject()
+	proto.self._putProp("constructor", f.val, true, false, true)
+	return f._putProp("prototype", proto, true, false, false)
+}
+
+func (f *funcObject) getProp(n Value) Value {
+	return f.getPropStr(n.String())
+}
+
+func (f *funcObject) hasOwnProperty(n Value) bool {
+	if r := f.baseObject.hasOwnProperty(n); r {
+		return true
+	}
+
+	name := n.String()
+	if name == "prototype" {
+		return true
+	}
+	return false
+}
+
+func (f *funcObject) hasOwnPropertyStr(name string) bool {
+	if r := f.baseObject.hasOwnPropertyStr(name); r {
+		return true
+	}
+
+	if name == "prototype" {
+		return true
+	}
+	return false
+}
+
+func (f *funcObject) construct(args []Value) *Object {
+	proto := f.getStr("prototype")
+	var protoObj *Object
+	if p, ok := proto.(*Object); ok {
+		protoObj = p
+	} else {
+		protoObj = f.val.runtime.global.ObjectPrototype
+	}
+	obj := f.val.runtime.newBaseObject(protoObj, classObject).val
+	ret := f.Call(FunctionCall{
+		This:      obj,
+		Arguments: args,
+	})
+
+	if ret, ok := ret.(*Object); ok {
+		return ret
+	}
+	return obj
+}
+
+func (f *funcObject) Call(call FunctionCall) Value {
+	vm := f.val.runtime.vm
+	pc := vm.pc
+	vm.push(f.val)
+	vm.push(call.This)
+	for _, arg := range call.Arguments {
+		vm.push(arg)
+	}
+	vm.pc = -1
+	vm.pushCtx()
+	vm.args = len(call.Arguments)
+	vm.prg = f.prg
+	vm.stash = f.stash
+	vm.pc = 0
+	vm.run()
+	vm.pc = pc
+	vm.halt = false
+	return vm.pop()
+}
+
+func (f *funcObject) export() interface{} {
+	return f.Call
+}
+
+func (f *funcObject) exportType() reflect.Type {
+	return reflect.TypeOf(f.Call)
+}
+
+func (f *funcObject) assertCallable() (func(FunctionCall) Value, bool) {
+	return f.Call, true
+}
+
+func (f *baseFuncObject) init(name string, length int) {
+	f.baseObject.init()
+
+	f.nameProp.configurable = true
+	f.nameProp.value = newStringValue(name)
+	f._put("name", &f.nameProp)
+
+	f.lenProp.configurable = true
+	f.lenProp.value = valueInt(length)
+	f._put("length", &f.lenProp)
+}
+
+func (f *baseFuncObject) hasInstance(v Value) bool {
+	if v, ok := v.(*Object); ok {
+		o := f.val.self.getStr("prototype")
+		if o1, ok := o.(*Object); ok {
+			for {
+				v = v.self.proto()
+				if v == nil {
+					return false
+				}
+				if o1 == v {
+					return true
+				}
+			}
+		} else {
+			f.val.runtime.typeErrorResult(true, "prototype is not an object")
+		}
+	}
+
+	return false
+}
+
+func (f *nativeFuncObject) defaultConstruct(args []Value) Value {
+	proto := f.getStr("prototype")
+	var protoObj *Object
+	if p, ok := proto.(*Object); ok {
+		protoObj = p
+	} else {
+		protoObj = f.val.runtime.global.ObjectPrototype
+	}
+	obj := f.val.runtime.newBaseObject(protoObj, classObject).val
+	ret := f.f(FunctionCall{
+		This:      obj,
+		Arguments: args,
+	})
+
+	if ret, ok := ret.(*Object); ok {
+		return ret
+	}
+	return obj
+}
+
+func (f *nativeFuncObject) assertCallable() (func(FunctionCall) Value, bool) {
+	if f.f != nil {
+		return f.f, true
+	}
+	return nil, false
+}
+
+func (f *boundFuncObject) getProp(n Value) Value {
+	return f.getPropStr(n.String())
+}
+
+func (f *boundFuncObject) getPropStr(name string) Value {
+	if name == "caller" || name == "arguments" {
+		//f.runtime.typeErrorResult(true, "'caller' and 'arguments' are restricted function properties and cannot be accessed in this context.")
+		return f.val.runtime.global.throwerProperty
+	}
+	return f.nativeFuncObject.getPropStr(name)
+}
+
+func (f *boundFuncObject) delete(n Value, throw bool) bool {
+	return f.deleteStr(n.String(), throw)
+}
+
+func (f *boundFuncObject) deleteStr(name string, throw bool) bool {
+	if name == "caller" || name == "arguments" {
+		return true
+	}
+	return f.nativeFuncObject.deleteStr(name, throw)
+}
+
+func (f *boundFuncObject) putStr(name string, val Value, throw bool) {
+	if name == "caller" || name == "arguments" {
+		f.val.runtime.typeErrorResult(true, "'caller' and 'arguments' are restricted function properties and cannot be accessed in this context.")
+	}
+	f.nativeFuncObject.putStr(name, val, throw)
+}
+
+func (f *boundFuncObject) put(n Value, val Value, throw bool) {
+	f.putStr(n.String(), val, throw)
+}

+ 0 - 239
object.go

@@ -69,16 +69,6 @@ type baseObject struct {
 	propNames []string
 	propNames []string
 }
 }
 
 
-type funcObject struct {
-	baseObject
-
-	nameProp, lenProp valueProperty
-
-	stash *stash
-	prg   *Program
-	src   string
-}
-
 type primitiveValueObject struct {
 type primitiveValueObject struct {
 	baseObject
 	baseObject
 	pValue Value
 	pValue Value
@@ -104,25 +94,6 @@ func (f FunctionCall) Argument(idx int) Value {
 	return _undefined
 	return _undefined
 }
 }
 
 
-type nativeFuncObject struct {
-	baseObject
-	nameProp, lenProp valueProperty
-	f                 func(FunctionCall) Value
-	construct         func(args []Value) *Object
-}
-
-func (f *nativeFuncObject) export() interface{} {
-	return f.f
-}
-
-func (f *nativeFuncObject) exportType() reflect.Type {
-	return reflect.TypeOf(f.f)
-}
-
-type boundFuncObject struct {
-	nativeFuncObject
-}
-
 func (o *baseObject) init() {
 func (o *baseObject) init() {
 	o.values = make(map[string]Value)
 	o.values = make(map[string]Value)
 }
 }
@@ -657,217 +628,7 @@ func (o *baseObject) equal(other objectImpl) bool {
 	return false
 	return false
 }
 }
 
 
-func (f *funcObject) getPropStr(name string) Value {
-	switch name {
-	case "prototype":
-		if _, exists := f.values["prototype"]; !exists {
-			return f.addPrototype()
-		}
-	}
-
-	return f.baseObject.getPropStr(name)
-}
-
-func (f *funcObject) addPrototype() Value {
-	proto := f.val.runtime.NewObject()
-	proto.self._putProp("constructor", f.val, true, false, true)
-	return f._putProp("prototype", proto, true, false, false)
-}
-
-func (f *funcObject) getProp(n Value) Value {
-	return f.getPropStr(n.String())
-}
-
-func (f *funcObject) hasOwnProperty(n Value) bool {
-	if r := f.baseObject.hasOwnProperty(n); r {
-		return true
-	}
-
-	name := n.String()
-	if name == "prototype" {
-		return true
-	}
-	return false
-}
-
-func (f *funcObject) hasOwnPropertyStr(name string) bool {
-	if r := f.baseObject.hasOwnPropertyStr(name); r {
-		return true
-	}
-
-	if name == "prototype" {
-		return true
-	}
-	return false
-}
-
-func (f *funcObject) construct(args []Value) *Object {
-	proto := f.getStr("prototype")
-	var protoObj *Object
-	if p, ok := proto.(*Object); ok {
-		protoObj = p
-	} else {
-		protoObj = f.val.runtime.global.ObjectPrototype
-	}
-	obj := f.val.runtime.newBaseObject(protoObj, classObject).val
-	ret := f.Call(FunctionCall{
-		This:      obj,
-		Arguments: args,
-	})
-
-	if ret, ok := ret.(*Object); ok {
-		return ret
-	}
-	return obj
-}
-
-func (f *funcObject) Call(call FunctionCall) Value {
-	vm := f.val.runtime.vm
-	pc := vm.pc
-	vm.push(f.val)
-	vm.push(call.This)
-	for _, arg := range call.Arguments {
-		vm.push(arg)
-	}
-	vm.pc = -1
-	vm.pushCtx()
-	vm.args = len(call.Arguments)
-	vm.prg = f.prg
-	vm.stash = f.stash
-	vm.pc = 0
-	vm.run()
-	vm.pc = pc
-	vm.halt = false
-	return vm.pop()
-}
-
-func (f *funcObject) export() interface{} {
-	return f.Call
-}
-
-func (f *funcObject) exportType() reflect.Type {
-	return reflect.TypeOf(f.Call)
-}
-
-func (f *funcObject) assertCallable() (func(FunctionCall) Value, bool) {
-	return f.Call, true
-}
-
-func (f *funcObject) init(name string, length int) {
-	f.baseObject.init()
-
-	f.nameProp.configurable = true
-	f.nameProp.value = newStringValue(name)
-	f.values["name"] = &f.nameProp
-
-	f.lenProp.configurable = true
-	f.lenProp.value = valueInt(length)
-	f.values["length"] = &f.lenProp
-}
-
 func (o *baseObject) hasInstance(v Value) bool {
 func (o *baseObject) hasInstance(v Value) bool {
 	o.val.runtime.typeErrorResult(true, "Expecting a function in instanceof check, but got %s", o.val.ToString())
 	o.val.runtime.typeErrorResult(true, "Expecting a function in instanceof check, but got %s", o.val.ToString())
 	panic("Unreachable")
 	panic("Unreachable")
 }
 }
-
-func (f *funcObject) hasInstance(v Value) bool {
-	return f._hasInstance(v)
-}
-
-func (f *nativeFuncObject) hasInstance(v Value) bool {
-	return f._hasInstance(v)
-}
-
-func (f *baseObject) _hasInstance(v Value) bool {
-	if v, ok := v.(*Object); ok {
-		o := f.val.self.getStr("prototype")
-		if o1, ok := o.(*Object); ok {
-			for {
-				v = v.self.proto()
-				if v == nil {
-					return false
-				}
-				if o1 == v {
-					return true
-				}
-			}
-		} else {
-			f.val.runtime.typeErrorResult(true, "prototype is not an object")
-		}
-	}
-
-	return false
-}
-
-func (f *nativeFuncObject) defaultConstruct(args []Value) Value {
-	proto := f.getStr("prototype")
-	var protoObj *Object
-	if p, ok := proto.(*Object); ok {
-		protoObj = p
-	} else {
-		protoObj = f.val.runtime.global.ObjectPrototype
-	}
-	obj := f.val.runtime.newBaseObject(protoObj, classObject).val
-	ret := f.f(FunctionCall{
-		This:      obj,
-		Arguments: args,
-	})
-
-	if ret, ok := ret.(*Object); ok {
-		return ret
-	}
-	return obj
-}
-
-func (f *nativeFuncObject) assertCallable() (func(FunctionCall) Value, bool) {
-	if f.f != nil {
-		return f.f, true
-	}
-	return nil, false
-}
-
-func (f *nativeFuncObject) init(name string, length int) {
-	f.baseObject.init()
-
-	f.nameProp.configurable = true
-	f.nameProp.value = newStringValue(name)
-	f._put("name", &f.nameProp)
-
-	f.lenProp.configurable = true
-	f.lenProp.value = valueInt(length)
-	f._put("length", &f.lenProp)
-}
-
-func (f *boundFuncObject) getProp(n Value) Value {
-	return f.getPropStr(n.String())
-}
-
-func (f *boundFuncObject) getPropStr(name string) Value {
-	if name == "caller" || name == "arguments" {
-		//f.runtime.typeErrorResult(true, "'caller' and 'arguments' are restricted function properties and cannot be accessed in this context.")
-		return f.val.runtime.global.throwerProperty
-	}
-	return f.nativeFuncObject.getPropStr(name)
-}
-
-func (f *boundFuncObject) delete(n Value, throw bool) bool {
-	return f.deleteStr(n.String(), throw)
-}
-
-func (f *boundFuncObject) deleteStr(name string, throw bool) bool {
-	if name == "caller" || name == "arguments" {
-		return true
-	}
-	return f.nativeFuncObject.deleteStr(name, throw)
-}
-
-func (f *boundFuncObject) putStr(name string, val Value, throw bool) {
-	if name == "caller" || name == "arguments" {
-		f.val.runtime.typeErrorResult(true, "'caller' and 'arguments' are restricted function properties and cannot be accessed in this context.")
-	}
-	f.nativeFuncObject.putStr(name, val, throw)
-}
-
-func (f *boundFuncObject) put(n Value, val Value, throw bool) {
-	f.putStr(n.String(), val, throw)
-}

+ 22 - 16
runtime.go

@@ -315,11 +315,13 @@ func (r *Runtime) newFunc(name string, len int, strict bool) (f *funcObject) {
 
 
 func (r *Runtime) newNativeFuncObj(v *Object, call func(FunctionCall) Value, construct func(args []Value) *Object, name string, proto *Object, length int) *nativeFuncObject {
 func (r *Runtime) newNativeFuncObj(v *Object, call func(FunctionCall) Value, construct func(args []Value) *Object, name string, proto *Object, length int) *nativeFuncObject {
 	f := &nativeFuncObject{
 	f := &nativeFuncObject{
-		baseObject: baseObject{
-			class:      classFunction,
-			val:        v,
-			extensible: true,
-			prototype:  r.global.FunctionPrototype,
+		baseFuncObject: baseFuncObject{
+			baseObject: baseObject{
+				class:      classFunction,
+				val:        v,
+				extensible: true,
+				prototype:  r.global.FunctionPrototype,
+			},
 		},
 		},
 		f:         call,
 		f:         call,
 		construct: construct,
 		construct: construct,
@@ -336,11 +338,13 @@ func (r *Runtime) newNativeFunc(call func(FunctionCall) Value, construct func(ar
 	v := &Object{runtime: r}
 	v := &Object{runtime: r}
 
 
 	f := &nativeFuncObject{
 	f := &nativeFuncObject{
-		baseObject: baseObject{
-			class:      classFunction,
-			val:        v,
-			extensible: true,
-			prototype:  r.global.FunctionPrototype,
+		baseFuncObject: baseFuncObject{
+			baseObject: baseObject{
+				class:      classFunction,
+				val:        v,
+				extensible: true,
+				prototype:  r.global.FunctionPrototype,
+			},
 		},
 		},
 		f:         call,
 		f:         call,
 		construct: construct,
 		construct: construct,
@@ -354,13 +358,15 @@ func (r *Runtime) newNativeFunc(call func(FunctionCall) Value, construct func(ar
 	return v
 	return v
 }
 }
 
 
-func (r *Runtime) newNativeFuncConstructObj(v *Object, construct func(args []Value, proto *Object) *Object, name string, proto *Object, length int) objectImpl {
+func (r *Runtime) newNativeFuncConstructObj(v *Object, construct func(args []Value, proto *Object) *Object, name string, proto *Object, length int) *nativeFuncObject {
 	f := &nativeFuncObject{
 	f := &nativeFuncObject{
-		baseObject: baseObject{
-			class:      classFunction,
-			val:        v,
-			extensible: true,
-			prototype:  r.global.FunctionPrototype,
+		baseFuncObject: baseFuncObject{
+			baseObject: baseObject{
+				class:      classFunction,
+				val:        v,
+				extensible: true,
+				prototype:  r.global.FunctionPrototype,
+			},
 		},
 		},
 		f: r.constructWrap(construct, proto),
 		f: r.constructWrap(construct, proto),
 		construct: func(args []Value) *Object {
 		construct: func(args []Value) *Object {