Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 258 lines (207 sloc) 8.702 kb
e5a3ec5 Pawel Murias Evaling perl5 code loads the Perl5Interpreter class.
pmurias authored
1 using Niecza;
1e1a24e Pawel Murias Eval runs basic perl5 code. The Makefile needs review to check if it can
pmurias authored
2 using System.Runtime.InteropServices;
4266b44 Pawel Murias Argumentless method call on perl5 objects.
pmurias authored
3 using System;
5868454 Load the perl5 side interop support from a directory relative to the
Paweł Murias authored
4 using System.IO;
a9d984a Pawel Murias make perl5 now always rebuilds Niecza.pm.
pmurias authored
5 using System.Collections.Generic;
59c6a7b Pawel Murias Unbitrot perl5 interopability.
pmurias authored
6 using Niecza.Serialization;
1e1a24e Pawel Murias Eval runs basic perl5 code. The Makefile needs review to check if it can
pmurias authored
7
65732d5 Pawel Murias prefix the name of the interface with an I
pmurias authored
8 public class Perl5Interpreter : IForeignInterpreter {
bef38b1 Pawel Murias Make the perl5 interop work outside the niecza directory and hopefully o...
pmurias authored
9 [DllImport("p5embed", EntryPoint="p5embed_initialize")]
02fe910 Pawel Murias Rename Niecza::Interoperability to Niecza.
pmurias authored
10 public static extern void Initialize(string path1,string path2);
1e1a24e Pawel Murias Eval runs basic perl5 code. The Makefile needs review to check if it can
pmurias authored
11
bef38b1 Pawel Murias Make the perl5 interop work outside the niecza directory and hopefully o...
pmurias authored
12 [DllImport("p5embed", EntryPoint="p5embed_dispose")]
1e1a24e Pawel Murias Eval runs basic perl5 code. The Makefile needs review to check if it can
pmurias authored
13 public static extern void Dispose();
14
bef38b1 Pawel Murias Make the perl5 interop work outside the niecza directory and hopefully o...
pmurias authored
15 [DllImport("p5embed", EntryPoint="p5embed_eval")]
4266b44 Pawel Murias Argumentless method call on perl5 objects.
pmurias authored
16 public static extern IntPtr EvalPerl5(string code);
17
bef38b1 Pawel Murias Make the perl5 interop work outside the niecza directory and hopefully o...
pmurias authored
18 [DllImport("p5embed", EntryPoint="p5embed_SvIV")]
18b719f Pawel Murias Perl5 integers are converted rather than wrapped.
pmurias authored
19 public static extern int SvIV(IntPtr sv);
4266b44 Pawel Murias Argumentless method call on perl5 objects.
pmurias authored
20
bef38b1 Pawel Murias Make the perl5 interop work outside the niecza directory and hopefully o...
pmurias authored
21 [DllImport("p5embed", EntryPoint="p5embed_SvPV_nolen")]
c43c708 Pawel Murias Convert perl 5 string in an extremely naive fashion ignoring utf and nul...
pmurias authored
22 public static extern string SvPV_nolen(IntPtr sv);
23
bef38b1 Pawel Murias Make the perl5 interop work outside the niecza directory and hopefully o...
pmurias authored
24 [DllImport("p5embed", EntryPoint="p5embed_SvPVutf8_nolen")]
bfb4205 Pawel Murias Sending string with nulls in the middle from p5 land works.
pmurias authored
25 public static extern IntPtr SvPVutf8_nolen(IntPtr sv);
26
bef38b1 Pawel Murias Make the perl5 interop work outside the niecza directory and hopefully o...
pmurias authored
27 [DllImport("p5embed", EntryPoint="p5embed_SvPVutf8_length")]
bfb4205 Pawel Murias Sending string with nulls in the middle from p5 land works.
pmurias authored
28 public static extern int SvPVutf8_length(IntPtr sv);
29
bef38b1 Pawel Murias Make the perl5 interop work outside the niecza directory and hopefully o...
pmurias authored
30 [DllImport("p5embed", EntryPoint="p5embed_SvNV")]
f20f832 Pawel Murias Perl5 NV values are converted.
pmurias authored
31 public static extern double SvNV(IntPtr sv);
32
bef38b1 Pawel Murias Make the perl5 interop work outside the niecza directory and hopefully o...
pmurias authored
33 [DllImport("p5embed", EntryPoint="p5embed_SvIOKp")]
18b719f Pawel Murias Perl5 integers are converted rather than wrapped.
pmurias authored
34 public static extern int SvIOKp(IntPtr sv);
35
bef38b1 Pawel Murias Make the perl5 interop work outside the niecza directory and hopefully o...
pmurias authored
36 [DllImport("p5embed", EntryPoint="p5embed_SvNOKp")]
18b719f Pawel Murias Perl5 integers are converted rather than wrapped.
pmurias authored
37 public static extern int SvNOKp(IntPtr sv);
38
bef38b1 Pawel Murias Make the perl5 interop work outside the niecza directory and hopefully o...
pmurias authored
39 [DllImport("p5embed", EntryPoint="p5embed_SvPOKp")]
18b719f Pawel Murias Perl5 integers are converted rather than wrapped.
pmurias authored
40 public static extern int SvPOKp(IntPtr sv);
41
bef38b1 Pawel Murias Make the perl5 interop work outside the niecza directory and hopefully o...
pmurias authored
42 [DllImport("p5embed", EntryPoint="p5embed_SvOK")]
9856167 Pawel Murias Turn p5 undef into Nil.
pmurias authored
43 public static extern int SvOK(IntPtr sv);
44
a9d984a Pawel Murias make perl5 now always rebuilds Niecza.pm.
pmurias authored
45 [DllImport("p5embed", EntryPoint="p5embed_SvRV")]
46 public static extern IntPtr SvRV(IntPtr sv);
47
48 [DllImport("p5embed", EntryPoint="p5embed_sv_isa")]
49 public static extern int sv_isa(IntPtr sv,string name);
50
bef38b1 Pawel Murias Make the perl5 interop work outside the niecza directory and hopefully o...
pmurias authored
51 [DllImport("p5embed", EntryPoint="p5embed_newSVpvn")]
fb15db4 Pawel Murias Passing string with null bytes and unicode to perl5 land correctly.
pmurias authored
52 public static extern IntPtr newSVpvn(IntPtr s,int length);
53
bef38b1 Pawel Murias Make the perl5 interop work outside the niecza directory and hopefully o...
pmurias authored
54 [DllImport("p5embed", EntryPoint="p5embed_SvUTF8_on")]
fb15db4 Pawel Murias Passing string with null bytes and unicode to perl5 land correctly.
pmurias authored
55 public static extern void SvUTF8_on(IntPtr sv);
e1988ad Pawel Murias Perl 6 string can be converted to Perl 5 strings.
pmurias authored
56
bef38b1 Pawel Murias Make the perl5 interop work outside the niecza directory and hopefully o...
pmurias authored
57 [DllImport("p5embed", EntryPoint="p5embed_subcall")]
935bc30 Pawel Murias Perl 5 code refs are invokable.
pmurias authored
58 public static extern IntPtr SubCall(
bf0cd86 Pawel Murias implement S01-perl-5-integration/context.t
pmurias authored
59 int context,
935bc30 Pawel Murias Perl 5 code refs are invokable.
pmurias authored
60 IntPtr[] arguments,
61 int argument_n
62 );
63
a9d984a Pawel Murias make perl5 now always rebuilds Niecza.pm.
pmurias authored
64
65 public delegate int create_LoS_delegate(int len,IntPtr data);
66
67 [DllImport("p5embed", EntryPoint="p5embed_set_create_LoS")]
68 public static extern void Set_p5embed_create_LoS(create_LoS_delegate f);
69
70
bfb4205 Pawel Murias Sending string with nulls in the middle from p5 land works.
pmurias authored
71 // We can't use the standard char* conversion because some strings can contain nulls
72 public static string UnmarshalString(IntPtr sv) {
73 int len = SvPVutf8_length(sv);
74 byte[] target = new byte[len];
75 IntPtr data = SvPVutf8_nolen(sv);
76 Marshal.Copy(data, target, 0, len);
77 return System.Text.Encoding.UTF8.GetString(target);
78 }
79
a9d984a Pawel Murias make perl5 now always rebuilds Niecza.pm.
pmurias authored
80 static Dictionary<int,Variable> ExportedObjects;
81 static int ExportedID;
82
18b719f Pawel Murias Perl5 integers are converted rather than wrapped.
pmurias authored
83 public static Variable SVToVariable(IntPtr sv) {
bf0cd86 Pawel Murias implement S01-perl-5-integration/context.t
pmurias authored
84 if (sv == IntPtr.Zero) {
85 //TODO: check - cargo culted
d67e96f Stefan O'Rear Move all [CORESaved] statics to instance variables of Compartment
authored
86 return Compartment.Top.Nil;
bf0cd86 Pawel Murias implement S01-perl-5-integration/context.t
pmurias authored
87 }
9856167 Pawel Murias Turn p5 undef into Nil.
pmurias authored
88 if (SvOK(sv) == 0) {
d67e96f Stefan O'Rear Move all [CORESaved] statics to instance variables of Compartment
authored
89 return Compartment.Top.Nil;
9856167 Pawel Murias Turn p5 undef into Nil.
pmurias authored
90 }
91
18b719f Pawel Murias Perl5 integers are converted rather than wrapped.
pmurias authored
92 if (SvIOKp(sv) != 0) {
93 return Builtins.MakeInt(SvIV(sv));
f20f832 Pawel Murias Perl5 NV values are converted.
pmurias authored
94 } else if (SvNOKp(sv) != 0) {
95 return Builtins.MakeFloat(SvNV(sv));
c43c708 Pawel Murias Convert perl 5 string in an extremely naive fashion ignoring utf and nul...
pmurias authored
96 } else if (SvPOKp(sv) != 0) {
bfb4205 Pawel Murias Sending string with nulls in the middle from p5 land works.
pmurias authored
97 string s = UnmarshalString(sv); //SvPV_nolen(sv);
d67e96f Stefan O'Rear Move all [CORESaved] statics to instance variables of Compartment
authored
98 return Kernel.BoxAnyMO(s, Compartment.Top.StrMO);
a9d984a Pawel Murias make perl5 now always rebuilds Niecza.pm.
pmurias authored
99 } else if (sv_isa(sv,"Niecza::Object") != 0) {
100 return ExportedObjects[SvIV(SvRV(sv))];
18b719f Pawel Murias Perl5 integers are converted rather than wrapped.
pmurias authored
101 } else {
102 return new SVVariable(sv);
103 }
104 }
1e1a24e Pawel Murias Eval runs basic perl5 code. The Makefile needs review to check if it can
pmurias authored
105
e5a3ec5 Pawel Murias Evaling perl5 code loads the Perl5Interpreter class.
pmurias authored
106 public Perl5Interpreter() {
a9d984a Pawel Murias make perl5 now always rebuilds Niecza.pm.
pmurias authored
107 ExportedObjects = new Dictionary<int,Variable>();
108 ExportedID = 8;
5868454 Load the perl5 side interop support from a directory relative to the
Paweł Murias authored
109 string location = System.Reflection.Assembly.GetExecutingAssembly().Location;
02fe910 Pawel Murias Rename Niecza::Interoperability to Niecza.
pmurias authored
110
111 string[] paths = new string[] {"perl5/Niecza/blib/lib","perl5/Niecza/blib/arch"};
112
113 for (int i=0;i<2;i++) {
114 // Try to construct the path in a platform portable manner
115 string p5lib = Path.GetDirectoryName(Path.GetDirectoryName(location));
116 foreach (string part in paths[i].Split('/')) {
117 p5lib = Path.Combine(p5lib,part);
118 }
119 paths[i] = p5lib;
120 }
a9d984a Pawel Murias make perl5 now always rebuilds Niecza.pm.
pmurias authored
121 Set_p5embed_create_LoS(delegate(int len,IntPtr data) {
122 int id = ExportedID++;
123 IntPtr[] target = new IntPtr[len];
124 Marshal.Copy(data, target, 0, len);
125
126 string[] args = new string[len];
127 for (int i=0;i<len;i++) {
128 args[i] = UnmarshalString(target[i]);
129 }
130 ExportedObjects[id] = Builtins.BoxLoS(args);
131 return id;
132 });
02fe910 Pawel Murias Rename Niecza::Interoperability to Niecza.
pmurias authored
133 Initialize(paths[0],paths[1]);
e5a3ec5 Pawel Murias Evaling perl5 code loads the Perl5Interpreter class.
pmurias authored
134 }
16ef0c8 Pawel Murias cleanup the perl5 interpreter in Perl5Interpreter destructor
pmurias authored
135 ~Perl5Interpreter() {
136 Dispose();
137 }
4266b44 Pawel Murias Argumentless method call on perl5 objects.
pmurias authored
138 public Variable Eval(string code) {
8dbcaa8 Pawel Murias one more debug statement
pmurias authored
139 IntPtr sv = EvalPerl5(code);
140 return SVToVariable(sv);
4266b44 Pawel Murias Argumentless method call on perl5 objects.
pmurias authored
141 }
142 }
143
144 public class SVVariable : Variable {
145 public IntPtr sv;
146 public SVVariable(IntPtr _sv) {
147 sv = _sv;
148 }
149 public override P6any Fetch() {
150 return new SVany(sv);
151 }
152 public override void Store(P6any v) {
153 }
59c6a7b Pawel Murias Unbitrot perl5 interopability.
pmurias authored
154 public override void Freeze(FreezeBuffer fb) {
155 throw new NieczaException("Freezing perl5 SV* NYI.");
156 }
e5a3ec5 Pawel Murias Evaling perl5 code loads the Perl5Interpreter class.
pmurias authored
157 }
4266b44 Pawel Murias Argumentless method call on perl5 objects.
pmurias authored
158 public class SVany : P6any {
159 [DllImport("obj/p5embed.so", EntryPoint="p5method_call")]
a20956d Pawel Murias Arguments are passed to perl 5 methods.
pmurias authored
160 public static extern IntPtr MethodCall(
161 string name,
2e3e4ba Pawel Murias Perl 5 methods can return a value.
pmurias authored
162 IntPtr[] arguments,
163 int argument_n
a20956d Pawel Murias Arguments are passed to perl 5 methods.
pmurias authored
164 );
165
59c6a7b Pawel Murias Unbitrot perl5 interopability.
pmurias authored
166 public override void Freeze(FreezeBuffer fb) {
167 throw new NieczaException("Freezing perl5 SV* NYI.");
168 }
169
fb15db4 Pawel Murias Passing string with null bytes and unicode to perl5 land correctly.
pmurias authored
170
bfb4205 Pawel Murias Sending string with nulls in the middle from p5 land works.
pmurias authored
171 // We can't use the standard char* conversion because some strings can contain nulls
fb15db4 Pawel Murias Passing string with null bytes and unicode to perl5 land correctly.
pmurias authored
172 public static IntPtr MarshalString(string s) {
173 byte[] array = System.Text.Encoding.UTF8.GetBytes(s);
174 int size = Marshal.SizeOf(typeof(byte)) * (array.Length + 1);
175
176 IntPtr ptr = Marshal.AllocHGlobal(size);
177
178 /* This is a hack not to crash on mono!!! */
179 //allocated.Add(ptr, null);
180
181 Marshal.Copy(array, 0, ptr, array.Length);
182 Marshal.WriteByte(ptr, array.Length, 0);
183
184 IntPtr sv = Perl5Interpreter.newSVpvn(ptr,array.Length);
185 Perl5Interpreter.SvUTF8_on(sv);
82ae125 Pawel Murias Fix memory leak.
pmurias authored
186 Marshal.FreeHGlobal(ptr);
fb15db4 Pawel Murias Passing string with null bytes and unicode to perl5 land correctly.
pmurias authored
187 return sv;
bfb4205 Pawel Murias Sending string with nulls in the middle from p5 land works.
pmurias authored
188 }
189
fb15db4 Pawel Murias Passing string with null bytes and unicode to perl5 land correctly.
pmurias authored
190
191
a20956d Pawel Murias Arguments are passed to perl 5 methods.
pmurias authored
192 public static IntPtr VariableToSV(Variable var) {
193 P6any obj = var.Fetch();
194 if (obj is SVany) {
195 return ((SVany)obj).sv;
d67e96f Stefan O'Rear Move all [CORESaved] statics to instance variables of Compartment
authored
196 } else if (obj.Does(Compartment.Top.StrMO)) {
e1988ad Pawel Murias Perl 6 string can be converted to Perl 5 strings.
pmurias authored
197 string s = Kernel.UnboxAny<string>(obj);
fb15db4 Pawel Murias Passing string with null bytes and unicode to perl5 land correctly.
pmurias authored
198 return MarshalString(s);
a20956d Pawel Murias Arguments are passed to perl 5 methods.
pmurias authored
199 } else {
200 throw new NieczaException("can't convert argument to p5 type");
201 }
202 }
4266b44 Pawel Murias Argumentless method call on perl5 objects.
pmurias authored
203
bf0cd86 Pawel Murias implement S01-perl-5-integration/context.t
pmurias authored
204 static int Context(Variable var) {
205 P6any obj = var.Fetch();
206 string s = Kernel.UnboxAny<string>(obj);
207 if (s == "list") {
208 return 0;
209 } else if (s == "scalar") {
210 return 1;
211 } else if (s == "void") {
212 return 2;
213 } else {
214 throw new NieczaException("unknown p5 context type: "+s);
215 }
216 }
217
935bc30 Pawel Murias Perl 5 code refs are invokable.
pmurias authored
218 static IntPtr[] MarshalPositionals(Variable[] pos) {
a20956d Pawel Murias Arguments are passed to perl 5 methods.
pmurias authored
219 IntPtr[] args = new IntPtr[pos.Length];
220 for (int i=0;i<pos.Length;i++) {
221 args[i] = VariableToSV(pos[i]);
222 }
935bc30 Pawel Murias Perl 5 code refs are invokable.
pmurias authored
223 return args;
224 }
225
226 public IntPtr sv;
227 public override Frame InvokeMethod(Frame caller, string name,
228 Variable[] pos, VarHash named) {
229
230 if (name == "postcircumfix:<( )>") {
bf0cd86 Pawel Murias implement S01-perl-5-integration/context.t
pmurias authored
231 int context = 1;
d05a5fe Exporting a single sub works.
Paweł Murias authored
232 if (named != null && named.ContainsKey("context") && named["context"] != null) {
bf0cd86 Pawel Murias implement S01-perl-5-integration/context.t
pmurias authored
233 context = Context(named["context"]);
234 }
935bc30 Pawel Murias Perl 5 code refs are invokable.
pmurias authored
235 IntPtr[] args = MarshalPositionals(pos);
bf0cd86 Pawel Murias implement S01-perl-5-integration/context.t
pmurias authored
236 IntPtr ret = Perl5Interpreter.SubCall(context,args,args.Length);
237
238
935bc30 Pawel Murias Perl 5 code refs are invokable.
pmurias authored
239 caller.resultSlot = Perl5Interpreter.SVToVariable(ret);
240 return caller;
241 } else {
242 IntPtr[] args = MarshalPositionals(pos);
243 IntPtr ret = MethodCall(name,args,args.Length);
244 caller.resultSlot = Perl5Interpreter.SVToVariable(ret);
245 }
246
4266b44 Pawel Murias Argumentless method call on perl5 objects.
pmurias authored
247 return caller;
248 }
a20956d Pawel Murias Arguments are passed to perl 5 methods.
pmurias authored
249
59c6a7b Pawel Murias Unbitrot perl5 interopability.
pmurias authored
250 public override string ReprName() { return "P6opaque"; }
251
4266b44 Pawel Murias Argumentless method call on perl5 objects.
pmurias authored
252 public SVany(IntPtr _sv) {
d67e96f Stefan O'Rear Move all [CORESaved] statics to instance variables of Compartment
authored
253 mo = Compartment.Top.AnyMO;
4266b44 Pawel Murias Argumentless method call on perl5 objects.
pmurias authored
254 sv = _sv;
255 }
256 }
257
Something went wrong with that request. Please try again.