PageRenderTime 73ms CodeModel.GetById 34ms RepoModel.GetById 0ms app.codeStats 1ms

/racket/src/racket/src/compile.c

http://github.com/plt/racket
C | 2251 lines | 1705 code | 414 blank | 132 comment | 417 complexity | 9b0805316960cc9bf6180210cb4c2362 MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0, BSD-3-Clause, CC-BY-SA-3.0

Large files files are truncated, but you can click here to view the full file

  1. /* This file implements front-end compilation.
  2. The intermediate format generated from here accumulates references
  3. to non-local variables in a prefix, and it indicates whether each
  4. local variable is mutatble.
  5. See "eval.c" for an overview of compilation passes.
  6. The main compile loop is compile_expr(). */
  7. #include "schpriv.h"
  8. #include "schmach.h"
  9. /* globals */
  10. READ_ONLY Scheme_Object scheme_undefined[1];
  11. /* symbols */
  12. ROSYM static Scheme_Object *lambda_symbol;
  13. ROSYM static Scheme_Object *case_lambda_symbol;
  14. ROSYM static Scheme_Object *ref_symbol;
  15. ROSYM static Scheme_Object *quote_symbol;
  16. ROSYM static Scheme_Object *if_symbol;
  17. ROSYM static Scheme_Object *set_symbol;
  18. ROSYM static Scheme_Object *let_values_symbol;
  19. ROSYM static Scheme_Object *letrec_values_symbol;
  20. ROSYM static Scheme_Object *begin_symbol;
  21. ROSYM static Scheme_Object *begin0_symbol;
  22. ROSYM static Scheme_Object *with_cont_mark_symbol;
  23. ROSYM static Scheme_Object *define_values_symbol;
  24. ROSYM static Scheme_Object *compiler_inline_hint_symbol;
  25. ROSYM static Scheme_Object *protected_symbol;
  26. ROSYM static Scheme_Object *values_symbol;
  27. ROSYM static Scheme_Object *call_with_values_symbol;
  28. ROSYM static Scheme_Object *inferred_name_symbol;
  29. ROSYM static Scheme_Object *source_name_symbol;
  30. /* locals */
  31. static Scheme_Object *lambda_compile(Scheme_Object *form, Scheme_Comp_Env *env);
  32. static Scheme_Object *case_lambda_compile(Scheme_Object *form, Scheme_Comp_Env *env);
  33. static Scheme_Object *ref_compile(Scheme_Object *form, Scheme_Comp_Env *env);
  34. static Scheme_Object *quote_compile(Scheme_Object *form, Scheme_Comp_Env *env);
  35. static Scheme_Object *if_compile(Scheme_Object *form, Scheme_Comp_Env *env);
  36. static Scheme_Object *set_compile(Scheme_Object *form, Scheme_Comp_Env *env);
  37. static Scheme_Object *letrec_values_compile (Scheme_Object *form, Scheme_Comp_Env *env);
  38. static Scheme_Object *begin_compile (Scheme_Object *form, Scheme_Comp_Env *env);
  39. static Scheme_Object *begin0_compile (Scheme_Object *form, Scheme_Comp_Env *env);
  40. static Scheme_Object *with_cont_mark_compile(Scheme_Object *form, Scheme_Comp_Env *env);
  41. static Scheme_Object *compile_expr(Scheme_Object *form, Scheme_Comp_Env *env, int app_position);
  42. static Scheme_Object *compile_list(Scheme_Object *form,
  43. Scheme_Comp_Env *first_env, Scheme_Comp_Env *env, Scheme_Comp_Env *last_env,
  44. int start_app_position);
  45. static Scheme_Object *compile_app(Scheme_Object *form, Scheme_Comp_Env *env);
  46. static Scheme_Object *generate_defn_name(Scheme_Object *base_sym,
  47. Scheme_Hash_Tree *used_names,
  48. Scheme_Hash_Tree *also_used_names,
  49. int search_start);
  50. static Scheme_Object *extract_source_name(Scheme_Object *e, int no_default);
  51. #ifdef MZ_PRECISE_GC
  52. static void register_traversers(void);
  53. #endif
  54. #define cons(a,b) scheme_make_pair(a,b)
  55. #define icons(a,b) scheme_make_pair(a,b)
  56. /**********************************************************************/
  57. /* initialization */
  58. /**********************************************************************/
  59. void scheme_init_compile (Scheme_Startup_Env *env)
  60. {
  61. #ifdef MZ_PRECISE_GC
  62. register_traversers();
  63. #endif
  64. REGISTER_SO(lambda_symbol);
  65. REGISTER_SO(case_lambda_symbol);
  66. REGISTER_SO(ref_symbol);
  67. REGISTER_SO(quote_symbol);
  68. REGISTER_SO(if_symbol);
  69. REGISTER_SO(set_symbol);
  70. REGISTER_SO(let_values_symbol);
  71. REGISTER_SO(letrec_values_symbol);
  72. REGISTER_SO(begin_symbol);
  73. REGISTER_SO(begin0_symbol);
  74. REGISTER_SO(with_cont_mark_symbol);
  75. REGISTER_SO(define_values_symbol);
  76. lambda_symbol = scheme_intern_symbol("lambda");
  77. case_lambda_symbol = scheme_intern_symbol("case-lambda");
  78. ref_symbol = scheme_intern_symbol("#%variable-reference");
  79. quote_symbol = scheme_intern_symbol("quote");
  80. if_symbol = scheme_intern_symbol("if");
  81. set_symbol = scheme_intern_symbol("set!");
  82. let_values_symbol = scheme_intern_symbol("let-values");
  83. letrec_values_symbol = scheme_intern_symbol("letrec-values");
  84. begin_symbol = scheme_intern_symbol("begin");
  85. begin0_symbol = scheme_intern_symbol("begin0");
  86. with_cont_mark_symbol = scheme_intern_symbol("with-continuation-mark");
  87. define_values_symbol = scheme_intern_symbol("define-values");
  88. REGISTER_SO(compiler_inline_hint_symbol);
  89. REGISTER_SO(inferred_name_symbol);
  90. REGISTER_SO(source_name_symbol);
  91. scheme_undefined->type = scheme_undefined_type;
  92. compiler_inline_hint_symbol = scheme_intern_symbol("compiler-hint:cross-module-inline");
  93. inferred_name_symbol = scheme_intern_symbol("inferred-name");
  94. source_name_symbol = scheme_intern_symbol("source-name");
  95. REGISTER_SO(protected_symbol);
  96. REGISTER_SO(values_symbol);
  97. REGISTER_SO(call_with_values_symbol);
  98. protected_symbol = scheme_intern_symbol("protected");
  99. values_symbol = scheme_intern_symbol("values");
  100. call_with_values_symbol = scheme_intern_symbol("call-with-values");
  101. scheme_init_marshal(env);
  102. }
  103. void scheme_init_compile_places()
  104. {
  105. }
  106. /**********************************************************************/
  107. /* utilities */
  108. /**********************************************************************/
  109. static int check_form(Scheme_Object *form, Scheme_Object *base_form)
  110. {
  111. int i;
  112. for (i = 0; SCHEME_STX_PAIRP(form); i++) {
  113. form = SCHEME_STX_CDR(form);
  114. }
  115. if (!SCHEME_STX_NULLP(form)) {
  116. scheme_wrong_syntax(NULL, form, base_form, IMPROPER_LIST_FORM);
  117. }
  118. return i;
  119. }
  120. static void bad_form(Scheme_Object *form, int l)
  121. {
  122. scheme_wrong_syntax(NULL, NULL, form,
  123. "bad syntax;\n has %d part%s after keyword",
  124. l - 1, (l != 2) ? "s" : "");
  125. }
  126. static Scheme_Comp_Env *check_name_property(Scheme_Object *code, Scheme_Comp_Env *env)
  127. {
  128. Scheme_Object *name;
  129. name = scheme_stx_property(code, inferred_name_symbol, NULL);
  130. if (name && SCHEME_SYMBOLP(name))
  131. return scheme_set_comp_env_name(env, name);
  132. else
  133. return env;
  134. }
  135. /**********************************************************************/
  136. /* lambda utils */
  137. /**********************************************************************/
  138. static Scheme_Object *lambda_check(Scheme_Object *form)
  139. {
  140. if (SCHEME_STX_PAIRP(form)
  141. && SCHEME_STX_PAIRP(SCHEME_STX_CDR(form))) {
  142. Scheme_Object *rest;
  143. rest = SCHEME_STX_CDR(form);
  144. if (SCHEME_STX_PAIRP(SCHEME_STX_CDR(rest))) {
  145. int len;
  146. len = check_form(form, form);
  147. if (len != 3)
  148. bad_form(form, len);
  149. return form;
  150. }
  151. }
  152. scheme_wrong_syntax(NULL, NULL, form, NULL);
  153. return NULL;
  154. }
  155. static void lambda_check_args(Scheme_Object *args, Scheme_Object *form, Scheme_Comp_Env *env)
  156. {
  157. Scheme_Object *v, *a;
  158. DupCheckRecord r;
  159. if (!SCHEME_STX_SYMBOLP(args)) {
  160. for (v = args; SCHEME_STX_PAIRP(v); v = SCHEME_STX_CDR(v)) {
  161. a = SCHEME_STX_CAR(v);
  162. scheme_check_identifier(NULL, a, NULL, form);
  163. }
  164. if (!SCHEME_STX_NULLP(v)) {
  165. if (!SCHEME_STX_SYMBOLP(v)) {
  166. scheme_check_identifier(NULL, v, NULL, form);
  167. }
  168. }
  169. /* Check for duplicate names: */
  170. scheme_begin_dup_symbol_check(&r);
  171. for (v = args; SCHEME_STX_PAIRP(v); v = SCHEME_STX_CDR(v)) {
  172. Scheme_Object *name;
  173. name = SCHEME_STX_CAR(v);
  174. scheme_dup_symbol_check(&r, NULL, name, "argument", form);
  175. }
  176. if (!SCHEME_STX_NULLP(v)) {
  177. scheme_dup_symbol_check(&r, NULL, v, "argument", form);
  178. }
  179. }
  180. }
  181. Scheme_Object *scheme_source_to_name(Scheme_Object *code)
  182. /* Makes up a procedure name when there's not a good one in the source */
  183. {
  184. Scheme_Stx *cstx = (Scheme_Stx *)code;
  185. if (!SCHEME_STXP(code))
  186. return NULL;
  187. if ((cstx->srcloc->col >= 0) || (cstx->srcloc->pos >= 0)) {
  188. char buf[50], src[20];
  189. Scheme_Object *name, *bstr;
  190. int convert_backslash = 0;
  191. if (cstx->srcloc->src) {
  192. if (SCHEME_PATHP(cstx->srcloc->src)) {
  193. bstr = cstx->srcloc->src;
  194. /* for generating consistent names on machines with different platform
  195. conventions, convert "\" to "/" */
  196. convert_backslash = 1;
  197. } else if (SCHEME_CHAR_STRINGP(cstx->srcloc->src))
  198. bstr = scheme_char_string_to_byte_string(cstx->srcloc->src);
  199. else
  200. bstr = NULL;
  201. } else
  202. bstr = NULL;
  203. if (bstr) {
  204. if (SCHEME_BYTE_STRLEN_VAL(bstr) < 20)
  205. memcpy(src, SCHEME_BYTE_STR_VAL(bstr), SCHEME_BYTE_STRLEN_VAL(bstr) + 1);
  206. else {
  207. memcpy(src, SCHEME_BYTE_STR_VAL(bstr) + SCHEME_BYTE_STRLEN_VAL(bstr) - 19, 20);
  208. src[0] = '.';
  209. src[1] = '.';
  210. src[2] = '.';
  211. }
  212. if (convert_backslash) {
  213. int i;
  214. for (i = 0; src[i]; i++) {
  215. if (src[i] == '\\')
  216. src[i] = '/';
  217. }
  218. }
  219. } else {
  220. return NULL;
  221. }
  222. if (cstx->srcloc->line >= 0) {
  223. sprintf(buf, "%s%s%" PRIdPTR ":%" PRIdPTR,
  224. src, (src[0] ? ":" : ""), cstx->srcloc->line, cstx->srcloc->col - 1);
  225. } else {
  226. sprintf(buf, "%s%s%" PRIdPTR,
  227. src, (src[0] ? "::" : ""), cstx->srcloc->pos);
  228. }
  229. name = scheme_intern_exact_symbol(buf, strlen(buf));
  230. return name;
  231. }
  232. return NULL;
  233. }
  234. Scheme_Object *combine_name_with_srcloc(Scheme_Object *name, Scheme_Object *code, int src_based_name)
  235. {
  236. Scheme_Stx *cstx = (Scheme_Stx *)code;
  237. if (!SCHEME_STXP(code))
  238. return name;
  239. if (((cstx->srcloc->col >= 0) || (cstx->srcloc->pos >= 0))
  240. && cstx->srcloc->src) {
  241. Scheme_Object *vec;
  242. vec = scheme_make_vector(7, NULL);
  243. SCHEME_VEC_ELS(vec)[0] = name;
  244. SCHEME_VEC_ELS(vec)[1] = cstx->srcloc->src;
  245. if (cstx->srcloc->line >= 0) {
  246. SCHEME_VEC_ELS(vec)[2] = scheme_make_integer(cstx->srcloc->line);
  247. SCHEME_VEC_ELS(vec)[3] = scheme_make_integer(cstx->srcloc->col-1);
  248. } else {
  249. SCHEME_VEC_ELS(vec)[2] = scheme_false;
  250. SCHEME_VEC_ELS(vec)[3] = scheme_false;
  251. }
  252. if (cstx->srcloc->pos >= 0)
  253. SCHEME_VEC_ELS(vec)[4] = scheme_make_integer(cstx->srcloc->pos);
  254. else
  255. SCHEME_VEC_ELS(vec)[4] = scheme_false;
  256. if (cstx->srcloc->span >= 0)
  257. SCHEME_VEC_ELS(vec)[5] = scheme_make_integer(cstx->srcloc->span);
  258. else
  259. SCHEME_VEC_ELS(vec)[5] = scheme_false;
  260. SCHEME_VEC_ELS(vec)[6] = (src_based_name ? scheme_true : scheme_false);
  261. return vec;
  262. }
  263. return name;
  264. }
  265. Scheme_Object *scheme_build_closure_name(Scheme_Object *code, Scheme_Comp_Env *env)
  266. {
  267. Scheme_Object *name;
  268. name = scheme_stx_property(code, inferred_name_symbol, NULL);
  269. if (name && SCHEME_SYMBOLP(name)) {
  270. name = combine_name_with_srcloc(name, code, 0);
  271. } else if (name && SCHEME_VOIDP(name)) {
  272. name = scheme_source_to_name(code);
  273. if (name)
  274. name = combine_name_with_srcloc(name, code, 1);
  275. } else {
  276. name = env->value_name;
  277. if (name)
  278. name = SCHEME_STX_SYM(name);
  279. if (!name || SCHEME_FALSEP(name)) {
  280. name = scheme_source_to_name(code);
  281. if (name)
  282. name = combine_name_with_srcloc(name, code, 1);
  283. } else {
  284. name = combine_name_with_srcloc(name, code, 0);
  285. }
  286. }
  287. #if RECORD_ALLOCATION_COUNTS
  288. if (!name) {
  289. /* Try harder to synthesize a name */
  290. char *s;
  291. int len;
  292. s = scheme_write_to_string(scheme_syntax_to_datum(code),
  293. NULL);
  294. len = strlen(s);
  295. if (len > 100) s[100] = 0;
  296. name = scheme_make_symbol(s);
  297. }
  298. #endif
  299. return name;
  300. }
  301. static Scheme_Object *make_lambda(Scheme_Comp_Env *env, Scheme_Object *code)
  302. /* Compiles a `lambda' expression */
  303. {
  304. Scheme_Object *allparams, *params, *forms, *param, *name;
  305. Scheme_Lambda *lam;
  306. intptr_t num_params;
  307. Scheme_IR_Local *var, **vars;
  308. Scheme_IR_Lambda_Info *cl;
  309. int i;
  310. lam = MALLOC_ONE_TAGGED(Scheme_Lambda);
  311. lam->iso.so.type = scheme_ir_lambda_type;
  312. params = SCHEME_STX_CDR(code);
  313. params = SCHEME_STX_CAR(params);
  314. allparams = params;
  315. num_params = 0;
  316. for (; SCHEME_STX_PAIRP(params); params = SCHEME_STX_CDR(params)) {
  317. num_params++;
  318. }
  319. SCHEME_LAMBDA_FLAGS(lam) = 0;
  320. if (!SCHEME_STX_NULLP(params)) {
  321. SCHEME_LAMBDA_FLAGS(lam) |= LAMBDA_HAS_REST;
  322. num_params++;
  323. }
  324. lam->num_params = num_params;
  325. if ((lam->num_params > 0) && scheme_has_method_property(code))
  326. SCHEME_LAMBDA_FLAGS(lam) |= LAMBDA_IS_METHOD;
  327. forms = SCHEME_STX_CDR(code);
  328. forms = SCHEME_STX_CDR(forms);
  329. env = check_name_property(code, env);
  330. name = scheme_build_closure_name(code, env);
  331. lam->name = name;
  332. env = scheme_set_comp_env_name(env, NULL);
  333. vars = MALLOC_N(Scheme_IR_Local*, num_params);
  334. params = allparams;
  335. for (i = 0; i < num_params; i++) {
  336. if (!SCHEME_STX_PAIRP(params))
  337. param = params;
  338. else
  339. param = SCHEME_STX_CAR(params);
  340. var = scheme_make_ir_local(param);
  341. vars[i] = var;
  342. env = scheme_extend_comp_env(env, param, (Scheme_Object *)var, i > 0, 0);
  343. if (SCHEME_STX_PAIRP(params))
  344. params = SCHEME_STX_CDR (params);
  345. }
  346. if (SCHEME_STX_NULLP(forms))
  347. scheme_wrong_syntax(NULL, NULL, code, "empty body not allowed");
  348. {
  349. Scheme_Object *body;
  350. body = compile_expr(SCHEME_STX_CAR(forms), env, 0);
  351. lam->body = body;
  352. }
  353. cl = MALLOC_ONE_RT(Scheme_IR_Lambda_Info);
  354. SET_REQUIRED_TAG(cl->type = scheme_rt_ir_lambda_info);
  355. cl->vars = vars;
  356. lam->ir_info = cl;
  357. return (Scheme_Object *)lam;
  358. }
  359. static Scheme_Object *lambda_compile (Scheme_Object *form, Scheme_Comp_Env *env)
  360. {
  361. Scheme_Object *args;
  362. form = lambda_check(form);
  363. args = SCHEME_STX_CDR(form);
  364. args = SCHEME_STX_CAR(args);
  365. lambda_check_args(args, form, env);
  366. return make_lambda(env, form);
  367. }
  368. Scheme_Object *scheme_clone_vector(Scheme_Object *lam, int skip, int set_type)
  369. {
  370. Scheme_Object *naya;
  371. int i, size;
  372. size = SCHEME_VEC_SIZE(lam);
  373. naya = scheme_make_vector(size - skip, NULL);
  374. for (i = skip; i < size; i++) {
  375. SCHEME_VEC_ELS(naya)[i - skip] = SCHEME_VEC_ELS(lam)[i];
  376. }
  377. if (set_type)
  378. naya->type = lam->type;
  379. return naya;
  380. }
  381. /**********************************************************************/
  382. /* quote */
  383. /**********************************************************************/
  384. static Scheme_Object *quote_compile (Scheme_Object *form, Scheme_Comp_Env *env)
  385. {
  386. Scheme_Object *v, *rest;
  387. rest = SCHEME_STX_CDR(form);
  388. if (!(SCHEME_STX_PAIRP(rest) && SCHEME_STX_NULLP(SCHEME_STX_CDR(rest))))
  389. scheme_wrong_syntax(NULL, NULL, form, "wrong number of parts");
  390. v = SCHEME_STX_CAR(rest);
  391. return scheme_syntax_to_datum(v);
  392. }
  393. /**********************************************************************/
  394. /* if */
  395. /**********************************************************************/
  396. static void check_if_len(Scheme_Object *form, int len)
  397. {
  398. if (len != 4) {
  399. if (len == 3) {
  400. scheme_wrong_syntax(NULL, NULL, form,
  401. "missing an \"else\" expression");
  402. } else {
  403. bad_form(form, len);
  404. }
  405. }
  406. }
  407. Scheme_Object *scheme_make_branch(Scheme_Object *test, Scheme_Object *thenp,
  408. Scheme_Object *elsep)
  409. {
  410. Scheme_Branch_Rec *b;
  411. if (SCHEME_TYPE(test) > _scheme_ir_values_types_) {
  412. if (SCHEME_FALSEP(test))
  413. return elsep;
  414. else
  415. return thenp;
  416. }
  417. b = MALLOC_ONE_TAGGED(Scheme_Branch_Rec);
  418. b->so.type = scheme_branch_type;
  419. b->test = test;
  420. b->tbranch = thenp;
  421. b->fbranch = elsep;
  422. return (Scheme_Object *)b;
  423. }
  424. static Scheme_Object *if_compile (Scheme_Object *form, Scheme_Comp_Env *env)
  425. {
  426. int len, opt;
  427. Scheme_Object *test, *thenp, *elsep, *rest;
  428. len = check_form(form, form);
  429. check_if_len(form, len);
  430. env = check_name_property(form, env);
  431. rest = SCHEME_STX_CDR(form);
  432. test = SCHEME_STX_CAR(rest);
  433. rest = SCHEME_STX_CDR(rest);
  434. thenp = SCHEME_STX_CAR(rest);
  435. if (len == 4) {
  436. rest = SCHEME_STX_CDR(rest);
  437. elsep = SCHEME_STX_CAR(rest);
  438. } else
  439. elsep = scheme_compiled_void();
  440. test = compile_expr(test, scheme_set_comp_env_name(env, NULL), 0);
  441. if (SCHEME_TYPE(test) > _scheme_ir_values_types_) {
  442. opt = 1;
  443. if (SCHEME_FALSEP(test)) {
  444. /* compile other branch only to get syntax checking: */
  445. compile_expr(thenp, scheme_set_comp_env_flags(env, COMP_ENV_DONT_COUNT_AS_USE), 0);
  446. if (len == 4)
  447. test = compile_expr(elsep, env, 0);
  448. else
  449. test = elsep;
  450. } else {
  451. if (len == 4) {
  452. /* compile other branch only to get syntax checking: */
  453. compile_expr(elsep, scheme_set_comp_env_flags(env, COMP_ENV_DONT_COUNT_AS_USE), 0);
  454. }
  455. test = compile_expr(thenp, env, 0);
  456. }
  457. } else {
  458. opt = 0;
  459. thenp = compile_expr(thenp, env, 0);
  460. if (len == 4)
  461. elsep = compile_expr(elsep, env, 0);
  462. }
  463. if (opt)
  464. return test;
  465. else
  466. return scheme_make_branch(test, thenp, elsep);
  467. }
  468. /**********************************************************************/
  469. /* with-continuation-mark */
  470. /**********************************************************************/
  471. static Scheme_Object *with_cont_mark_compile(Scheme_Object *form, Scheme_Comp_Env *env)
  472. {
  473. Scheme_Object *key, *val, *expr;
  474. Scheme_Comp_Env *k_env;
  475. Scheme_With_Continuation_Mark *wcm;
  476. int len;
  477. len = check_form(form, form);
  478. if (len != 4)
  479. bad_form(form, len);
  480. form = SCHEME_STX_CDR(form);
  481. key = SCHEME_STX_CAR(form);
  482. form = SCHEME_STX_CDR(form);
  483. val = SCHEME_STX_CAR(form);
  484. form = SCHEME_STX_CDR(form);
  485. expr = SCHEME_STX_CAR(form);
  486. k_env = scheme_set_comp_env_name(env, NULL);
  487. key = compile_expr(key, k_env, 0);
  488. val = compile_expr(val, k_env, 0);
  489. expr = compile_expr(expr, env, 0);
  490. wcm = MALLOC_ONE_TAGGED(Scheme_With_Continuation_Mark);
  491. wcm->so.type = scheme_with_cont_mark_type;
  492. wcm->key = key;
  493. wcm->val = val;
  494. wcm->body = expr;
  495. return (Scheme_Object *)wcm;
  496. }
  497. /**********************************************************************/
  498. /* set! */
  499. /**********************************************************************/
  500. static Scheme_Object *set_compile (Scheme_Object *form, Scheme_Comp_Env *env)
  501. {
  502. Scheme_Set_Bang *sb;
  503. Scheme_Object *var, *val, *name, *body, *rest;
  504. int l, set_undef;
  505. l = check_form(form, form);
  506. if (l != 3)
  507. bad_form(form, l);
  508. rest = SCHEME_STX_CDR(form);
  509. name = SCHEME_STX_CAR(rest);
  510. rest = SCHEME_STX_CDR(rest);
  511. body = SCHEME_STX_CAR(rest);
  512. scheme_check_identifier("set!", name, NULL, form);
  513. var = scheme_compile_lookup(name, env, SCHEME_SETTING);
  514. if (SAME_TYPE(SCHEME_TYPE(var), scheme_ir_toplevel_type)) {
  515. if (((Scheme_IR_Toplevel *)var)->instance_pos != -1)
  516. scheme_wrong_syntax(NULL, form, name, "cannot mutate imported variable");
  517. SCHEME_IR_TOPLEVEL_FLAGS(((Scheme_IR_Toplevel *)var)) |= SCHEME_IR_TOPLEVEL_MUTATED;
  518. } else if (SAME_TYPE(SCHEME_TYPE(var), scheme_ir_local_type)) {
  519. if (((Scheme_IR_Local *)var)->compile.keep_assignment)
  520. ((Scheme_IR_Local *)var)->compile.keep_assignment = 2; /* keep permanently */
  521. }
  522. env = scheme_set_comp_env_name(env, SCHEME_STX_SYM(name));
  523. val = compile_expr(body, env, 0);
  524. set_undef = (env->flags & COMP_ENV_ALLOW_SET_UNDEFINED);
  525. sb = MALLOC_ONE_TAGGED(Scheme_Set_Bang);
  526. sb->so.type = scheme_set_bang_type;
  527. sb->var = var;
  528. sb->val = val;
  529. sb->set_undef = set_undef;
  530. return (Scheme_Object *)sb;
  531. }
  532. /**********************************************************************/
  533. /* #%variable-reference */
  534. /**********************************************************************/
  535. static Scheme_Object *ref_compile (Scheme_Object *form, Scheme_Comp_Env *env)
  536. {
  537. Scheme_Object *var, *name, *rest, *pseudo_var;
  538. int l, ok;
  539. l = check_form(form, form);
  540. /* retaining `pseudo-var' ensures that the environment stays
  541. linked from the actual variable */
  542. if ((l == 1) || !(env->flags & COMP_ENV_CHECKING_CONSTANT))
  543. pseudo_var = (Scheme_Object *)scheme_make_ir_toplevel(-1, -1, 0);
  544. else {
  545. /* If the variable reference will be used only for
  546. `variable-reference-constant?`, then we don't want a string
  547. reference to the enclsoing instance. */
  548. pseudo_var = scheme_false;
  549. }
  550. if (l == 1) {
  551. var = scheme_false;
  552. } else {
  553. if (l != 2)
  554. bad_form(form, l);
  555. rest = SCHEME_STX_CDR(form);
  556. name = SCHEME_STX_CAR(rest);
  557. ok = SCHEME_STX_SYMBOLP(name);
  558. if (!ok) {
  559. scheme_wrong_syntax("#%variable-reference", name,
  560. form,
  561. "not an identifier");
  562. return NULL;
  563. }
  564. var = scheme_compile_lookup(name, env, SCHEME_REFERENCING);
  565. if (!SAME_TYPE(SCHEME_TYPE(var), scheme_ir_toplevel_type)
  566. && !SAME_TYPE(SCHEME_TYPE(var), scheme_ir_local_type)
  567. && !SCHEME_SYMBOLP(var)) { /* symbol means primitive instance */
  568. scheme_wrong_syntax(NULL, name, form, "identifier does not refer to a variable");
  569. }
  570. }
  571. {
  572. Scheme_Object *o;
  573. o = scheme_alloc_object();
  574. o->type = scheme_varref_form_type;
  575. SCHEME_PTR1_VAL(o) = var;
  576. SCHEME_PTR2_VAL(o) = pseudo_var;
  577. return o;
  578. }
  579. }
  580. /**********************************************************************/
  581. /* case-lambda */
  582. /**********************************************************************/
  583. Scheme_Object *scheme_unclose_case_lambda(Scheme_Object *expr, int mode)
  584. {
  585. Scheme_Case_Lambda *cl = (Scheme_Case_Lambda *)expr;
  586. Scheme_Closure *c;
  587. int i;
  588. for (i = cl->count; i--; ) {
  589. c = (Scheme_Closure *)cl->array[i];
  590. if (!ZERO_SIZED_CLOSUREP(c)) {
  591. break;
  592. }
  593. }
  594. if (i < 0) {
  595. /* We can reconstruct a case-lambda syntactic form. */
  596. Scheme_Case_Lambda *cl2;
  597. cl2 = (Scheme_Case_Lambda *)scheme_malloc_tagged(sizeof(Scheme_Case_Lambda)
  598. + ((cl->count - mzFLEX_DELTA) * sizeof(Scheme_Object*)));
  599. cl2->so.type = scheme_case_lambda_sequence_type;
  600. cl2->count = cl->count;
  601. cl2->name = cl->name;
  602. for (i = cl->count; i--; ) {
  603. c = (Scheme_Closure *)cl->array[i];
  604. cl2->array[i] = (Scheme_Object *)c->code;
  605. }
  606. if (mode == 2) {
  607. /* sfs */
  608. return (Scheme_Object *)cl2;
  609. #ifdef MZ_USE_JIT
  610. } else if (mode == 1) {
  611. /* JIT */
  612. return scheme_case_lambda_jit((Scheme_Object *)cl2);
  613. #endif
  614. } else
  615. return (Scheme_Object *)cl2;
  616. }
  617. return expr;
  618. }
  619. static void case_lambda_check_line(Scheme_Object *line, Scheme_Object *form, Scheme_Comp_Env *env)
  620. {
  621. Scheme_Object *body, *args;
  622. if (!SCHEME_STX_PAIRP(line))
  623. scheme_wrong_syntax(NULL, line, form, NULL);
  624. body = SCHEME_STX_CDR(line);
  625. args = SCHEME_STX_CAR(line);
  626. lambda_check_args(args, form, env);
  627. if (!SCHEME_STX_PAIRP(body))
  628. scheme_wrong_syntax(NULL, line, form, "%s",
  629. SCHEME_STX_NULLP(body) ? "empty body not allowed" : IMPROPER_LIST_FORM);
  630. }
  631. static Scheme_Object *case_lambda_compile (Scheme_Object *form, Scheme_Comp_Env *env)
  632. {
  633. Scheme_Object *list, *last, *c, *orig_form = form, *name;
  634. Scheme_Case_Lambda *cl;
  635. int i, count = 0;
  636. form = SCHEME_STX_CDR(form);
  637. env = check_name_property(orig_form, env);
  638. name = scheme_build_closure_name(orig_form, env);
  639. if (SCHEME_STX_NULLP(form)) {
  640. /* Case where there are no cases... */
  641. form = (Scheme_Object *)scheme_malloc_tagged(sizeof(Scheme_Case_Lambda)
  642. - (mzFLEX_DELTA * sizeof(Scheme_Object*)));
  643. form->type = scheme_case_lambda_sequence_type;
  644. ((Scheme_Case_Lambda *)form)->count = 0;
  645. ((Scheme_Case_Lambda *)form)->name = name;
  646. if (scheme_has_method_property(orig_form)) {
  647. /* See note in schpriv.h about the IS_METHOD hack */
  648. if (!name)
  649. name = scheme_false;
  650. name = scheme_box(name);
  651. ((Scheme_Case_Lambda *)form)->name = name;
  652. }
  653. return form;
  654. }
  655. if (!SCHEME_STX_PAIRP(form))
  656. scheme_wrong_syntax(NULL, form, orig_form, NULL);
  657. if (SCHEME_STX_NULLP(SCHEME_STX_CDR(form))) {
  658. c = SCHEME_STX_CAR(form);
  659. case_lambda_check_line(c, orig_form, env);
  660. c = cons(lambda_symbol, c);
  661. c = scheme_datum_to_syntax(c, orig_form, DTS_COPY_PROPS);
  662. return lambda_compile(c, env);
  663. }
  664. list = last = NULL;
  665. while (SCHEME_STX_PAIRP(form)) {
  666. Scheme_Object *clause;
  667. clause = SCHEME_STX_CAR(form);
  668. case_lambda_check_line(clause, orig_form, env);
  669. c = cons(lambda_symbol, clause);
  670. c = scheme_datum_to_syntax(c, clause, 0);
  671. c = cons(c, scheme_null);
  672. if (list)
  673. SCHEME_CDR(last) = c;
  674. else
  675. list = c;
  676. last = c;
  677. form = SCHEME_STX_CDR(form);
  678. count++;
  679. }
  680. if (!SCHEME_STX_NULLP(form))
  681. scheme_wrong_syntax(NULL, form, orig_form, NULL);
  682. cl = (Scheme_Case_Lambda *)
  683. scheme_malloc_tagged(sizeof(Scheme_Case_Lambda)
  684. + (count - mzFLEX_DELTA) * sizeof(Scheme_Object *));
  685. cl->so.type = scheme_case_lambda_sequence_type;
  686. cl->count = count;
  687. cl->name = SCHEME_TRUEP(name) ? name : NULL;
  688. env = scheme_set_comp_env_name(env, NULL);
  689. for (i = 0; i < count; i++) {
  690. Scheme_Object *ce;
  691. ce = SCHEME_CAR(list);
  692. ce = compile_expr(ce, env, 0);
  693. cl->array[i] = ce;
  694. list = SCHEME_CDR(list);
  695. }
  696. if (scheme_has_method_property(orig_form)) {
  697. Scheme_Lambda *lam;
  698. /* Make sure no branch has 0 arguments: */
  699. for (i = 0; i < count; i++) {
  700. lam = (Scheme_Lambda *)cl->array[i];
  701. if (!lam->num_params)
  702. break;
  703. }
  704. if (i >= count) {
  705. lam = (Scheme_Lambda *)cl->array[0];
  706. SCHEME_LAMBDA_FLAGS(lam) |= LAMBDA_IS_METHOD;
  707. }
  708. }
  709. return (Scheme_Object *)cl;
  710. }
  711. /**********************************************************************/
  712. /* let, let-values, letrec, etc. */
  713. /**********************************************************************/
  714. static Scheme_IR_Let_Header *make_header(Scheme_Object *first, int num_bindings, int num_clauses,
  715. int flags)
  716. {
  717. Scheme_IR_Let_Header *head;
  718. head = MALLOC_ONE_TAGGED(Scheme_IR_Let_Header);
  719. head->iso.so.type = scheme_ir_let_header_type;
  720. head->body = first;
  721. head->count = num_bindings;
  722. head->num_clauses = num_clauses;
  723. SCHEME_LET_FLAGS(head) = flags;
  724. return head;
  725. }
  726. static Scheme_Object *do_let_compile (Scheme_Object *form, Scheme_Comp_Env *origenv, char *formname,
  727. int recursive)
  728. {
  729. Scheme_Object *bindings, *l, *binding, *name, **names, *forms;
  730. int num_clauses, num_bindings, i, k, m, pre_k, mutate_frame = 0, *use_box;
  731. Scheme_Comp_Env *frame, *rhs_env;
  732. Scheme_Object *first = NULL;
  733. Scheme_IR_Let_Value *last = NULL, *lv;
  734. Scheme_IR_Local *var, **vars;
  735. DupCheckRecord r;
  736. Scheme_IR_Let_Header *head;
  737. i = check_form(form, form);
  738. if (i != 3)
  739. bad_form(form, i);
  740. bindings = SCHEME_STX_CDR(form);
  741. bindings = SCHEME_STX_CAR(bindings);
  742. num_clauses = scheme_stx_proper_list_length(bindings);
  743. if (num_clauses < 0)
  744. scheme_wrong_syntax(NULL, bindings, form, NULL);
  745. /* forms ends up being the let body */
  746. forms = SCHEME_STX_CDR(form);
  747. forms = SCHEME_STX_CDR(forms);
  748. forms = SCHEME_STX_CAR(forms);
  749. origenv = check_name_property(form, origenv);
  750. if (!num_clauses)
  751. return compile_expr(forms, origenv, 0);
  752. num_bindings = 0;
  753. l = bindings;
  754. while (!SCHEME_STX_NULLP(l)) {
  755. Scheme_Object *clause, *names, *rest;
  756. int num_names;
  757. clause = SCHEME_STX_CAR(l);
  758. if (!SCHEME_STX_PAIRP(clause))
  759. rest = NULL;
  760. else {
  761. rest = SCHEME_STX_CDR(clause);
  762. if (!SCHEME_STX_PAIRP(rest))
  763. rest = NULL;
  764. else {
  765. rest = SCHEME_STX_CDR(rest);
  766. if (!SCHEME_STX_NULLP(rest))
  767. rest = NULL;
  768. }
  769. }
  770. if (!rest)
  771. scheme_wrong_syntax(NULL, clause, form, NULL);
  772. names = SCHEME_STX_CAR(clause);
  773. num_names = scheme_stx_proper_list_length(names);
  774. if (num_names < 0)
  775. scheme_wrong_syntax(NULL, names, form, NULL);
  776. num_bindings += num_names;
  777. l = SCHEME_STX_CDR(l);
  778. }
  779. names = MALLOC_N(Scheme_Object *, num_bindings);
  780. frame = scheme_set_comp_env_name(origenv, NULL);
  781. if (recursive) {
  782. use_box = MALLOC_N_ATOMIC(int, 1);
  783. *use_box = -1;
  784. } else
  785. use_box = NULL;
  786. scheme_begin_dup_symbol_check(&r);
  787. k = 0;
  788. for (i = 0; i < num_clauses; i++) {
  789. if (!SCHEME_STX_PAIRP(bindings))
  790. scheme_wrong_syntax(NULL, bindings, form, NULL);
  791. binding = SCHEME_STX_CAR(bindings);
  792. if (!SCHEME_STX_PAIRP(binding) || !SCHEME_STX_PAIRP(SCHEME_STX_CDR(binding)))
  793. scheme_wrong_syntax(NULL, binding, form, NULL);
  794. {
  795. Scheme_Object *rest;
  796. rest = SCHEME_STX_CDR(binding);
  797. if (!SCHEME_STX_NULLP(SCHEME_STX_CDR(rest)))
  798. scheme_wrong_syntax(NULL, binding, form, NULL);
  799. }
  800. pre_k = k;
  801. name = SCHEME_STX_CAR(binding);
  802. while (!SCHEME_STX_NULLP(name)) {
  803. Scheme_Object *n;
  804. n = SCHEME_STX_CAR(name);
  805. names[k] = n;
  806. scheme_check_identifier(NULL, names[k], NULL, form);
  807. scheme_dup_symbol_check(&r, NULL, names[k], "binding", form);
  808. k++;
  809. name = SCHEME_STX_CDR(name);
  810. }
  811. vars = MALLOC_N(Scheme_IR_Local*, k-pre_k);
  812. lv = MALLOC_ONE_TAGGED(Scheme_IR_Let_Value);
  813. lv->iso.so.type = scheme_ir_let_value_type;
  814. if (!last)
  815. first = (Scheme_Object *)lv;
  816. else
  817. last->body = (Scheme_Object *)lv;
  818. last = lv;
  819. lv->count = (k - pre_k);
  820. lv->vars = vars;
  821. {
  822. Scheme_Object *rhs;
  823. rhs = SCHEME_STX_CDR(binding);
  824. rhs = SCHEME_STX_CAR(rhs);
  825. if (!recursive) {
  826. if (lv->count == 1)
  827. rhs_env = scheme_set_comp_env_name(origenv, names[pre_k]);
  828. else
  829. rhs_env = scheme_set_comp_env_name(origenv, NULL);
  830. rhs = SCHEME_STX_CDR(binding);
  831. rhs = SCHEME_STX_CAR(rhs);
  832. rhs = compile_expr(rhs, rhs_env, 0);
  833. }
  834. lv->value = rhs;
  835. }
  836. for (m = pre_k; m < k; m++) {
  837. var = scheme_make_ir_local(names[m]);
  838. if (recursive) {
  839. var->mode = SCHEME_VAR_MODE_COMPILE;
  840. var->compile.use_box = use_box;
  841. var->compile.use_position = m;
  842. var->compile.keep_assignment = 1;
  843. }
  844. vars[m-pre_k] = var;
  845. frame = scheme_extend_comp_env(frame, names[m], (Scheme_Object *)var, mutate_frame, 0);
  846. mutate_frame = 1;
  847. }
  848. bindings = SCHEME_STX_CDR(bindings);
  849. }
  850. head = make_header(first, num_bindings, num_clauses,
  851. (recursive ? SCHEME_LET_RECURSIVE : 0));
  852. if (recursive) {
  853. int prev_might_invoke = 0, j;
  854. int group_clauses = 0;
  855. Scheme_Object *rhs;
  856. k = 0;
  857. lv = (Scheme_IR_Let_Value *)first;
  858. for (i = 0; i < num_clauses; i++, lv = (Scheme_IR_Let_Value *)lv->body) {
  859. rhs = lv->value;
  860. if (lv->count == 1)
  861. rhs_env = scheme_set_comp_env_name(frame, names[k]);
  862. else
  863. rhs_env = scheme_set_comp_env_name(frame, NULL);
  864. rhs = compile_expr(rhs, rhs_env, 0);
  865. lv->value = rhs;
  866. for (j = lv->count; j--; ) {
  867. if (lv->vars[j]->compile.keep_assignment < 2)
  868. lv->vars[j]->compile.keep_assignment = 0;
  869. }
  870. /* Record when this binding doesn't use any or later bindings in
  871. the same set. Break bindings into smaller sets based on this
  872. information, we have to be conservative as reflected by
  873. scheme_might_invoke_call_cc(). Implement splitting by
  874. recording with SCHEME_IRLV_NO_GROUP_LATER_USES and check
  875. again at the end. */
  876. if (!prev_might_invoke && !scheme_might_invoke_call_cc(rhs)) {
  877. group_clauses++;
  878. if ((group_clauses == 1) && (*use_box < k)) {
  879. /* A clause that should be in its own `let' */
  880. SCHEME_IRLV_FLAGS(lv) |= SCHEME_IRLV_NO_GROUP_USES;
  881. group_clauses = 0;
  882. } else if (*use_box < (k + lv->count)) {
  883. /* End a recursive `letrec' group */
  884. SCHEME_IRLV_FLAGS(lv) |= SCHEME_IRLV_NO_GROUP_LATER_USES;
  885. group_clauses = 0;
  886. }
  887. } else
  888. prev_might_invoke = 1;
  889. k += lv->count;
  890. }
  891. if (!prev_might_invoke) {
  892. Scheme_IR_Let_Header *current_head = head;
  893. Scheme_IR_Let_Value *next = NULL;
  894. int group_count = 0;
  895. lv = (Scheme_IR_Let_Value *)first;
  896. group_clauses = 0;
  897. for (i = 0; i < num_clauses; i++, lv = next) {
  898. next = (Scheme_IR_Let_Value *)lv->body;
  899. group_clauses++;
  900. group_count += lv->count;
  901. if (SCHEME_IRLV_FLAGS(lv) & (SCHEME_IRLV_NO_GROUP_USES
  902. | SCHEME_IRLV_NO_GROUP_LATER_USES)) {
  903. /* A clause that should be in its own `let' */
  904. Scheme_IR_Let_Header *next_head;
  905. int single = (SCHEME_IRLV_FLAGS(lv) & SCHEME_IRLV_NO_GROUP_USES);
  906. MZ_ASSERT(!single || (group_clauses == 1));
  907. if (current_head->num_clauses - group_clauses) {
  908. next_head = make_header(lv->body,
  909. current_head->count - group_count,
  910. current_head->num_clauses - group_clauses,
  911. SCHEME_LET_RECURSIVE);
  912. lv->body = (Scheme_Object *)next_head;
  913. current_head->num_clauses = group_clauses;
  914. current_head->count = group_count;
  915. } else
  916. next_head = NULL;
  917. if (single)
  918. SCHEME_LET_FLAGS(current_head) -= SCHEME_LET_RECURSIVE;
  919. current_head = next_head;
  920. group_clauses = 0;
  921. group_count = 0;
  922. }
  923. }
  924. }
  925. }
  926. frame = scheme_set_comp_env_name(frame, origenv->value_name);
  927. forms = compile_expr(forms, frame, 0);
  928. last->body = forms;
  929. return (Scheme_Object *)head;
  930. }
  931. static Scheme_Object *let_values_compile (Scheme_Object *form, Scheme_Comp_Env *env)
  932. {
  933. return do_let_compile(form, env, "let-values", 0);
  934. }
  935. static Scheme_Object *letrec_values_compile (Scheme_Object *form, Scheme_Comp_Env *env)
  936. {
  937. return do_let_compile(form, env, "letrec-values", 1);
  938. }
  939. /**********************************************************************/
  940. /* begin, begin0, implicit begins */
  941. /**********************************************************************/
  942. Scheme_Object *scheme_compiled_void()
  943. {
  944. return scheme_void;
  945. }
  946. static Scheme_Object *do_begin_compile(char *name,
  947. Scheme_Object *form, Scheme_Comp_Env *env,
  948. int zero)
  949. {
  950. Scheme_Comp_Env *nontail_env;
  951. Scheme_Object *forms, *body;
  952. forms = SCHEME_STX_CDR(form);
  953. if (SCHEME_STX_NULLP(forms)) {
  954. if (!zero)
  955. return scheme_compiled_void();
  956. scheme_wrong_syntax(NULL, NULL, form, "empty form not allowed");
  957. return NULL;
  958. }
  959. check_form(form, form);
  960. env = check_name_property(form, env);
  961. nontail_env = scheme_set_comp_env_name(env, NULL);
  962. /* if the `begin` has only one expression inside, drop the `begin`;
  963. this is allowed even for `begin0`, where the initial expression
  964. is considered in tail position if it's syntactically the only
  965. expression */
  966. if (SCHEME_STX_NULLP(SCHEME_STX_CDR(forms))) {
  967. forms = SCHEME_STX_CAR(forms);
  968. return compile_expr(forms, env, 0);
  969. }
  970. if (zero) {
  971. Scheme_Object *first, *rest;
  972. first = SCHEME_STX_CAR(forms);
  973. first = compile_expr(first, env, 0);
  974. rest = SCHEME_STX_CDR(forms);
  975. rest = compile_list(rest, nontail_env, nontail_env, nontail_env, 0);
  976. body = cons(first, rest);
  977. } else {
  978. body = compile_list(forms, nontail_env, nontail_env, env, 0);
  979. }
  980. forms = scheme_make_sequence_compilation(body, zero ? -1 : 1, 0);
  981. return forms;
  982. }
  983. static Scheme_Object *begin_compile (Scheme_Object *form, Scheme_Comp_Env *env)
  984. {
  985. return do_begin_compile("begin", form, env, 0);
  986. }
  987. static Scheme_Object *begin0_compile (Scheme_Object *form, Scheme_Comp_Env *env)
  988. {
  989. return do_begin_compile("begin0", form, env, 1);
  990. }
  991. static Scheme_Sequence *malloc_big_sequence(int count)
  992. {
  993. intptr_t sz;
  994. Scheme_Sequence *seq;
  995. sz = scheme_check_overflow((count - mzFLEX_DELTA), sizeof(Scheme_Object *), sizeof(Scheme_Sequence));
  996. seq = (Scheme_Sequence *)scheme_malloc_fail_ok(scheme_malloc_tagged, sz);
  997. if (!seq) scheme_signal_error("out of memory allocating sequence bytecode");
  998. return seq;
  999. }
  1000. Scheme_Sequence *scheme_malloc_sequence(int count) XFORM_ASSERT_NO_CONVERSION
  1001. {
  1002. if (count < 4096)
  1003. return (Scheme_Sequence *)scheme_malloc_tagged(sizeof(Scheme_Sequence)
  1004. + (count - mzFLEX_DELTA)
  1005. * sizeof(Scheme_Object *));
  1006. else
  1007. return malloc_big_sequence(count);
  1008. }
  1009. Scheme_Object *scheme_make_sequence_compilation(Scheme_Object *seq, int opt, int resolved)
  1010. {
  1011. /* We have to be defensive in processing `seq'; it might be bad due
  1012. to a bad .zo */
  1013. Scheme_Object *list, *v, *good;
  1014. Scheme_Sequence *o;
  1015. int count, i, k, total, last, first, setgood;
  1016. Scheme_Type type;
  1017. type = scheme_sequence_type;
  1018. list = seq;
  1019. count = i = 0;
  1020. good = NULL;
  1021. total = 0;
  1022. first = 1;
  1023. setgood = 1;
  1024. while (SCHEME_PAIRP(list)) {
  1025. v = SCHEME_CAR(list);
  1026. list = SCHEME_CDR(list);
  1027. last = SCHEME_NULLP(list);
  1028. if (((opt > 0) || !first) && SAME_TYPE(SCHEME_TYPE(v), type)) {
  1029. /* "Inline" nested begins */
  1030. count += ((Scheme_Sequence *)v)->count;
  1031. total++;
  1032. } else if (opt
  1033. && (((opt > 0) && !last) || ((opt < 0) && !first))
  1034. && scheme_omittable_expr(v, -1, -1,
  1035. (resolved ? OMITTABLE_RESOLVED : OMITTABLE_KEEP_VARS),
  1036. NULL, NULL)) {
  1037. /* A value that is not the result. We'll drop it. */
  1038. total++;
  1039. } else {
  1040. if (setgood)
  1041. good = v;
  1042. count++;
  1043. total++;
  1044. }
  1045. i++;
  1046. if (first) {
  1047. if (opt < 0)
  1048. setgood = 0;
  1049. first = 0;
  1050. }
  1051. }
  1052. if (!SCHEME_NULLP(list))
  1053. return NULL; /* bad .zo */
  1054. if (!count)
  1055. return scheme_compiled_void();
  1056. if (count == 1) {
  1057. if (opt < -1) {
  1058. /* can't optimize away a begin0 reading a .zo time */
  1059. } else if ((opt < 0)
  1060. && !scheme_omittable_expr(SCHEME_CAR(seq), 1, -1,
  1061. (resolved ? OMITTABLE_RESOLVED : OMITTABLE_KEEP_VARS),
  1062. NULL, NULL)) {
  1063. /* We can't optimize (begin0 expr cont) to expr because
  1064. exp is not in tail position in the original (so we'd mess
  1065. up continuation marks). */
  1066. } else
  1067. return good;
  1068. }
  1069. o = scheme_malloc_sequence(count);
  1070. o->so.type = ((opt < 0) ? scheme_begin0_sequence_type : scheme_sequence_type);
  1071. o->count = count;
  1072. --total;
  1073. for (i = k = 0; i < count; k++) {
  1074. v = SCHEME_CAR(seq);
  1075. seq = SCHEME_CDR(seq);
  1076. if (((opt > 0) || k) && SAME_TYPE(SCHEME_TYPE(v), type)) {
  1077. int c, j;
  1078. Scheme_Object **a;
  1079. c = ((Scheme_Sequence *)v)->count;
  1080. a = ((Scheme_Sequence *)v)->array; /* <-- mismaligned for precise GC */
  1081. for (j = 0; j < c; j++) {
  1082. o->array[i++] = a[j];
  1083. }
  1084. } else if (opt
  1085. && (((opt > 0) && (k < total))
  1086. || ((opt < 0) && k))
  1087. && scheme_omittable_expr(v, -1, -1,
  1088. (resolved ? OMITTABLE_RESOLVED : OMITTABLE_KEEP_VARS),
  1089. NULL, NULL)) {
  1090. /* Value not the result. Do nothing. */
  1091. } else
  1092. o->array[i++] = v;
  1093. }
  1094. return (Scheme_Object *)o;
  1095. }
  1096. /*========================================================================*/
  1097. /* applications */
  1098. /*========================================================================*/
  1099. int scheme_get_eval_type(Scheme_Object *obj)
  1100. /* Categories for short-cutting recursive calls to the evaluator */
  1101. {
  1102. Scheme_Type type;
  1103. type = SCHEME_TYPE(obj);
  1104. if (type > _scheme_values_types_)
  1105. return SCHEME_EVAL_CONSTANT;
  1106. else if (SAME_TYPE(type, scheme_ir_local_type)
  1107. || SAME_TYPE(type, scheme_local_type))
  1108. return SCHEME_EVAL_LOCAL;
  1109. else if (SAME_TYPE(type, scheme_local_unbox_type))
  1110. return SCHEME_EVAL_LOCAL_UNBOX;
  1111. else if (SAME_TYPE(type, scheme_toplevel_type))
  1112. return SCHEME_EVAL_GLOBAL;
  1113. else
  1114. return SCHEME_EVAL_GENERAL;
  1115. }
  1116. Scheme_Object *scheme_try_apply(Scheme_Object *f, Scheme_Object *args, Optimize_Info *info)
  1117. /* Apply `f' to `args' and ignore failures --- used for constant
  1118. folding attempts */
  1119. {
  1120. Scheme_Object * volatile result;
  1121. Scheme_Object * volatile exn = NULL;
  1122. mz_jmp_buf *savebuf, newbuf;
  1123. scheme_current_thread->reading_delayed = NULL;
  1124. scheme_current_thread->constant_folding = (info ? info : (Optimize_Info *)scheme_false);
  1125. savebuf = scheme_current_thread->error_buf;
  1126. scheme_current_thread->error_buf = &newbuf;
  1127. if (scheme_setjmp(newbuf)) {
  1128. result = NULL;
  1129. exn = scheme_current_thread->reading_delayed;
  1130. } else
  1131. result = _scheme_apply_to_list(f, args);
  1132. scheme_current_thread->error_buf = savebuf;
  1133. scheme_current_thread->constant_folding = NULL;
  1134. scheme_current_thread->reading_delayed = NULL;
  1135. if (scheme_current_thread->cjs.is_kill) {
  1136. scheme_longjmp(*scheme_current_thread->error_buf, 1);
  1137. }
  1138. if (exn)
  1139. scheme_raise(exn);
  1140. return result;
  1141. }
  1142. static int foldable_body(Scheme_Object *f)
  1143. {
  1144. Scheme_Lambda *d;
  1145. d = SCHEME_CLOSURE_CODE(f);
  1146. scheme_delay_load_closure(d);
  1147. return (SCHEME_TYPE(d->body) > _scheme_values_types_);
  1148. }
  1149. int scheme_is_foldable_prim(Scheme_Object *f)
  1150. {
  1151. if (SCHEME_PRIMP(f)
  1152. && ((((Scheme_Primitive_Proc *)f)->pp.flags & SCHEME_PRIM_OPT_MASK)
  1153. == SCHEME_PRIM_OPT_FOLDING))
  1154. return 1;
  1155. if (SCHEME_CLSD_PRIMP(f)
  1156. && ((((Scheme_Closed_Primitive_Proc *)f)->pp.flags & SCHEME_PRIM_OPT_MASK)
  1157. == SCHEME_PRIM_OPT_FOLDING))
  1158. return 1;
  1159. return 0;
  1160. }
  1161. Scheme_Object *scheme_make_application(Scheme_Object *v, Optimize_Info *info)
  1162. {
  1163. Scheme_Object *o;
  1164. int i, nv;
  1165. volatile int n;
  1166. o = v;
  1167. n = 0;
  1168. nv = 0;
  1169. while (!SCHEME_NULLP(o)) {
  1170. Scheme_Type type;
  1171. n++;
  1172. type = SCHEME_TYPE(SCHEME_CAR(o));
  1173. if (type < _scheme_ir_values_types_)
  1174. nv = 1;
  1175. o = SCHEME_CDR(o);
  1176. }
  1177. if (!nv) {
  1178. /* They're all values. Applying folding prim or closure? */
  1179. Scheme_Object *f;
  1180. f = SCHEME_CAR(v);
  1181. if (scheme_is_foldable_prim(f)
  1182. || (SAME_TYPE(SCHEME_TYPE(f), scheme_closure_type)
  1183. && (foldable_body(f)))) {
  1184. f = scheme_try_apply(f, SCHEME_CDR(v), info);
  1185. if (f)
  1186. return f;
  1187. }
  1188. }
  1189. if (n == 2) {
  1190. Scheme_App2_Rec *app;
  1191. app = MALLOC_ONE_TAGGED(Scheme_App2_Rec);
  1192. app->iso.so.type = scheme_application2_type;
  1193. app->rator = SCHEME_CAR(v);
  1194. v = SCHEME_CDR(v);
  1195. app->rand = SCHEME_CAR(v);
  1196. return (Scheme_Object *)app;
  1197. } else if (n == 3) {
  1198. Scheme_App3_Rec *app;
  1199. app = MALLOC_ONE_TAGGED(Scheme_App3_Rec);
  1200. app->iso.so.type = scheme_application3_type;
  1201. app->rator = SCHEME_CAR(v);
  1202. v = SCHEME_CDR(v);
  1203. app->rand1 = SCHEME_CAR(v);
  1204. v = SCHEME_CDR(v);
  1205. app->rand2 = SCHEME_CAR(v);
  1206. return (Scheme_Object *)app;
  1207. } else {
  1208. Scheme_App_Rec *app;
  1209. app = scheme_malloc_application(n);
  1210. for (i = 0; i < n; i++, v = SCHEME_CDR(v)) {
  1211. app->args[i] = SCHEME_CAR(v);
  1212. }
  1213. return (Scheme_Object *)app;
  1214. }
  1215. }
  1216. Scheme_App_Rec *scheme_malloc_application(int n)
  1217. {
  1218. Scheme_App_Rec *app;
  1219. intptr_t size;
  1220. if (n < 0) {
  1221. scheme_signal_error("bad application count");
  1222. app = NULL;
  1223. } else if (n > 4096) {
  1224. size = scheme_check_overflow(n,
  1225. sizeof(char),
  1226. (sizeof(Scheme_App_Rec)
  1227. + ((n - mzFLEX_DELTA) * sizeof(Scheme_Object *))));
  1228. app = (Scheme_App_Rec *)scheme_malloc_fail_ok(scheme_malloc_tagged, size);
  1229. if (!app) scheme_signal_error("out of memory allocating application bytecode");
  1230. } else {
  1231. size = (sizeof(Scheme_App_Rec)
  1232. + ((n - mzFLEX_DELTA) * sizeof(Scheme_Object *))
  1233. + n * sizeof(char));
  1234. app = (Scheme_App_Rec *)scheme_malloc_tagged(size);
  1235. }
  1236. app->iso.so.type = scheme_application_type;
  1237. app->num_args = n - 1;
  1238. return app;
  1239. }
  1240. void scheme_finish_application(Scheme_App_Rec *app)
  1241. {
  1242. int i, devals, n;
  1243. n = app->num_args + 1;
  1244. devals = sizeof(Scheme_App_Rec) + ((app->num_args + 1 - mzFLEX_DELTA) * sizeof(Scheme_Object *));
  1245. for (i = 0; i < n; i++) {
  1246. char etype;
  1247. etype = scheme_get_eval_type(app->args[i]);
  1248. ((char *)app XFORM_OK_PLUS devals)[i] = etype;
  1249. }
  1250. }
  1251. /*========================================================================*/
  1252. /* application */
  1253. /*========================================================================*/
  1254. static Scheme_Object *
  1255. compile_list(Scheme_Object *form,
  1256. Scheme_Comp_Env *first_env, Scheme_Comp_Env *env, Scheme_Comp_Env *last_env,
  1257. int start_app_position)
  1258. {
  1259. int len;
  1260. len = scheme_stx_proper_list_length(form);
  1261. if (!len) {
  1262. return scheme_null;
  1263. } else if (len > 0) {
  1264. int i;
  1265. Scheme_Object *c, *p, *comp_first, *comp_last, *first, *rest;
  1266. comp_first = comp_last = NULL;
  1267. for (i = 0, rest = form; i < len; i++) {
  1268. first = SCHEME_STX_CAR(rest);
  1269. rest = SCHEME_STX_CDR(rest);
  1270. c = compile_expr(first,
  1271. (!i ? first_env : ((i == (len-1)) ? last_env : env)),
  1272. !i && start_app_position);
  1273. p = scheme_make_pair(c, scheme_null);
  1274. if (comp_last)
  1275. SCHEME_CDR(comp_last) = p;
  1276. else
  1277. comp_first = p;
  1278. comp_last = p;
  1279. if (!i && start_app_position && (len == 2)
  1280. && SAME_OBJ(c, scheme_varref_const_p_proc))
  1281. last_env = scheme_set_comp_env_flags(last_env, COMP_ENV_CHECKING_CONSTANT);
  1282. }
  1283. return comp_first;
  1284. } else {
  1285. scheme_signal_error("internal error: compile-list on non-list");
  1286. return NULL;
  1287. }
  1288. }
  1289. static Scheme_Object *compile_plain_app(Scheme_Object *form, Scheme_Comp_Env *env)
  1290. {
  1291. Scheme_Object *result, *rator;
  1292. int len;
  1293. len = scheme_stx_proper_list_length(form);
  1294. if (len < 0)
  1295. scheme_wrong_syntax("application", NULL, form, NULL);
  1296. env = scheme_set_comp_env_name(env, NULL);
  1297. form = compile_list(form, env, env, env, 1);
  1298. result = scheme_make_application(form, NULL);
  1299. /* Record which application this is for a variable that is used only in
  1300. application positions. */
  1301. if (SAME_TYPE(SCHEME_TYPE(result), scheme_application_type))
  1302. rator = ((Scheme_App_Rec *)result)->args[0];
  1303. else if (SAME_TYPE(SCHEME_TYPE(result), scheme_application2_type))
  1304. rator = ((Scheme_App2_Rec *)result)->rator;
  1305. else if (SAME_TYPE(SCHEME_TYPE(result), scheme_application3_type))
  1306. rator = ((Scheme_App3_Rec *)result)->rator;
  1307. else
  1308. rator = NULL;
  1309. if (rator) {
  1310. rator = scheme_optimize_extract_tail_inside(rator);
  1311. if (SAME_TYPE(SCHEME_TYPE(rator), scheme_ir_local_type)) {
  1312. if (SCHEME_VAR(rator)->use_count < SCHEME_USE_COUNT_INF) {
  1313. if (SAME_TYPE(SCHEME_TYPE(result), scheme_application_type))
  1314. SCHEME_APPN_FLAGS((Scheme_App_Rec *)result) |= SCHEME_VAR(rator)->use_count;
  1315. else if (SAME_TYPE(SCHEME_TYPE(result), scheme_application2_type))
  1316. SCHEME_APPN_FLAGS((Scheme_App2_Rec *)result) |= SCHEME_VAR(rator)->use_count;
  1317. else if (SAME_TYPE(SCHEME_TYPE(result), scheme_application3_type))
  1318. SCHEME_APPN_FLAGS((Scheme_App3_Rec *)result) |= SCHEME_VAR(rator)->use_count;
  1319. }
  1320. }
  1321. }
  1322. return result;
  1323. }
  1324. static int arg_count(Scheme_Object *lam)
  1325. {
  1326. Scheme_Object *l, *id, *form = lam;
  1327. int cnt = 0;
  1328. DupCheckRecord r;
  1329. lam = SCHEME_STX_CDR(lam);
  1330. if (!SCHEME_STX_PAIRP(lam)) return -1;
  1331. l = SCHEME_STX_CAR(lam);
  1332. lam = SCHEME_STX_CDR(lam);
  1333. if (!SCHEME_STX_PAIRP(lam)) return -1;
  1334. while (SCHEME_STX_PAIRP(lam)) { lam = SCHEME_STX_CDR(lam); }
  1335. if (!SCHEME_STX_NULLP(lam)) return -1;
  1336. scheme_begin_dup_symbol_check(&r);
  1337. while (SCHEME_STX_PAIRP(l)) {
  1338. id = SCHEME_STX_CAR(l);
  1339. scheme_check_identifier("lambda", id, "argument", form);
  1340. scheme_dup_symbol_check(&r, NULL, id, "argument", form);
  1341. l = SCHEME_STX_CDR(l);
  1342. cnt++;
  1343. }
  1344. if (!SCHEME_STX_NULLP(l)) return -1;
  1345. return cnt;
  1346. }
  1347. static Scheme_Object *compile_app(Scheme_Object *orig_form, Scheme_Comp_Env *env)
  1348. {
  1349. Scheme_Object *form, *forms, *orig_vname = env->value_name;
  1350. forms = orig_form;
  1351. form = forms;
  1352. if (SCHEME_STX_NULLP(form)) {
  1353. /* Compile/expand empty application to null list: */
  1354. return scheme_null;
  1355. } else if (!SCHEME_STX_PAIRP(form)) {
  1356. /* will end in error */
  1357. return compile_plain_app(form, env);
  1358. } else {
  1359. Scheme_Object *name, *origname, *orig_rest_form, *rest_form;
  1360. name = SCHEME_STX_CAR(form);
  1361. origname = name;
  1362. /* look for ((lambda (x ...) ....) ....) or ((lambda x ....) ....) */
  1363. if (SAME_OBJ(SCHEME_STX_SYM(name), lambda_symbol)) {
  1364. Scheme_Object *argsnbody;
  1365. argsnbody = SCHEME_STX_CDR(name);
  1366. if (SCHEME_STX_PAIRP(argsnbody)) {
  1367. Scheme_Object *args, *body;
  1368. args = SCHEME_STX_CAR(argsnbody);
  1369. body = SCHEME_STX_CDR(argsnbody);
  1370. if (SCHEME_STX_PAIRP(body)) {
  1371. int pl;
  1372. pl = scheme_stx_proper_list_length(args);
  1373. if ((pl >= 0) || SCHEME_STX_SYMBOLP(args)) {
  1374. Scheme_Object *bindings = scheme_null, *last = NULL;
  1375. Scheme_Object *rest;
  1376. int al;
  1377. rest = SCHEME_STX_CDR(form);
  1378. al = scheme_stx_proper_list_length(rest);
  1379. if ((pl < 0) || (al == pl)) {
  1380. DupCheckRecord r;
  1381. scheme_begin_dup_symbol_check(&r);
  1382. while (!SCHEME_STX_NULLP(args)) {
  1383. Scheme_Object *v, *n;
  1384. if (pl < 0)
  1385. n = args;
  1386. else
  1387. n = SCHEME_STX_CAR(args);

Large files files are truncated, but you can click here to view the full file