jscompile.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428
  1. #include "jsi.h"
  2. #define cexp jsC_cexp /* collision with math.h */
  3. #define JF js_State *J, js_Function *F
  4. JS_NORETURN void jsC_error(js_State *J, js_Ast *node, const char *fmt, ...) JS_PRINTFLIKE(3,4);
  5. static void cfunbody(JF, js_Ast *name, js_Ast *params, js_Ast *body, int is_fun_exp);
  6. static void cexp(JF, js_Ast *exp);
  7. static void cstmlist(JF, js_Ast *list);
  8. static void cstm(JF, js_Ast *stm);
  9. void jsC_error(js_State *J, js_Ast *node, const char *fmt, ...)
  10. {
  11. va_list ap;
  12. char buf[512];
  13. char msgbuf[256];
  14. va_start(ap, fmt);
  15. vsnprintf(msgbuf, 256, fmt, ap);
  16. va_end(ap);
  17. snprintf(buf, 256, "%s:%d: ", J->filename, node->line);
  18. strcat(buf, msgbuf);
  19. js_newsyntaxerror(J, buf);
  20. js_throw(J);
  21. }
  22. static const char *futurewords[] = {
  23. "class", "const", "enum", "export", "extends", "import", "super",
  24. };
  25. static const char *strictfuturewords[] = {
  26. "implements", "interface", "let", "package", "private", "protected",
  27. "public", "static", "yield",
  28. };
  29. static void checkfutureword(JF, js_Ast *exp)
  30. {
  31. if (jsY_findword(exp->string, futurewords, nelem(futurewords)) >= 0)
  32. jsC_error(J, exp, "'%s' is a future reserved word", exp->string);
  33. if (F->strict) {
  34. if (jsY_findword(exp->string, strictfuturewords, nelem(strictfuturewords)) >= 0)
  35. jsC_error(J, exp, "'%s' is a strict mode future reserved word", exp->string);
  36. }
  37. }
  38. static js_Function *newfun(js_State *J, int line, js_Ast *name, js_Ast *params, js_Ast *body, int script, int default_strict, int is_fun_exp)
  39. {
  40. js_Function *F = js_malloc(J, sizeof *F);
  41. memset(F, 0, sizeof *F);
  42. F->gcmark = 0;
  43. F->gcnext = J->gcfun;
  44. J->gcfun = F;
  45. ++J->gccounter;
  46. F->filename = js_intern(J, J->filename);
  47. F->line = line;
  48. F->script = script;
  49. F->strict = default_strict;
  50. F->name = name ? name->string : "";
  51. cfunbody(J, F, name, params, body, is_fun_exp);
  52. return F;
  53. }
  54. /* Emit opcodes, constants and jumps */
  55. static void emitraw(JF, int value)
  56. {
  57. if (value != (js_Instruction)value)
  58. js_syntaxerror(J, "integer overflow in instruction coding");
  59. if (F->codelen >= F->codecap) {
  60. F->codecap = F->codecap ? F->codecap * 2 : 64;
  61. F->code = js_realloc(J, F->code, F->codecap * sizeof *F->code);
  62. }
  63. F->code[F->codelen++] = value;
  64. }
  65. static void emit(JF, int value)
  66. {
  67. emitraw(J, F, F->lastline);
  68. emitraw(J, F, value);
  69. }
  70. static void emitarg(JF, int value)
  71. {
  72. emitraw(J, F, value);
  73. }
  74. static void emitline(JF, js_Ast *node)
  75. {
  76. F->lastline = node->line;
  77. }
  78. static int addfunction(JF, js_Function *value)
  79. {
  80. if (F->funlen >= F->funcap) {
  81. F->funcap = F->funcap ? F->funcap * 2 : 16;
  82. F->funtab = js_realloc(J, F->funtab, F->funcap * sizeof *F->funtab);
  83. }
  84. F->funtab[F->funlen] = value;
  85. return F->funlen++;
  86. }
  87. static int addlocal(JF, js_Ast *ident, int reuse)
  88. {
  89. const char *name = ident->string;
  90. if (F->strict) {
  91. if (!strcmp(name, "arguments"))
  92. jsC_error(J, ident, "redefining 'arguments' is not allowed in strict mode");
  93. if (!strcmp(name, "eval"))
  94. jsC_error(J, ident, "redefining 'eval' is not allowed in strict mode");
  95. } else {
  96. if (!strcmp(name, "eval"))
  97. js_evalerror(J, "%s:%d: invalid use of 'eval'", J->filename, ident->line);
  98. }
  99. if (reuse || F->strict) {
  100. int i;
  101. for (i = 0; i < F->varlen; ++i) {
  102. if (!strcmp(F->vartab[i], name)) {
  103. if (reuse)
  104. return i+1;
  105. if (F->strict)
  106. jsC_error(J, ident, "duplicate formal parameter '%s'", name);
  107. }
  108. }
  109. }
  110. if (F->varlen >= F->varcap) {
  111. F->varcap = F->varcap ? F->varcap * 2 : 16;
  112. F->vartab = js_realloc(J, F->vartab, F->varcap * sizeof *F->vartab);
  113. }
  114. F->vartab[F->varlen] = name;
  115. return ++F->varlen;
  116. }
  117. static int findlocal(JF, const char *name)
  118. {
  119. int i;
  120. for (i = F->varlen; i > 0; --i)
  121. if (!strcmp(F->vartab[i-1], name))
  122. return i;
  123. return -1;
  124. }
  125. static void emitfunction(JF, js_Function *fun)
  126. {
  127. F->lightweight = 0;
  128. emit(J, F, OP_CLOSURE);
  129. emitarg(J, F, addfunction(J, F, fun));
  130. }
  131. static void emitnumber(JF, double num)
  132. {
  133. if (num == 0) {
  134. emit(J, F, OP_INTEGER);
  135. emitarg(J, F, 32768);
  136. if (signbit(num))
  137. emit(J, F, OP_NEG);
  138. } else if (num >= SHRT_MIN && num <= SHRT_MAX && num == (int)num) {
  139. emit(J, F, OP_INTEGER);
  140. emitarg(J, F, num + 32768);
  141. } else {
  142. #define N (sizeof(num) / sizeof(js_Instruction))
  143. js_Instruction x[N];
  144. size_t i;
  145. emit(J, F, OP_NUMBER);
  146. memcpy(x, &num, sizeof(num));
  147. for (i = 0; i < N; ++i)
  148. emitarg(J, F, x[i]);
  149. #undef N
  150. }
  151. }
  152. static void emitstring(JF, int opcode, const char *str)
  153. {
  154. #define N (sizeof(str) / sizeof(js_Instruction))
  155. js_Instruction x[N];
  156. size_t i;
  157. emit(J, F, opcode);
  158. memcpy(x, &str, sizeof(str));
  159. for (i = 0; i < N; ++i)
  160. emitarg(J, F, x[i]);
  161. #undef N
  162. }
  163. static void emitlocal(JF, int oploc, int opvar, js_Ast *ident)
  164. {
  165. int is_arguments = !strcmp(ident->string, "arguments");
  166. int is_eval = !strcmp(ident->string, "eval");
  167. int i;
  168. if (is_arguments) {
  169. F->lightweight = 0;
  170. F->arguments = 1;
  171. }
  172. checkfutureword(J, F, ident);
  173. if (F->strict && oploc == OP_SETLOCAL) {
  174. if (is_arguments)
  175. jsC_error(J, ident, "'arguments' is read-only in strict mode");
  176. if (is_eval)
  177. jsC_error(J, ident, "'eval' is read-only in strict mode");
  178. }
  179. if (is_eval)
  180. js_evalerror(J, "%s:%d: invalid use of 'eval'", J->filename, ident->line);
  181. i = findlocal(J, F, ident->string);
  182. if (i < 0) {
  183. emitstring(J, F, opvar, ident->string);
  184. } else {
  185. emit(J, F, oploc);
  186. emitarg(J, F, i);
  187. }
  188. }
  189. static int here(JF)
  190. {
  191. return F->codelen;
  192. }
  193. static int emitjump(JF, int opcode)
  194. {
  195. int inst;
  196. emit(J, F, opcode);
  197. inst = F->codelen;
  198. emitarg(J, F, 0);
  199. return inst;
  200. }
  201. static void emitjumpto(JF, int opcode, int dest)
  202. {
  203. emit(J, F, opcode);
  204. if (dest != (js_Instruction)dest)
  205. js_syntaxerror(J, "jump address integer overflow");
  206. emitarg(J, F, dest);
  207. }
  208. static void labelto(JF, int inst, int addr)
  209. {
  210. if (addr != (js_Instruction)addr)
  211. js_syntaxerror(J, "jump address integer overflow");
  212. F->code[inst] = addr;
  213. }
  214. static void label(JF, int inst)
  215. {
  216. labelto(J, F, inst, F->codelen);
  217. }
  218. /* Expressions */
  219. static void ctypeof(JF, js_Ast *exp)
  220. {
  221. if (exp->a->type == EXP_IDENTIFIER) {
  222. emitline(J, F, exp->a);
  223. emitlocal(J, F, OP_GETLOCAL, OP_HASVAR, exp->a);
  224. } else {
  225. cexp(J, F, exp->a);
  226. }
  227. emitline(J, F, exp);
  228. emit(J, F, OP_TYPEOF);
  229. }
  230. static void cunary(JF, js_Ast *exp, int opcode)
  231. {
  232. cexp(J, F, exp->a);
  233. emitline(J, F, exp);
  234. emit(J, F, opcode);
  235. }
  236. static void cbinary(JF, js_Ast *exp, int opcode)
  237. {
  238. cexp(J, F, exp->a);
  239. cexp(J, F, exp->b);
  240. emitline(J, F, exp);
  241. emit(J, F, opcode);
  242. }
  243. static void carray(JF, js_Ast *list)
  244. {
  245. while (list) {
  246. emitline(J, F, list->a);
  247. if (list->a->type == EXP_ELISION) {
  248. emit(J, F, OP_SKIPARRAY);
  249. } else {
  250. cexp(J, F, list->a);
  251. emit(J, F, OP_INITARRAY);
  252. }
  253. list = list->b;
  254. }
  255. }
  256. static void checkdup(JF, js_Ast *list, js_Ast *end)
  257. {
  258. char nbuf[32], sbuf[32];
  259. const char *needle, *straw;
  260. if (end->a->type == EXP_NUMBER)
  261. needle = jsV_numbertostring(J, nbuf, end->a->number);
  262. else
  263. needle = end->a->string;
  264. while (list->a != end) {
  265. if (list->a->type == end->type) {
  266. js_Ast *prop = list->a->a;
  267. if (prop->type == EXP_NUMBER)
  268. straw = jsV_numbertostring(J, sbuf, prop->number);
  269. else
  270. straw = prop->string;
  271. if (!strcmp(needle, straw))
  272. jsC_error(J, list, "duplicate property '%s' in object literal", needle);
  273. }
  274. list = list->b;
  275. }
  276. }
  277. static void cobject(JF, js_Ast *list)
  278. {
  279. js_Ast *head = list;
  280. while (list) {
  281. js_Ast *kv = list->a;
  282. js_Ast *prop = kv->a;
  283. if (prop->type == AST_IDENTIFIER || prop->type == EXP_STRING) {
  284. emitline(J, F, prop);
  285. emitstring(J, F, OP_STRING, prop->string);
  286. } else if (prop->type == EXP_NUMBER) {
  287. emitline(J, F, prop);
  288. emitnumber(J, F, prop->number);
  289. } else {
  290. jsC_error(J, prop, "invalid property name in object initializer");
  291. }
  292. if (F->strict)
  293. checkdup(J, F, head, kv);
  294. switch (kv->type) {
  295. default: /* impossible */ break;
  296. case EXP_PROP_VAL:
  297. cexp(J, F, kv->b);
  298. emitline(J, F, kv);
  299. emit(J, F, OP_INITPROP);
  300. break;
  301. case EXP_PROP_GET:
  302. emitfunction(J, F, newfun(J, prop->line, NULL, NULL, kv->c, 0, F->strict, 1));
  303. emitline(J, F, kv);
  304. emit(J, F, OP_INITGETTER);
  305. break;
  306. case EXP_PROP_SET:
  307. emitfunction(J, F, newfun(J, prop->line, NULL, kv->b, kv->c, 0, F->strict, 1));
  308. emitline(J, F, kv);
  309. emit(J, F, OP_INITSETTER);
  310. break;
  311. }
  312. list = list->b;
  313. }
  314. }
  315. static int cargs(JF, js_Ast *list)
  316. {
  317. int n = 0;
  318. while (list) {
  319. cexp(J, F, list->a);
  320. list = list->b;
  321. ++n;
  322. }
  323. return n;
  324. }
  325. static void cassign(JF, js_Ast *exp)
  326. {
  327. js_Ast *lhs = exp->a;
  328. js_Ast *rhs = exp->b;
  329. switch (lhs->type) {
  330. case EXP_IDENTIFIER:
  331. cexp(J, F, rhs);
  332. emitline(J, F, exp);
  333. emitlocal(J, F, OP_SETLOCAL, OP_SETVAR, lhs);
  334. break;
  335. case EXP_INDEX:
  336. cexp(J, F, lhs->a);
  337. cexp(J, F, lhs->b);
  338. cexp(J, F, rhs);
  339. emitline(J, F, exp);
  340. emit(J, F, OP_SETPROP);
  341. break;
  342. case EXP_MEMBER:
  343. cexp(J, F, lhs->a);
  344. cexp(J, F, rhs);
  345. emitline(J, F, exp);
  346. emitstring(J, F, OP_SETPROP_S, lhs->b->string);
  347. break;
  348. default:
  349. jsC_error(J, lhs, "invalid l-value in assignment");
  350. }
  351. }
  352. static void cassignforin(JF, js_Ast *stm)
  353. {
  354. js_Ast *lhs = stm->a;
  355. if (stm->type == STM_FOR_IN_VAR) {
  356. if (lhs->b)
  357. jsC_error(J, lhs->b, "more than one loop variable in for-in statement");
  358. emitline(J, F, lhs->a);
  359. emitlocal(J, F, OP_SETLOCAL, OP_SETVAR, lhs->a->a); /* list(var-init(ident)) */
  360. emit(J, F, OP_POP);
  361. return;
  362. }
  363. switch (lhs->type) {
  364. case EXP_IDENTIFIER:
  365. emitline(J, F, lhs);
  366. emitlocal(J, F, OP_SETLOCAL, OP_SETVAR, lhs);
  367. emit(J, F, OP_POP);
  368. break;
  369. case EXP_INDEX:
  370. cexp(J, F, lhs->a);
  371. cexp(J, F, lhs->b);
  372. emitline(J, F, lhs);
  373. emit(J, F, OP_ROT3);
  374. emit(J, F, OP_SETPROP);
  375. emit(J, F, OP_POP);
  376. break;
  377. case EXP_MEMBER:
  378. cexp(J, F, lhs->a);
  379. emitline(J, F, lhs);
  380. emit(J, F, OP_ROT2);
  381. emitstring(J, F, OP_SETPROP_S, lhs->b->string);
  382. emit(J, F, OP_POP);
  383. break;
  384. default:
  385. jsC_error(J, lhs, "invalid l-value in for-in loop assignment");
  386. }
  387. }
  388. static void cassignop1(JF, js_Ast *lhs)
  389. {
  390. switch (lhs->type) {
  391. case EXP_IDENTIFIER:
  392. emitline(J, F, lhs);
  393. emitlocal(J, F, OP_GETLOCAL, OP_GETVAR, lhs);
  394. break;
  395. case EXP_INDEX:
  396. cexp(J, F, lhs->a);
  397. cexp(J, F, lhs->b);
  398. emitline(J, F, lhs);
  399. emit(J, F, OP_DUP2);
  400. emit(J, F, OP_GETPROP);
  401. break;
  402. case EXP_MEMBER:
  403. cexp(J, F, lhs->a);
  404. emitline(J, F, lhs);
  405. emit(J, F, OP_DUP);
  406. emitstring(J, F, OP_GETPROP_S, lhs->b->string);
  407. break;
  408. default:
  409. jsC_error(J, lhs, "invalid l-value in assignment");
  410. }
  411. }
  412. static void cassignop2(JF, js_Ast *lhs, int postfix)
  413. {
  414. switch (lhs->type) {
  415. case EXP_IDENTIFIER:
  416. emitline(J, F, lhs);
  417. if (postfix) emit(J, F, OP_ROT2);
  418. emitlocal(J, F, OP_SETLOCAL, OP_SETVAR, lhs);
  419. break;
  420. case EXP_INDEX:
  421. emitline(J, F, lhs);
  422. if (postfix) emit(J, F, OP_ROT4);
  423. emit(J, F, OP_SETPROP);
  424. break;
  425. case EXP_MEMBER:
  426. emitline(J, F, lhs);
  427. if (postfix) emit(J, F, OP_ROT3);
  428. emitstring(J, F, OP_SETPROP_S, lhs->b->string);
  429. break;
  430. default:
  431. jsC_error(J, lhs, "invalid l-value in assignment");
  432. }
  433. }
  434. static void cassignop(JF, js_Ast *exp, int opcode)
  435. {
  436. js_Ast *lhs = exp->a;
  437. js_Ast *rhs = exp->b;
  438. cassignop1(J, F, lhs);
  439. cexp(J, F, rhs);
  440. emitline(J, F, exp);
  441. emit(J, F, opcode);
  442. cassignop2(J, F, lhs, 0);
  443. }
  444. static void cdelete(JF, js_Ast *exp)
  445. {
  446. js_Ast *arg = exp->a;
  447. switch (arg->type) {
  448. case EXP_IDENTIFIER:
  449. if (F->strict)
  450. jsC_error(J, exp, "delete on an unqualified name is not allowed in strict mode");
  451. emitline(J, F, exp);
  452. emitlocal(J, F, OP_DELLOCAL, OP_DELVAR, arg);
  453. break;
  454. case EXP_INDEX:
  455. cexp(J, F, arg->a);
  456. cexp(J, F, arg->b);
  457. emitline(J, F, exp);
  458. emit(J, F, OP_DELPROP);
  459. break;
  460. case EXP_MEMBER:
  461. cexp(J, F, arg->a);
  462. emitline(J, F, exp);
  463. emitstring(J, F, OP_DELPROP_S, arg->b->string);
  464. break;
  465. default:
  466. jsC_error(J, exp, "invalid l-value in delete expression");
  467. }
  468. }
  469. static void ceval(JF, js_Ast *fun, js_Ast *args)
  470. {
  471. int n = cargs(J, F, args);
  472. F->lightweight = 0;
  473. F->arguments = 1;
  474. if (n == 0)
  475. emit(J, F, OP_UNDEF);
  476. else while (n-- > 1)
  477. emit(J, F, OP_POP);
  478. emit(J, F, OP_EVAL);
  479. }
  480. static void ccall(JF, js_Ast *fun, js_Ast *args)
  481. {
  482. int n;
  483. switch (fun->type) {
  484. case EXP_INDEX:
  485. cexp(J, F, fun->a);
  486. emit(J, F, OP_DUP);
  487. cexp(J, F, fun->b);
  488. emit(J, F, OP_GETPROP);
  489. emit(J, F, OP_ROT2);
  490. break;
  491. case EXP_MEMBER:
  492. cexp(J, F, fun->a);
  493. emit(J, F, OP_DUP);
  494. emitstring(J, F, OP_GETPROP_S, fun->b->string);
  495. emit(J, F, OP_ROT2);
  496. break;
  497. case EXP_IDENTIFIER:
  498. if (!strcmp(fun->string, "eval")) {
  499. ceval(J, F, fun, args);
  500. return;
  501. }
  502. /* fallthrough */
  503. default:
  504. cexp(J, F, fun);
  505. emit(J, F, OP_UNDEF);
  506. break;
  507. }
  508. n = cargs(J, F, args);
  509. emit(J, F, OP_CALL);
  510. emitarg(J, F, n);
  511. }
  512. static void cexp(JF, js_Ast *exp)
  513. {
  514. int then, end;
  515. int n;
  516. switch (exp->type) {
  517. case EXP_STRING:
  518. emitline(J, F, exp);
  519. emitstring(J, F, OP_STRING, exp->string);
  520. break;
  521. case EXP_NUMBER:
  522. emitline(J, F, exp);
  523. emitnumber(J, F, exp->number);
  524. break;
  525. case EXP_ELISION:
  526. break;
  527. case EXP_NULL:
  528. emitline(J, F, exp);
  529. emit(J, F, OP_NULL);
  530. break;
  531. case EXP_TRUE:
  532. emitline(J, F, exp);
  533. emit(J, F, OP_TRUE);
  534. break;
  535. case EXP_FALSE:
  536. emitline(J, F, exp);
  537. emit(J, F, OP_FALSE);
  538. break;
  539. case EXP_THIS:
  540. emitline(J, F, exp);
  541. emit(J, F, OP_THIS);
  542. break;
  543. case EXP_REGEXP:
  544. emitline(J, F, exp);
  545. emitstring(J, F, OP_NEWREGEXP, exp->string);
  546. emitarg(J, F, exp->number);
  547. break;
  548. case EXP_OBJECT:
  549. emitline(J, F, exp);
  550. emit(J, F, OP_NEWOBJECT);
  551. cobject(J, F, exp->a);
  552. break;
  553. case EXP_ARRAY:
  554. emitline(J, F, exp);
  555. emit(J, F, OP_NEWARRAY);
  556. carray(J, F, exp->a);
  557. break;
  558. case EXP_FUN:
  559. emitline(J, F, exp);
  560. emitfunction(J, F, newfun(J, exp->line, exp->a, exp->b, exp->c, 0, F->strict, 1));
  561. break;
  562. case EXP_IDENTIFIER:
  563. emitline(J, F, exp);
  564. emitlocal(J, F, OP_GETLOCAL, OP_GETVAR, exp);
  565. break;
  566. case EXP_INDEX:
  567. cexp(J, F, exp->a);
  568. cexp(J, F, exp->b);
  569. emitline(J, F, exp);
  570. emit(J, F, OP_GETPROP);
  571. break;
  572. case EXP_MEMBER:
  573. cexp(J, F, exp->a);
  574. emitline(J, F, exp);
  575. emitstring(J, F, OP_GETPROP_S, exp->b->string);
  576. break;
  577. case EXP_CALL:
  578. ccall(J, F, exp->a, exp->b);
  579. break;
  580. case EXP_NEW:
  581. cexp(J, F, exp->a);
  582. n = cargs(J, F, exp->b);
  583. emitline(J, F, exp);
  584. emit(J, F, OP_NEW);
  585. emitarg(J, F, n);
  586. break;
  587. case EXP_DELETE:
  588. cdelete(J, F, exp);
  589. break;
  590. case EXP_PREINC:
  591. cassignop1(J, F, exp->a);
  592. emitline(J, F, exp);
  593. emit(J, F, OP_INC);
  594. cassignop2(J, F, exp->a, 0);
  595. break;
  596. case EXP_PREDEC:
  597. cassignop1(J, F, exp->a);
  598. emitline(J, F, exp);
  599. emit(J, F, OP_DEC);
  600. cassignop2(J, F, exp->a, 0);
  601. break;
  602. case EXP_POSTINC:
  603. cassignop1(J, F, exp->a);
  604. emitline(J, F, exp);
  605. emit(J, F, OP_POSTINC);
  606. cassignop2(J, F, exp->a, 1);
  607. emit(J, F, OP_POP);
  608. break;
  609. case EXP_POSTDEC:
  610. cassignop1(J, F, exp->a);
  611. emitline(J, F, exp);
  612. emit(J, F, OP_POSTDEC);
  613. cassignop2(J, F, exp->a, 1);
  614. emit(J, F, OP_POP);
  615. break;
  616. case EXP_VOID:
  617. cexp(J, F, exp->a);
  618. emitline(J, F, exp);
  619. emit(J, F, OP_POP);
  620. emit(J, F, OP_UNDEF);
  621. break;
  622. case EXP_TYPEOF: ctypeof(J, F, exp); break;
  623. case EXP_POS: cunary(J, F, exp, OP_POS); break;
  624. case EXP_NEG: cunary(J, F, exp, OP_NEG); break;
  625. case EXP_BITNOT: cunary(J, F, exp, OP_BITNOT); break;
  626. case EXP_LOGNOT: cunary(J, F, exp, OP_LOGNOT); break;
  627. case EXP_BITOR: cbinary(J, F, exp, OP_BITOR); break;
  628. case EXP_BITXOR: cbinary(J, F, exp, OP_BITXOR); break;
  629. case EXP_BITAND: cbinary(J, F, exp, OP_BITAND); break;
  630. case EXP_EQ: cbinary(J, F, exp, OP_EQ); break;
  631. case EXP_NE: cbinary(J, F, exp, OP_NE); break;
  632. case EXP_STRICTEQ: cbinary(J, F, exp, OP_STRICTEQ); break;
  633. case EXP_STRICTNE: cbinary(J, F, exp, OP_STRICTNE); break;
  634. case EXP_LT: cbinary(J, F, exp, OP_LT); break;
  635. case EXP_GT: cbinary(J, F, exp, OP_GT); break;
  636. case EXP_LE: cbinary(J, F, exp, OP_LE); break;
  637. case EXP_GE: cbinary(J, F, exp, OP_GE); break;
  638. case EXP_INSTANCEOF: cbinary(J, F, exp, OP_INSTANCEOF); break;
  639. case EXP_IN: cbinary(J, F, exp, OP_IN); break;
  640. case EXP_SHL: cbinary(J, F, exp, OP_SHL); break;
  641. case EXP_SHR: cbinary(J, F, exp, OP_SHR); break;
  642. case EXP_USHR: cbinary(J, F, exp, OP_USHR); break;
  643. case EXP_ADD: cbinary(J, F, exp, OP_ADD); break;
  644. case EXP_SUB: cbinary(J, F, exp, OP_SUB); break;
  645. case EXP_MUL: cbinary(J, F, exp, OP_MUL); break;
  646. case EXP_DIV: cbinary(J, F, exp, OP_DIV); break;
  647. case EXP_MOD: cbinary(J, F, exp, OP_MOD); break;
  648. case EXP_ASS: cassign(J, F, exp); break;
  649. case EXP_ASS_MUL: cassignop(J, F, exp, OP_MUL); break;
  650. case EXP_ASS_DIV: cassignop(J, F, exp, OP_DIV); break;
  651. case EXP_ASS_MOD: cassignop(J, F, exp, OP_MOD); break;
  652. case EXP_ASS_ADD: cassignop(J, F, exp, OP_ADD); break;
  653. case EXP_ASS_SUB: cassignop(J, F, exp, OP_SUB); break;
  654. case EXP_ASS_SHL: cassignop(J, F, exp, OP_SHL); break;
  655. case EXP_ASS_SHR: cassignop(J, F, exp, OP_SHR); break;
  656. case EXP_ASS_USHR: cassignop(J, F, exp, OP_USHR); break;
  657. case EXP_ASS_BITAND: cassignop(J, F, exp, OP_BITAND); break;
  658. case EXP_ASS_BITXOR: cassignop(J, F, exp, OP_BITXOR); break;
  659. case EXP_ASS_BITOR: cassignop(J, F, exp, OP_BITOR); break;
  660. case EXP_COMMA:
  661. cexp(J, F, exp->a);
  662. emitline(J, F, exp);
  663. emit(J, F, OP_POP);
  664. cexp(J, F, exp->b);
  665. break;
  666. case EXP_LOGOR:
  667. cexp(J, F, exp->a);
  668. emitline(J, F, exp);
  669. emit(J, F, OP_DUP);
  670. end = emitjump(J, F, OP_JTRUE);
  671. emit(J, F, OP_POP);
  672. cexp(J, F, exp->b);
  673. label(J, F, end);
  674. break;
  675. case EXP_LOGAND:
  676. cexp(J, F, exp->a);
  677. emitline(J, F, exp);
  678. emit(J, F, OP_DUP);
  679. end = emitjump(J, F, OP_JFALSE);
  680. emit(J, F, OP_POP);
  681. cexp(J, F, exp->b);
  682. label(J, F, end);
  683. break;
  684. case EXP_COND:
  685. cexp(J, F, exp->a);
  686. emitline(J, F, exp);
  687. then = emitjump(J, F, OP_JTRUE);
  688. cexp(J, F, exp->c);
  689. end = emitjump(J, F, OP_JUMP);
  690. label(J, F, then);
  691. cexp(J, F, exp->b);
  692. label(J, F, end);
  693. break;
  694. default:
  695. jsC_error(J, exp, "unknown expression type");
  696. }
  697. }
  698. /* Patch break and continue statements */
  699. static void addjump(JF, enum js_AstType type, js_Ast *target, int inst)
  700. {
  701. js_JumpList *jump = js_malloc(J, sizeof *jump);
  702. jump->type = type;
  703. jump->inst = inst;
  704. jump->next = target->jumps;
  705. target->jumps = jump;
  706. }
  707. static void labeljumps(JF, js_Ast *stm, int baddr, int caddr)
  708. {
  709. js_JumpList *jump = stm->jumps;
  710. while (jump) {
  711. js_JumpList *next = jump->next;
  712. if (jump->type == STM_BREAK)
  713. labelto(J, F, jump->inst, baddr);
  714. if (jump->type == STM_CONTINUE)
  715. labelto(J, F, jump->inst, caddr);
  716. js_free(J, jump);
  717. jump = next;
  718. }
  719. stm->jumps = NULL;
  720. }
  721. static int isloop(enum js_AstType T)
  722. {
  723. return T == STM_DO || T == STM_WHILE ||
  724. T == STM_FOR || T == STM_FOR_VAR ||
  725. T == STM_FOR_IN || T == STM_FOR_IN_VAR;
  726. }
  727. static int isfun(enum js_AstType T)
  728. {
  729. return T == AST_FUNDEC || T == EXP_FUN || T == EXP_PROP_GET || T == EXP_PROP_SET;
  730. }
  731. static int matchlabel(js_Ast *node, const char *label)
  732. {
  733. while (node && node->type == STM_LABEL) {
  734. if (!strcmp(node->a->string, label))
  735. return 1;
  736. node = node->parent;
  737. }
  738. return 0;
  739. }
  740. static js_Ast *breaktarget(JF, js_Ast *node, const char *label)
  741. {
  742. while (node) {
  743. if (isfun(node->type))
  744. break;
  745. if (!label) {
  746. if (isloop(node->type) || node->type == STM_SWITCH)
  747. return node;
  748. } else {
  749. if (matchlabel(node->parent, label))
  750. return node;
  751. }
  752. node = node->parent;
  753. }
  754. return NULL;
  755. }
  756. static js_Ast *continuetarget(JF, js_Ast *node, const char *label)
  757. {
  758. while (node) {
  759. if (isfun(node->type))
  760. break;
  761. if (isloop(node->type)) {
  762. if (!label)
  763. return node;
  764. else if (matchlabel(node->parent, label))
  765. return node;
  766. }
  767. node = node->parent;
  768. }
  769. return NULL;
  770. }
  771. static js_Ast *returntarget(JF, js_Ast *node)
  772. {
  773. while (node) {
  774. if (isfun(node->type))
  775. return node;
  776. node = node->parent;
  777. }
  778. return NULL;
  779. }
  780. /* Emit code to rebalance stack and scopes during an abrupt exit */
  781. static void cexit(JF, enum js_AstType T, js_Ast *node, js_Ast *target)
  782. {
  783. js_Ast *prev;
  784. do {
  785. prev = node, node = node->parent;
  786. switch (node->type) {
  787. default:
  788. /* impossible */
  789. break;
  790. case STM_WITH:
  791. emitline(J, F, node);
  792. emit(J, F, OP_ENDWITH);
  793. break;
  794. case STM_FOR_IN:
  795. case STM_FOR_IN_VAR:
  796. emitline(J, F, node);
  797. /* pop the iterator if leaving the loop */
  798. if (F->script) {
  799. if (T == STM_RETURN || T == STM_BREAK || (T == STM_CONTINUE && target != node)) {
  800. /* pop the iterator, save the return or exp value */
  801. emit(J, F, OP_ROT2);
  802. emit(J, F, OP_POP);
  803. }
  804. if (T == STM_CONTINUE)
  805. emit(J, F, OP_ROT2); /* put the iterator back on top */
  806. } else {
  807. if (T == STM_RETURN) {
  808. /* pop the iterator, save the return value */
  809. emit(J, F, OP_ROT2);
  810. emit(J, F, OP_POP);
  811. }
  812. if (T == STM_BREAK || (T == STM_CONTINUE && target != node))
  813. emit(J, F, OP_POP); /* pop the iterator */
  814. }
  815. break;
  816. case STM_TRY:
  817. emitline(J, F, node);
  818. /* came from try block */
  819. if (prev == node->a) {
  820. emit(J, F, OP_ENDTRY);
  821. if (node->d) cstm(J, F, node->d); /* finally */
  822. }
  823. /* came from catch block */
  824. if (prev == node->c) {
  825. /* ... with finally */
  826. if (node->d) {
  827. emit(J, F, OP_ENDCATCH);
  828. emit(J, F, OP_ENDTRY);
  829. cstm(J, F, node->d); /* finally */
  830. } else {
  831. emit(J, F, OP_ENDCATCH);
  832. }
  833. }
  834. break;
  835. }
  836. } while (node != target);
  837. }
  838. /* Try/catch/finally */
  839. static void ctryfinally(JF, js_Ast *trystm, js_Ast *finallystm)
  840. {
  841. int L1;
  842. L1 = emitjump(J, F, OP_TRY);
  843. {
  844. /* if we get here, we have caught an exception in the try block */
  845. cstm(J, F, finallystm); /* inline finally block */
  846. emit(J, F, OP_THROW); /* rethrow exception */
  847. }
  848. label(J, F, L1);
  849. cstm(J, F, trystm);
  850. emit(J, F, OP_ENDTRY);
  851. cstm(J, F, finallystm);
  852. }
  853. static void ctrycatch(JF, js_Ast *trystm, js_Ast *catchvar, js_Ast *catchstm)
  854. {
  855. int L1, L2;
  856. L1 = emitjump(J, F, OP_TRY);
  857. {
  858. /* if we get here, we have caught an exception in the try block */
  859. checkfutureword(J, F, catchvar);
  860. if (F->strict) {
  861. if (!strcmp(catchvar->string, "arguments"))
  862. jsC_error(J, catchvar, "redefining 'arguments' is not allowed in strict mode");
  863. if (!strcmp(catchvar->string, "eval"))
  864. jsC_error(J, catchvar, "redefining 'eval' is not allowed in strict mode");
  865. }
  866. emitline(J, F, catchvar);
  867. emitstring(J, F, OP_CATCH, catchvar->string);
  868. cstm(J, F, catchstm);
  869. emit(J, F, OP_ENDCATCH);
  870. L2 = emitjump(J, F, OP_JUMP); /* skip past the try block */
  871. }
  872. label(J, F, L1);
  873. cstm(J, F, trystm);
  874. emit(J, F, OP_ENDTRY);
  875. label(J, F, L2);
  876. }
  877. static void ctrycatchfinally(JF, js_Ast *trystm, js_Ast *catchvar, js_Ast *catchstm, js_Ast *finallystm)
  878. {
  879. int L1, L2, L3;
  880. L1 = emitjump(J, F, OP_TRY);
  881. {
  882. /* if we get here, we have caught an exception in the try block */
  883. L2 = emitjump(J, F, OP_TRY);
  884. {
  885. /* if we get here, we have caught an exception in the catch block */
  886. cstm(J, F, finallystm); /* inline finally block */
  887. emit(J, F, OP_THROW); /* rethrow exception */
  888. }
  889. label(J, F, L2);
  890. if (F->strict) {
  891. checkfutureword(J, F, catchvar);
  892. if (!strcmp(catchvar->string, "arguments"))
  893. jsC_error(J, catchvar, "redefining 'arguments' is not allowed in strict mode");
  894. if (!strcmp(catchvar->string, "eval"))
  895. jsC_error(J, catchvar, "redefining 'eval' is not allowed in strict mode");
  896. }
  897. emitline(J, F, catchvar);
  898. emitstring(J, F, OP_CATCH, catchvar->string);
  899. cstm(J, F, catchstm);
  900. emit(J, F, OP_ENDCATCH);
  901. emit(J, F, OP_ENDTRY);
  902. L3 = emitjump(J, F, OP_JUMP); /* skip past the try block to the finally block */
  903. }
  904. label(J, F, L1);
  905. cstm(J, F, trystm);
  906. emit(J, F, OP_ENDTRY);
  907. label(J, F, L3);
  908. cstm(J, F, finallystm);
  909. }
  910. /* Switch */
  911. static void cswitch(JF, js_Ast *ref, js_Ast *head)
  912. {
  913. js_Ast *node, *clause, *def = NULL;
  914. int end;
  915. cexp(J, F, ref);
  916. /* emit an if-else chain of tests for the case clause expressions */
  917. for (node = head; node; node = node->b) {
  918. clause = node->a;
  919. if (clause->type == STM_DEFAULT) {
  920. if (def)
  921. jsC_error(J, clause, "more than one default label in switch");
  922. def = clause;
  923. } else {
  924. cexp(J, F, clause->a);
  925. emitline(J, F, clause);
  926. clause->casejump = emitjump(J, F, OP_JCASE);
  927. }
  928. }
  929. emit(J, F, OP_POP);
  930. if (def) {
  931. emitline(J, F, def);
  932. def->casejump = emitjump(J, F, OP_JUMP);
  933. end = 0;
  934. } else {
  935. end = emitjump(J, F, OP_JUMP);
  936. }
  937. /* emit the case clause bodies */
  938. for (node = head; node; node = node->b) {
  939. clause = node->a;
  940. label(J, F, clause->casejump);
  941. if (clause->type == STM_DEFAULT)
  942. cstmlist(J, F, clause->a);
  943. else
  944. cstmlist(J, F, clause->b);
  945. }
  946. if (end)
  947. label(J, F, end);
  948. }
  949. /* Statements */
  950. static void cvarinit(JF, js_Ast *list)
  951. {
  952. while (list) {
  953. js_Ast *var = list->a;
  954. if (var->b) {
  955. cexp(J, F, var->b);
  956. emitline(J, F, var);
  957. emitlocal(J, F, OP_SETLOCAL, OP_SETVAR, var->a);
  958. emit(J, F, OP_POP);
  959. }
  960. list = list->b;
  961. }
  962. }
  963. static void cstm(JF, js_Ast *stm)
  964. {
  965. js_Ast *target;
  966. int loop, cont, then, end;
  967. emitline(J, F, stm);
  968. switch (stm->type) {
  969. case AST_FUNDEC:
  970. break;
  971. case STM_BLOCK:
  972. cstmlist(J, F, stm->a);
  973. break;
  974. case STM_EMPTY:
  975. if (F->script) {
  976. emitline(J, F, stm);
  977. emit(J, F, OP_POP);
  978. emit(J, F, OP_UNDEF);
  979. }
  980. break;
  981. case STM_VAR:
  982. cvarinit(J, F, stm->a);
  983. break;
  984. case STM_IF:
  985. if (stm->c) {
  986. cexp(J, F, stm->a);
  987. emitline(J, F, stm);
  988. then = emitjump(J, F, OP_JTRUE);
  989. cstm(J, F, stm->c);
  990. emitline(J, F, stm);
  991. end = emitjump(J, F, OP_JUMP);
  992. label(J, F, then);
  993. cstm(J, F, stm->b);
  994. label(J, F, end);
  995. } else {
  996. cexp(J, F, stm->a);
  997. emitline(J, F, stm);
  998. end = emitjump(J, F, OP_JFALSE);
  999. cstm(J, F, stm->b);
  1000. label(J, F, end);
  1001. }
  1002. break;
  1003. case STM_DO:
  1004. loop = here(J, F);
  1005. cstm(J, F, stm->a);
  1006. cont = here(J, F);
  1007. cexp(J, F, stm->b);
  1008. emitline(J, F, stm);
  1009. emitjumpto(J, F, OP_JTRUE, loop);
  1010. labeljumps(J, F, stm, here(J,F), cont);
  1011. break;
  1012. case STM_WHILE:
  1013. loop = here(J, F);
  1014. cexp(J, F, stm->a);
  1015. emitline(J, F, stm);
  1016. end = emitjump(J, F, OP_JFALSE);
  1017. cstm(J, F, stm->b);
  1018. emitline(J, F, stm);
  1019. emitjumpto(J, F, OP_JUMP, loop);
  1020. label(J, F, end);
  1021. labeljumps(J, F, stm, here(J,F), loop);
  1022. break;
  1023. case STM_FOR:
  1024. case STM_FOR_VAR:
  1025. if (stm->type == STM_FOR_VAR) {
  1026. cvarinit(J, F, stm->a);
  1027. } else {
  1028. if (stm->a) {
  1029. cexp(J, F, stm->a);
  1030. emit(J, F, OP_POP);
  1031. }
  1032. }
  1033. loop = here(J, F);
  1034. if (stm->b) {
  1035. cexp(J, F, stm->b);
  1036. emitline(J, F, stm);
  1037. end = emitjump(J, F, OP_JFALSE);
  1038. } else {
  1039. end = 0;
  1040. }
  1041. cstm(J, F, stm->d);
  1042. cont = here(J, F);
  1043. if (stm->c) {
  1044. cexp(J, F, stm->c);
  1045. emit(J, F, OP_POP);
  1046. }
  1047. emitline(J, F, stm);
  1048. emitjumpto(J, F, OP_JUMP, loop);
  1049. if (end)
  1050. label(J, F, end);
  1051. labeljumps(J, F, stm, here(J,F), cont);
  1052. break;
  1053. case STM_FOR_IN:
  1054. case STM_FOR_IN_VAR:
  1055. cexp(J, F, stm->b);
  1056. emitline(J, F, stm);
  1057. emit(J, F, OP_ITERATOR);
  1058. loop = here(J, F);
  1059. {
  1060. emitline(J, F, stm);
  1061. emit(J, F, OP_NEXTITER);
  1062. end = emitjump(J, F, OP_JFALSE);
  1063. cassignforin(J, F, stm);
  1064. if (F->script) {
  1065. emit(J, F, OP_ROT2);
  1066. cstm(J, F, stm->c);
  1067. emit(J, F, OP_ROT2);
  1068. } else {
  1069. cstm(J, F, stm->c);
  1070. }
  1071. emitline(J, F, stm);
  1072. emitjumpto(J, F, OP_JUMP, loop);
  1073. }
  1074. label(J, F, end);
  1075. labeljumps(J, F, stm, here(J,F), loop);
  1076. break;
  1077. case STM_SWITCH:
  1078. cswitch(J, F, stm->a, stm->b);
  1079. labeljumps(J, F, stm, here(J,F), 0);
  1080. break;
  1081. case STM_LABEL:
  1082. cstm(J, F, stm->b);
  1083. /* skip consecutive labels */
  1084. while (stm->type == STM_LABEL)
  1085. stm = stm->b;
  1086. /* loops and switches have already been labelled */
  1087. if (!isloop(stm->type) && stm->type != STM_SWITCH)
  1088. labeljumps(J, F, stm, here(J,F), 0);
  1089. break;
  1090. case STM_BREAK:
  1091. if (stm->a) {
  1092. checkfutureword(J, F, stm->a);
  1093. target = breaktarget(J, F, stm->parent, stm->a->string);
  1094. if (!target)
  1095. jsC_error(J, stm, "break label '%s' not found", stm->a->string);
  1096. } else {
  1097. target = breaktarget(J, F, stm->parent, NULL);
  1098. if (!target)
  1099. jsC_error(J, stm, "unlabelled break must be inside loop or switch");
  1100. }
  1101. cexit(J, F, STM_BREAK, stm, target);
  1102. emitline(J, F, stm);
  1103. addjump(J, F, STM_BREAK, target, emitjump(J, F, OP_JUMP));
  1104. break;
  1105. case STM_CONTINUE:
  1106. if (stm->a) {
  1107. checkfutureword(J, F, stm->a);
  1108. target = continuetarget(J, F, stm->parent, stm->a->string);
  1109. if (!target)
  1110. jsC_error(J, stm, "continue label '%s' not found", stm->a->string);
  1111. } else {
  1112. target = continuetarget(J, F, stm->parent, NULL);
  1113. if (!target)
  1114. jsC_error(J, stm, "continue must be inside loop");
  1115. }
  1116. cexit(J, F, STM_CONTINUE, stm, target);
  1117. emitline(J, F, stm);
  1118. addjump(J, F, STM_CONTINUE, target, emitjump(J, F, OP_JUMP));
  1119. break;
  1120. case STM_RETURN:
  1121. if (stm->a)
  1122. cexp(J, F, stm->a);
  1123. else
  1124. emit(J, F, OP_UNDEF);
  1125. target = returntarget(J, F, stm->parent);
  1126. if (!target)
  1127. jsC_error(J, stm, "return not in function");
  1128. cexit(J, F, STM_RETURN, stm, target);
  1129. emitline(J, F, stm);
  1130. emit(J, F, OP_RETURN);
  1131. break;
  1132. case STM_THROW:
  1133. cexp(J, F, stm->a);
  1134. emitline(J, F, stm);
  1135. emit(J, F, OP_THROW);
  1136. break;
  1137. case STM_WITH:
  1138. F->lightweight = 0;
  1139. if (F->strict)
  1140. jsC_error(J, stm->a, "'with' statements are not allowed in strict mode");
  1141. cexp(J, F, stm->a);
  1142. emitline(J, F, stm);
  1143. emit(J, F, OP_WITH);
  1144. cstm(J, F, stm->b);
  1145. emitline(J, F, stm);
  1146. emit(J, F, OP_ENDWITH);
  1147. break;
  1148. case STM_TRY:
  1149. emitline(J, F, stm);
  1150. if (stm->b && stm->c) {
  1151. F->lightweight = 0;
  1152. if (stm->d)
  1153. ctrycatchfinally(J, F, stm->a, stm->b, stm->c, stm->d);
  1154. else
  1155. ctrycatch(J, F, stm->a, stm->b, stm->c);
  1156. } else {
  1157. ctryfinally(J, F, stm->a, stm->d);
  1158. }
  1159. break;
  1160. case STM_DEBUGGER:
  1161. emitline(J, F, stm);
  1162. emit(J, F, OP_DEBUGGER);
  1163. break;
  1164. default:
  1165. if (F->script) {
  1166. emitline(J, F, stm);
  1167. emit(J, F, OP_POP);
  1168. cexp(J, F, stm);
  1169. } else {
  1170. cexp(J, F, stm);
  1171. emitline(J, F, stm);
  1172. emit(J, F, OP_POP);
  1173. }
  1174. break;
  1175. }
  1176. }
  1177. static void cstmlist(JF, js_Ast *list)
  1178. {
  1179. while (list) {
  1180. cstm(J, F, list->a);
  1181. list = list->b;
  1182. }
  1183. }
  1184. /* Declarations and programs */
  1185. static int listlength(js_Ast *list)
  1186. {
  1187. int n = 0;
  1188. while (list) ++n, list = list->b;
  1189. return n;
  1190. }
  1191. static void cparams(JF, js_Ast *list, js_Ast *fname)
  1192. {
  1193. F->numparams = listlength(list);
  1194. while (list) {
  1195. checkfutureword(J, F, list->a);
  1196. addlocal(J, F, list->a, 0);
  1197. list = list->b;
  1198. }
  1199. }
  1200. static void cvardecs(JF, js_Ast *node)
  1201. {
  1202. if (node->type == AST_LIST) {
  1203. while (node) {
  1204. cvardecs(J, F, node->a);
  1205. node = node->b;
  1206. }
  1207. return;
  1208. }
  1209. if (isfun(node->type))
  1210. return; /* stop at inner functions */
  1211. if (node->type == EXP_VAR) {
  1212. checkfutureword(J, F, node->a);
  1213. addlocal(J, F, node->a, 1);
  1214. }
  1215. if (node->a) cvardecs(J, F, node->a);
  1216. if (node->b) cvardecs(J, F, node->b);
  1217. if (node->c) cvardecs(J, F, node->c);
  1218. if (node->d) cvardecs(J, F, node->d);
  1219. }
  1220. static void cfundecs(JF, js_Ast *list)
  1221. {
  1222. while (list) {
  1223. js_Ast *stm = list->a;
  1224. if (stm->type == AST_FUNDEC) {
  1225. emitline(J, F, stm);
  1226. emitfunction(J, F, newfun(J, stm->line, stm->a, stm->b, stm->c, 0, F->strict, 0));
  1227. emitline(J, F, stm);
  1228. emit(J, F, OP_SETLOCAL);
  1229. emitarg(J, F, addlocal(J, F, stm->a, 1));
  1230. emit(J, F, OP_POP);
  1231. }
  1232. list = list->b;
  1233. }
  1234. }
  1235. static void cfunbody(JF, js_Ast *name, js_Ast *params, js_Ast *body, int is_fun_exp)
  1236. {
  1237. F->lightweight = 1;
  1238. F->arguments = 0;
  1239. if (F->script)
  1240. F->lightweight = 0;
  1241. /* Check if first statement is 'use strict': */
  1242. if (body && body->type == AST_LIST && body->a && body->a->type == EXP_STRING)
  1243. if (!strcmp(body->a->string, "use strict"))
  1244. F->strict = 1;
  1245. F->lastline = F->line;
  1246. cparams(J, F, params, name);
  1247. if (body) {
  1248. cvardecs(J, F, body);
  1249. cfundecs(J, F, body);
  1250. }
  1251. if (name) {
  1252. checkfutureword(J, F, name);
  1253. if (is_fun_exp) {
  1254. if (findlocal(J, F, name->string) < 0) {
  1255. /* TODO: make this binding immutable! */
  1256. emit(J, F, OP_CURRENT);
  1257. emit(J, F, OP_SETLOCAL);
  1258. emitarg(J, F, addlocal(J, F, name, 1));
  1259. emit(J, F, OP_POP);
  1260. }
  1261. }
  1262. }
  1263. if (F->script) {
  1264. emit(J, F, OP_UNDEF);
  1265. cstmlist(J, F, body);
  1266. emit(J, F, OP_RETURN);
  1267. } else {
  1268. cstmlist(J, F, body);
  1269. emit(J, F, OP_UNDEF);
  1270. emit(J, F, OP_RETURN);
  1271. }
  1272. }
  1273. js_Function *jsC_compilefunction(js_State *J, js_Ast *prog)
  1274. {
  1275. return newfun(J, prog->line, prog->a, prog->b, prog->c, 0, J->default_strict, 1);
  1276. }
  1277. js_Function *jsC_compilescript(js_State *J, js_Ast *prog, int default_strict)
  1278. {
  1279. return newfun(J, prog ? prog->line : 0, NULL, NULL, prog, 1, default_strict, 0);
  1280. }