Browse files

make perl5 now always rebuilds Niecza.pm.

Added Niecza::create_LoS which creates a Perl6 list of string from p5
land.
  • Loading branch information...
1 parent 09d5111 commit a9d984a6843b57d39d596ca27507228cb796972a @pmurias pmurias committed Feb 26, 2012
Showing with 87 additions and 2 deletions.
  1. +6 −1 Makefile
  2. +33 −0 lib/Perl5Interpreter.cs
  3. +14 −0 lib/p5embed.c
  4. +1 −0 perl5/Niecza/lib/Niecza.pm
  5. +20 −0 perl5/Niecza/lib/Niecza.xs
  6. +2 −0 perl5/Niecza/lib/Niecza/Object.pm
  7. +0 −1 perl5/build_interop
  8. +11 −0 t/p5/create_LoS.t
View
7 Makefile
@@ -55,7 +55,12 @@ obj/Kernel.dll: $(patsubst %,lib/%,$(cskernel)) lib/unidata
$(CSC) /target:exe /out:obj/Kernel.dll /lib:obj /unsafe+ \
/res:lib/unidata $(patsubst %,lib/%,$(cskernel))
-perl5: obj/Perl5Interpreter.dll obj/p5embed.so
+
+.PHONY: Niecza_pm
+perl5: obj/Perl5Interpreter.dll obj/p5embed.so Niecza_pm
+Niecza_pm:
+ cd perl5/Niecza;perl Build.PL;perl Build
+
obj/Perl5Interpreter.dll: obj/Run.Kernel.dll lib/Perl5Interpreter.cs
$(CSC) /target:library /lib:obj /out:obj/Perl5Interpreter.dll /r:Run.Kernel.dll lib/Perl5Interpreter.cs
View
33 lib/Perl5Interpreter.cs
@@ -2,6 +2,7 @@
using System.Runtime.InteropServices;
using System;
using System.IO;
+using System.Collections.Generic;
using Niecza.Serialization;
public class Perl5Interpreter : IForeignInterpreter {
@@ -41,6 +42,12 @@ public class Perl5Interpreter : IForeignInterpreter {
[DllImport("p5embed", EntryPoint="p5embed_SvOK")]
public static extern int SvOK(IntPtr sv);
+ [DllImport("p5embed", EntryPoint="p5embed_SvRV")]
+ public static extern IntPtr SvRV(IntPtr sv);
+
+ [DllImport("p5embed", EntryPoint="p5embed_sv_isa")]
+ public static extern int sv_isa(IntPtr sv,string name);
+
[DllImport("p5embed", EntryPoint="p5embed_newSVpvn")]
public static extern IntPtr newSVpvn(IntPtr s,int length);
@@ -54,6 +61,13 @@ public class Perl5Interpreter : IForeignInterpreter {
int argument_n
);
+
+ public delegate int create_LoS_delegate(int len,IntPtr data);
+
+ [DllImport("p5embed", EntryPoint="p5embed_set_create_LoS")]
+ public static extern void Set_p5embed_create_LoS(create_LoS_delegate f);
+
+
// We can't use the standard char* conversion because some strings can contain nulls
public static string UnmarshalString(IntPtr sv) {
int len = SvPVutf8_length(sv);
@@ -63,6 +77,9 @@ int argument_n
return System.Text.Encoding.UTF8.GetString(target);
}
+ static Dictionary<int,Variable> ExportedObjects;
+ static int ExportedID;
+
public static Variable SVToVariable(IntPtr sv) {
if (sv == IntPtr.Zero) {
//TODO: check - cargo culted
@@ -79,12 +96,16 @@ int argument_n
} else if (SvPOKp(sv) != 0) {
string s = UnmarshalString(sv); //SvPV_nolen(sv);
return Kernel.BoxAnyMO(s, Kernel.StrMO);
+ } else if (sv_isa(sv,"Niecza::Object") != 0) {
+ return ExportedObjects[SvIV(SvRV(sv))];
} else {
return new SVVariable(sv);
}
}
public Perl5Interpreter() {
+ ExportedObjects = new Dictionary<int,Variable>();
+ ExportedID = 8;
string location = System.Reflection.Assembly.GetExecutingAssembly().Location;
string[] paths = new string[] {"perl5/Niecza/blib/lib","perl5/Niecza/blib/arch"};
@@ -97,6 +118,18 @@ int argument_n
}
paths[i] = p5lib;
}
+ Set_p5embed_create_LoS(delegate(int len,IntPtr data) {
+ int id = ExportedID++;
+ IntPtr[] target = new IntPtr[len];
+ Marshal.Copy(data, target, 0, len);
+
+ string[] args = new string[len];
+ for (int i=0;i<len;i++) {
+ args[i] = UnmarshalString(target[i]);
+ }
+ ExportedObjects[id] = Builtins.BoxLoS(args);
+ return id;
+ });
Initialize(paths[0],paths[1]);
}
~Perl5Interpreter() {
View
14 lib/p5embed.c
@@ -16,6 +16,12 @@ xs_init(pTHX)
newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
}
+/* Haven't found a better way to call managed code*/
+int (*p5embed_create_LoS)(int,SV**);
+void p5embed_set_create_LoS(int (*f)(int,SV**)) {
+ p5embed_create_LoS = f;
+}
+
static PerlInterpreter *my_perl;
void p5embed_initialize(char* path1,char* path2)
{
@@ -137,6 +143,14 @@ char* p5embed_SvPV_nolen(SV* sv) {
return SvPV_nolen(sv);
}
+
+SV* p5embed_SvRV(SV* sv) {
+ return SvRV(sv);
+}
+int p5embed_sv_isa(SV* sv,char* name) {
+ return sv_isa(sv,name);
+}
+
char* p5embed_SvPVutf8_nolen(SV* sv) {
return SvPVutf8_nolen(sv);
}
View
1 perl5/Niecza/lib/Niecza.pm
@@ -19,6 +19,7 @@ require XSLoader;
XSLoader::load('Niecza', $VERSION);
use Niecza::Helpers;
+use Niecza::Object;
=head1 SYNOPSIS
View
20 perl5/Niecza/lib/Niecza.xs
@@ -4,6 +4,26 @@
#include "ppport.h"
+extern int (*p5embed_create_LoS)(int,SV**);
MODULE = Niecza PACKAGE = Niecza
+SV*
+create_LoS(SV* arg)
+ CODE:
+ AV* array = SvRV(arg);
+ int len = av_len(array)+1;
+ int i = 0;
+ SV** svs = malloc(sizeof(SV*) * len);
+ for (i=0;i<len;i++) {
+ SV** ptr = av_fetch(array,i,0);
+ svs[i] = *ptr;
+ }
+ int LoS = p5embed_create_LoS(len,svs);
+ SV* pointer = newSViv(PTR2IV(LoS));
+ SV* object = newRV_noinc(pointer);
+ HV* class = gv_stashpv("Niecza::Object", 0);
+ sv_bless(object, class);
+ RETVAL = object;
+ OUTPUT:
+ RETVAL
View
2 perl5/Niecza/lib/Niecza/Object.pm
@@ -0,0 +1,2 @@
+package Niecza::Object;
+1;
View
1 perl5/build_interop
@@ -17,4 +17,3 @@ chomp($ldopts);
my $cc = "$Config{cc} -m32 -shared";
system("$cc lib/p5embed.c -o $path $ccopts $ldopts");
-system("cd perl5/Niecza;perl Build.PL;perl Build");
View
11 t/p5/create_LoS.t
@@ -0,0 +1,11 @@
+use v6;
+use Test;
+my $LoS = eval(:lang<perl5>,q:to/PERL5/);
+use Data::Dumper;
+my $LoS = Niecza::create_LoS(["foo1","bar1","baz1"]);
+$LoS;
+PERL5
+is $LoS[0],"foo1";
+is $LoS[1],"bar1";
+is $LoS[2],"baz1";
+done;

0 comments on commit a9d984a

Please sign in to comment.