Skip to content

Commit

Permalink
make perl5 now always rebuilds Niecza.pm.
Browse files Browse the repository at this point in the history
Added Niecza::create_LoS which creates a Perl6 list of string from p5
land.
  • Loading branch information
pmurias committed Feb 26, 2012
1 parent 09d5111 commit a9d984a
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 2 deletions.
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
33 changes: 33 additions & 0 deletions lib/Perl5Interpreter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Runtime.InteropServices;
using System;
using System.IO;
using System.Collections.Generic;
using Niecza.Serialization;

public class Perl5Interpreter : IForeignInterpreter {
Expand Down Expand Up @@ -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);

Expand All @@ -54,6 +61,13 @@ public static extern IntPtr SubCall(
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);
Expand All @@ -63,6 +77,9 @@ public static string UnmarshalString(IntPtr sv) {
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
Expand All @@ -79,12 +96,16 @@ public static Variable SVToVariable(IntPtr sv) {
} 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"};
Expand All @@ -97,6 +118,18 @@ public Perl5Interpreter() {
}
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() {
Expand Down
14 changes: 14 additions & 0 deletions lib/p5embed.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
}
Expand Down
1 change: 1 addition & 0 deletions perl5/Niecza/lib/Niecza.pm
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ require XSLoader;
XSLoader::load('Niecza', $VERSION);

use Niecza::Helpers;
use Niecza::Object;

=head1 SYNOPSIS
Expand Down
20 changes: 20 additions & 0 deletions perl5/Niecza/lib/Niecza.xs
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 2 additions & 0 deletions perl5/Niecza/lib/Niecza/Object.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
package Niecza::Object;
1;
1 change: 0 additions & 1 deletion perl5/build_interop
Original file line number Diff line number Diff line change
Expand Up @@ -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");
11 changes: 11 additions & 0 deletions t/p5/create_LoS.t
Original file line number Diff line number Diff line change
@@ -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.