runtime.go 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223
  1. package goja
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "github.com/dop251/goja/parser"
  7. "go/ast"
  8. "math"
  9. "math/rand"
  10. "reflect"
  11. "strconv"
  12. )
  13. const (
  14. sqrt1_2 float64 = math.Sqrt2 / 2
  15. )
  16. type global struct {
  17. Object *Object
  18. Array *Object
  19. Function *Object
  20. String *Object
  21. Number *Object
  22. Boolean *Object
  23. RegExp *Object
  24. Date *Object
  25. ArrayBuffer *Object
  26. Error *Object
  27. TypeError *Object
  28. ReferenceError *Object
  29. SyntaxError *Object
  30. RangeError *Object
  31. EvalError *Object
  32. URIError *Object
  33. GoError *Object
  34. ObjectPrototype *Object
  35. ArrayPrototype *Object
  36. NumberPrototype *Object
  37. StringPrototype *Object
  38. BooleanPrototype *Object
  39. FunctionPrototype *Object
  40. RegExpPrototype *Object
  41. DatePrototype *Object
  42. ArrayBufferPrototype *Object
  43. ErrorPrototype *Object
  44. TypeErrorPrototype *Object
  45. SyntaxErrorPrototype *Object
  46. RangeErrorPrototype *Object
  47. ReferenceErrorPrototype *Object
  48. EvalErrorPrototype *Object
  49. URIErrorPrototype *Object
  50. GoErrorPrototype *Object
  51. Eval *Object
  52. thrower *Object
  53. throwerProperty Value
  54. }
  55. type RandSource func() float64
  56. type Runtime struct {
  57. global global
  58. globalObject *Object
  59. stringSingleton *stringObject
  60. rand RandSource
  61. vm *vm
  62. }
  63. type stackFrame struct {
  64. prg *Program
  65. funcName string
  66. pc int
  67. }
  68. func (f stackFrame) position() Position {
  69. return f.prg.src.Position(f.prg.sourceOffset(f.pc))
  70. }
  71. type Exception struct {
  72. val Value
  73. stack []stackFrame
  74. }
  75. type InterruptedError struct {
  76. Exception
  77. iface interface{}
  78. }
  79. func (e *InterruptedError) Value() interface{} {
  80. return e.iface
  81. }
  82. func (e *Exception) String() string {
  83. if e == nil {
  84. return "<nil>"
  85. }
  86. var b bytes.Buffer
  87. if e.val != nil {
  88. b.WriteString(e.val.String())
  89. }
  90. b.WriteByte('\n')
  91. for _, frame := range e.stack {
  92. b.WriteString("\tat ")
  93. if frame.prg != nil {
  94. if n := frame.prg.funcName; n != "" {
  95. b.WriteString(n)
  96. b.WriteString(" (")
  97. }
  98. if n := frame.prg.src.name; n != "" {
  99. b.WriteString(n)
  100. } else {
  101. b.WriteString("<eval>")
  102. }
  103. b.WriteByte(':')
  104. b.WriteString(frame.position().String())
  105. b.WriteByte('(')
  106. b.WriteString(strconv.Itoa(frame.pc))
  107. b.WriteByte(')')
  108. if frame.prg.funcName != "" {
  109. b.WriteByte(')')
  110. }
  111. } else {
  112. if frame.funcName != "" {
  113. b.WriteString(frame.funcName)
  114. b.WriteString(" (")
  115. }
  116. b.WriteString("native")
  117. if frame.funcName != "" {
  118. b.WriteByte(')')
  119. }
  120. }
  121. b.WriteByte('\n')
  122. }
  123. return b.String()
  124. }
  125. func (e *Exception) Error() string {
  126. if e == nil || e.val == nil {
  127. return "<nil>"
  128. }
  129. return e.val.String()
  130. }
  131. func (e *Exception) Value() Value {
  132. return e.val
  133. }
  134. func (r *Runtime) addToGlobal(name string, value Value) {
  135. r.globalObject.self._putProp(name, value, true, false, true)
  136. }
  137. func (r *Runtime) init() {
  138. r.rand = rand.Float64
  139. r.global.ObjectPrototype = r.newBaseObject(nil, classObject).val
  140. r.globalObject = r.NewObject()
  141. r.vm = &vm{
  142. r: r,
  143. }
  144. r.vm.init()
  145. r.global.FunctionPrototype = r.newNativeFunc(nil, nil, "Empty", nil, 0)
  146. r.initObject()
  147. r.initFunction()
  148. r.initArray()
  149. r.initString()
  150. r.initNumber()
  151. r.initRegExp()
  152. r.initDate()
  153. r.initBoolean()
  154. r.initErrors()
  155. r.global.Eval = r.newNativeFunc(r.builtin_eval, nil, "eval", nil, 1)
  156. r.addToGlobal("eval", r.global.Eval)
  157. r.initGlobalObject()
  158. r.initMath()
  159. r.initJSON()
  160. //r.initTypedArrays()
  161. r.global.thrower = r.newNativeFunc(r.builtin_thrower, nil, "thrower", nil, 0)
  162. r.global.throwerProperty = &valueProperty{
  163. getterFunc: r.global.thrower,
  164. setterFunc: r.global.thrower,
  165. accessor: true,
  166. }
  167. }
  168. func (r *Runtime) typeErrorResult(throw bool, args ...interface{}) {
  169. if throw {
  170. panic(r.NewTypeError(args...))
  171. }
  172. }
  173. func (r *Runtime) newError(typ *Object, format string, args ...interface{}) Value {
  174. msg := fmt.Sprintf(format, args...)
  175. return r.builtin_new(typ, []Value{newStringValue(msg)})
  176. }
  177. func (r *Runtime) throwReferenceError(name string) {
  178. panic(r.newError(r.global.ReferenceError, "%s is not defined", name))
  179. }
  180. func (r *Runtime) newSyntaxError(msg string, offset int) Value {
  181. return r.builtin_new((r.global.SyntaxError), []Value{newStringValue(msg)})
  182. }
  183. func (r *Runtime) newArray(prototype *Object) (a *arrayObject) {
  184. v := &Object{runtime: r}
  185. a = &arrayObject{}
  186. a.class = classArray
  187. a.val = v
  188. a.extensible = true
  189. v.self = a
  190. a.prototype = prototype
  191. a.init()
  192. return
  193. }
  194. func (r *Runtime) newArrayObject() *arrayObject {
  195. return r.newArray(r.global.ArrayPrototype)
  196. }
  197. func (r *Runtime) newArrayValues(values []Value) *Object {
  198. v := &Object{runtime: r}
  199. a := &arrayObject{}
  200. a.class = classArray
  201. a.val = v
  202. a.extensible = true
  203. v.self = a
  204. a.prototype = r.global.ArrayPrototype
  205. a.init()
  206. a.values = values
  207. a.length = int64(len(values))
  208. a.objCount = a.length
  209. return v
  210. }
  211. func (r *Runtime) newArrayLength(l int64) *Object {
  212. a := r.newArrayValues(nil)
  213. a.self.putStr("length", intToValue(l), true)
  214. return a
  215. }
  216. func (r *Runtime) newBaseObject(proto *Object, class string) (o *baseObject) {
  217. v := &Object{runtime: r}
  218. o = &baseObject{}
  219. o.class = class
  220. o.val = v
  221. o.extensible = true
  222. v.self = o
  223. o.prototype = proto
  224. o.init()
  225. return
  226. }
  227. func (r *Runtime) NewObject() (v *Object) {
  228. return r.newBaseObject(r.global.ObjectPrototype, classObject).val
  229. }
  230. func (r *Runtime) NewTypeError(args ...interface{}) *Object {
  231. msg := ""
  232. if len(args) > 0 {
  233. f, _ := args[0].(string)
  234. msg = fmt.Sprintf(f, args[1:]...)
  235. }
  236. return r.builtin_new(r.global.TypeError, []Value{newStringValue(msg)})
  237. }
  238. func (r *Runtime) NewGoError(err error) *Object {
  239. e := r.newError(r.global.GoError, err.Error()).(*Object)
  240. e.Set("value", err)
  241. return e
  242. }
  243. func (r *Runtime) newFunc(name string, len int, strict bool) (f *funcObject) {
  244. v := &Object{runtime: r}
  245. f = &funcObject{}
  246. f.class = classFunction
  247. f.val = v
  248. f.extensible = true
  249. v.self = f
  250. f.prototype = r.global.FunctionPrototype
  251. f.init(name, len)
  252. if strict {
  253. f._put("caller", r.global.throwerProperty)
  254. f._put("arguments", r.global.throwerProperty)
  255. }
  256. return
  257. }
  258. func (r *Runtime) newNativeFuncObj(v *Object, call func(FunctionCall) Value, construct func(args []Value) *Object, name string, proto *Object, length int) *nativeFuncObject {
  259. f := &nativeFuncObject{
  260. baseObject: baseObject{
  261. class: classFunction,
  262. val: v,
  263. extensible: true,
  264. prototype: r.global.FunctionPrototype,
  265. },
  266. f: call,
  267. construct: construct,
  268. }
  269. v.self = f
  270. f.init(name, length)
  271. if proto != nil {
  272. f._putProp("prototype", proto, false, false, false)
  273. }
  274. return f
  275. }
  276. func (r *Runtime) newNativeFunc(call func(FunctionCall) Value, construct func(args []Value) *Object, name string, proto *Object, length int) *Object {
  277. v := &Object{runtime: r}
  278. f := &nativeFuncObject{
  279. baseObject: baseObject{
  280. class: classFunction,
  281. val: v,
  282. extensible: true,
  283. prototype: r.global.FunctionPrototype,
  284. },
  285. f: call,
  286. construct: construct,
  287. }
  288. v.self = f
  289. f.init(name, length)
  290. if proto != nil {
  291. f._putProp("prototype", proto, false, false, false)
  292. proto.self._putProp("constructor", v, true, false, true)
  293. }
  294. return v
  295. }
  296. func (r *Runtime) newNativeFuncConstructObj(v *Object, construct func(args []Value, proto *Object) *Object, name string, proto *Object, length int) objectImpl {
  297. f := &nativeFuncObject{
  298. baseObject: baseObject{
  299. class: classFunction,
  300. val: v,
  301. extensible: true,
  302. prototype: r.global.FunctionPrototype,
  303. },
  304. f: r.constructWrap(construct, proto),
  305. construct: func(args []Value) *Object {
  306. return construct(args, proto)
  307. },
  308. }
  309. f.init(name, length)
  310. if proto != nil {
  311. f._putProp("prototype", proto, false, false, false)
  312. }
  313. return f
  314. }
  315. func (r *Runtime) newNativeFuncConstruct(construct func(args []Value, proto *Object) *Object, name string, prototype *Object, length int) *Object {
  316. return r.newNativeFuncConstructProto(construct, name, prototype, r.global.FunctionPrototype, length)
  317. }
  318. func (r *Runtime) newNativeFuncConstructProto(construct func(args []Value, proto *Object) *Object, name string, prototype, proto *Object, length int) *Object {
  319. v := &Object{runtime: r}
  320. f := &nativeFuncObject{}
  321. f.class = classFunction
  322. f.val = v
  323. f.extensible = true
  324. v.self = f
  325. f.prototype = proto
  326. f.f = r.constructWrap(construct, prototype)
  327. f.construct = func(args []Value) *Object {
  328. return construct(args, prototype)
  329. }
  330. f.init(name, length)
  331. if prototype != nil {
  332. f._putProp("prototype", prototype, false, false, false)
  333. prototype.self._putProp("constructor", v, true, false, true)
  334. }
  335. return v
  336. }
  337. func (r *Runtime) newPrimitiveObject(value Value, proto *Object, class string) *Object {
  338. v := &Object{runtime: r}
  339. o := &primitiveValueObject{}
  340. o.class = class
  341. o.val = v
  342. o.extensible = true
  343. v.self = o
  344. o.prototype = proto
  345. o.pValue = value
  346. o.init()
  347. return v
  348. }
  349. func (r *Runtime) builtin_Number(call FunctionCall) Value {
  350. if len(call.Arguments) > 0 {
  351. return call.Arguments[0].ToNumber()
  352. } else {
  353. return intToValue(0)
  354. }
  355. }
  356. func (r *Runtime) builtin_newNumber(args []Value) *Object {
  357. var v Value
  358. if len(args) > 0 {
  359. v = args[0].ToNumber()
  360. } else {
  361. v = intToValue(0)
  362. }
  363. return r.newPrimitiveObject(v, r.global.NumberPrototype, classNumber)
  364. }
  365. func (r *Runtime) builtin_Boolean(call FunctionCall) Value {
  366. if len(call.Arguments) > 0 {
  367. if call.Arguments[0].ToBoolean() {
  368. return valueTrue
  369. } else {
  370. return valueFalse
  371. }
  372. } else {
  373. return valueFalse
  374. }
  375. }
  376. func (r *Runtime) builtin_newBoolean(args []Value) *Object {
  377. var v Value
  378. if len(args) > 0 {
  379. if args[0].ToBoolean() {
  380. v = valueTrue
  381. } else {
  382. v = valueFalse
  383. }
  384. } else {
  385. v = valueFalse
  386. }
  387. return r.newPrimitiveObject(v, r.global.BooleanPrototype, classBoolean)
  388. }
  389. func (r *Runtime) error_toString(call FunctionCall) Value {
  390. obj := call.This.ToObject(r).self
  391. msg := obj.getStr("message")
  392. name := obj.getStr("name")
  393. var nameStr, msgStr string
  394. if name != nil && name != _undefined {
  395. nameStr = name.String()
  396. }
  397. if msg != nil && msg != _undefined {
  398. msgStr = msg.String()
  399. }
  400. if nameStr != "" && msgStr != "" {
  401. return newStringValue(fmt.Sprintf("%s: %s", name.String(), msgStr))
  402. } else {
  403. if nameStr != "" {
  404. return name.ToString()
  405. } else {
  406. return msg.ToString()
  407. }
  408. }
  409. }
  410. func (r *Runtime) builtin_Error(args []Value, proto *Object) *Object {
  411. obj := r.newBaseObject(proto, classError)
  412. if len(args) > 0 && args[0] != _undefined {
  413. obj._putProp("message", args[0], true, false, true)
  414. }
  415. return obj.val
  416. }
  417. func (r *Runtime) builtin_new(construct *Object, args []Value) *Object {
  418. repeat:
  419. switch f := construct.self.(type) {
  420. case *nativeFuncObject:
  421. if f.construct != nil {
  422. return f.construct(args)
  423. } else {
  424. panic("Not a constructor")
  425. }
  426. case *boundFuncObject:
  427. if f.construct != nil {
  428. return f.construct(args)
  429. } else {
  430. panic("Not a constructor")
  431. }
  432. case *funcObject:
  433. // TODO: implement
  434. panic("Not implemented")
  435. case *lazyObject:
  436. construct.self = f.create(construct)
  437. goto repeat
  438. default:
  439. panic("Not a constructor")
  440. }
  441. }
  442. func (r *Runtime) throw(e Value) {
  443. panic(e)
  444. }
  445. func (r *Runtime) builtin_thrower(call FunctionCall) Value {
  446. r.typeErrorResult(true, "'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them")
  447. return nil
  448. }
  449. func (r *Runtime) eval(src string, direct, strict bool, this Value) Value {
  450. p, err := r.compile("<eval>", src, strict, true)
  451. if err != nil {
  452. panic(err)
  453. }
  454. vm := r.vm
  455. vm.pushCtx()
  456. vm.prg = p
  457. vm.pc = 0
  458. if !direct {
  459. vm.stash = nil
  460. }
  461. vm.sb = vm.sp
  462. vm.push(this)
  463. if strict {
  464. vm.push(valueTrue)
  465. } else {
  466. vm.push(valueFalse)
  467. }
  468. vm.run()
  469. vm.popCtx()
  470. vm.halt = false
  471. retval := vm.stack[vm.sp-1]
  472. vm.sp -= 2
  473. return retval
  474. }
  475. func (r *Runtime) builtin_eval(call FunctionCall) Value {
  476. if len(call.Arguments) == 0 {
  477. return _undefined
  478. }
  479. if str, ok := call.Arguments[0].assertString(); ok {
  480. return r.eval(str.String(), false, false, r.globalObject)
  481. }
  482. return call.Arguments[0]
  483. }
  484. func (r *Runtime) constructWrap(construct func(args []Value, proto *Object) *Object, proto *Object) func(call FunctionCall) Value {
  485. return func(call FunctionCall) Value {
  486. return construct(call.Arguments, proto)
  487. }
  488. }
  489. func (r *Runtime) toCallable(v Value) func(FunctionCall) Value {
  490. if call, ok := r.toObject(v).self.assertCallable(); ok {
  491. return call
  492. }
  493. r.typeErrorResult(true, "Value is not callable: %s", v.ToString())
  494. return nil
  495. }
  496. func (r *Runtime) checkObjectCoercible(v Value) {
  497. switch v.(type) {
  498. case valueUndefined, valueNull:
  499. r.typeErrorResult(true, "Value is not object coercible")
  500. }
  501. }
  502. func toUInt32(v Value) uint32 {
  503. v = v.ToNumber()
  504. if i, ok := v.assertInt(); ok {
  505. return uint32(i)
  506. }
  507. if f, ok := v.assertFloat(); ok {
  508. return uint32(int64(f))
  509. }
  510. return 0
  511. }
  512. func toUInt16(v Value) uint16 {
  513. v = v.ToNumber()
  514. if i, ok := v.assertInt(); ok {
  515. return uint16(i)
  516. }
  517. if f, ok := v.assertFloat(); ok {
  518. return uint16(int64(f))
  519. }
  520. return 0
  521. }
  522. func toLength(v Value) int64 {
  523. if v == nil {
  524. return 0
  525. }
  526. i := v.ToInteger()
  527. if i < 0 {
  528. return 0
  529. }
  530. if i >= maxInt {
  531. return maxInt - 1
  532. }
  533. return i
  534. }
  535. func toInt32(v Value) int32 {
  536. v = v.ToNumber()
  537. if i, ok := v.assertInt(); ok {
  538. return int32(i)
  539. }
  540. if f, ok := v.assertFloat(); ok {
  541. if !math.IsNaN(f) && !math.IsInf(f, 0) {
  542. return int32(int64(f))
  543. }
  544. }
  545. return 0
  546. }
  547. func (r *Runtime) toBoolean(b bool) Value {
  548. if b {
  549. return valueTrue
  550. } else {
  551. return valueFalse
  552. }
  553. }
  554. // New creates an instance of a Javascript runtime that can be used to run code. Multiple instances may be created and
  555. // used simultaneously, however it is not possible to pass JS values across runtimes.
  556. func New() *Runtime {
  557. r := &Runtime{}
  558. r.init()
  559. return r
  560. }
  561. // Compile creates an internal representation of the JavaScript code that can be later run using the Runtime.RunProgram()
  562. // method. This representation is not linked to a runtime in any way and can be run in multiple runtimes (possibly
  563. // at the same time).
  564. func Compile(name, src string, strict bool) (p *Program, err error) {
  565. return compile(name, src, strict, false)
  566. }
  567. func compile(name, src string, strict, eval bool) (p *Program, err error) {
  568. prg, err1 := parser.ParseFile(nil, name, src, 0)
  569. if err1 != nil {
  570. switch err1 := err1.(type) {
  571. case parser.ErrorList:
  572. if len(err1) > 0 && err1[0].Message == "Invalid left-hand side in assignment" {
  573. err = &CompilerReferenceError{
  574. CompilerError: CompilerError{
  575. Message: err1.Error(),
  576. },
  577. }
  578. return
  579. }
  580. }
  581. // FIXME offset
  582. err = &CompilerSyntaxError{
  583. CompilerError: CompilerError{
  584. Message: err1.Error(),
  585. },
  586. }
  587. return
  588. }
  589. c := newCompiler()
  590. c.scope.strict = strict
  591. c.scope.eval = eval
  592. defer func() {
  593. if x := recover(); x != nil {
  594. p = nil
  595. switch x1 := x.(type) {
  596. case *CompilerSyntaxError:
  597. err = x1
  598. default:
  599. panic(x)
  600. }
  601. }
  602. }()
  603. c.compile(prg)
  604. p = c.p
  605. return
  606. }
  607. func (r *Runtime) compile(name, src string, strict, eval bool) (p *Program, err error) {
  608. p, err = compile(name, src, strict, eval)
  609. if err != nil {
  610. switch x1 := err.(type) {
  611. case *CompilerSyntaxError:
  612. err = &Exception{
  613. val: r.builtin_new(r.global.SyntaxError, []Value{newStringValue(x1.Error())}),
  614. }
  615. case *CompilerReferenceError:
  616. err = &Exception{
  617. val: r.newError(r.global.ReferenceError, x1.Message),
  618. } // TODO proper message
  619. }
  620. }
  621. return
  622. }
  623. // RunString executes the given string in the global context.
  624. func (r *Runtime) RunString(str string) (Value, error) {
  625. return r.RunScript("", str)
  626. }
  627. // RunScript executes the given string in the global context.
  628. func (r *Runtime) RunScript(name, src string) (Value, error) {
  629. p, err := Compile(name, src, false)
  630. if err != nil {
  631. return nil, err
  632. }
  633. return r.RunProgram(p)
  634. }
  635. // RunProgram executes a pre-compiled (see Compile()) code in the global context.
  636. func (r *Runtime) RunProgram(p *Program) (result Value, err error) {
  637. defer func() {
  638. if x := recover(); x != nil {
  639. if intr, ok := x.(*InterruptedError); ok {
  640. err = intr
  641. } else {
  642. panic(x)
  643. }
  644. }
  645. }()
  646. recursive := false
  647. if len(r.vm.callStack) > 0 {
  648. recursive = true
  649. r.vm.pushCtx()
  650. }
  651. r.vm.prg = p
  652. r.vm.pc = 0
  653. ex := r.vm.runTry()
  654. if ex == nil {
  655. result = r.vm.pop()
  656. } else {
  657. err = ex
  658. }
  659. if recursive {
  660. r.vm.popCtx()
  661. r.vm.halt = false
  662. } else {
  663. r.vm.stack = nil
  664. }
  665. return
  666. }
  667. // Interrupt a running JavaScript. The corresponding Go call will return an *InterruptedError containing v.
  668. // Note, it only works while in JavaScript code, it does not interrupt native Go functions (which includes all built-ins).
  669. func (r *Runtime) Interrupt(v interface{}) {
  670. r.vm.Interrupt(v)
  671. }
  672. /*
  673. ToValue converts a Go value into JavaScript value.
  674. Primitive types (ints and uints, floats, string, bool) are converted to the corresponding JavaScript primitives.
  675. func(FunctionCall) Value is treated as a native JavaScript function.
  676. map[string]interface{} is converted into a host object that largely behaves like a JavaScript Object.
  677. []interface{} is converted into a host object that behaves largely like a JavaScript Array, however it's not extensible
  678. because extending it can change the pointer so it becomes detached from the original.
  679. *[]interface{} same as above, but the array becomes extensible.
  680. A function is wrapped within a native JavaScript function. When called the arguments are automatically converted to
  681. the appropriate Go types. If conversion is not possible, a TypeError is thrown.
  682. A slice type is converted into a generic reflect based host object that behaves similar to an unexpandable Array.
  683. Any other type is converted to a generic reflect based host object. Depending on the underlying type it behaves similar
  684. to a Number, String, Boolean or Object.
  685. Note that the underlying type is not lost, calling Export() returns the original Go value. This applies to all
  686. reflect based types.
  687. */
  688. func (r *Runtime) ToValue(i interface{}) Value {
  689. switch i := i.(type) {
  690. case nil:
  691. return _undefined
  692. case Value:
  693. // TODO: prevent importing Objects from a different runtime
  694. return i
  695. case string:
  696. return newStringValue(i)
  697. case bool:
  698. if i {
  699. return valueTrue
  700. } else {
  701. return valueFalse
  702. }
  703. case func(FunctionCall) Value:
  704. return r.newNativeFunc(i, nil, "", nil, 0)
  705. case int:
  706. return intToValue(int64(i))
  707. case int8:
  708. return intToValue(int64(i))
  709. case int16:
  710. return intToValue(int64(i))
  711. case int32:
  712. return intToValue(int64(i))
  713. case int64:
  714. return intToValue(i)
  715. case uint:
  716. if int64(i) <= math.MaxInt64 {
  717. return intToValue(int64(i))
  718. } else {
  719. return floatToValue(float64(i))
  720. }
  721. case uint64:
  722. if i <= math.MaxInt64 {
  723. return intToValue(int64(i))
  724. } else {
  725. return floatToValue(float64(i))
  726. }
  727. case uint8:
  728. return intToValue(int64(i))
  729. case uint16:
  730. return intToValue(int64(i))
  731. case uint32:
  732. return intToValue(int64(i))
  733. case map[string]interface{}:
  734. obj := &Object{runtime: r}
  735. m := &objectGoMapSimple{
  736. baseObject: baseObject{
  737. val: obj,
  738. extensible: true,
  739. },
  740. data: i,
  741. }
  742. obj.self = m
  743. m.init()
  744. return obj
  745. case []interface{}:
  746. obj := &Object{runtime: r}
  747. a := &objectGoSlice{
  748. baseObject: baseObject{
  749. val: obj,
  750. },
  751. data: &i,
  752. }
  753. obj.self = a
  754. a.init()
  755. return obj
  756. case *[]interface{}:
  757. obj := &Object{runtime: r}
  758. a := &objectGoSlice{
  759. baseObject: baseObject{
  760. val: obj,
  761. },
  762. data: i,
  763. sliceExtensible: true,
  764. }
  765. obj.self = a
  766. a.init()
  767. return obj
  768. }
  769. origValue := reflect.ValueOf(i)
  770. value := origValue
  771. for value.Kind() == reflect.Ptr {
  772. value = reflect.Indirect(value)
  773. }
  774. switch value.Kind() {
  775. case reflect.Map:
  776. if value.Type().Name() == "" {
  777. switch value.Type().Key().Kind() {
  778. case reflect.String, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
  779. reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
  780. reflect.Float64, reflect.Float32:
  781. obj := &Object{runtime: r}
  782. m := &objectGoMapReflect{
  783. objectGoReflect: objectGoReflect{
  784. baseObject: baseObject{
  785. val: obj,
  786. extensible: true,
  787. },
  788. origValue: origValue,
  789. value: value,
  790. },
  791. }
  792. m.init()
  793. obj.self = m
  794. return obj
  795. }
  796. }
  797. case reflect.Slice:
  798. obj := &Object{runtime: r}
  799. a := &objectGoSliceReflect{
  800. objectGoReflect: objectGoReflect{
  801. baseObject: baseObject{
  802. val: obj,
  803. },
  804. origValue: origValue,
  805. value: value,
  806. },
  807. }
  808. a.init()
  809. obj.self = a
  810. return obj
  811. case reflect.Func:
  812. return r.newNativeFunc(r.wrapReflectFunc(value), nil, "", nil, value.Type().NumIn())
  813. }
  814. obj := &Object{runtime: r}
  815. o := &objectGoReflect{
  816. baseObject: baseObject{
  817. val: obj,
  818. },
  819. origValue: origValue,
  820. value: value,
  821. }
  822. obj.self = o
  823. o.init()
  824. return obj
  825. }
  826. func (r *Runtime) wrapReflectFunc(value reflect.Value) func(FunctionCall) Value {
  827. return func(call FunctionCall) Value {
  828. typ := value.Type()
  829. nargs := typ.NumIn()
  830. if len(call.Arguments) != nargs {
  831. if typ.IsVariadic() {
  832. if len(call.Arguments) < nargs-1 {
  833. panic(r.newError(r.global.TypeError, "expected at least %d arguments; got %d", nargs-1, len(call.Arguments)))
  834. }
  835. } else {
  836. panic(r.newError(r.global.TypeError, "expected %d argument(s); got %d", nargs, len(call.Arguments)))
  837. }
  838. }
  839. in := make([]reflect.Value, len(call.Arguments))
  840. callSlice := false
  841. for i, a := range call.Arguments {
  842. var t reflect.Type
  843. n := i
  844. if n >= nargs-1 && typ.IsVariadic() {
  845. if n > nargs-1 {
  846. n = nargs - 1
  847. }
  848. t = typ.In(n).Elem()
  849. } else {
  850. t = typ.In(n)
  851. }
  852. // if this is a variadic Go function, and the caller has supplied
  853. // exactly the number of JavaScript arguments required, and this
  854. // is the last JavaScript argument, try treating the it as the
  855. // actual set of variadic Go arguments. if that succeeds, break
  856. // out of the loop.
  857. if typ.IsVariadic() && len(call.Arguments) == nargs && i == nargs-1 {
  858. if v, err := r.toReflectValue(a, typ.In(n)); err == nil {
  859. in[i] = v
  860. callSlice = true
  861. break
  862. }
  863. }
  864. var err error
  865. in[i], err = r.toReflectValue(a, t)
  866. if err != nil {
  867. panic(r.newError(r.global.TypeError, "Could not convert function call parameter %v to %v", a, t))
  868. }
  869. }
  870. var out []reflect.Value
  871. if callSlice {
  872. out = value.CallSlice(in)
  873. } else {
  874. out = value.Call(in)
  875. }
  876. if len(out) == 0 {
  877. return _undefined
  878. }
  879. if last := out[len(out)-1]; last.Type().Name() == "error" {
  880. if !last.IsNil() {
  881. err := last.Interface()
  882. if _, ok := err.(*Exception); ok {
  883. panic(err)
  884. }
  885. panic(r.NewGoError(last.Interface().(error)))
  886. }
  887. out = out[:len(out)-1]
  888. }
  889. switch len(out) {
  890. case 0:
  891. return _undefined
  892. case 1:
  893. return r.ToValue(out[0].Interface())
  894. default:
  895. s := make([]interface{}, len(out))
  896. for i, v := range out {
  897. s[i] = v.Interface()
  898. }
  899. return r.ToValue(s)
  900. }
  901. }
  902. }
  903. func (r *Runtime) toReflectValue(v Value, typ reflect.Type) (reflect.Value, error) {
  904. switch typ.Kind() {
  905. case reflect.String:
  906. return reflect.ValueOf(v.String()).Convert(typ), nil
  907. case reflect.Bool:
  908. return reflect.ValueOf(v.ToBoolean()).Convert(typ), nil
  909. case reflect.Int:
  910. i, _ := toInt(v)
  911. return reflect.ValueOf(int(i)).Convert(typ), nil
  912. case reflect.Int64:
  913. i, _ := toInt(v)
  914. return reflect.ValueOf(i).Convert(typ), nil
  915. case reflect.Int32:
  916. i, _ := toInt(v)
  917. return reflect.ValueOf(int32(i)).Convert(typ), nil
  918. case reflect.Int16:
  919. i, _ := toInt(v)
  920. return reflect.ValueOf(int16(i)).Convert(typ), nil
  921. case reflect.Int8:
  922. i, _ := toInt(v)
  923. return reflect.ValueOf(int8(i)).Convert(typ), nil
  924. case reflect.Uint:
  925. i, _ := toInt(v)
  926. return reflect.ValueOf(uint(i)).Convert(typ), nil
  927. case reflect.Uint64:
  928. i, _ := toInt(v)
  929. return reflect.ValueOf(uint64(i)).Convert(typ), nil
  930. case reflect.Uint32:
  931. i, _ := toInt(v)
  932. return reflect.ValueOf(uint32(i)).Convert(typ), nil
  933. case reflect.Uint16:
  934. i, _ := toInt(v)
  935. return reflect.ValueOf(uint16(i)).Convert(typ), nil
  936. case reflect.Uint8:
  937. i, _ := toInt(v)
  938. return reflect.ValueOf(uint8(i)).Convert(typ), nil
  939. }
  940. et := v.ExportType()
  941. if et.AssignableTo(typ) {
  942. return reflect.ValueOf(v.Export()), nil
  943. } else if et.ConvertibleTo(typ) {
  944. return reflect.ValueOf(v.Export()).Convert(typ), nil
  945. }
  946. switch typ.Kind() {
  947. case reflect.Slice:
  948. if o, ok := v.(*Object); ok {
  949. if o.self.className() == classArray {
  950. l := int(toLength(o.self.getStr("length")))
  951. s := reflect.MakeSlice(typ, l, l)
  952. elemTyp := typ.Elem()
  953. for i := 0; i < l; i++ {
  954. item := o.self.get(intToValue(int64(i)))
  955. itemval, err := r.toReflectValue(item, elemTyp)
  956. if err != nil {
  957. return reflect.Value{}, fmt.Errorf("Could not convert array element %v to %v at %d", v, typ, i)
  958. }
  959. s.Index(i).Set(itemval)
  960. }
  961. return s, nil
  962. }
  963. }
  964. case reflect.Map:
  965. if o, ok := v.(*Object); ok {
  966. m := reflect.MakeMap(typ)
  967. keyTyp := typ.Key()
  968. elemTyp := typ.Elem()
  969. needConvertKeys := !reflect.ValueOf("").Type().AssignableTo(keyTyp)
  970. for item, f := o.self.enumerate(false, false)(); f != nil; item, f = f() {
  971. var kv reflect.Value
  972. var err error
  973. if needConvertKeys {
  974. kv, err = r.toReflectValue(newStringValue(item.name), keyTyp)
  975. if err != nil {
  976. return reflect.Value{}, fmt.Errorf("Could not convert map key %s to %v", item.name, typ)
  977. }
  978. } else {
  979. kv = reflect.ValueOf(item.name)
  980. }
  981. ival := item.value
  982. if ival == nil {
  983. ival = o.self.getStr(item.name)
  984. }
  985. if ival != nil {
  986. vv, err := r.toReflectValue(ival, elemTyp)
  987. if err != nil {
  988. return reflect.Value{}, fmt.Errorf("Could not convert map value %v to %v at key %s", ival, typ, item.name)
  989. }
  990. m.SetMapIndex(kv, vv)
  991. } else {
  992. m.SetMapIndex(kv, reflect.Zero(elemTyp))
  993. }
  994. }
  995. return m, nil
  996. }
  997. case reflect.Struct:
  998. if o, ok := v.(*Object); ok {
  999. s := reflect.New(typ).Elem()
  1000. for i := 0; i < typ.NumField(); i++ {
  1001. field := typ.Field(i)
  1002. if ast.IsExported(field.Name) {
  1003. v := o.self.getStr(field.Name)
  1004. if v != nil {
  1005. vv, err := r.toReflectValue(v, field.Type)
  1006. if err != nil {
  1007. return reflect.Value{}, fmt.Errorf("Could not convert struct value %v to %v for field %s", v, field.Type, field.Name)
  1008. }
  1009. s.Field(i).Set(vv)
  1010. }
  1011. }
  1012. }
  1013. return s, nil
  1014. }
  1015. }
  1016. return reflect.Value{}, fmt.Errorf("Could not convert %v to %v", v, typ)
  1017. }
  1018. // ExportTo converts a JavaScript value into the specified Go value. The second parameter must be a non-nil pointer.
  1019. // Returns error if conversion is not possible.
  1020. func (r *Runtime) ExportTo(v Value, target interface{}) error {
  1021. tval := reflect.ValueOf(target)
  1022. if tval.Kind() != reflect.Ptr || tval.IsNil() {
  1023. return errors.New("target must be a non-nil pointer")
  1024. }
  1025. vv, err := r.toReflectValue(v, tval.Elem().Type())
  1026. if err != nil {
  1027. return err
  1028. }
  1029. tval.Elem().Set(vv)
  1030. return nil
  1031. }
  1032. // Set the specified value as a property of the global object.
  1033. // The value is first converted using ToValue()
  1034. func (r *Runtime) Set(name string, value interface{}) {
  1035. r.globalObject.self.putStr(name, r.ToValue(value), false)
  1036. }
  1037. // Get the specified property of the global object.
  1038. func (r *Runtime) Get(name string) Value {
  1039. return r.globalObject.self.getStr(name)
  1040. }
  1041. // SetRandSource sets random source for this Runtime. If not called, the default math/rand is used.
  1042. func (r *Runtime) SetRandSource(source RandSource) {
  1043. r.rand = source
  1044. }
  1045. // Callable represents a JavaScript function that can be called from Go.
  1046. type Callable func(this Value, args ...Value) (Value, error)
  1047. // AssertFunction checks if the Value is a function and returns a Callable.
  1048. func AssertFunction(v Value) (Callable, bool) {
  1049. if obj, ok := v.(*Object); ok {
  1050. if f, ok := obj.self.assertCallable(); ok {
  1051. return func(this Value, args ...Value) (ret Value, err error) {
  1052. ex := obj.runtime.vm.try(func() {
  1053. ret = f(FunctionCall{
  1054. This: this,
  1055. Arguments: args,
  1056. })
  1057. })
  1058. if ex != nil {
  1059. err = ex
  1060. }
  1061. return
  1062. }, true
  1063. }
  1064. }
  1065. return nil, false
  1066. }
  1067. // IsUndefined returns true if the supplied Value is undefined. Note, it checks against the real undefined, not
  1068. // against the global object's 'undefined' property.
  1069. func IsUndefined(v Value) bool {
  1070. return v == _undefined
  1071. }
  1072. // IsNull returns true if the supplied Value is null.
  1073. func IsNull(v Value) bool {
  1074. return v == _null
  1075. }
  1076. // Undefined returns JS undefined value. Note if global 'undefined' property is changed this still returns the original value.
  1077. func Undefined() Value {
  1078. return _undefined
  1079. }
  1080. // Null returns JS null value.
  1081. func Null() Value {
  1082. return _undefined
  1083. }