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);