func.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. package goja
  2. import (
  3. "reflect"
  4. "github.com/dop251/goja/unistring"
  5. )
  6. type baseFuncObject struct {
  7. baseObject
  8. lenProp valueProperty
  9. }
  10. type baseJsFuncObject struct {
  11. baseFuncObject
  12. stash *stash
  13. prg *Program
  14. src string
  15. strict bool
  16. }
  17. type funcObject struct {
  18. baseJsFuncObject
  19. }
  20. type methodFuncObject struct {
  21. baseJsFuncObject
  22. }
  23. type arrowFuncObject struct {
  24. baseJsFuncObject
  25. this Value
  26. newTarget Value
  27. }
  28. type nativeFuncObject struct {
  29. baseFuncObject
  30. f func(FunctionCall) Value
  31. construct func(args []Value, newTarget *Object) *Object
  32. }
  33. type boundFuncObject struct {
  34. nativeFuncObject
  35. wrapped *Object
  36. }
  37. func (f *nativeFuncObject) export(*objectExportCtx) interface{} {
  38. return f.f
  39. }
  40. func (f *nativeFuncObject) exportType() reflect.Type {
  41. return reflect.TypeOf(f.f)
  42. }
  43. func (f *funcObject) _addProto(n unistring.String) Value {
  44. if n == "prototype" {
  45. if _, exists := f.values[n]; !exists {
  46. return f.addPrototype()
  47. }
  48. }
  49. return nil
  50. }
  51. func (f *funcObject) getStr(p unistring.String, receiver Value) Value {
  52. return f.getStrWithOwnProp(f.getOwnPropStr(p), p, receiver)
  53. }
  54. func (f *funcObject) getOwnPropStr(name unistring.String) Value {
  55. if v := f._addProto(name); v != nil {
  56. return v
  57. }
  58. return f.baseObject.getOwnPropStr(name)
  59. }
  60. func (f *funcObject) setOwnStr(name unistring.String, val Value, throw bool) bool {
  61. f._addProto(name)
  62. return f.baseObject.setOwnStr(name, val, throw)
  63. }
  64. func (f *funcObject) setForeignStr(name unistring.String, val, receiver Value, throw bool) (bool, bool) {
  65. return f._setForeignStr(name, f.getOwnPropStr(name), val, receiver, throw)
  66. }
  67. func (f *funcObject) defineOwnPropertyStr(name unistring.String, descr PropertyDescriptor, throw bool) bool {
  68. f._addProto(name)
  69. return f.baseObject.defineOwnPropertyStr(name, descr, throw)
  70. }
  71. func (f *funcObject) deleteStr(name unistring.String, throw bool) bool {
  72. f._addProto(name)
  73. return f.baseObject.deleteStr(name, throw)
  74. }
  75. func (f *funcObject) addPrototype() Value {
  76. proto := f.val.runtime.NewObject()
  77. proto.self._putProp("constructor", f.val, true, false, true)
  78. return f._putProp("prototype", proto, true, false, false)
  79. }
  80. func (f *funcObject) hasOwnPropertyStr(name unistring.String) bool {
  81. if r := f.baseObject.hasOwnPropertyStr(name); r {
  82. return true
  83. }
  84. if name == "prototype" {
  85. return true
  86. }
  87. return false
  88. }
  89. func (f *funcObject) stringKeys(all bool, accum []Value) []Value {
  90. if all {
  91. if _, exists := f.values["prototype"]; !exists {
  92. accum = append(accum, asciiString("prototype"))
  93. }
  94. }
  95. return f.baseFuncObject.stringKeys(all, accum)
  96. }
  97. func (f *funcObject) iterateStringKeys() iterNextFunc {
  98. if _, exists := f.values["prototype"]; !exists {
  99. f.addPrototype()
  100. }
  101. return f.baseFuncObject.iterateStringKeys()
  102. }
  103. func (f *funcObject) construct(args []Value, newTarget *Object) *Object {
  104. if newTarget == nil {
  105. newTarget = f.val
  106. }
  107. proto := newTarget.self.getStr("prototype", nil)
  108. var protoObj *Object
  109. if p, ok := proto.(*Object); ok {
  110. protoObj = p
  111. } else {
  112. protoObj = f.val.runtime.global.ObjectPrototype
  113. }
  114. obj := f.val.runtime.newBaseObject(protoObj, classObject).val
  115. ret := f.call(FunctionCall{
  116. This: obj,
  117. Arguments: args,
  118. }, newTarget)
  119. if ret, ok := ret.(*Object); ok {
  120. return ret
  121. }
  122. return obj
  123. }
  124. func (f *baseJsFuncObject) Call(call FunctionCall) Value {
  125. return f.call(call, nil)
  126. }
  127. func (f *arrowFuncObject) Call(call FunctionCall) Value {
  128. return f._call(call, f.newTarget, f.this)
  129. }
  130. func (f *baseJsFuncObject) _call(call FunctionCall, newTarget, this Value) Value {
  131. vm := f.val.runtime.vm
  132. pc := vm.pc
  133. vm.stack.expand(vm.sp + len(call.Arguments) + 1)
  134. vm.stack[vm.sp] = f.val
  135. vm.sp++
  136. vm.stack[vm.sp] = this
  137. vm.sp++
  138. for _, arg := range call.Arguments {
  139. if arg != nil {
  140. vm.stack[vm.sp] = arg
  141. } else {
  142. vm.stack[vm.sp] = _undefined
  143. }
  144. vm.sp++
  145. }
  146. vm.pc = -1
  147. vm.pushCtx()
  148. vm.args = len(call.Arguments)
  149. vm.prg = f.prg
  150. vm.stash = f.stash
  151. vm.newTarget = newTarget
  152. vm.pc = 0
  153. vm.run()
  154. vm.pc = pc
  155. vm.halt = false
  156. return vm.pop()
  157. }
  158. func (f *baseJsFuncObject) call(call FunctionCall, newTarget Value) Value {
  159. return f._call(call, newTarget, nilSafe(call.This))
  160. }
  161. func (f *funcObject) export(*objectExportCtx) interface{} {
  162. return f.Call
  163. }
  164. func (f *funcObject) exportType() reflect.Type {
  165. return reflect.TypeOf(f.Call)
  166. }
  167. func (f *baseJsFuncObject) assertCallable() (func(FunctionCall) Value, bool) {
  168. return f.Call, true
  169. }
  170. func (f *funcObject) assertConstructor() func(args []Value, newTarget *Object) *Object {
  171. return f.construct
  172. }
  173. func (f *arrowFuncObject) exportType() reflect.Type {
  174. return reflect.TypeOf(f.Call)
  175. }
  176. func (f *arrowFuncObject) assertCallable() (func(FunctionCall) Value, bool) {
  177. return f.Call, true
  178. }
  179. func (f *baseFuncObject) init(name unistring.String, length Value) {
  180. f.baseObject.init()
  181. f.lenProp.configurable = true
  182. f.lenProp.value = length
  183. f._put("length", &f.lenProp)
  184. f._putProp("name", stringValueFromRaw(name), false, false, true)
  185. }
  186. func (f *baseFuncObject) hasInstance(v Value) bool {
  187. if v, ok := v.(*Object); ok {
  188. o := f.val.self.getStr("prototype", nil)
  189. if o1, ok := o.(*Object); ok {
  190. for {
  191. v = v.self.proto()
  192. if v == nil {
  193. return false
  194. }
  195. if o1 == v {
  196. return true
  197. }
  198. }
  199. } else {
  200. f.val.runtime.typeErrorResult(true, "prototype is not an object")
  201. }
  202. }
  203. return false
  204. }
  205. func (f *nativeFuncObject) defaultConstruct(ccall func(ConstructorCall) *Object, args []Value, newTarget *Object) *Object {
  206. proto := f.getStr("prototype", nil)
  207. var protoObj *Object
  208. if p, ok := proto.(*Object); ok {
  209. protoObj = p
  210. } else {
  211. protoObj = f.val.runtime.global.ObjectPrototype
  212. }
  213. obj := f.val.runtime.newBaseObject(protoObj, classObject).val
  214. ret := ccall(ConstructorCall{
  215. This: obj,
  216. Arguments: args,
  217. NewTarget: newTarget,
  218. })
  219. if ret != nil {
  220. return ret
  221. }
  222. return obj
  223. }
  224. func (f *nativeFuncObject) assertCallable() (func(FunctionCall) Value, bool) {
  225. if f.f != nil {
  226. return f.f, true
  227. }
  228. return nil, false
  229. }
  230. func (f *nativeFuncObject) assertConstructor() func(args []Value, newTarget *Object) *Object {
  231. return f.construct
  232. }
  233. /*func (f *boundFuncObject) getStr(p unistring.String, receiver Value) Value {
  234. return f.getStrWithOwnProp(f.getOwnPropStr(p), p, receiver)
  235. }
  236. func (f *boundFuncObject) getOwnPropStr(name unistring.String) Value {
  237. if name == "caller" || name == "arguments" {
  238. return f.val.runtime.global.throwerProperty
  239. }
  240. return f.nativeFuncObject.getOwnPropStr(name)
  241. }
  242. func (f *boundFuncObject) deleteStr(name unistring.String, throw bool) bool {
  243. if name == "caller" || name == "arguments" {
  244. return true
  245. }
  246. return f.nativeFuncObject.deleteStr(name, throw)
  247. }
  248. func (f *boundFuncObject) setOwnStr(name unistring.String, val Value, throw bool) bool {
  249. if name == "caller" || name == "arguments" {
  250. panic(f.val.runtime.NewTypeError("'caller' and 'arguments' are restricted function properties and cannot be accessed in this context."))
  251. }
  252. return f.nativeFuncObject.setOwnStr(name, val, throw)
  253. }
  254. func (f *boundFuncObject) setForeignStr(name unistring.String, val, receiver Value, throw bool) (bool, bool) {
  255. return f._setForeignStr(name, f.getOwnPropStr(name), val, receiver, throw)
  256. }
  257. */
  258. func (f *boundFuncObject) hasInstance(v Value) bool {
  259. return instanceOfOperator(v, f.wrapped)
  260. }