@@ -34,15 +34,18 @@ public class RuntimeError: Error, Hashable, CustomStringConvertible {
34
34
public let irritants : [ Expr ]
35
35
public private( set) var library : Expr ?
36
36
public private( set) var stackTrace : [ Procedure ] ?
37
+ public private( set) var callTrace : [ String ] ?
37
38
38
39
internal init ( _ pos: SourcePosition ,
39
40
_ descriptor: ErrorDescriptor ,
40
41
_ irritants: [ Expr ] ,
41
- _ stackTrace: [ Procedure ] ? = nil ) {
42
+ stackTrace: [ Procedure ] ? = nil ,
43
+ callTrace: [ String ] ? = nil ) {
42
44
self . pos = pos
43
45
self . descriptor = descriptor
44
46
self . irritants = irritants
45
- self . stackTrace = nil
47
+ self . stackTrace = stackTrace
48
+ self . callTrace = callTrace
46
49
}
47
50
48
51
public class func lexical( _ error: LexicalError ,
@@ -129,15 +132,25 @@ public class RuntimeError: Error, Hashable, CustomStringConvertible {
129
132
}
130
133
131
134
public class func abortion( at pos: SourcePosition = SourcePosition . unknown,
132
- stackTrace: [ Procedure ] ? = nil ) -> RuntimeError {
133
- return RuntimeError ( pos, ErrorDescriptor . abortion, [ ] , stackTrace)
135
+ stackTrace: [ Procedure ] ? = nil ,
136
+ callTrace: [ String ] ? = nil ) -> RuntimeError {
137
+ return RuntimeError ( pos,
138
+ ErrorDescriptor . abortion,
139
+ [ ] ,
140
+ stackTrace: stackTrace,
141
+ callTrace: callTrace)
134
142
}
135
143
136
144
public class func uncaught( _ expr: Expr ,
137
145
at pos: SourcePosition = SourcePosition . unknown,
138
- stackTrace: [ Procedure ] ? = nil ) -> RuntimeError {
146
+ stackTrace: [ Procedure ] ? = nil ,
147
+ callTrace: [ String ] ? = nil ) -> RuntimeError {
139
148
// TODO: figure out if we want uncaught of uncaught exceptions?
140
- return RuntimeError ( pos, ErrorDescriptor . uncaught, [ expr] , stackTrace)
149
+ return RuntimeError ( pos,
150
+ ErrorDescriptor . uncaught,
151
+ [ expr] ,
152
+ stackTrace: stackTrace,
153
+ callTrace: callTrace)
141
154
}
142
155
143
156
public class func custom( _ kind: String ,
@@ -148,7 +161,29 @@ public class RuntimeError: Error, Hashable, CustomStringConvertible {
148
161
}
149
162
150
163
public func at( _ pos: SourcePosition ) -> RuntimeError {
151
- return RuntimeError ( pos, self . descriptor, self . irritants, self . stackTrace)
164
+ return RuntimeError ( pos,
165
+ self . descriptor,
166
+ self . irritants,
167
+ stackTrace: self . stackTrace,
168
+ callTrace: self . callTrace)
169
+ }
170
+
171
+ @discardableResult public func attach( callTrace: [ String ] ? ) -> RuntimeError {
172
+ if self . callTrace == nil {
173
+ self . callTrace = callTrace
174
+ }
175
+ return self
176
+ }
177
+
178
+ @discardableResult public func attach( vm: VirtualMachine ,
179
+ current: Procedure ? = nil ) -> RuntimeError {
180
+ if self . stackTrace == nil {
181
+ self . stackTrace = vm. getStackTrace ( current: current)
182
+ }
183
+ if self . callTrace == nil {
184
+ self . callTrace = vm. getCallTraceInfo ( current: current)
185
+ }
186
+ return self
152
187
}
153
188
154
189
@discardableResult public func attach( stackTrace: [ Procedure ] ) -> RuntimeError {
@@ -212,7 +247,7 @@ public class RuntimeError: Error, Hashable, CustomStringConvertible {
212
247
irritantSeparator: String = " , " ,
213
248
positionHeader: String ? = " \n at: " ,
214
249
libraryHeader: String ? = " \n library: " ,
215
- stackTraceHeader: String ? = " \n stack trace: " ,
250
+ stackTraceHeader: String ? = " \n call trace: " ,
216
251
stackTraceSeparator: String = " , " ) -> String {
217
252
if self . descriptor == . uncaught,
218
253
self . irritants. count == 1 ,
@@ -269,14 +304,26 @@ public class RuntimeError: Error, Hashable, CustomStringConvertible {
269
304
let libraryName = self . library? . description {
270
305
builder. append ( " \( libraryHeader) \( libraryName) " )
271
306
}
272
- if let stackTraceHeader = stackTraceHeader,
273
- let stackTrace = self . stackTrace {
307
+ if let stackTraceHeader = stackTraceHeader, self . callTrace != nil || self . stackTrace != nil {
274
308
builder = StringBuilder ( prefix: builder. description,
275
309
postfix: " " ,
276
310
separator: stackTraceSeparator,
277
311
initial: stackTraceHeader)
278
- for proc in stackTrace {
279
- builder. append ( proc. name)
312
+ if let callTrace = self . callTrace {
313
+ for call in callTrace {
314
+ builder. append ( call)
315
+ }
316
+ if let stackTrace = self . stackTrace, stackTrace. count > callTrace. count {
317
+ if stackTrace. count == callTrace. count + 1 {
318
+ builder. append ( " +1 call " )
319
+ } else {
320
+ builder. append ( " + \( stackTrace. count - callTrace. count) calls " )
321
+ }
322
+ }
323
+ } else if let stackTrace = self . stackTrace {
324
+ for proc in stackTrace {
325
+ builder. append ( proc. name)
326
+ }
280
327
}
281
328
}
282
329
return builder. description
0 commit comments