PageRenderTime 63ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/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
  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);
  1388. scheme_check_identifier("lambda", n, NULL, name);
  1389. /* If we don't check here, the error is in terms of `let': */
  1390. scheme_dup_symbol_check(&r, NULL, n, "argument", name);
  1391. if (pl < 0) {
  1392. v = scheme_intern_symbol("list");
  1393. v = cons(v, rest);
  1394. } else
  1395. v = SCHEME_STX_CAR(rest);
  1396. v = cons(cons(cons(n, scheme_null), cons(v, scheme_null)), scheme_null);
  1397. if (last)
  1398. SCHEME_CDR(last) = v;
  1399. else
  1400. bindings = v;
  1401. last = v;
  1402. if (pl < 0) {
  1403. /* rator is (lambda rest-x ....) */
  1404. break;
  1405. } else {
  1406. args = SCHEME_STX_CDR(args);
  1407. rest = SCHEME_STX_CDR(rest);
  1408. }
  1409. }
  1410. body = scheme_datum_to_syntax(cons(let_values_symbol,
  1411. cons(bindings, body)),
  1412. form,
  1413. DTS_COPY_PROPS);
  1414. env = scheme_set_comp_env_name(env, orig_vname);
  1415. return compile_expr(body, env, 0);
  1416. }
  1417. }
  1418. }
  1419. }
  1420. }
  1421. orig_rest_form = SCHEME_STX_CDR(form);
  1422. /* Look for (call-with-values (lambda () M) (lambda (id ...) N)) */
  1423. if (SAME_OBJ(SCHEME_STX_SYM(name), call_with_values_symbol)) {
  1424. Scheme_Object *at_first, *at_second, *the_end;
  1425. at_first = SCHEME_STX_CDR(form);
  1426. if (SCHEME_STX_PAIRP(at_first)) {
  1427. at_second = SCHEME_STX_CDR(at_first);
  1428. if (SCHEME_STX_PAIRP(at_second)) {
  1429. the_end = SCHEME_STX_CDR(at_second);
  1430. if (SCHEME_STX_NULLP(the_end)) {
  1431. Scheme_Object *first;
  1432. first = SCHEME_STX_CAR(at_first);
  1433. if (SCHEME_STX_PAIRP(first)
  1434. && SAME_OBJ(SCHEME_STX_SYM(SCHEME_STX_CAR(first)), lambda_symbol)
  1435. && (arg_count(first) == 0)) {
  1436. Scheme_Object *second;
  1437. second = SCHEME_STX_CAR(at_second);
  1438. if (SCHEME_STX_PAIRP(second)
  1439. && SAME_OBJ(SCHEME_STX_SYM(SCHEME_STX_CAR(second)), lambda_symbol)
  1440. && (arg_count(second) >= 0)) {
  1441. Scheme_Object *lhs;
  1442. second = SCHEME_STX_CDR(second);
  1443. lhs = SCHEME_STX_CAR(second);
  1444. second = SCHEME_STX_CDR(second);
  1445. first = SCHEME_STX_CDR(first);
  1446. first = SCHEME_STX_CDR(first);
  1447. first = icons(begin_symbol, first);
  1448. first = scheme_datum_to_syntax(first, at_first, DTS_COPY_PROPS);
  1449. second = icons(begin_symbol, second);
  1450. second = scheme_datum_to_syntax(second, at_second, DTS_COPY_PROPS);
  1451. /* Convert to let-values: */
  1452. name = icons(let_values_symbol,
  1453. icons(icons(icons(lhs, icons(first, scheme_null)),
  1454. scheme_null),
  1455. icons(second, scheme_null)));
  1456. form = scheme_datum_to_syntax(name, forms, DTS_COPY_PROPS);
  1457. env->value_name = orig_vname;
  1458. return compile_expr(form, env, 0);
  1459. }
  1460. }
  1461. }
  1462. }
  1463. }
  1464. rest_form = at_first;
  1465. } else {
  1466. rest_form = orig_rest_form;
  1467. }
  1468. if (NOT_SAME_OBJ(name, origname)
  1469. || NOT_SAME_OBJ(rest_form, orig_rest_form)) {
  1470. form = scheme_datum_to_syntax(scheme_make_pair(name, rest_form), forms, DTS_COPY_PROPS);
  1471. }
  1472. return compile_plain_app(form, env);
  1473. }
  1474. }
  1475. /*========================================================================*/
  1476. /* expression compilation dispatcher */
  1477. /*========================================================================*/
  1478. static Scheme_Object *compile_expr_k(void)
  1479. {
  1480. Scheme_Thread *p = scheme_current_thread;
  1481. Scheme_Object *form = (Scheme_Object *)p->ku.k.p1;
  1482. Scheme_Comp_Env *env = (Scheme_Comp_Env *)p->ku.k.p2;
  1483. p->ku.k.p1 = NULL;
  1484. p->ku.k.p2 = NULL;
  1485. return compile_expr(form, env, p->ku.k.i1);
  1486. }
  1487. Scheme_Object *compile_expr(Scheme_Object *form, Scheme_Comp_Env *env, int app_position)
  1488. {
  1489. #ifdef DO_STACK_CHECK
  1490. {
  1491. # include "mzstkchk.h"
  1492. {
  1493. Scheme_Thread *p = scheme_current_thread;
  1494. p->ku.k.p1 = (void *)form;
  1495. p->ku.k.p2 = (void *)env;
  1496. p->ku.k.i1 = app_position;
  1497. return scheme_handle_stack_overflow(compile_expr_k);
  1498. }
  1499. }
  1500. #endif
  1501. DO_CHECK_FOR_BREAK(scheme_current_thread, ;);
  1502. if (!SCHEME_STX_PAIRP(form)) {
  1503. Scheme_Object *val = SCHEME_STX_SYM(form);
  1504. if (SCHEME_SYMBOLP(val))
  1505. return scheme_compile_lookup(form, env, (app_position ? SCHEME_APP_POS : 0));
  1506. else if (SCHEME_NUMBERP(val)
  1507. || SCHEME_CHAR_STRINGP(val)
  1508. || SCHEME_BYTE_STRINGP(val)
  1509. || SAME_OBJ(val, scheme_true)
  1510. || SAME_OBJ(val, scheme_false))
  1511. return val;
  1512. else
  1513. scheme_wrong_syntax("compile", form, NULL, "unrecognized form");
  1514. } else {
  1515. Scheme_Object *name = SCHEME_STX_CAR(form);
  1516. if (SCHEME_STX_SYMBOLP(name)) {
  1517. /* check for primitive expression forms */
  1518. name = SCHEME_STX_SYM(name);
  1519. if (SAME_OBJ(name, quote_symbol))
  1520. return quote_compile(form, env);
  1521. else if (SAME_OBJ(name, let_values_symbol))
  1522. return let_values_compile(form, env);
  1523. else if (SAME_OBJ(name, letrec_values_symbol))
  1524. return letrec_values_compile(form, env);
  1525. else if (SAME_OBJ(name, lambda_symbol))
  1526. return lambda_compile(form, env);
  1527. else if (SAME_OBJ(name, case_lambda_symbol))
  1528. return case_lambda_compile(form, env);
  1529. else if (SAME_OBJ(name, set_symbol))
  1530. return set_compile(form, env);
  1531. else if (SAME_OBJ(name, if_symbol))
  1532. return if_compile(form, env);
  1533. else if (SAME_OBJ(name, begin_symbol))
  1534. return begin_compile(form, env);
  1535. else if (SAME_OBJ(name, begin0_symbol))
  1536. return begin0_compile(form, env);
  1537. else if (SAME_OBJ(name, with_cont_mark_symbol))
  1538. return with_cont_mark_compile(form, env);
  1539. else if (SAME_OBJ(name, ref_symbol))
  1540. return ref_compile(form, env);
  1541. else if (SAME_OBJ(name, ref_symbol))
  1542. return ref_compile(form, env);
  1543. }
  1544. }
  1545. return compile_app(form, env);
  1546. }
  1547. /*========================================================================*/
  1548. /* linklet compilation */
  1549. /*========================================================================*/
  1550. static int is_define_values(Scheme_Object *form)
  1551. {
  1552. Scheme_Object *rest;
  1553. if (!SCHEME_STX_PAIRP(form))
  1554. return 0;
  1555. rest = SCHEME_STX_CAR(form);
  1556. if (!SAME_OBJ(SCHEME_STX_SYM(rest), define_values_symbol))
  1557. return 0;
  1558. return 1;
  1559. }
  1560. static Scheme_Object *define_parse(Scheme_Object *form,
  1561. Scheme_Object **_vars, Scheme_Object **_val,
  1562. Scheme_Comp_Env **_env,
  1563. DupCheckRecord *r,
  1564. int *_extra_vars_pos,
  1565. Scheme_Hash_Tree **_source_names)
  1566. {
  1567. Scheme_Object *vars, *rest, *name, *src_name, *v, *extra_vars = scheme_null;
  1568. Scheme_Comp_Env *env;
  1569. Scheme_Hash_Tree *source_names = *_source_names;
  1570. int len;
  1571. len = check_form(form, form);
  1572. if (len != 3)
  1573. bad_form(form, len);
  1574. rest = SCHEME_STX_CDR(form);
  1575. vars = SCHEME_STX_CAR(rest);
  1576. rest = SCHEME_STX_CDR(rest);
  1577. *_val = SCHEME_STX_CAR(rest);
  1578. *_vars = vars;
  1579. while (SCHEME_STX_PAIRP(vars)) {
  1580. name = SCHEME_STX_CAR(vars);
  1581. scheme_check_identifier(NULL, name, NULL, form);
  1582. src_name = extract_source_name(name, 0);
  1583. if (!SAME_OBJ(src_name, SCHEME_STX_SYM(name)))
  1584. source_names = scheme_hash_tree_set(source_names, SCHEME_STX_SYM(name), src_name);
  1585. vars = SCHEME_STX_CDR(vars);
  1586. scheme_dup_symbol_check(r, NULL, name, "binding", form);
  1587. v = scheme_compile_lookup(name, *_env, SCHEME_NULL_FOR_UNBOUND);
  1588. if (v && (!SAME_TYPE(SCHEME_TYPE(v), scheme_ir_toplevel_type)
  1589. || ((Scheme_IR_Toplevel *)v)->instance_pos != -1))
  1590. scheme_wrong_syntax(NULL, name, form, "not a definable variable");
  1591. if (!v) {
  1592. v = (Scheme_Object *)scheme_make_ir_toplevel(-1, *_extra_vars_pos, 0);
  1593. env = scheme_extend_comp_env(*_env, name, v, 1, 0);
  1594. *_env = env;
  1595. extra_vars = scheme_make_pair(name, extra_vars);
  1596. (*_extra_vars_pos)++;
  1597. }
  1598. }
  1599. if (!SCHEME_STX_NULLP(vars))
  1600. scheme_wrong_syntax(NULL, vars, form, "bad variable list");
  1601. *_source_names = source_names;
  1602. return extra_vars;
  1603. }
  1604. static void check_import_export_clause(Scheme_Object *e, Scheme_Object *orig_form)
  1605. {
  1606. if (SCHEME_STX_SYMBOLP(e))
  1607. return;
  1608. if (SCHEME_STX_PAIRP(e)) {
  1609. if (SCHEME_STX_SYMBOLP(SCHEME_STX_CAR(e))) {
  1610. e = SCHEME_STX_CDR(e);
  1611. if (SCHEME_STX_PAIRP(e)) {
  1612. if (SCHEME_STX_SYMBOLP(SCHEME_STX_CAR(e))) {
  1613. e = SCHEME_STX_CDR(e);
  1614. if (SCHEME_STX_NULLP(e))
  1615. return;
  1616. }
  1617. }
  1618. }
  1619. }
  1620. scheme_wrong_syntax(NULL, e, orig_form, "bad import/export clause");
  1621. }
  1622. static Scheme_Object *extract_source_name(Scheme_Object *e, int no_default)
  1623. {
  1624. Scheme_Object *a;
  1625. a = scheme_stx_property(e, source_name_symbol, NULL);
  1626. if (!a || !SCHEME_SYMBOLP(a)) {
  1627. if (no_default)
  1628. a = NULL;
  1629. else
  1630. a = SCHEME_STX_SYM(e);
  1631. }
  1632. return a;
  1633. }
  1634. Scheme_Linklet *scheme_compile_linklet(Scheme_Object *form, int set_undef, Scheme_Object *import_keys)
  1635. {
  1636. Scheme_Linklet *linklet;
  1637. Scheme_Object *orig_form = form, *imports, *exports;
  1638. Scheme_Object *defn_syms, *a, *e, *extra_vars, *vec, *v;
  1639. Scheme_Object *import_syms, *import_symss, *bodies, *all_extra_vars;
  1640. Scheme_Hash_Tree *source_names, *also_used_names;
  1641. Scheme_IR_Toplevel *tl;
  1642. int body_len, len, islen, i, j, extra_vars_pos;
  1643. Scheme_Comp_Env *env, *d_env;
  1644. DupCheckRecord r;
  1645. body_len = check_form(form, form);
  1646. if (body_len < 3)
  1647. bad_form(form, body_len);
  1648. linklet = MALLOC_ONE_TAGGED(Scheme_Linklet);
  1649. linklet->so.type = scheme_linklet_type;
  1650. env = scheme_new_comp_env(linklet, set_undef ? COMP_ENV_ALLOW_SET_UNDEFINED : 0);
  1651. form = SCHEME_STX_CDR(form);
  1652. imports = SCHEME_STX_CAR(form);
  1653. form = SCHEME_STX_CDR(form);
  1654. exports = SCHEME_STX_CAR(form);
  1655. form = SCHEME_STX_CDR(form);
  1656. body_len -= 3;
  1657. /* Parse imports, filling in `ilens` and `import_syms`, and also
  1658. extending `env`. */
  1659. islen = scheme_stx_proper_list_length(imports);
  1660. if (islen < 0)
  1661. scheme_wrong_syntax(NULL, imports, orig_form, IMPROPER_LIST_FORM);
  1662. if (import_keys && (SCHEME_VEC_SIZE(import_keys) != islen))
  1663. scheme_contract_error("compile-linklet",
  1664. "import count of linklet form does not match given number of import keys",
  1665. "linklet", 1, linklet,
  1666. "linklet form imports", 1, scheme_make_integer(islen),
  1667. "given keys", 1, scheme_make_integer(SCHEME_VEC_SIZE(import_keys)),
  1668. NULL);
  1669. import_symss = scheme_make_vector(islen, scheme_false);
  1670. for (i = 0; i < islen; i++, imports = SCHEME_STX_CDR(imports)) {
  1671. a = SCHEME_STX_CAR(imports);
  1672. len = scheme_stx_proper_list_length(a);
  1673. import_syms = scheme_make_vector(len, NULL);
  1674. SCHEME_VEC_ELS(import_symss)[i] = import_syms;
  1675. for (j = 0; j < len; j++, a = SCHEME_STX_CDR(a)) {
  1676. e = SCHEME_STX_CAR(a);
  1677. check_import_export_clause(e, orig_form);
  1678. if (SCHEME_STX_SYMBOLP(e)) {
  1679. SCHEME_VEC_ELS(import_syms)[j] = SCHEME_STX_SYM(e);
  1680. } else {
  1681. SCHEME_VEC_ELS(import_syms)[j] = SCHEME_STX_SYM(SCHEME_STX_CAR(e));
  1682. e = SCHEME_STX_CADR(e);
  1683. }
  1684. tl = scheme_make_ir_toplevel(i, j, SCHEME_TOPLEVEL_READY);
  1685. env = scheme_extend_comp_env(env, e, (Scheme_Object *)tl, 1, 1);
  1686. if (!env)
  1687. scheme_wrong_syntax("linklet", e, NULL, "duplicate import");
  1688. }
  1689. linklet->num_total_imports += len;
  1690. }
  1691. /* Parse exports, filling in `defn_syms` and extending `env`. */
  1692. len = scheme_stx_proper_list_length(exports);
  1693. if (len < 0)
  1694. scheme_wrong_syntax(NULL, exports, orig_form, IMPROPER_LIST_FORM);
  1695. linklet->num_exports = len;
  1696. scheme_begin_dup_symbol_check(&r);
  1697. defn_syms = scheme_make_vector(len, NULL);
  1698. source_names = scheme_make_hash_tree(0);
  1699. also_used_names = scheme_make_hash_tree(0);
  1700. for (j = 0; j < len; j++, exports = SCHEME_STX_CDR(exports)) {
  1701. e = SCHEME_STX_CAR(exports);
  1702. check_import_export_clause(e, orig_form);
  1703. if (SCHEME_STX_SYMBOLP(e)) {
  1704. a = SCHEME_STX_SYM(e);
  1705. } else {
  1706. a = SCHEME_STX_SYM(SCHEME_STX_CADR(e));
  1707. e = SCHEME_STX_CAR(e);
  1708. }
  1709. /* The export name is used as the variable name. Note that the
  1710. export name at the `linklet` level will correspond to the
  1711. definition name at the `module` level. */
  1712. SCHEME_VEC_ELS(defn_syms)[j] = a;
  1713. if (scheme_hash_tree_get(source_names, a) || scheme_hash_tree_get(also_used_names, a)) {
  1714. scheme_wrong_syntax("linklet", a, NULL, "duplicate export");
  1715. }
  1716. /* Alternative source name supplied? */
  1717. a = extract_source_name(e, 1);
  1718. if (a) {
  1719. if (!SAME_OBJ(a, SCHEME_VEC_ELS(defn_syms)[j]))
  1720. source_names = scheme_hash_tree_set(source_names, SCHEME_VEC_ELS(defn_syms)[j], a);
  1721. else
  1722. also_used_names = scheme_hash_tree_set(also_used_names, SCHEME_VEC_ELS(defn_syms)[j], scheme_true);
  1723. } else {
  1724. /* Otherwise, use the export name (not the defined name) as the public name;
  1725. it matches the variable name */
  1726. also_used_names = scheme_hash_tree_set(also_used_names, SCHEME_VEC_ELS(defn_syms)[j], scheme_true);
  1727. }
  1728. tl = scheme_make_ir_toplevel(-1, j, 0);
  1729. env = scheme_extend_comp_env(env, e, (Scheme_Object *)tl, 1, 1);
  1730. if (!env)
  1731. scheme_wrong_syntax("linklet", e, NULL, "export duplicates import");
  1732. }
  1733. /* Looks for `define-values` forms to detect variables that are defined but
  1734. not exported */
  1735. extra_vars_pos = len;
  1736. all_extra_vars = scheme_null;
  1737. for (i = 0, a = form; i < body_len; i++, a = SCHEME_STX_CDR(a)) {
  1738. e = SCHEME_STX_CAR(a);
  1739. if (is_define_values(e)) {
  1740. Scheme_Object *vars, *vals;
  1741. extra_vars = define_parse(e, &vars, &vals, &env, &r, &extra_vars_pos, &source_names);
  1742. if (extra_vars) {
  1743. all_extra_vars = scheme_append(extra_vars, all_extra_vars);
  1744. }
  1745. }
  1746. }
  1747. if (extra_vars_pos) {
  1748. a = defn_syms;
  1749. defn_syms = scheme_make_vector(extra_vars_pos, NULL);
  1750. for (i = 0; i < len; i++) {
  1751. SCHEME_VEC_ELS(defn_syms)[i] = SCHEME_VEC_ELS(a)[i];
  1752. }
  1753. all_extra_vars = scheme_reverse(all_extra_vars);
  1754. for (i = len; i < extra_vars_pos; i++, all_extra_vars = SCHEME_CDR(all_extra_vars)) {
  1755. e = SCHEME_CAR(all_extra_vars);
  1756. a = SCHEME_STX_SYM(e);
  1757. if (scheme_hash_tree_get(source_names, a) || scheme_hash_tree_get(also_used_names, a)) {
  1758. /* Internal name conflicts with an exported name --- which is allowed, but means
  1759. that we need to pick a different name for the bucket */
  1760. a = generate_defn_name(a, source_names, also_used_names, extra_vars_pos);
  1761. }
  1762. SCHEME_VEC_ELS(defn_syms)[i] = a;
  1763. a = extract_source_name(e, 0);
  1764. if (!SAME_OBJ(a, SCHEME_VEC_ELS(defn_syms)[i]))
  1765. source_names = scheme_hash_tree_set(source_names, SCHEME_VEC_ELS(defn_syms)[i], a);
  1766. else
  1767. also_used_names = scheme_hash_tree_set(also_used_names, a, scheme_true);
  1768. }
  1769. }
  1770. /* Prepare linklet record */
  1771. linklet->importss = import_symss;
  1772. linklet->defns = defn_syms;
  1773. linklet->source_names = source_names;
  1774. /* Compile body forms */
  1775. bodies = scheme_make_vector(body_len, scheme_false);
  1776. linklet->bodies = bodies;
  1777. for (i = 0; i < body_len; i++, form = SCHEME_STX_CDR(form)) {
  1778. e = SCHEME_STX_CAR(form);
  1779. if (is_define_values(e)) {
  1780. a = SCHEME_STX_CADR(e);
  1781. len = scheme_stx_proper_list_length(a);
  1782. vec = scheme_make_vector(len+1, NULL);
  1783. if (len == 1)
  1784. d_env = scheme_set_comp_env_name(env, SCHEME_STX_CAR(a));
  1785. else
  1786. d_env = env;
  1787. for (j = 0; j < len; j++, a = SCHEME_STX_CDR(a)) {
  1788. v = scheme_compile_lookup(SCHEME_STX_CAR(a), env, 0);
  1789. MZ_ASSERT(SAME_TYPE(SCHEME_TYPE(v), scheme_ir_toplevel_type));
  1790. MZ_ASSERT(((Scheme_IR_Toplevel *)v)->instance_pos == -1);
  1791. SCHEME_DEFN_VAR_(vec, j) = v;
  1792. }
  1793. a = compile_expr(SCHEME_STX_CADR(SCHEME_STX_CDR(e)), d_env, 0);
  1794. SCHEME_DEFN_RHS(vec) = a;
  1795. if (SCHEME_TRUEP(scheme_stx_property(e, compiler_inline_hint_symbol, NULL))) {
  1796. /* mark compiler-inline hint: */
  1797. SCHEME_SET_DEFN_ALWAYS_INLINE(vec);
  1798. }
  1799. e = vec;
  1800. e->type = scheme_define_values_type;
  1801. } else {
  1802. e = compile_expr(e, env, 0);
  1803. }
  1804. SCHEME_VEC_ELS(bodies)[i] = e;
  1805. }
  1806. return linklet;
  1807. }
  1808. static Scheme_Object *generate_defn_name(Scheme_Object *base_sym,
  1809. Scheme_Hash_Tree *used_names,
  1810. Scheme_Hash_Tree *also_used_names,
  1811. int search_start)
  1812. {
  1813. char buf[32];
  1814. Scheme_Object *n;
  1815. while (1) {
  1816. sprintf(buf, ".%d", search_start);
  1817. n = scheme_intern_exact_parallel_symbol(buf, strlen(buf));
  1818. n = scheme_symbol_append(base_sym, n);
  1819. if (!scheme_hash_tree_get(used_names, n) && !scheme_hash_tree_get(also_used_names, n))
  1820. return n;
  1821. }
  1822. }
  1823. /**********************************************************************/
  1824. /* precise GC */
  1825. /**********************************************************************/
  1826. #ifdef MZ_PRECISE_GC
  1827. START_XFORM_SKIP;
  1828. #include "mzmark_compile.inc"
  1829. static void register_traversers(void)
  1830. {
  1831. GC_REG_TRAV(scheme_rt_ir_lambda_info, mark_ir_lambda_info);
  1832. }
  1833. END_XFORM_SKIP;
  1834. #endif