Mercurial > hg > xemacs-beta
comparison src/mule-ccl.c @ 4745:0c54de4c4b9d
Resolve the unregistered-CCL-programs-get-garbage-collected problem correctly
src/ChangeLog addition:
2009-11-15 Aidan Kehoe <kehoea@parhasard.net>
* mule-ccl.c (CCL_CALL_FOR_MAP_INSTRUCTION): Assert that we always
have a symbol in this macro.
(setup_ccl_program): Ensure we're not allocating unreachable
memory in this function; all symbols must have been resolved in a
given CCL program before this function is called.
(find_ccl_program): New function, return a CCL program with all
its symbols resolved if it is valid (possibly allocating memory),
Qnil otherwise.
(get_ccl_program): New function, exported to other files; call
find_ccl_program, and error if it gives nil.
(Fccl_program_p): Call find_ccl_program from this function instead
of implementing the bulk of it here.
(Fccl_execute): Call get_ccl_program instead of implementing the
bulk of it here.
(Fccl_execute_on_string): Ditto.
* mule-ccl.h (Vfont_ccl_encoder_alist): Remove this declaration,
it hasn't been used in years.
(get_ccl_program): Declare this function.
* mule-coding.c (ccl_putprop): Use get_ccl_program on any
specified encode or decode CCL program property.
(fixed_width_putprop): Ditto.
* mule-charset.c (Fmake_charset): Use get_ccl_program on any
specified ccl-program.
(Fset_charset_ccl_program): Ditto.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Sun, 15 Nov 2009 16:53:14 +0000 |
parents | d64f1060cd65 |
children | 27b09b4219b1 |
comparison
equal
deleted
inserted
replaced
4744:17f7e9191c0b | 4745:0c54de4c4b9d |
---|---|
625 } while (0) | 625 } while (0) |
626 | 626 |
627 #define CCL_CALL_FOR_MAP_INSTRUCTION(symbol, ret_ic) \ | 627 #define CCL_CALL_FOR_MAP_INSTRUCTION(symbol, ret_ic) \ |
628 do { \ | 628 do { \ |
629 struct ccl_program called_ccl; \ | 629 struct ccl_program called_ccl; \ |
630 /* We shouldn't ever call setup_ccl_program on a vector in \ | |
631 this context: */ \ | |
632 text_checking_assert (SYMBOLP (symbol)); \ | |
630 if (stack_idx >= 256 \ | 633 if (stack_idx >= 256 \ |
631 || (setup_ccl_program (&called_ccl, (symbol)) != 0)) \ | 634 || (setup_ccl_program (&called_ccl, (symbol)) != 0)) \ |
632 { \ | 635 { \ |
633 if (stack_idx > 0) \ | 636 if (stack_idx > 0) \ |
634 { \ | 637 { \ |
2148 setup_ccl_program (struct ccl_program *ccl, Lisp_Object ccl_prog) | 2151 setup_ccl_program (struct ccl_program *ccl, Lisp_Object ccl_prog) |
2149 { | 2152 { |
2150 xzero (*ccl); /* XEmacs change */ | 2153 xzero (*ccl); /* XEmacs change */ |
2151 if (! NILP (ccl_prog)) | 2154 if (! NILP (ccl_prog)) |
2152 { | 2155 { |
2153 ccl_prog = ccl_get_compiled_code (ccl_prog); | 2156 Lisp_Object new_prog = ccl_get_compiled_code (ccl_prog); |
2157 | |
2158 if (VECTORP (ccl_prog)) | |
2159 { | |
2160 /* Make sure we're not allocating unreachable memory in this | |
2161 function: */ | |
2162 assert (ccl_prog == new_prog); | |
2163 } | |
2164 | |
2165 ccl_prog = new_prog; | |
2166 | |
2154 if (! VECTORP (ccl_prog)) | 2167 if (! VECTORP (ccl_prog)) |
2155 return -1; | 2168 return -1; |
2169 | |
2156 ccl->size = XVECTOR_LENGTH (ccl_prog); | 2170 ccl->size = XVECTOR_LENGTH (ccl_prog); |
2157 ccl->prog = XVECTOR_DATA (ccl_prog); | 2171 ccl->prog = XVECTOR_DATA (ccl_prog); |
2158 ccl->eof_ic = XINT (XVECTOR_DATA (ccl_prog)[CCL_HEADER_EOF]); | 2172 ccl->eof_ic = XINT (XVECTOR_DATA (ccl_prog)[CCL_HEADER_EOF]); |
2159 ccl->buf_magnification = XINT (XVECTOR_DATA (ccl_prog)[CCL_HEADER_BUF_MAG]); | 2173 ccl->buf_magnification = XINT (XVECTOR_DATA (ccl_prog)[CCL_HEADER_BUF_MAG]); |
2160 } | 2174 } |
2161 ccl->ic = CCL_HEADER_MAIN; | 2175 ccl->ic = CCL_HEADER_MAIN; |
2162 ccl->eol_type = CCL_CODING_EOL_LF; | 2176 ccl->eol_type = CCL_CODING_EOL_LF; |
2163 return 0; | 2177 return 0; |
2164 } | 2178 } |
2165 | 2179 |
2180 static Lisp_Object | |
2181 find_ccl_program (Lisp_Object object, int *unresolved_symbols) | |
2182 { | |
2183 struct ccl_program test_ccl; | |
2184 | |
2185 if (NULL != unresolved_symbols) | |
2186 { | |
2187 *unresolved_symbols = 0; | |
2188 } | |
2189 | |
2190 if (VECTORP (object)) | |
2191 { | |
2192 object = resolve_symbol_ccl_program (object); | |
2193 if (EQ (Qt, object)) | |
2194 { | |
2195 if (NULL != unresolved_symbols) | |
2196 { | |
2197 *unresolved_symbols = 1; | |
2198 } | |
2199 return Qnil; | |
2200 } | |
2201 } | |
2202 else if (!SYMBOLP (object)) | |
2203 { | |
2204 return Qnil; | |
2205 } | |
2206 | |
2207 if (setup_ccl_program (&test_ccl, object) < 0) | |
2208 { | |
2209 return Qnil; | |
2210 } | |
2211 | |
2212 return object; | |
2213 } | |
2214 | |
2215 Lisp_Object | |
2216 get_ccl_program (Lisp_Object object) | |
2217 { | |
2218 int unresolved_symbols = 0; | |
2219 Lisp_Object val = find_ccl_program (object, &unresolved_symbols); | |
2220 | |
2221 if (unresolved_symbols) | |
2222 { | |
2223 invalid_argument ("Unresolved symbol(s) in CCL program", object); | |
2224 } | |
2225 else if (NILP (val)) | |
2226 { | |
2227 invalid_argument ("Invalid CCL program", object); | |
2228 } | |
2229 | |
2230 return val; | |
2231 } | |
2232 | |
2166 #ifdef emacs | 2233 #ifdef emacs |
2167 | 2234 |
2168 DEFUN ("ccl-program-p", Fccl_program_p, 1, 1, 0, /* | 2235 DEFUN ("ccl-program-p", Fccl_program_p, 1, 1, 0, /* |
2169 Return t if OBJECT is a CCL program name or a compiled CCL program code. | 2236 Return t if OBJECT is a CCL program name or a compiled CCL program code. |
2170 See the documentation of `define-ccl-program' for the detail of CCL program. | 2237 See the documentation of `define-ccl-program' for the detail of CCL program. |
2171 */ | 2238 */ |
2172 (object)) | 2239 (object)) |
2173 { | 2240 { |
2174 Lisp_Object val; | 2241 return NILP (find_ccl_program (object, NULL)) ? Qnil : Qt; |
2175 | |
2176 if (VECTORP (object)) | |
2177 { | |
2178 val = resolve_symbol_ccl_program (object); | |
2179 return (VECTORP (val) ? Qt : Qnil); | |
2180 } | |
2181 if (!SYMBOLP (object)) | |
2182 return Qnil; | |
2183 | |
2184 val = Fget (object, Qccl_program_idx, Qnil); | |
2185 return ((! NATNUMP (val) | |
2186 || XINT (val) >= XVECTOR_LENGTH (Vccl_program_table)) | |
2187 ? Qnil : Qt); | |
2188 } | 2242 } |
2189 | 2243 |
2190 DEFUN ("ccl-execute", Fccl_execute, 2, 2, 0, /* | 2244 DEFUN ("ccl-execute", Fccl_execute, 2, 2, 0, /* |
2191 Execute CCL-PROGRAM with registers initialized by REGISTERS. | 2245 Execute CCL-PROGRAM with registers initialized by REGISTERS. |
2192 | 2246 |
2204 See the documentation of `define-ccl-program' for the detail of CCL program. | 2258 See the documentation of `define-ccl-program' for the detail of CCL program. |
2205 */ | 2259 */ |
2206 (ccl_prog, reg)) | 2260 (ccl_prog, reg)) |
2207 { | 2261 { |
2208 struct ccl_program ccl; | 2262 struct ccl_program ccl; |
2263 struct gcpro gcpro1; | |
2209 int i; | 2264 int i; |
2210 | 2265 |
2211 if (setup_ccl_program (&ccl, ccl_prog) < 0) | 2266 ccl_prog = get_ccl_program (ccl_prog); |
2212 syntax_error ("Invalid CCL program", Qunbound); | 2267 /* get_ccl_program may have consed. GCPROing shouldn't be necessary at the |
2268 moment, but maybe someday CCL will call Lisp: */ | |
2269 GCPRO1 (ccl_prog); | |
2270 | |
2271 i = setup_ccl_program (&ccl, ccl_prog); | |
2272 | |
2273 text_checking_assert (i >= 0); | |
2213 | 2274 |
2214 CHECK_VECTOR (reg); | 2275 CHECK_VECTOR (reg); |
2215 if (XVECTOR_LENGTH (reg) != 8) | 2276 if (XVECTOR_LENGTH (reg) != 8) |
2216 syntax_error ("Length of vector REGISTERS is not 8", Qunbound); | 2277 syntax_error ("Length of vector REGISTERS is not 8", Qunbound); |
2217 | 2278 |
2227 if (ccl.status != CCL_STAT_SUCCESS) | 2288 if (ccl.status != CCL_STAT_SUCCESS) |
2228 signal_error (Qccl_error, "Error in CCL program at code numbered ...", make_int (ccl.ic)); | 2289 signal_error (Qccl_error, "Error in CCL program at code numbered ...", make_int (ccl.ic)); |
2229 | 2290 |
2230 for (i = 0; i < 8; i++) | 2291 for (i = 0; i < 8; i++) |
2231 XVECTOR (reg)->contents[i] = make_int (ccl.reg[i]); | 2292 XVECTOR (reg)->contents[i] = make_int (ccl.reg[i]); |
2232 return Qnil; | 2293 |
2294 RETURN_UNGCPRO (Qnil); | |
2233 } | 2295 } |
2234 | 2296 |
2235 DEFUN ("ccl-execute-on-string", Fccl_execute_on_string, | 2297 DEFUN ("ccl-execute-on-string", Fccl_execute_on_string, |
2236 3, 4, 0, /* | 2298 3, 4, 0, /* |
2237 Execute CCL-PROGRAM with initial STATUS on STRING. | 2299 Execute CCL-PROGRAM with initial STATUS on STRING. |
2261 { | 2323 { |
2262 Lisp_Object val; | 2324 Lisp_Object val; |
2263 struct ccl_program ccl; | 2325 struct ccl_program ccl; |
2264 int i, produced; | 2326 int i, produced; |
2265 unsigned_char_dynarr *outbuf; | 2327 unsigned_char_dynarr *outbuf; |
2266 struct gcpro gcpro1, gcpro2; | 2328 struct gcpro gcpro1, gcpro2, gcpro3; |
2267 | 2329 |
2268 if (setup_ccl_program (&ccl, ccl_prog) < 0) | 2330 ccl_prog = get_ccl_program (ccl_prog); |
2269 syntax_error ("Invalid CCL program", Qunbound); | 2331 i = setup_ccl_program (&ccl, ccl_prog); |
2332 | |
2333 text_checking_assert (i >= 0); | |
2270 | 2334 |
2271 CHECK_VECTOR (status); | 2335 CHECK_VECTOR (status); |
2272 if (XVECTOR (status)->size != 9) | 2336 if (XVECTOR (status)->size != 9) |
2273 syntax_error ("Length of vector STATUS is not 9", Qunbound); | 2337 syntax_error ("Length of vector STATUS is not 9", Qunbound); |
2274 CHECK_STRING (string); | 2338 CHECK_STRING (string); |
2275 | 2339 |
2276 GCPRO2 (status, string); | 2340 GCPRO3 (status, string, ccl_prog); |
2277 | 2341 |
2278 for (i = 0; i < 8; i++) | 2342 for (i = 0; i < 8; i++) |
2279 { | 2343 { |
2280 if (NILP (XVECTOR_DATA (status)[i])) | 2344 if (NILP (XVECTOR_DATA (status)[i])) |
2281 XVECTOR_DATA (status)[i] = make_int (0); | 2345 XVECTOR_DATA (status)[i] = make_int (0); |