builtin_function.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. package goja
  2. import (
  3. "math"
  4. "sync"
  5. )
  6. func (r *Runtime) functionCtor(args []Value, proto *Object, async, generator bool) *Object {
  7. var sb StringBuilder
  8. if async {
  9. if generator {
  10. sb.WriteString(asciiString("(async function* anonymous("))
  11. } else {
  12. sb.WriteString(asciiString("(async function anonymous("))
  13. }
  14. } else {
  15. if generator {
  16. sb.WriteString(asciiString("(function* anonymous("))
  17. } else {
  18. sb.WriteString(asciiString("(function anonymous("))
  19. }
  20. }
  21. if len(args) > 1 {
  22. ar := args[:len(args)-1]
  23. for i, arg := range ar {
  24. sb.WriteString(arg.toString())
  25. if i < len(ar)-1 {
  26. sb.WriteRune(',')
  27. }
  28. }
  29. }
  30. sb.WriteString(asciiString("\n) {\n"))
  31. if len(args) > 0 {
  32. sb.WriteString(args[len(args)-1].toString())
  33. }
  34. sb.WriteString(asciiString("\n})"))
  35. ret := r.toObject(r.eval(sb.String(), false, false))
  36. ret.self.setProto(proto, true)
  37. return ret
  38. }
  39. func (r *Runtime) builtin_Function(args []Value, proto *Object) *Object {
  40. return r.functionCtor(args, proto, false, false)
  41. }
  42. func (r *Runtime) builtin_asyncFunction(args []Value, proto *Object) *Object {
  43. return r.functionCtor(args, proto, true, false)
  44. }
  45. func (r *Runtime) builtin_generatorFunction(args []Value, proto *Object) *Object {
  46. return r.functionCtor(args, proto, false, true)
  47. }
  48. func (r *Runtime) functionproto_toString(call FunctionCall) Value {
  49. obj := r.toObject(call.This)
  50. switch f := obj.self.(type) {
  51. case funcObjectImpl:
  52. return f.source()
  53. case *proxyObject:
  54. if _, ok := f.target.self.(funcObjectImpl); ok {
  55. return asciiString("function () { [native code] }")
  56. }
  57. }
  58. panic(r.NewTypeError("Function.prototype.toString requires that 'this' be a Function"))
  59. }
  60. func (r *Runtime) functionproto_hasInstance(call FunctionCall) Value {
  61. if o, ok := call.This.(*Object); ok {
  62. if _, ok = o.self.assertCallable(); ok {
  63. return r.toBoolean(o.self.hasInstance(call.Argument(0)))
  64. }
  65. }
  66. return valueFalse
  67. }
  68. func (r *Runtime) createListFromArrayLike(a Value) []Value {
  69. o := r.toObject(a)
  70. if arr := r.checkStdArrayObj(o); arr != nil {
  71. return arr.values
  72. }
  73. l := toLength(o.self.getStr("length", nil))
  74. res := make([]Value, 0, l)
  75. for k := int64(0); k < l; k++ {
  76. res = append(res, nilSafe(o.self.getIdx(valueInt(k), nil)))
  77. }
  78. return res
  79. }
  80. func (r *Runtime) functionproto_apply(call FunctionCall) Value {
  81. var args []Value
  82. if len(call.Arguments) >= 2 {
  83. args = r.createListFromArrayLike(call.Arguments[1])
  84. }
  85. f := r.toCallable(call.This)
  86. return f(FunctionCall{
  87. This: call.Argument(0),
  88. Arguments: args,
  89. })
  90. }
  91. func (r *Runtime) functionproto_call(call FunctionCall) Value {
  92. var args []Value
  93. if len(call.Arguments) > 0 {
  94. args = call.Arguments[1:]
  95. }
  96. f := r.toCallable(call.This)
  97. return f(FunctionCall{
  98. This: call.Argument(0),
  99. Arguments: args,
  100. })
  101. }
  102. func (r *Runtime) boundCallable(target func(FunctionCall) Value, boundArgs []Value) func(FunctionCall) Value {
  103. var this Value
  104. var args []Value
  105. if len(boundArgs) > 0 {
  106. this = boundArgs[0]
  107. args = make([]Value, len(boundArgs)-1)
  108. copy(args, boundArgs[1:])
  109. } else {
  110. this = _undefined
  111. }
  112. return func(call FunctionCall) Value {
  113. a := append(args, call.Arguments...)
  114. return target(FunctionCall{
  115. This: this,
  116. Arguments: a,
  117. })
  118. }
  119. }
  120. func (r *Runtime) boundConstruct(f *Object, target func([]Value, *Object) *Object, boundArgs []Value) func([]Value, *Object) *Object {
  121. if target == nil {
  122. return nil
  123. }
  124. var args []Value
  125. if len(boundArgs) > 1 {
  126. args = make([]Value, len(boundArgs)-1)
  127. copy(args, boundArgs[1:])
  128. }
  129. return func(fargs []Value, newTarget *Object) *Object {
  130. a := append(args, fargs...)
  131. if newTarget == f {
  132. newTarget = nil
  133. }
  134. return target(a, newTarget)
  135. }
  136. }
  137. func (r *Runtime) functionproto_bind(call FunctionCall) Value {
  138. obj := r.toObject(call.This)
  139. fcall := r.toCallable(call.This)
  140. construct := obj.self.assertConstructor()
  141. var l = _positiveZero
  142. if obj.self.hasOwnPropertyStr("length") {
  143. var li int64
  144. switch lenProp := nilSafe(obj.self.getStr("length", nil)).(type) {
  145. case valueInt:
  146. li = lenProp.ToInteger()
  147. case valueFloat:
  148. switch lenProp {
  149. case _positiveInf:
  150. l = lenProp
  151. goto lenNotInt
  152. case _negativeInf:
  153. goto lenNotInt
  154. case _negativeZero:
  155. // no-op, li == 0
  156. default:
  157. if !math.IsNaN(float64(lenProp)) {
  158. li = int64(math.Abs(float64(lenProp)))
  159. } // else li = 0
  160. }
  161. }
  162. if len(call.Arguments) > 1 {
  163. li -= int64(len(call.Arguments)) - 1
  164. }
  165. if li < 0 {
  166. li = 0
  167. }
  168. l = intToValue(li)
  169. }
  170. lenNotInt:
  171. name := obj.self.getStr("name", nil)
  172. nameStr := stringBound_
  173. if s, ok := name.(String); ok {
  174. nameStr = nameStr.Concat(s)
  175. }
  176. v := &Object{runtime: r}
  177. ff := r.newNativeFuncAndConstruct(v, r.boundCallable(fcall, call.Arguments), r.boundConstruct(v, construct, call.Arguments), nil, nameStr.string(), l)
  178. bf := &boundFuncObject{
  179. nativeFuncObject: *ff,
  180. wrapped: obj,
  181. }
  182. bf.prototype = obj.self.proto()
  183. v.self = bf
  184. return v
  185. }
  186. func (r *Runtime) getThrower() *Object {
  187. ret := r.global.thrower
  188. if ret == nil {
  189. ret = r.newNativeFunc(r.builtin_thrower, "", 0)
  190. r.global.thrower = ret
  191. r.object_freeze(FunctionCall{Arguments: []Value{ret}})
  192. }
  193. return ret
  194. }
  195. func (r *Runtime) newThrowerProperty(configurable bool) Value {
  196. thrower := r.getThrower()
  197. return &valueProperty{
  198. getterFunc: thrower,
  199. setterFunc: thrower,
  200. accessor: true,
  201. configurable: configurable,
  202. }
  203. }
  204. func createFunctionProtoTemplate() *objectTemplate {
  205. t := newObjectTemplate()
  206. t.protoFactory = func(r *Runtime) *Object {
  207. return r.global.ObjectPrototype
  208. }
  209. t.putStr("constructor", func(r *Runtime) Value { return valueProp(r.getFunction(), true, false, true) })
  210. t.putStr("length", func(r *Runtime) Value { return valueProp(_positiveZero, false, false, true) })
  211. t.putStr("name", func(r *Runtime) Value { return valueProp(stringEmpty, false, false, true) })
  212. t.putStr("apply", func(r *Runtime) Value { return r.methodProp(r.functionproto_apply, "apply", 2) })
  213. t.putStr("bind", func(r *Runtime) Value { return r.methodProp(r.functionproto_bind, "bind", 1) })
  214. t.putStr("call", func(r *Runtime) Value { return r.methodProp(r.functionproto_call, "call", 1) })
  215. t.putStr("toString", func(r *Runtime) Value { return r.methodProp(r.functionproto_toString, "toString", 0) })
  216. t.putStr("caller", func(r *Runtime) Value { return r.newThrowerProperty(true) })
  217. t.putStr("arguments", func(r *Runtime) Value { return r.newThrowerProperty(true) })
  218. t.putSym(SymHasInstance, func(r *Runtime) Value {
  219. return valueProp(r.newNativeFunc(r.functionproto_hasInstance, "[Symbol.hasInstance]", 1), false, false, false)
  220. })
  221. return t
  222. }
  223. var functionProtoTemplate *objectTemplate
  224. var functionProtoTemplateOnce sync.Once
  225. func getFunctionProtoTemplate() *objectTemplate {
  226. functionProtoTemplateOnce.Do(func() {
  227. functionProtoTemplate = createFunctionProtoTemplate()
  228. })
  229. return functionProtoTemplate
  230. }
  231. func (r *Runtime) getFunctionPrototype() *Object {
  232. ret := r.global.FunctionPrototype
  233. if ret == nil {
  234. ret = &Object{runtime: r}
  235. r.global.FunctionPrototype = ret
  236. r.newTemplatedFuncObject(getFunctionProtoTemplate(), ret, func(FunctionCall) Value {
  237. return _undefined
  238. }, nil)
  239. }
  240. return ret
  241. }
  242. func (r *Runtime) createFunction(v *Object) objectImpl {
  243. return r.newNativeFuncConstructObj(v, r.builtin_Function, "Function", r.getFunctionPrototype(), 1)
  244. }
  245. func (r *Runtime) createAsyncFunctionProto(val *Object) objectImpl {
  246. o := &baseObject{
  247. class: classObject,
  248. val: val,
  249. extensible: true,
  250. prototype: r.getFunctionPrototype(),
  251. }
  252. o.init()
  253. o._putProp("constructor", r.getAsyncFunction(), true, false, true)
  254. o._putSym(SymToStringTag, valueProp(asciiString(classAsyncFunction), false, false, true))
  255. return o
  256. }
  257. func (r *Runtime) getAsyncFunctionPrototype() *Object {
  258. var o *Object
  259. if o = r.global.AsyncFunctionPrototype; o == nil {
  260. o = &Object{runtime: r}
  261. r.global.AsyncFunctionPrototype = o
  262. o.self = r.createAsyncFunctionProto(o)
  263. }
  264. return o
  265. }
  266. func (r *Runtime) createAsyncFunction(val *Object) objectImpl {
  267. o := r.newNativeFuncConstructObj(val, r.builtin_asyncFunction, "AsyncFunction", r.getAsyncFunctionPrototype(), 1)
  268. return o
  269. }
  270. func (r *Runtime) getAsyncFunction() *Object {
  271. var o *Object
  272. if o = r.global.AsyncFunction; o == nil {
  273. o = &Object{runtime: r}
  274. r.global.AsyncFunction = o
  275. o.self = r.createAsyncFunction(o)
  276. }
  277. return o
  278. }
  279. func (r *Runtime) builtin_genproto_next(call FunctionCall) Value {
  280. if o, ok := call.This.(*Object); ok {
  281. if gen, ok := o.self.(*generatorObject); ok {
  282. return gen.next(call.Argument(0))
  283. }
  284. }
  285. panic(r.NewTypeError("Method [Generator].prototype.next called on incompatible receiver"))
  286. }
  287. func (r *Runtime) builtin_genproto_return(call FunctionCall) Value {
  288. if o, ok := call.This.(*Object); ok {
  289. if gen, ok := o.self.(*generatorObject); ok {
  290. return gen._return(call.Argument(0))
  291. }
  292. }
  293. panic(r.NewTypeError("Method [Generator].prototype.return called on incompatible receiver"))
  294. }
  295. func (r *Runtime) builtin_genproto_throw(call FunctionCall) Value {
  296. if o, ok := call.This.(*Object); ok {
  297. if gen, ok := o.self.(*generatorObject); ok {
  298. return gen.throw(call.Argument(0))
  299. }
  300. }
  301. panic(r.NewTypeError("Method [Generator].prototype.throw called on incompatible receiver"))
  302. }
  303. func (r *Runtime) createGeneratorFunctionProto(val *Object) objectImpl {
  304. o := newBaseObjectObj(val, r.getFunctionPrototype(), classObject)
  305. o._putProp("constructor", r.getGeneratorFunction(), false, false, true)
  306. o._putProp("prototype", r.getGeneratorPrototype(), false, false, true)
  307. o._putSym(SymToStringTag, valueProp(asciiString(classGeneratorFunction), false, false, true))
  308. return o
  309. }
  310. func (r *Runtime) getGeneratorFunctionPrototype() *Object {
  311. var o *Object
  312. if o = r.global.GeneratorFunctionPrototype; o == nil {
  313. o = &Object{runtime: r}
  314. r.global.GeneratorFunctionPrototype = o
  315. o.self = r.createGeneratorFunctionProto(o)
  316. }
  317. return o
  318. }
  319. func (r *Runtime) createGeneratorFunction(val *Object) objectImpl {
  320. o := r.newNativeFuncConstructObj(val, r.builtin_generatorFunction, "GeneratorFunction", r.getGeneratorFunctionPrototype(), 1)
  321. return o
  322. }
  323. func (r *Runtime) getGeneratorFunction() *Object {
  324. var o *Object
  325. if o = r.global.GeneratorFunction; o == nil {
  326. o = &Object{runtime: r}
  327. r.global.GeneratorFunction = o
  328. o.self = r.createGeneratorFunction(o)
  329. }
  330. return o
  331. }
  332. func (r *Runtime) createGeneratorProto(val *Object) objectImpl {
  333. o := newBaseObjectObj(val, r.getIteratorPrototype(), classObject)
  334. o._putProp("constructor", r.getGeneratorFunctionPrototype(), false, false, true)
  335. o._putProp("next", r.newNativeFunc(r.builtin_genproto_next, "next", 1), true, false, true)
  336. o._putProp("return", r.newNativeFunc(r.builtin_genproto_return, "return", 1), true, false, true)
  337. o._putProp("throw", r.newNativeFunc(r.builtin_genproto_throw, "throw", 1), true, false, true)
  338. o._putSym(SymToStringTag, valueProp(asciiString(classGenerator), false, false, true))
  339. return o
  340. }
  341. func (r *Runtime) getGeneratorPrototype() *Object {
  342. var o *Object
  343. if o = r.global.GeneratorPrototype; o == nil {
  344. o = &Object{runtime: r}
  345. r.global.GeneratorPrototype = o
  346. o.self = r.createGeneratorProto(o)
  347. }
  348. return o
  349. }
  350. func (r *Runtime) getFunction() *Object {
  351. ret := r.global.Function
  352. if ret == nil {
  353. ret = &Object{runtime: r}
  354. r.global.Function = ret
  355. ret.self = r.createFunction(ret)
  356. }
  357. return ret
  358. }