@@ -34,8 +34,8 @@ function tryReadFile(path) {
34
34
35
35
// Parse the given JavaScript script and return an AST compatible with Fuzzilli's protobuf-based AST format.
36
36
function parse ( script , proto ) {
37
- let ast = Parser . parse ( script , { plugins : [ "v8intrinsic" ] } ) ;
38
-
37
+ let ast = Parser . parse ( script , { plugins : [ "v8intrinsic" ] } ) ;
38
+
39
39
function assertNoError ( err ) {
40
40
if ( err ) throw err ;
41
41
}
@@ -77,6 +77,20 @@ function parse(script, proto) {
77
77
return make ( 'Parameter' , { name : param . name } ) ;
78
78
}
79
79
80
+ function visitParameters ( params ) {
81
+ return params . map ( visitParameter )
82
+ }
83
+
84
+ // Processes the body of a block statement node and returns a list of statements.
85
+ function visitBody ( node ) {
86
+ assert ( node . type === 'BlockStatement' , "Expected block statement, found " + node . type ) ;
87
+ let statements = [ ] ;
88
+ for ( let stmt of node . body ) {
89
+ statements . push ( visitStatement ( stmt ) ) ;
90
+ }
91
+ return statements ;
92
+ }
93
+
80
94
function visitVariableDeclaration ( node ) {
81
95
let kind ;
82
96
if ( node . kind === "var" ) {
@@ -102,22 +116,18 @@ function parse(script, proto) {
102
116
return { kind, declarations } ;
103
117
}
104
118
105
-
106
119
function visitStatement ( node ) {
107
120
switch ( node . type ) {
108
121
case 'EmptyStatement' : {
109
122
return makeStatement ( 'EmptyStatement' , { } ) ;
110
123
}
111
124
case 'BlockStatement' : {
112
- let body = [ ] ;
113
- for ( let stmt of node . body ) {
114
- body . push ( visitStatement ( stmt ) ) ;
115
- }
116
- return makeStatement ( 'BlockStatement' , { body} ) ;
125
+ let body = visitBody ( node ) ;
126
+ return makeStatement ( 'BlockStatement' , { body } ) ;
117
127
}
118
128
case 'ExpressionStatement' : {
119
- let expr = visitExpression ( node . expression ) ;
120
- return makeStatement ( 'ExpressionStatement' , { expression : expr } ) ;
129
+ let expression = visitExpression ( node . expression ) ;
130
+ return makeStatement ( 'ExpressionStatement' , { expression } ) ;
121
131
}
122
132
case 'VariableDeclaration' : {
123
133
return makeStatement ( 'VariableDeclaration' , visitVariableDeclaration ( node ) ) ;
@@ -133,9 +143,9 @@ function parse(script, proto) {
133
143
} else if ( node . async ) {
134
144
type = 2 ; //"ASYNC";
135
145
}
136
- let parameters = node . params . map ( visitParameter ) ;
146
+ let parameters = visitParameters ( node . params ) ;
137
147
assert ( node . body . type === 'BlockStatement' , "Expected block statement as function declaration body, found " + node . body . type ) ;
138
- let body = node . body . body . map ( visitStatement ) ;
148
+ let body = visitBody ( node . body ) ;
139
149
return makeStatement ( 'FunctionDeclaration' , { name, type, parameters, body } ) ;
140
150
}
141
151
case 'ClassDeclaration' : {
@@ -182,29 +192,29 @@ function parse(script, proto) {
182
192
assert ( name === 'constructor' , "Expected name to be exactly 'constructor'" ) ;
183
193
assert ( ! isStatic , "Expected isStatic to be false" ) ;
184
194
185
- let parameters = method . params . map ( visitParameter ) ;
186
- let body = method . body . body . map ( visitStatement ) ;
195
+ let parameters = visitParameters ( method . params ) ;
196
+ let body = visitBody ( method . body ) ;
187
197
field . ctor = make ( 'ClassConstructor' , { parameters, body } ) ;
188
198
} else if ( method . kind === 'method' ) {
189
199
assert ( method . body . type === 'BlockStatement' , "Expected method.body.type to be exactly 'BlockStatement'" ) ;
190
200
191
- let parameters = method . params . map ( visitParameter ) ;
192
- let body = method . body . body . map ( visitStatement ) ;
201
+ let parameters = visitParameters ( method . params ) ;
202
+ let body = visitBody ( method . body ) ;
193
203
field . method = make ( 'ClassMethod' , { name, isStatic, parameters, body } ) ;
194
204
} else if ( method . kind === 'get' ) {
195
205
assert ( method . params . length === 0 , "Expected method.params.length to be exactly 0" ) ;
196
206
assert ( ! method . generator && ! method . async , "Expected both conditions to hold: !method.generator and !method.async" ) ;
197
207
assert ( method . body . type === 'BlockStatement' , "Expected method.body.type to be exactly 'BlockStatement'" ) ;
198
208
199
- let body = method . body . body . map ( visitStatement ) ;
209
+ let body = visitBody ( method . body ) ;
200
210
field . getter = make ( 'ClassGetter' , { name, isStatic, body } ) ;
201
211
} else if ( method . kind === 'set' ) {
202
212
assert ( method . params . length === 1 , "Expected method.params.length to be exactly 1" ) ;
203
213
assert ( ! method . generator && ! method . async , "Expected both conditions to hold: !method.generator and !method.async" ) ;
204
214
assert ( method . body . type === 'BlockStatement' , "Expected method.body.type to be exactly 'BlockStatement'" ) ;
205
215
206
216
let parameter = visitParameter ( method . params [ 0 ] ) ;
207
- let body = method . body . body . map ( visitStatement ) ;
217
+ let body = visitBody ( method . body ) ;
208
218
field . setter = make ( 'ClassSetter' , { name, isStatic, parameter, body } ) ;
209
219
} else {
210
220
throw "Unknown method kind: " + method . kind ;
@@ -299,7 +309,7 @@ function parse(script, proto) {
299
309
case 'TryStatement' : {
300
310
assert ( node . block . type === 'BlockStatement' , "Expected block statement as body of a try block" ) ;
301
311
let tryStatement = { }
302
- tryStatement . body = node . block . body . map ( visitStatement ) ;
312
+ tryStatement . body = visitBody ( node . block ) ;
303
313
assert ( node . handler !== null || node . finalizer !== null , "TryStatements require either a handler or a finalizer (or both)" )
304
314
if ( node . handler !== null ) {
305
315
assert ( node . handler . type === 'CatchClause' , "Expected catch clause as try handler" ) ;
@@ -308,13 +318,13 @@ function parse(script, proto) {
308
318
if ( node . handler . param !== null ) {
309
319
catchClause . parameter = visitParameter ( node . handler . param ) ;
310
320
}
311
- catchClause . body = node . handler . body . body . map ( visitStatement ) ;
321
+ catchClause . body = visitBody ( node . handler . body ) ;
312
322
tryStatement . catch = make ( 'CatchClause' , catchClause ) ;
313
323
}
314
324
if ( node . finalizer !== null ) {
315
325
assert ( node . finalizer . type === 'BlockStatement' , "Expected block statement as body of finally block" ) ;
316
326
let finallyClause = { } ;
317
- finallyClause . body = node . finalizer . body . map ( visitStatement ) ;
327
+ finallyClause . body = visitBody ( node . finalizer ) ;
318
328
tryStatement . finally = make ( 'FinallyClause' , finallyClause ) ;
319
329
}
320
330
return makeStatement ( 'TryStatement' , tryStatement ) ;
@@ -442,23 +452,23 @@ function parse(script, proto) {
442
452
} else if ( method . async ) {
443
453
out . type = 2 ; //"ASYNC";
444
454
}
445
- out . parameters = method . params . map ( visitParameter ) ;
446
- out . body = method . body . body . map ( visitStatement ) ;
455
+ out . parameters = visitParameters ( method . params ) ;
456
+ out . body = visitBody ( method . body ) ;
447
457
field . method = make ( 'ObjectMethod' , out ) ;
448
458
} else if ( method . kind === 'get' ) {
449
459
assert ( method . params . length === 0 , "Expected method.params.length to be exactly 0" ) ;
450
460
assert ( ! method . generator && ! method . async , "Expected both conditions to hold: !method.generator and !method.async" ) ;
451
461
assert ( method . body . type === 'BlockStatement' , "Expected method.body.type to be exactly 'BlockStatement'" ) ;
452
462
453
- out . body = method . body . body . map ( visitStatement ) ;
463
+ out . body = visitBody ( method . body ) ;
454
464
field . getter = make ( 'ObjectGetter' , out ) ;
455
465
} else if ( method . kind === 'set' ) {
456
466
assert ( method . params . length === 1 , "Expected method.params.length to be exactly 1" ) ;
457
467
assert ( ! method . generator && ! method . async , "Expected both conditions to hold: !method.generator and !method.async" ) ;
458
468
assert ( method . body . type === 'BlockStatement' , "Expected method.body.type to be exactly 'BlockStatement'" ) ;
459
469
460
470
out . parameter = visitParameter ( method . params [ 0 ] ) ;
461
- out . body = method . body . body . map ( visitStatement ) ;
471
+ out . body = visitBody ( method . body ) ;
462
472
field . setter = make ( 'ObjectSetter' , out ) ;
463
473
} else {
464
474
throw "Unknown method kind: " + method . kind ;
@@ -489,9 +499,9 @@ function parse(script, proto) {
489
499
} else if ( node . async ) {
490
500
type = 2 ; //"ASYNC";
491
501
}
492
- let parameters = node . params . map ( visitParameter ) ;
502
+ let parameters = visitParameters ( node . params ) ;
493
503
assert ( node . body . type === 'BlockStatement' , "Expected block statement as function expression body, found " + node . body . type ) ;
494
- let body = node . body . body . map ( visitStatement ) ;
504
+ let body = visitBody ( node . body ) ;
495
505
return makeExpression ( 'FunctionExpression' , { type, parameters, body } ) ;
496
506
}
497
507
case 'ArrowFunctionExpression' : {
@@ -501,7 +511,7 @@ function parse(script, proto) {
501
511
if ( node . async ) {
502
512
type = 2 ; //"ASYNC";
503
513
}
504
- let parameters = node . params . map ( visitParameter ) ;
514
+ let parameters = visitParameters ( node . params ) ;
505
515
let out = { type, parameters } ;
506
516
if ( node . body . type === 'BlockStatement' ) {
507
517
out . block = visitStatement ( node . body ) ;
@@ -621,7 +631,7 @@ protobuf.load(astProtobufDefinitionPath, function(err, root) {
621
631
622
632
// Uncomment this to print the AST to stdout (will be very verbose).
623
633
//console.log(JSON.stringify(ast, null, 2));
624
-
634
+
625
635
const AST = root . lookupType ( 'compiler.protobuf.AST' ) ;
626
636
let buffer = AST . encode ( ast ) . finish ( ) ;
627
637
0 commit comments