vm.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  1. // vm, the virtual low level machine that runs MUESLI.
  2. package muesli
  3. import (
  4. "fmt"
  5. "strings"
  6. )
  7. // Handler function
  8. type Handler func(vm *VM, arguments ...Value) []Value
  9. func (handler *Handler) Call(vm *VM, arguments ...Value) []Value {
  10. return (*handler)(vm, arguments...)
  11. }
  12. // A callable Value must implement the Callable interface
  13. type Callable interface {
  14. // Callable can be called
  15. Call(vm *VM, arguments ...Value) []Value
  16. // Position is the source code position where it was defined. Needed for tracebacks.
  17. Position() *Position
  18. // Signature are the types of the parameters of this function.
  19. Signature() Signature
  20. }
  21. // A helper Value has a help text available.
  22. // This help text can be set as well.
  23. type Helper interface {
  24. HelperName() string
  25. Help() string
  26. SetHelp(string) string
  27. }
  28. // BasicCallable is an embeddable struct that makes it easier to
  29. // implement the Caller and Helper interface.
  30. type BasicCallable struct {
  31. // Name of the callable
  32. Name string
  33. // Help string for the callable.
  34. HelpText string
  35. // Signature of the callable for type checking.
  36. signature Signature
  37. // Position where the callable is defined.
  38. position Position
  39. }
  40. func (val BasicCallable) Signature() Signature {
  41. return val.signature
  42. }
  43. // Implement Helper interface
  44. func (val BasicCallable) Help() string {
  45. return val.HelpText
  46. }
  47. // Implement Helper interface
  48. func (val * BasicCallable) SetHelp(help string) string {
  49. val.HelpText = help
  50. return val.HelpText
  51. }
  52. // Implement Helper interface
  53. func (val BasicCallable) HelperName() string {
  54. return val.Name
  55. }
  56. // AppendHelp appends help to an existing helper.
  57. func AppendHelp(helper Helper, extra string) string {
  58. return helper.SetHelp( helper.Help() + extra)
  59. }
  60. // ClearHelp rresets the help text to an empty string.
  61. func ClearHelp(helper Helper, extra string) string {
  62. return helper.SetHelp("")
  63. }
  64. func (bc * BasicCallable) Takes(arguments ...TypeValue) *BasicCallable {
  65. bc.signature.SetParameters(arguments...)
  66. return bc
  67. }
  68. func (bc * BasicCallable) Returns(arguments ...TypeValue) *BasicCallable {
  69. bc.signature.SetReturns(arguments...)
  70. return bc
  71. }
  72. func (val BasicCallable) String() string {
  73. return val.Name
  74. }
  75. func (val BasicCallable) Type() TypeValue {
  76. return TypeValue("Callable")
  77. }
  78. func (from BasicCallable) Convert(to interface{}) error {
  79. return NewErrorValuef("Cannot convert the callable value %v to %v: Not implemented.", from, to)
  80. }
  81. func (val *BasicCallable) Call(vm *VM, arguments ...Value) []Value {
  82. panic("Not implemented")
  83. }
  84. // A struct to store a built in function
  85. type BuiltinValue struct {
  86. BasicCallable
  87. Handler
  88. }
  89. func NewBasicCallable(name string) BasicCallable {
  90. return BasicCallable{name, "", NoSignature(), Position{name, 1, 1}}
  91. }
  92. func NewBuiltinValue(name string, handler Handler) *BuiltinValue {
  93. result := &BuiltinValue{}
  94. result.Name = name
  95. result.Handler = handler
  96. return result
  97. }
  98. // A block in a script.
  99. type BlockValue struct {
  100. BasicCallable
  101. Ast *Ast
  102. }
  103. func NewBlockValue(definition *Ast) *BlockValue {
  104. result := &BlockValue{}
  105. result.Name = fmt.Sprintf("<block:%s>", definition.String())
  106. result.Ast = definition
  107. return result
  108. }
  109. func (block * BlockValue) Position() *Position {
  110. if block == nil {
  111. return nil
  112. }
  113. if block.Ast == nil {
  114. return nil
  115. }
  116. pos := block.Ast.Token().Position
  117. return &pos
  118. }
  119. func (defined * DefinedValue) Position() *Position {
  120. if defined == nil {
  121. return nil
  122. }
  123. if defined.Body == nil {
  124. return nil
  125. }
  126. return defined.Body.Position()
  127. }
  128. func (cv BasicCallable) Position() *Position {
  129. return &cv.position
  130. }
  131. // A script defined function
  132. type DefinedValue struct {
  133. BasicCallable
  134. Body *BlockValue
  135. }
  136. func NewDefinedValue(name string, signature Signature, body *BlockValue) *DefinedValue {
  137. result := &DefinedValue{}
  138. result.Name = name
  139. result.Body = body
  140. result.signature = signature
  141. return result
  142. }
  143. func (defined *DefinedValue) Call(vm *VM, arguments ...Value) []Value {
  144. vm.Trace("Call defined value: %v %v %v", defined, defined.signature, arguments)
  145. for i , arg := range arguments {
  146. if i >= len(defined.signature.Parameters) {
  147. break
  148. }
  149. param := defined.signature.Parameters[i]
  150. expectedType := param.Type
  151. vm.Trace("Signature check: %d %v", i, param)
  152. if !expectedType.IsMatch(arg.Type()) {
  153. return Fail(NewErrorValuef("Argument %d type mismatch: %s<->%s", i, expectedType, arg.Type()))
  154. }
  155. vm.Register(param.Name.String(), arg)
  156. vm.Trace("DefinedValue.Call: vm.Register: %v %v", param.Name.String(), arg)
  157. }
  158. res := defined.Body.Call(vm, arguments...)
  159. return res
  160. }
  161. func (defined *DefinedValue) Help() string {
  162. help := defined.BasicCallable.Help()
  163. extra := "["
  164. for _, parameter := range defined.signature.Parameters {
  165. extra = fmt.Sprintf("%s %s %s", extra, parameter.Name, parameter.Type)
  166. }
  167. extra = extra + "]:"
  168. return extra + help
  169. }
  170. // Assert that DefinedValue is callable.
  171. var _ Callable = &DefinedValue{}
  172. const (
  173. CoverTypeValue = TypeValue("Cover")
  174. BuiltinTypeValue = TypeValue("Builtin")
  175. DefinedTypeValue = TypeValue("Defined")
  176. BlockTypeValue = TypeValue("Block")
  177. )
  178. func (v CoverValue) Type() TypeValue { return CoverTypeValue }
  179. func (v BuiltinValue) Type() TypeValue { return BuiltinTypeValue }
  180. func (v DefinedValue) Type() TypeValue { return DefinedTypeValue }
  181. func (v BlockValue) Type() TypeValue { return BlockTypeValue }
  182. func (from CoverValue) Convert(to interface{}) error {
  183. return NewErrorValuef("Cannot convert the cover value %v to %v", from, to)
  184. }
  185. func (from BuiltinValue) Convert(to interface{}) error {
  186. return NewErrorValuef("Cannot convert the builtin value %v to %v", from, to)
  187. }
  188. func (from DefinedValue) Convert(to interface{}) error {
  189. return NewErrorValuef("Cannot convert the defined value %v to %v", from, to)
  190. }
  191. func (from BlockValue) Convert(to interface{}) error {
  192. if toValue, isOk := to.(*BlockValue) ; isOk {
  193. (*toValue) = from
  194. return nil
  195. }
  196. return NewErrorValuef("Cannot convert the block value %v to %v", from, to)
  197. }
  198. func (cv * CoverValue) AddOverloadWithSignature(name string, callable Callable, signature Signature) Overload {
  199. ov := Overload { Name: name, Callable: callable }
  200. cv.Overloads[signature] = ov
  201. return ov
  202. }
  203. func (cv * CoverValue) AddOverloadCallable(name string, callable Callable) Overload {
  204. return cv.AddOverloadWithSignature(name, callable, callable.Signature())
  205. }
  206. func (cv * CoverValue) AddOverload(name string, callable Callable, tv ... TypeValue) error {
  207. signature := Signature{}
  208. length := len(tv)
  209. if length > len(signature.Parameters) {
  210. length = len(signature.Parameters)
  211. }
  212. for i := 0; i < length; i++ {
  213. signature.Parameters[i].Type = tv[i]
  214. }
  215. cv.AddOverloadWithSignature(name, callable, signature)
  216. return nil
  217. }
  218. func (vm * VM) AddOverloadCallable(from, target string, level int, callable Callable) error {
  219. var cover *CoverValue
  220. var ok bool
  221. lookup := vm.Lookup(from)
  222. if lookup == nil {
  223. cover = vm.RegisterCover(from, level)
  224. } else if cover, ok = lookup.(*CoverValue) ; !ok {
  225. return fmt.Errorf("%s exists and is not a cover value", from)
  226. }
  227. cover.AddOverloadCallable(target, callable)
  228. return nil
  229. }
  230. func (vm *VM) LookupCallable(target string) (Callable, error) {
  231. var callable Callable
  232. var ok bool
  233. lookup := vm.Lookup(target)
  234. if lookup == nil {
  235. return nil, fmt.Errorf("%s is not defined", target)
  236. }
  237. if callable, ok = lookup.(Callable) ; !ok {
  238. return nil, fmt.Errorf("%s is not a callable value", target)
  239. }
  240. return callable, nil
  241. }
  242. // AddOverloadByName overloads the from command to call the target command
  243. // if the argument list matches the signature based on the given type values
  244. func (vm * VM) AddOverload(from, target string, level int, tv... TypeValue) error {
  245. var cover *CoverValue
  246. var callable Callable
  247. var ok bool
  248. var err error
  249. lookup := vm.Lookup(from)
  250. if lookup == nil {
  251. cover = vm.RegisterCover(from, level)
  252. } else if cover, ok = lookup.(*CoverValue) ; !ok {
  253. return fmt.Errorf("%s exists and is not a cover value", from)
  254. }
  255. callable, err = vm.LookupCallable(target)
  256. if err != nil {
  257. return err
  258. }
  259. return cover.AddOverload(target, callable, tv...)
  260. }
  261. // AddOverloadByName overloads the from command to call the target command
  262. // if the argment lists matches the signature of the target command.
  263. func (vm * VM) AddOverloadByName(from, target string, level int) error {
  264. callable, err := vm.LookupCallable(target)
  265. if err != nil {
  266. return err
  267. }
  268. return vm.AddOverloadCallable(from, target, level, callable)
  269. }
  270. type OverloadDescription struct {
  271. Target string
  272. Types []TypeValue
  273. Level int
  274. }
  275. func (vm * VM) AddOverloads(from string, descriptions ... OverloadDescription) error {
  276. for _, od := range descriptions {
  277. err := vm.AddOverload(from, od.Target, od.Level, od.Types...)
  278. if err != nil {
  279. panic(fmt.Errorf("internal error: could not register overloads: %s", err))
  280. }
  281. }
  282. return nil
  283. }
  284. func Over(target string, level int, types ... TypeValue) OverloadDescription {
  285. return OverloadDescription { Target: target, Level: level, Types: types}
  286. }
  287. func (vm * VM) SetHelp(target, help string) error {
  288. var helper Helper
  289. var ok bool
  290. lookup := vm.Lookup(target)
  291. if lookup == nil {
  292. return fmt.Errorf("%s not found", target)
  293. } else if helper, ok = lookup.(Helper) ; !ok {
  294. return fmt.Errorf("%s exists but cannot set help text.", target)
  295. }
  296. helper.SetHelp(help)
  297. return nil
  298. }
  299. // Scope of symbols defined in the VM, hierarchical
  300. type Scope struct {
  301. parent *Scope
  302. children []*Scope
  303. symbols map[string]Value
  304. }
  305. func NewScope(parent *Scope) *Scope {
  306. return &Scope{parent, make([]*Scope, 0), make(map[string]Value)}
  307. }
  308. func (scope *Scope) Lookup(name string) Value {
  309. value, ok := scope.symbols[name]
  310. if ok {
  311. return value
  312. }
  313. if scope.parent != nil {
  314. return scope.parent.Lookup(name)
  315. }
  316. return NilValue
  317. }
  318. func (scope *Scope) Register(name string, value Value) Value {
  319. scope.symbols[name] = value
  320. return value
  321. }
  322. func (scope * Scope) Known(filter func(string, Value) bool) map[string]Value {
  323. res := make(map[string]Value)
  324. if scope.parent != nil {
  325. res = scope.parent.Known(filter)
  326. }
  327. for k, v := range scope.symbols {
  328. if (filter == nil) || filter(k, v) {
  329. res[k] = v
  330. }
  331. }
  332. return res
  333. }
  334. func (scope * Scope) ForEachDefined(do func(string, Value) (bool, error)) (bool, error) {
  335. var res bool = true
  336. var err error
  337. if (do == nil) {
  338. return false, fmt.Errorf("do may not be nil")
  339. }
  340. if scope.parent != nil {
  341. res, err = scope.parent.ForEachDefined(do)
  342. }
  343. if res == false || err != nil {
  344. return res, err
  345. }
  346. for k, v := range scope.symbols {
  347. res, err = do(k, v)
  348. if res == false || err != nil {
  349. return res, err
  350. }
  351. }
  352. return res, err
  353. }
  354. func (scope* Scope) DefinedHelpers() []Helper {
  355. res := []Helper{}
  356. scope.ForEachDefined(func (k string, v Value) (bool, error) {
  357. helper, hok := v.(Helper)
  358. if hok {
  359. res = append(res, helper)
  360. }
  361. return true, nil
  362. })
  363. return res
  364. }
  365. // Frame of execution of a function
  366. type Frame struct {
  367. parent *Frame
  368. arguments []Value
  369. results []Value
  370. failed bool
  371. returned bool
  372. position *Position
  373. }
  374. func NewFrame(parent *Frame, position *Position) *Frame {
  375. return &Frame{parent, EmptyValueArray(), EmptyValueArray(), false, false, position}
  376. }
  377. type Tracer interface {
  378. Trace(vm VM, fmt string, args ... interface{}) bool
  379. }
  380. // Virtual machine
  381. type VM struct {
  382. TopScope *Scope // Top level scope
  383. TopFrame *Frame // Top level scope
  384. *Scope // Current Scope
  385. *Frame // Current frame
  386. Tracer // Tracer to emit tracing info to, could be used for logging or debugging
  387. ExitStatus int
  388. }
  389. func NewVM() *VM {
  390. vm := &VM{NewScope(nil), NewFrame(nil, nil), nil, nil, nil, 0}
  391. vm.Scope = vm.TopScope
  392. vm.Frame = vm.TopFrame
  393. return vm
  394. }
  395. func (vm *VM) Trace(fm string, args ... interface{}) {
  396. if vm.Tracer != nil {
  397. vm.Tracer.Trace(*vm, fm, args...)
  398. }
  399. }
  400. func (vm *VM) PushNewFrame(position *Position) *Frame {
  401. frame := NewFrame(vm.Frame, position)
  402. vm.Trace("PushFrame %v->%v\n", vm.Frame, frame)
  403. vm.Frame = frame
  404. return frame
  405. }
  406. func (vm *VM) PushNewScope() *Scope {
  407. scope := NewScope(vm.Scope)
  408. vm.Scope = scope
  409. return scope
  410. }
  411. func (vm *VM) Return(results ...Value) []Value {
  412. return results
  413. }
  414. func (vm *VM) PopFrame() *Frame {
  415. oldFrame := vm.Frame
  416. vm.Trace("PopFrame %v->%v\n", vm.Frame, vm.Frame.parent)
  417. if (vm.Frame != vm.TopFrame) && (vm.Frame.parent != nil) {
  418. frame := vm.Frame
  419. vm.Frame = frame.parent
  420. // Copy frame results up.
  421. vm.Frame.returned = oldFrame.returned
  422. vm.Frame.failed = oldFrame.failed
  423. vm.Frame.results = oldFrame.results
  424. return frame
  425. }
  426. return nil
  427. }
  428. func (vm *VM) PopScope() *Scope {
  429. if (vm.Scope != vm.TopScope) && (vm.Scope.parent != nil) {
  430. scope := vm.Scope
  431. vm.Scope = scope.parent
  432. return scope
  433. }
  434. return nil
  435. }
  436. func (block * BlockValue) Call(vm *VM, arguments ...Value) []Value {
  437. ast := block.Ast
  438. // Now, don't run the block itself but the Statements node
  439. // that should be in it.
  440. children := ast.Children()
  441. if len(children) < 1 {
  442. return Fail(fmt.Errorf("Block has no statements."))
  443. }
  444. if len(children) > 1 {
  445. return Fail(fmt.Errorf("Block has too many statements."))
  446. }
  447. statements := children[0]
  448. arr := vm.RunAst(*statements, arguments...)
  449. return arr
  450. }
  451. func (builtin * BuiltinValue) Call(vm *VM, arguments ...Value) []Value {
  452. err := builtin.signature.TypeCheck(arguments...)
  453. if err != nil {
  454. return Fail(ErrorValue{err})
  455. }
  456. handler := builtin.Handler
  457. return handler.Call(vm, arguments...)
  458. }
  459. func (vm *VM) AddTrace(err error) error {
  460. res := ""
  461. for frame := vm.Frame; frame != nil; frame = frame.parent {
  462. if frame.position == nil {
  463. res = fmt.Sprintf("%s\nIn frame %v", res, frame)
  464. } else {
  465. res = fmt.Sprintf("%s\nIn %s", res, frame.position.String())
  466. }
  467. }
  468. return fmt.Errorf("%s: %s", res, err)
  469. }
  470. func (vm *VM) CallCallable(callable Callable, arguments ...Value) []Value {
  471. defer vm.PopScope()
  472. defer vm.PopFrame()
  473. vm.PushNewFrame(callable.Position())
  474. vm.PushNewScope()
  475. result := callable.Call(vm, arguments...)
  476. return result
  477. }
  478. func (vm *VM) CallNamed(name string, arguments ...Value) []Value {
  479. value := vm.Lookup(name)
  480. if value == nil {
  481. return ReturnError(vm.AddTrace(NewErrorValuef("Cannot call %s: not found.", name)))
  482. }
  483. if callable, ok := value.(Callable) ; ok {
  484. return vm.CallCallable(callable, arguments...)
  485. } else {
  486. return ReturnError(vm.AddTrace(NewErrorValuef("Cannot call %s: %v. Not callable", name, value)))
  487. }
  488. }
  489. /*
  490. func (vm * VM) CallNamedFramed(name string, arguments ...) []Value {
  491. frame := vm.PushNewFrame()
  492. }
  493. */
  494. // ScopeUp Returns the levelth scope up from the current one where 0 is the
  495. // current scope. Returns the toplevel scope if l is greater than the current
  496. // scope stack depth.
  497. func (vm * VM) ScopeUp(level int) *Scope {
  498. scope := vm.Scope
  499. for now := 0; now < level; now++ {
  500. if scope.parent == nil {
  501. return scope
  502. }
  503. scope = scope.parent
  504. }
  505. return scope
  506. }
  507. // RegisterTop registers a value at top level scope.
  508. func (vm *VM) RegisterTop(name string, value Value) Value {
  509. scope := vm.TopScope
  510. return scope.Register(name, value)
  511. }
  512. // RegisterUp registers in level scopes up from the current scope,
  513. // or at toplevel if the level is greater than the total depth
  514. func (vm *VM) RegisterUp(name string, value Value, level int) Value {
  515. scope := vm.ScopeUp(level)
  516. return scope.Register(name, value)
  517. }
  518. func (vm *VM) Register(name string, value Value) Value {
  519. return vm.Scope.Register(name, value)
  520. }
  521. func (vm *VM) RegisterCover(name string, level int) *CoverValue {
  522. value := NewCoverValue(name)
  523. vm.RegisterUp(name, value, level)
  524. return value
  525. }
  526. func (vm *VM) RegisterBuiltin(name string, handler Handler) *BuiltinValue {
  527. value := NewBuiltinValue(name, handler)
  528. vm.Register(name, value)
  529. return value
  530. }
  531. func (vm *VM) RegisterDefined(name string, signature Signature, block *BlockValue, level int) *DefinedValue {
  532. value := NewDefinedValue(name, signature, block)
  533. vm.RegisterUp(name, value, level)
  534. return value
  535. }
  536. // RegisterBuiltinWithHelp
  537. func (vm *VM) RegisterBuiltinWithHelp(name string, handler Handler, help string) *BuiltinValue {
  538. res := vm.RegisterBuiltin(name, handler)
  539. vm.SetHelp(name, help)
  540. return res
  541. }
  542. func (vm *VM) Fail() {
  543. vm.Frame.failed = true
  544. }
  545. func (vm *VM) RunAst(ast Ast, args ...Value) []Value {
  546. var result []Value
  547. /*pos := ast.Token().Position
  548. vm.PushNewFrame(&pos)
  549. defer vm.PopFrame()
  550. */
  551. // vm.Logf("RunAst: %s\n", ast.Kind().String())
  552. // Leaf nodes, both declared and in practice are self evaluating.
  553. if ast.Kind().IsLeaf() || ast.CountChildren() < 1 {
  554. result = ast.Eval(vm)
  555. if vm.Frame.returned || vm.Frame.failed {
  556. result = vm.Frame.results
  557. vm.Frame.returned = false
  558. vm.Frame.failed = false
  559. }
  560. } else {
  561. var subResult = []Value{}
  562. // Depth first recursion.
  563. for i, child := range ast.Children() {
  564. sub := vm.RunAst(*child)
  565. subResult = append(subResult, sub...)
  566. vm.Trace("RunAst: %d %v %v %v\n", i, child, sub, vm.Frame)
  567. /*
  568. if frame.failed && frame.parent != nil {
  569. // XXX failures are like panics and propagate up the call tree
  570. * // Or should they?
  571. frame.parent.failed = true
  572. frame.parent.results = frame.results
  573. }
  574. */
  575. if vm.Frame.returned || vm.Frame.failed {
  576. subResult = vm.Frame.results
  577. vm.Frame.returned = false
  578. vm.Frame.failed = false
  579. break;
  580. }
  581. }
  582. // vm.Logf("RunAst subResult: %v\n", subResult)
  583. result = ast.Eval(vm, subResult...)
  584. }
  585. // vm.Logf("RunAst result: %v\n", result)
  586. return result
  587. }
  588. func (vm *VM) DefinedHelpers() []Helper {
  589. return vm.Scope.DefinedHelpers()
  590. }
  591. func (vm * VM) BackTraceFrames() []*Frame {
  592. bt := []*Frame{}
  593. for frame := vm.Frame ; frame.parent != nil ; frame = frame.parent {
  594. bt = append(bt, frame)
  595. }
  596. return bt
  597. }
  598. func (vm * VM) BackTracePositions() []*Position {
  599. bt := []*Position{}
  600. for frame := vm.Frame ; frame.parent != nil ; frame = frame.parent {
  601. bt = append(bt, frame.position)
  602. }
  603. return bt
  604. }
  605. func (vm * VM) BackTraceStrings() []string {
  606. bt := []string{}
  607. for frame := vm.Frame ; frame.parent != nil ; frame = frame.parent {
  608. bt = append(bt, frame.position.String())
  609. }
  610. return bt
  611. }
  612. func (vm * VM) BackTrace() string {
  613. return strings.Join(vm.BackTraceStrings(), "\n")
  614. }