264 |
FUNCTION_GETTER_OR_SETTER |
FUNCTION_GETTER_OR_SETTER |
265 |
}; |
}; |
266 |
|
|
267 |
|
static void output_for_in(JSParseNode * node, Stream * f) { |
268 |
|
assert(node->pn_type == TOK_FOR); |
269 |
|
assert(node->pn_arity == PN_BINARY); |
270 |
|
Stream_write_string(f, "for "); |
271 |
|
if (node->pn_iflags & JSITER_FOREACH) { |
272 |
|
Stream_write_string(f, "each "); |
273 |
|
} |
274 |
|
Stream_write_char(f, '('); |
275 |
|
instrument_expression(node->pn_left, f); |
276 |
|
Stream_write_char(f, ')'); |
277 |
|
} |
278 |
|
|
279 |
static void instrument_function(JSParseNode * node, Stream * f, int indent, enum FunctionType type) { |
static void instrument_function(JSParseNode * node, Stream * f, int indent, enum FunctionType type) { |
280 |
assert(node->pn_type == TOK_FUNCTION); |
assert(node->pn_type == TOK_FUNCTION); |
281 |
assert(node->pn_arity == PN_FUNC); |
assert(node->pn_arity == PN_FUNC); |
332 |
} |
} |
333 |
|
|
334 |
static void instrument_function_call(JSParseNode * node, Stream * f) { |
static void instrument_function_call(JSParseNode * node, Stream * f) { |
335 |
instrument_expression(node->pn_head, f); |
if (node->pn_head->pn_type == TOK_FUNCTION) { |
336 |
Stream_write_char(f, '('); |
/* it's a generator expression */ |
337 |
for (struct JSParseNode * p = node->pn_head->pn_next; p != NULL; p = p->pn_next) { |
JSParseNode * function_node = node->pn_head; |
338 |
if (p != node->pn_head->pn_next) { |
JSParseNode * lexical_scope_node = function_node->pn_body; |
339 |
Stream_write_string(f, ", "); |
assert(lexical_scope_node->pn_type == TOK_LEXICALSCOPE); |
340 |
|
assert(lexical_scope_node->pn_arity == PN_NAME); |
341 |
|
JSParseNode * for_node = lexical_scope_node->pn_body; |
342 |
|
assert(for_node->pn_type == TOK_FOR); |
343 |
|
assert(for_node->pn_arity == PN_BINARY); |
344 |
|
JSParseNode * if_node = NULL; |
345 |
|
JSParseNode * semi_node; |
346 |
|
switch (for_node->pn_right->pn_type) { |
347 |
|
case TOK_SEMI: |
348 |
|
semi_node = for_node->pn_right; |
349 |
|
break; |
350 |
|
case TOK_IF: |
351 |
|
if_node = for_node->pn_right; |
352 |
|
assert(if_node->pn_arity == PN_TERNARY); |
353 |
|
semi_node = if_node->pn_kid2; |
354 |
|
assert(semi_node->pn_type == TOK_SEMI); |
355 |
|
break; |
356 |
|
default: |
357 |
|
abort(); |
358 |
|
break; |
359 |
} |
} |
360 |
instrument_expression(p, f); |
assert(semi_node->pn_arity == PN_UNARY); |
361 |
|
JSParseNode * yield_node = semi_node->pn_kid; |
362 |
|
assert(yield_node->pn_type == TOK_YIELD); |
363 |
|
Stream_write_char(f, '('); |
364 |
|
instrument_expression(yield_node->pn_kid, f); |
365 |
|
Stream_write_char(f, ' '); |
366 |
|
output_for_in(for_node, f); |
367 |
|
if (if_node) { |
368 |
|
Stream_write_string(f, " if ("); |
369 |
|
instrument_expression(if_node->pn_kid1, f); |
370 |
|
Stream_write_char(f, ')'); |
371 |
|
} |
372 |
|
Stream_write_char(f, ')'); |
373 |
|
} |
374 |
|
else { |
375 |
|
instrument_expression(node->pn_head, f); |
376 |
|
Stream_write_char(f, '('); |
377 |
|
for (struct JSParseNode * p = node->pn_head->pn_next; p != NULL; p = p->pn_next) { |
378 |
|
if (p != node->pn_head->pn_next) { |
379 |
|
Stream_write_string(f, ", "); |
380 |
|
} |
381 |
|
instrument_expression(p, f); |
382 |
|
} |
383 |
|
Stream_write_char(f, ')'); |
384 |
} |
} |
|
Stream_write_char(f, ')'); |
|
385 |
} |
} |
386 |
|
|
387 |
static void instrument_declarations(JSParseNode * list, Stream * f) { |
static void instrument_declarations(JSParseNode * list, Stream * f) { |
412 |
} |
} |
413 |
} |
} |
414 |
|
|
|
static void output_for_in(JSParseNode * node, Stream * f) { |
|
|
assert(node->pn_type == TOK_FOR); |
|
|
assert(node->pn_arity == PN_BINARY); |
|
|
Stream_write_string(f, "for "); |
|
|
if (node->pn_iflags & JSITER_FOREACH) { |
|
|
Stream_write_string(f, "each "); |
|
|
} |
|
|
Stream_write_char(f, '('); |
|
|
instrument_expression(node->pn_left, f); |
|
|
Stream_write_char(f, ')'); |
|
|
} |
|
|
|
|
415 |
/* |
/* |
416 |
See <Expressions> in jsparse.h. |
See <Expressions> in jsparse.h. |
417 |
TOK_FUNCTION is handled as a statement and as an expression. |
TOK_FUNCTION is handled as a statement and as an expression. |
752 |
JSParseNode * for_node = block_node->pn_expr; |
JSParseNode * for_node = block_node->pn_expr; |
753 |
assert(for_node->pn_type == TOK_FOR); |
assert(for_node->pn_type == TOK_FOR); |
754 |
assert(for_node->pn_arity == PN_BINARY); |
assert(for_node->pn_arity == PN_BINARY); |
|
JSParseNode * push_node; |
|
755 |
JSParseNode * if_node = NULL; |
JSParseNode * if_node = NULL; |
756 |
|
JSParseNode * push_node; |
757 |
switch (for_node->pn_right->pn_type) { |
switch (for_node->pn_right->pn_type) { |
758 |
case TOK_ARRAYPUSH: |
case TOK_ARRAYPUSH: |
759 |
push_node = for_node->pn_right; |
push_node = for_node->pn_right; |