2a9e71d3e36741adbe2b9955ef561b09c8372ef5
[perl4caml.git] / perl_c.c
1 /* Interface to Perl from OCaml.
2  * Copyright (C) 2003 Merjis Ltd.
3  * $Id: perl_c.c,v 1.4 2003-10-12 17:33:14 rich Exp $
4  */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <assert.h>
9 #include <unistd.h>
10 #include <alloca.h>
11
12 #include <caml/alloc.h>
13 #include <caml/callback.h>
14 #include <caml/fail.h>
15 #include <caml/memory.h>
16 #include <caml/mlvalues.h>
17
18 /* XXX This was required to avoid an error on my machine when loading the Perl
19  * headers. Not clear why this is missing.
20  */
21 #define off64_t __off64_t
22
23 #include <EXTERN.h>
24 #include <perl.h>
25
26 /* Perl requires the interpreter to be called literally 'my_perl'! */
27 static PerlInterpreter *my_perl;
28
29 /* Wrap up an arbitrary void pointer in an opaque OCaml object. */
30 static value Val_voidptr (void *ptr);
31
32 /* Get the concrete value from an optional field. */
33 static value unoption (value option, value deflt);
34
35 /* Unwrap an arbitrary void pointer from an opaque OCaml object. */
36 #define Voidptr_val(type,rv) ((type *) Field ((rv), 0))
37
38 /* Hide Perl types in opaque OCaml objects. */
39 #define Val_perl(pl) (Val_voidptr ((pl)))
40 #define Perl_val(plv) (Voidptr_val (PerlInterpreter, (plv)))
41 #define Val_sv(sv) (Val_voidptr ((sv)))
42 #define Sv_val(svv) (Voidptr_val (SV, (svv)))
43
44 CAMLprim value
45 perl4caml_init (value unit)
46 {
47   static char *argv[] = { "", "-w", "-e", "0" };
48   int argc = sizeof argv / sizeof argv[0];
49
50   PERL_SYS_INIT3 (NULL, NULL, NULL);
51
52   /* Create a default interpreter. */
53   my_perl = perl_alloc ();
54   perl_construct (my_perl);
55   PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
56   perl_parse (my_perl, NULL, argc, argv, NULL);
57   /*perl_run (my_perl);*/
58
59   return Val_unit;
60 }
61
62 CAMLprim value
63 perl4caml_create (value optargs, value unit)
64 {
65   CAMLparam2 (optargs, unit);
66   CAMLlocal1 (args);
67   int argc, i;
68   char **argv;
69   static char *no_args[] = { "", "-e", "0" };
70
71   /* Arguments given? */
72   if (optargs == Val_int (0))   /* "None" */
73     {
74       argc = 3;
75       argv = no_args;
76     }
77   else                          /* "Some args" where args is a string array. */
78     {
79       args = Field (optargs, 0);
80       argc = Wosize_val (args);
81       argv = alloca (argc * sizeof (char *));
82       for (i = 0; i < argc; ++i) argv[i] = String_val (Field (args, i));
83     }
84
85   my_perl = perl_alloc ();
86   perl_construct (my_perl);
87   PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
88   perl_parse (my_perl, NULL, argc, argv, NULL);
89   /*perl_run (my_perl);*/
90
91   CAMLreturn (Val_perl (my_perl));
92 }
93
94 CAMLprim value
95 perl4caml_destroy (value unit)
96 {
97   CAMLparam1 (unit);
98
99   perl_destruct (my_perl);
100   perl_free (my_perl);
101
102   /* Force a segfault if someone tries to use a Perl function without
103    * creating another interpreter first.
104    */
105   my_perl = 0;
106
107   CAMLreturn (Val_unit);
108 }
109
110 CAMLprim value
111 perl4caml_set_context (value plv)
112 {
113   CAMLparam1 (plv);
114   PerlInterpreter *pl = Perl_val (plv);
115
116   PERL_SET_CONTEXT (pl);
117   my_perl = pl;
118
119   CAMLreturn (Val_unit);
120 }
121
122 CAMLprim value
123 perl4caml_int_of_sv (value svv)
124 {
125   CAMLparam1 (svv);
126   SV *sv = Sv_val (svv);
127   CAMLreturn (Val_int (SvIV (sv)));
128 }
129
130 CAMLprim value
131 perl4caml_sv_of_int (value iv)
132 {
133   CAMLparam1 (iv);
134   CAMLreturn (Val_sv (newSViv (Int_val (iv))));
135 }
136
137 CAMLprim value
138 perl4caml_float_of_sv (value svv)
139 {
140   CAMLparam1 (svv);
141   SV *sv = Sv_val (svv);
142   CAMLlocal1 (f);
143   f = copy_double (SvNV (sv));
144   CAMLreturn (f);
145 }
146
147 CAMLprim value
148 perl4caml_sv_of_float (value fv)
149 {
150   CAMLparam1 (fv);
151   CAMLreturn (Val_sv (newSViv (Double_val (fv))));
152 }
153
154 CAMLprim value
155 perl4caml_string_of_sv (value svv)
156 {
157   CAMLparam1 (svv);
158   SV *sv = Sv_val (svv);
159   char *str;
160   STRLEN len;
161   CAMLlocal1 (strv);
162   str = SvPV (sv, len);
163   /* XXX This won't work if the string contains NUL. */
164   strv = copy_string (str);
165   CAMLreturn (strv);
166 }
167
168 CAMLprim value
169 perl4caml_sv_of_string (value strv)
170 {
171   CAMLparam1 (strv);
172   CAMLreturn (Val_sv (newSVpv (String_val (strv), string_length (strv))));
173 }
174
175 CAMLprim value
176 perl4caml_sv_is_true (value svv)
177 {
178   CAMLparam1 (svv);
179   SV *sv = Sv_val (svv);
180   CAMLreturn (SvTRUE (sv) ? Val_true : Val_false);
181 }
182
183 CAMLprim value
184 perl4caml_sv_is_undef (value svv)
185 {
186   CAMLparam1 (svv);
187   SV *sv = Sv_val (svv);
188   CAMLreturn (sv == &PL_sv_undef ? Val_true : Val_false);
189 }
190
191 CAMLprim value
192 perl4caml_sv_undef (value unit)
193 {
194   CAMLparam1 (unit);
195   CAMLreturn (Val_sv (&PL_sv_undef));
196 }
197
198 CAMLprim value
199 perl4caml_sv_yes (value unit)
200 {
201   CAMLparam1 (unit);
202   CAMLreturn (Val_sv (&PL_sv_yes));
203 }
204
205 CAMLprim value
206 perl4caml_sv_no (value unit)
207 {
208   CAMLparam1 (unit);
209   CAMLreturn (Val_sv (&PL_sv_no));
210 }
211
212 CAMLprim value
213 perl4caml_sv_type (value svv)
214 {
215   CAMLparam1 (svv);
216   SV *sv = Sv_val (svv);
217
218   switch (SvTYPE (sv))
219     {
220     case SVt_IV: CAMLreturn (Val_int (1));
221     case SVt_NV: CAMLreturn (Val_int (2));
222     case SVt_PV: CAMLreturn (Val_int (3));
223     case SVt_RV: CAMLreturn (Val_int (4));
224     case SVt_PVAV: CAMLreturn (Val_int (5));
225     case SVt_PVHV: CAMLreturn (Val_int (6));
226     case SVt_PVCV: CAMLreturn (Val_int (7));
227     case SVt_PVGV: CAMLreturn (Val_int (8));
228     case SVt_PVMG: CAMLreturn (Val_int (9));
229     default: CAMLreturn (Val_int (0));
230     }
231 }
232
233 CAMLprim value
234 perl4caml_deref (value svv)
235 {
236   CAMLparam1 (svv);
237   CAMLlocal1 (rsvv);
238   SV *sv = Sv_val (svv);
239
240   if (SvTYPE (sv) != SVt_RV)
241     invalid_argument ("deref: SV is not a reference");
242   switch (SvTYPE (SvRV (sv))) {
243   case SVt_IV:
244   case SVt_NV:
245   case SVt_PV:
246   case SVt_RV:
247   case SVt_PVMG:
248     break;
249   default:
250     invalid_argument ("deref: SV is not a reference to a scalar");
251   }
252   rsvv = Val_sv (SvRV (sv));
253   CAMLreturn (rsvv);
254 }
255
256 CAMLprim value
257 perl4caml_get_sv (value optcreate, value name)
258 {
259   CAMLparam2 (optcreate, name);
260   CAMLlocal1 (create);
261   SV *sv;
262
263   create = unoption (optcreate, Val_false);
264   sv = get_sv (String_val (name), create == Val_true ? TRUE : FALSE);
265   if (sv == NULL) raise_not_found ();
266
267   CAMLreturn (Val_sv (sv));
268 }
269
270 static inline void
271 check_perl_failure ()
272 {
273   SV *errsv = get_sv ("@", TRUE);
274
275   if (SvTRUE (errsv))           /* Equivalent of $@ in Perl. */
276     {
277       CAMLlocal1 (errv);
278       STRLEN n_a;
279       const char *err = SvPV (errsv, n_a);
280
281       errv = copy_string (err);
282
283       raise_with_arg (*caml_named_value ("perl4caml_perl_failure"), errv);
284     }
285 }
286
287 CAMLprim value
288 perl4caml_call (value optsv, value optfnname, value arglist)
289 {
290   CAMLparam3 (optsv, optfnname, arglist);
291   dSP;
292   int count;
293   SV *sv;
294   CAMLlocal3 (errv, svv, fnname);
295
296   ENTER;
297   SAVETMPS;
298
299   /* Push the parameter list. */
300   PUSHMARK (SP);
301
302   /* Iteration over the linked list. */
303   for (; arglist != Val_int (0); arglist = Field (arglist, 1))
304     {
305       svv = Field (arglist, 0);
306       sv = Sv_val (svv);
307       XPUSHs (sv_2mortal (newSVsv (sv)));
308     }
309
310   PUTBACK;
311
312   if (optsv != Val_int (0))
313     {
314       svv = unoption (optsv, Val_false);
315       sv = Sv_val (svv);
316       count = call_sv (sv, G_EVAL|G_SCALAR);
317     }
318   else if (optfnname != Val_int (0))
319     {
320       fnname = unoption (optfnname, Val_false);
321       count = call_pv (String_val (fnname), G_EVAL|G_SCALAR);
322     }
323   else
324     {
325       fprintf (stderr,
326                "Perl.call: must supply either 'sv' or 'fn' parameters.");
327       abort ();
328     }
329
330   SPAGAIN;
331
332   assert (count == 1); /* Pretty sure it should never be anything else. */
333
334   /* Pop return value off the stack. Note that the return value on the
335    * stack is mortal, so we need to take a copy.
336    */
337   sv = newSVsv (POPs);
338   PUTBACK;
339   FREETMPS;
340   LEAVE;
341
342   check_perl_failure ();
343
344   svv = Val_sv (sv);
345   CAMLreturn (svv);
346 }
347
348 CAMLprim value
349 perl4caml_call_array (value optsv, value optfnname, value arglist)
350 {
351   CAMLparam3 (optsv, optfnname, arglist);
352   dSP;
353   int i, count;
354   SV *sv;
355   CAMLlocal5 (errv, svv, fnname, list, cons);
356
357   ENTER;
358   SAVETMPS;
359
360   /* Push the parameter list. */
361   PUSHMARK (SP);
362
363   /* Iteration over the linked list. */
364   for (; arglist != Val_int (0); arglist = Field (arglist, 1))
365     {
366       svv = Field (arglist, 0);
367       sv = Sv_val (svv);
368       XPUSHs (sv_2mortal (newSVsv (sv)));
369     }
370
371   PUTBACK;
372
373   if (optsv != Val_int (0))
374     {
375       svv = unoption (optsv, Val_false);
376       sv = Sv_val (svv);
377       count = call_sv (sv, G_EVAL|G_ARRAY);
378     }
379   else if (optfnname != Val_int (0))
380     {
381       fnname = unoption (optfnname, Val_false);
382       count = call_pv (String_val (fnname), G_EVAL|G_ARRAY);
383     }
384   else
385     {
386       fprintf (stderr,
387                "Perl.call_array: must supply either 'sv' or 'fn' parameters.");
388       abort ();
389     }
390
391   SPAGAIN;
392
393   /* Pop all the return values off the stack into a list. Values on the
394    * stack are mortal, so we must copy them.
395    */
396   list = Val_int (0);
397   for (i = 0; i < count; ++i) {
398     cons = alloc (2, 0);
399     Field (cons, 1) = list;
400     list = cons;
401     Field (cons, 0) = Val_sv (newSVsv (POPs));
402   }
403
404   /* Restore the stack. */
405   PUTBACK;
406   FREETMPS;
407   LEAVE;
408
409   check_perl_failure ();
410
411   CAMLreturn (list);
412 }
413
414 CAMLprim value
415 perl4caml_call_void (value optsv, value optfnname, value arglist)
416 {
417   CAMLparam3 (optsv, optfnname, arglist);
418   dSP;
419   int count;
420   SV *sv;
421   CAMLlocal3 (errv, svv, fnname);
422
423   ENTER;
424   SAVETMPS;
425
426   /* Push the parameter list. */
427   PUSHMARK (SP);
428
429   /* Iteration over the linked list. */
430   for (; arglist != Val_int (0); arglist = Field (arglist, 1))
431     {
432       svv = Field (arglist, 0);
433       sv = Sv_val (svv);
434       XPUSHs (sv_2mortal (newSVsv (sv)));
435     }
436
437   PUTBACK;
438
439   if (optsv != Val_int (0))
440     {
441       svv = unoption (optsv, Val_false);
442       sv = Sv_val (svv);
443       count = call_sv (sv, G_EVAL|G_VOID);
444     }
445   else if (optfnname != Val_int (0))
446     {
447       fnname = unoption (optfnname, Val_false);
448       count = call_pv (String_val (fnname), G_EVAL|G_VOID);
449     }
450   else
451     {
452       fprintf (stderr,
453                "Perl.call_void: must supply either 'sv' or 'fn' parameters.");
454       abort ();
455     }
456
457   SPAGAIN;
458
459   assert (count == 0); /* Pretty sure it should never be anything else. */
460
461   /* Restore the stack. */
462   PUTBACK;
463   FREETMPS;
464   LEAVE;
465
466   check_perl_failure ();
467
468   CAMLreturn (Val_unit);
469 }
470
471 CAMLprim value
472 perl4caml_eval (value expr)
473 {
474   CAMLparam1 (expr);
475   dSP;
476   SV *sv;
477   CAMLlocal2 (errv, svv);
478
479   sv = eval_pv (String_val (expr), G_SCALAR);
480
481   check_perl_failure ();
482
483   svv = Val_sv (sv);
484   CAMLreturn (svv);
485 }
486
487 CAMLprim value
488 perl4caml_call_method (value ref, value name, value arglist)
489 {
490   CAMLparam3 (ref, name, arglist);
491   dSP;
492   int count;
493   SV *sv;
494   CAMLlocal2 (errv, svv);
495
496   ENTER;
497   SAVETMPS;
498
499   /* Push the parameter list. */
500   PUSHMARK (SP);
501
502   sv = Sv_val (ref);
503   XPUSHs (sv_2mortal (newSVsv (sv)));
504
505   /* Iteration over the linked list. */
506   for (; arglist != Val_int (0); arglist = Field (arglist, 1))
507     {
508       svv = Field (arglist, 0);
509       sv = Sv_val (svv);
510       XPUSHs (sv_2mortal (newSVsv (sv)));
511     }
512
513   PUTBACK;
514
515   count = call_method (String_val (name), G_EVAL|G_SCALAR);
516
517   SPAGAIN;
518
519   assert (count == 1); /* Pretty sure it should never be anything else. */
520
521   /* Pop return value off the stack. Note that the return value on the
522    * stack is mortal, so we need to take a copy.
523    */
524   sv = newSVsv (POPs);
525   PUTBACK;
526   FREETMPS;
527   LEAVE;
528
529   check_perl_failure ();
530
531   svv = Val_sv (sv);
532   CAMLreturn (svv);
533 }
534
535 CAMLprim value
536 perl4caml_call_method_array (value ref, value name, value arglist)
537 {
538   CAMLparam3 (ref, name, arglist);
539   dSP;
540   int count, i;
541   SV *sv;
542   CAMLlocal4 (errv, svv, list, cons);
543
544   ENTER;
545   SAVETMPS;
546
547   /* Push the parameter list. */
548   PUSHMARK (SP);
549
550   sv = Sv_val (ref);
551   XPUSHs (sv_2mortal (newSVsv (sv)));
552
553   /* Iteration over the linked list. */
554   for (; arglist != Val_int (0); arglist = Field (arglist, 1))
555     {
556       svv = Field (arglist, 0);
557       sv = Sv_val (svv);
558       XPUSHs (sv_2mortal (newSVsv (sv)));
559     }
560
561   PUTBACK;
562
563   count = call_method (String_val (name), G_EVAL|G_ARRAY);
564
565   SPAGAIN;
566
567   /* Pop all return values off the stack. Note that the return values on the
568    * stack are mortal, so we need to take a copy.
569    */
570   list = Val_int (0);
571   for (i = 0; i < count; ++i) {
572     cons = alloc (2, 0);
573     Field (cons, 1) = list;
574     list = cons;
575     Field (cons, 0) = Val_sv (newSVsv (POPs));
576   }
577
578   /* Restore the stack. */
579   PUTBACK;
580   FREETMPS;
581   LEAVE;
582
583   check_perl_failure ();
584
585   CAMLreturn (list);
586 }
587
588 CAMLprim value
589 perl4caml_call_method_void (value ref, value name, value arglist)
590 {
591   CAMLparam3 (ref, name, arglist);
592   dSP;
593   int count;
594   SV *sv;
595   CAMLlocal2 (errv, svv);
596
597   ENTER;
598   SAVETMPS;
599
600   /* Push the parameter list. */
601   PUSHMARK (SP);
602
603   sv = Sv_val (ref);
604   XPUSHs (sv_2mortal (newSVsv (sv)));
605
606   /* Iteration over the linked list. */
607   for (; arglist != Val_int (0); arglist = Field (arglist, 1))
608     {
609       svv = Field (arglist, 0);
610       sv = Sv_val (svv);
611       XPUSHs (sv_2mortal (newSVsv (sv)));
612     }
613
614   PUTBACK;
615
616   count = call_method (String_val (name), G_EVAL|G_VOID);
617
618   SPAGAIN;
619
620   assert (count == 0); /* Pretty sure it should never be anything else. */
621
622   /* Restore the stack. */
623   PUTBACK;
624   FREETMPS;
625   LEAVE;
626
627   check_perl_failure ();
628
629   CAMLreturn (Val_unit);
630 }
631
632 CAMLprim value
633 perl4caml_call_class_method (value classname, value name, value arglist)
634 {
635   CAMLparam3 (classname, name, arglist);
636   dSP;
637   int count;
638   SV *sv;
639   CAMLlocal2 (errv, svv);
640
641   ENTER;
642   SAVETMPS;
643
644   /* Push the parameter list. */
645   PUSHMARK (SP);
646
647   XPUSHs (sv_2mortal (newSVpv (String_val (classname), 0)));
648
649   /* Iteration over the linked list. */
650   for (; arglist != Val_int (0); arglist = Field (arglist, 1))
651     {
652       svv = Field (arglist, 0);
653       sv = Sv_val (svv);
654       XPUSHs (sv_2mortal (newSVsv (sv)));
655     }
656
657   PUTBACK;
658
659   count = call_method (String_val (name), G_EVAL|G_SCALAR);
660
661   SPAGAIN;
662
663   assert (count == 1); /* Pretty sure it should never be anything else. */
664
665   /* Pop return value off the stack. Note that the return value on the
666    * stack is mortal, so we need to take a copy.
667    */
668   sv = newSVsv (POPs);
669   PUTBACK;
670   FREETMPS;
671   LEAVE;
672
673   check_perl_failure ();
674
675   svv = Val_sv (sv);
676   CAMLreturn (svv);
677 }
678
679 CAMLprim value
680 perl4caml_call_class_method_array (value classname, value name, value arglist)
681 {
682   CAMLparam3 (classname, name, arglist);
683   dSP;
684   int count, i;
685   SV *sv;
686   CAMLlocal4 (errv, svv, list, cons);
687
688   ENTER;
689   SAVETMPS;
690
691   /* Push the parameter list. */
692   PUSHMARK (SP);
693
694   XPUSHs (sv_2mortal (newSVpv (String_val (classname), 0)));
695
696   /* Iteration over the linked list. */
697   for (; arglist != Val_int (0); arglist = Field (arglist, 1))
698     {
699       svv = Field (arglist, 0);
700       sv = Sv_val (svv);
701       XPUSHs (sv_2mortal (newSVsv (sv)));
702     }
703
704   PUTBACK;
705
706   count = call_method (String_val (name), G_EVAL|G_ARRAY);
707
708   SPAGAIN;
709
710   /* Pop all return values off the stack. Note that the return values on the
711    * stack are mortal, so we need to take a copy.
712    */
713   list = Val_int (0);
714   for (i = 0; i < count; ++i) {
715     cons = alloc (2, 0);
716     Field (cons, 1) = list;
717     list = cons;
718     Field (cons, 0) = Val_sv (newSVsv (POPs));
719   }
720
721   /* Restore the stack. */
722   PUTBACK;
723   FREETMPS;
724   LEAVE;
725
726   check_perl_failure ();
727
728   CAMLreturn (list);
729 }
730
731 CAMLprim value
732 perl4caml_call_class_method_void (value classname, value name, value arglist)
733 {
734   CAMLparam3 (classname, name, arglist);
735   dSP;
736   int count;
737   SV *sv;
738   CAMLlocal2 (errv, svv);
739
740   ENTER;
741   SAVETMPS;
742
743   /* Push the parameter list. */
744   PUSHMARK (SP);
745
746   XPUSHs (sv_2mortal (newSVpv (String_val (classname), 0)));
747
748   /* Iteration over the linked list. */
749   for (; arglist != Val_int (0); arglist = Field (arglist, 1))
750     {
751       svv = Field (arglist, 0);
752       sv = Sv_val (svv);
753       XPUSHs (sv_2mortal (newSVsv (sv)));
754     }
755
756   PUTBACK;
757
758   count = call_method (String_val (name), G_EVAL|G_VOID);
759
760   SPAGAIN;
761
762   assert (count == 0); /* Pretty sure it should never be anything else. */
763
764   /* Restore the stack. */
765   PUTBACK;
766   FREETMPS;
767   LEAVE;
768
769   check_perl_failure ();
770
771   CAMLreturn (Val_unit);
772 }
773
774 static value
775 Val_voidptr (void *ptr)
776 {
777   value rv = alloc (1, Abstract_tag); /* XXX Is this correct? */
778   Field(rv, 0) = (value) ptr;
779   return rv;
780 }
781
782 static value
783 unoption (value option, value deflt)
784 {
785   if (option == Val_int (0))    /* "None" */
786     return deflt;
787   else                          /* "Some 'a" */
788     return Field (option, 0);
789 }