28 |
#include <jsapi.h> |
#include <jsapi.h> |
29 |
#include <jsarena.h> |
#include <jsarena.h> |
30 |
#include <jsatom.h> |
#include <jsatom.h> |
31 |
|
#include <jsemit.h> |
32 |
#include <jsexn.h> |
#include <jsexn.h> |
33 |
#include <jsfun.h> |
#include <jsfun.h> |
34 |
#include <jsinterp.h> |
#include <jsinterp.h> |
333 |
} |
} |
334 |
|
|
335 |
static void instrument_function_call(JSParseNode * node, Stream * f) { |
static void instrument_function_call(JSParseNode * node, Stream * f) { |
336 |
if (node->pn_head->pn_type == TOK_FUNCTION) { |
JSParseNode * function_node = node->pn_head; |
337 |
/* it's a generator expression */ |
if (function_node->pn_type == TOK_FUNCTION) { |
338 |
JSParseNode * function_node = node->pn_head; |
JSObject * object = function_node->pn_funpob->object; |
339 |
JSParseNode * lexical_scope_node = function_node->pn_body; |
assert(JS_ObjectIsFunction(context, object)); |
340 |
assert(lexical_scope_node->pn_type == TOK_LEXICALSCOPE); |
JSFunction * function = (JSFunction *) JS_GetPrivate(context, object); |
341 |
assert(lexical_scope_node->pn_arity == PN_NAME); |
assert(function); |
342 |
JSParseNode * for_node = lexical_scope_node->pn_body; |
assert(object == &function->object); |
343 |
assert(for_node->pn_type == TOK_FOR); |
|
344 |
assert(for_node->pn_arity == PN_BINARY); |
if (function_node->pn_flags & TCF_GENEXP_LAMBDA) { |
345 |
JSParseNode * if_node = NULL; |
/* it's a generator expression */ |
346 |
JSParseNode * semi_node; |
JSParseNode * lexical_scope_node = function_node->pn_body; |
347 |
switch (for_node->pn_right->pn_type) { |
assert(lexical_scope_node->pn_type == TOK_LEXICALSCOPE); |
348 |
case TOK_SEMI: |
assert(lexical_scope_node->pn_arity == PN_NAME); |
349 |
semi_node = for_node->pn_right; |
JSParseNode * for_node = lexical_scope_node->pn_body; |
350 |
break; |
assert(for_node->pn_type == TOK_FOR); |
351 |
case TOK_IF: |
assert(for_node->pn_arity == PN_BINARY); |
352 |
if_node = for_node->pn_right; |
JSParseNode * if_node = NULL; |
353 |
assert(if_node->pn_arity == PN_TERNARY); |
JSParseNode * semi_node; |
354 |
semi_node = if_node->pn_kid2; |
switch (for_node->pn_right->pn_type) { |
355 |
assert(semi_node->pn_type == TOK_SEMI); |
case TOK_SEMI: |
356 |
break; |
semi_node = for_node->pn_right; |
357 |
default: |
break; |
358 |
abort(); |
case TOK_IF: |
359 |
break; |
if_node = for_node->pn_right; |
360 |
|
assert(if_node->pn_arity == PN_TERNARY); |
361 |
|
semi_node = if_node->pn_kid2; |
362 |
|
assert(semi_node->pn_type == TOK_SEMI); |
363 |
|
break; |
364 |
|
default: |
365 |
|
abort(); |
366 |
|
break; |
367 |
|
} |
368 |
|
assert(semi_node->pn_arity == PN_UNARY); |
369 |
|
JSParseNode * yield_node = semi_node->pn_kid; |
370 |
|
assert(yield_node->pn_type == TOK_YIELD); |
371 |
|
Stream_write_char(f, '('); |
372 |
|
instrument_expression(yield_node->pn_kid, f); |
373 |
|
Stream_write_char(f, ' '); |
374 |
|
output_for_in(for_node, f); |
375 |
|
if (if_node) { |
376 |
|
Stream_write_string(f, " if ("); |
377 |
|
instrument_expression(if_node->pn_kid1, f); |
378 |
|
Stream_write_char(f, ')'); |
379 |
|
} |
380 |
|
Stream_write_char(f, ')'); |
381 |
|
return; |
382 |
} |
} |
383 |
assert(semi_node->pn_arity == PN_UNARY); |
else { |
384 |
JSParseNode * yield_node = semi_node->pn_kid; |
Stream_write_char(f, '('); |
385 |
assert(yield_node->pn_type == TOK_YIELD); |
instrument_expression(function_node, f); |
|
Stream_write_char(f, '('); |
|
|
instrument_expression(yield_node->pn_kid, f); |
|
|
Stream_write_char(f, ' '); |
|
|
output_for_in(for_node, f); |
|
|
if (if_node) { |
|
|
Stream_write_string(f, " if ("); |
|
|
instrument_expression(if_node->pn_kid1, f); |
|
386 |
Stream_write_char(f, ')'); |
Stream_write_char(f, ')'); |
387 |
} |
} |
|
Stream_write_char(f, ')'); |
|
388 |
} |
} |
389 |
else { |
else { |
390 |
instrument_expression(node->pn_head, f); |
instrument_expression(function_node, f); |
391 |
Stream_write_char(f, '('); |
} |
392 |
for (struct JSParseNode * p = node->pn_head->pn_next; p != NULL; p = p->pn_next) { |
Stream_write_char(f, '('); |
393 |
if (p != node->pn_head->pn_next) { |
for (struct JSParseNode * p = function_node->pn_next; p != NULL; p = p->pn_next) { |
394 |
Stream_write_string(f, ", "); |
if (p != node->pn_head->pn_next) { |
395 |
} |
Stream_write_string(f, ", "); |
|
instrument_expression(p, f); |
|
396 |
} |
} |
397 |
Stream_write_char(f, ')'); |
instrument_expression(p, f); |
398 |
} |
} |
399 |
|
Stream_write_char(f, ')'); |
400 |
} |
} |
401 |
|
|
402 |
static void instrument_declarations(JSParseNode * list, Stream * f) { |
static void instrument_declarations(JSParseNode * list, Stream * f) { |