Skip to content

Commit ad198bc

Browse files
committed
version 0.75
version 0.75 - see Changes
1 parent 2c640f6 commit ad198bc

19 files changed

+198
-76
lines changed

API.h

+44-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#
99
*/
1010

11+
#define NEED_sv_2pv_flags
1112
#include "ppport.h"
1213

1314
/* see https://rt.cpan.org/Ticket/Display.html?id=80217
@@ -139,8 +140,11 @@ typedef struct {
139140
//with static asserts
140141
#define CALL_PL_ST_EXTEND 3
141142

142-
#define PREP_SV_SET(sv) if(SvTHINKFIRST((sv))) sv_force_normal_flags((sv), SV_COW_DROP_PV)
143-
143+
#if PERL_BCDVERSION >= 0x5007001
144+
# define PREP_SV_SET(sv) if(SvTHINKFIRST((sv))) sv_force_normal_flags((sv), SV_COW_DROP_PV)
145+
#else
146+
# define PREP_SV_SET(sv) if(SvTHINKFIRST((sv))) sv_force_normal((sv))
147+
#endif
144148
//C=Callback, CIATP=Callback::IATPatch
145149
#define W32AC_T HV
146150
#define W32ACIATP_T HV
@@ -150,3 +154,41 @@ typedef struct {
150154
#ifndef WC_NO_BEST_FIT_CHARS
151155
# define WC_NO_BEST_FIT_CHARS 0x00000400
152156
#endif
157+
158+
#ifndef PERL_ARGS_ASSERT_CROAK_XS_USAGE
159+
#define PERL_ARGS_ASSERT_CROAK_XS_USAGE assert(cv); assert(params)
160+
161+
/* prototype to pass -Wmissing-prototypes */
162+
STATIC void
163+
S_croak_xs_usage(pTHX_ const CV *const cv, const char *const params);
164+
165+
STATIC void
166+
S_croak_xs_usage(pTHX_ const CV *const cv, const char *const params)
167+
{
168+
const GV *const gv = CvGV(cv);
169+
170+
PERL_ARGS_ASSERT_CROAK_XS_USAGE;
171+
172+
if (gv) {
173+
const char *const gvname = GvNAME(gv);
174+
const HV *const stash = GvSTASH(gv);
175+
const char *const hvname = stash ? HvNAME(stash) : NULL;
176+
177+
if (hvname)
178+
Perl_croak_nocontext("Usage: %s::%s(%s)", hvname, gvname, params);
179+
else
180+
Perl_croak_nocontext("Usage: %s(%s)", gvname, params);
181+
} else {
182+
/* Pants. I don't think that it should be possible to get here. */
183+
Perl_croak_nocontext("Usage: CODE(0x%"UVxf")(%s)", PTR2UV(cv), params);
184+
}
185+
}
186+
#undef PERL_ARGS_ASSERT_CROAK_XS_USAGE
187+
188+
#ifdef PERL_IMPLICIT_CONTEXT
189+
#define croak_xs_usage(a,b) S_croak_xs_usage(aTHX_ a,b)
190+
#else
191+
#define croak_xs_usage S_croak_xs_usage
192+
#endif
193+
194+
#endif

API.pm

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ use File::Basename ();
5858
#######################################################################
5959
# STATIC OBJECT PROPERTIES
6060
#
61-
$VERSION = '0.74';
61+
$VERSION = '0.75';
6262

6363
#### some package-global hash to
6464
#### keep track of the imported

Callback.pm

+17-6
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use strict;
1616
use warnings;
1717
use vars qw( $VERSION @ISA $Stage2FuncPtrPkd );
1818

19-
$VERSION = '0.74';
19+
$VERSION = '0.75';
2020

2121

2222
require Exporter; # to export the constants to the main:: space
@@ -42,9 +42,12 @@ use Config;
4242
BEGIN {
4343
#there is supposed to be 64 bit IVs on 32 bit perl compatibility here
4444
#but it is untested
45-
eval "sub IVSIZE () { ".length(pack('J',0))." }";
45+
#Win64 added in 5.7.3
46+
eval "sub IVSIZE () { ".length(pack($] >= 5.007003 ? 'J' : 'I' ,0))." }";
4647
#what kind of stack processing/calling convention/machine code we needed
4748
eval "sub ISX64 () { ".(index($Config{'archname'},"MSWin32-x64") == 0 ? 1 : 0)." }";
49+
eval 'sub OPV () {'.$].'}';
50+
sub OPV();
4851
sub CONTEXT_XMM0();
4952
sub CONTEXT_RAX();
5053
*UseMI64 = *Win32::API::UseMI64; #keep UseMI64 out of export list
@@ -53,6 +56,9 @@ BEGIN {
5356
*PTRSIZE = *Win32::API::PTRSIZE;
5457
sub PTRLET ();
5558
*PTRLET = *Win32::API::Type::pointer_pack_type;
59+
if(OPV <= 5.008000){ #dont have unpackstring in C
60+
eval('sub _CallUnpack {return unpack($_[0], $_[1]);}');
61+
}
5662
}
5763
#######################################################################
5864
# dynamically load in the API extension module.
@@ -179,14 +185,19 @@ sub MakeStruct {
179185
if(! ISX64 ) {
180186
*RunCB = sub {#32 bits
181187
my $self = $_[0];
182-
my (@pass_arr, $return, $typeletter, $inbytes);
188+
my (@pass_arr, $return, $typeletter, $inbytes, @arr);
183189
$inbytes = $self->{inbytes};
184190
#first is ebp copy then ret address
185191
$inbytes += PTRSIZE * 2;
186192
my $paramcount = $inbytes / PTRSIZE ;
187-
my $stackstr = unpack('P['.$inbytes.']', pack(PTRLET, $_[1]));
188-
my @arr = unpack("(a[".PTRLET."])[$paramcount]",$stackstr);
189-
#print Dumper(\@arr);
193+
my $stackstr = unpack('P'.$inbytes, pack(PTRLET, $_[1]));
194+
#pack () were added in 5.7.2
195+
if (OPV > 5.007002) {
196+
@arr = unpack("(a[".PTRLET."])[$paramcount]",$stackstr);
197+
} else {
198+
#letter can not be used for size, must be numeric on 5.6
199+
@arr = unpack(("a4") x $paramcount,$stackstr);
200+
}
190201
shift @arr, shift @arr; #remove ebp copy and ret address
191202
$paramcount -= 2;
192203
$return = &{$self->{sub}}(@{MakeParamArr($self, \@arr)});

Callback/Callback.xs

+12-4
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,6 @@ BOOL WINAPI DllMain(
7979
#define boolSV(b) ((b) ? &sv_yes : &sv_no)
8080
#endif
8181

82-
#ifndef PL_na
83-
# define PL_na na
84-
#endif
85-
8682
#ifndef SvPV_nolen
8783
# define SvPV_nolen(sv) SvPV(sv, PL_na)
8884
#endif
@@ -482,6 +478,9 @@ PREINIT:
482478
int iTypes;
483479
AV * Types;
484480
I32 lenTypes;
481+
#if (PERL_API_VERSION_LE(5, 8, 0))
482+
SV * unpacktypeSV = sv_newmortal();
483+
#endif
485484
PPCODE:
486485
//intypes array ref is always created in PM file
487486
Types = (AV*)SvRV(*hv_fetch(self, "intypes", sizeof("intypes")-1, 0));
@@ -582,8 +581,17 @@ PPCODE:
582581
}
583582
goto HAVEUNPACKED;
584583
}
584+
#if ! (PERL_API_VERSION_LE(5, 8, 0))
585585
PUTBACK;
586586
unpackstring(&type, &type+1, packedParam, packedParam+SvCUR(packedParamSV), 0);
587+
#else /* dont have unpackstring */
588+
PUSHMARK(SP);
589+
PUSHs(unpacktypeSV);
590+
PUSHs(packedParamSV);
591+
PUTBACK;
592+
sv_setpvn(unpacktypeSV,&type, 1);
593+
call_pv("Win32::API::Callback::_CallUnpack", G_SCALAR);
594+
#endif
587595
SPAGAIN;
588596
unpackedParamSV = POPs;
589597
#ifdef USEMI64

Callback/Makefile.PL

+1
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,6 @@ sub MY::post_constants {
3232
)),
3333
'VERSION_FROM' => '../API.pm',
3434
'dist' => {COMPRESS => 'gzip -9f', SUFFIX => 'gz'},
35+
($] > 5.007000 ? () : (TYPEMAPS => ['../typemap56'])),
3536
);
3637

Callback/t/02_Callback.t

+11-26
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use strict;
99
use Config;
1010
use Test::More;
1111
use Math::Int64 qw( int64 hex_to_uint64 uint64_to_hex);
12-
plan tests => 21;
12+
plan tests => 20;
1313
use vars qw(
1414
$function
1515
$result
@@ -18,11 +18,11 @@ use vars qw(
1818
);
1919

2020
BEGIN {
21-
eval "sub PTR_SIZE () { ".length(pack('J',0))." }";
21+
eval "sub PTR_SIZE () { ".length(pack(($] <= 5.007002 ? 'L':'J'),0))." }";
2222
}
2323
use_ok('Win32::API');
2424
use_ok('Win32::API::Callback');
25-
use_ok('Win32::API::Test');
25+
use Win32::API::Test;
2626

2727

2828
ok(1, 'loaded');
@@ -46,21 +46,6 @@ diag('Compiler version:', $cc_vers);
4646
'N',
4747
'N'
4848
);
49-
#make the the ActiveState distropref patch succeed
50-
=pod
51-
}
52-
53-
SKIP: {
54-
55-
skip('because callbacks currently /SEGFAULT/ all compilers but MSVC 6+', 1)
56-
unless $cc_name eq 'cl' && $cc_vers >= 12;
57-
58-
$result = $function->Call( $callback, 21 );
59-
is($result, 42, 'callback function works');
60-
}
61-
62-
#
63-
=cut
6449
ok($callback, 'callback function defined');
6550

6651
$function = new Win32::API($test_dll, 'do_callback', 'KI', 'I');
@@ -80,16 +65,16 @@ $callback = Win32::API::Callback->new(
8065
$chr = $_[0] & 0xFF; #x64 fill high bits with garbage
8166
die "bad char" if chr($chr) ne 'P';
8267
if(PTR_SIZE == 4){
83-
my ($low,$high) = unpack('JJ', $_[1]);
68+
my ($low,$high) = unpack(IV_LET.IV_LET, $_[1]);
8469
die "bad unsigned int64" if $low != 0xABCDEF12;
8570
die "bad unsigned int64" if $high != 0x12345678;
8671
}else{
8772
print "0x".unpack('H[16]', $_[1])."\n";
8873
no warnings 'portable', 'overflow'; #silence on 32 bits
8974
die "bad unsigned int64" if $_[1] != eval "0x12345678ABCDEF12";
9075
}
91-
my $f4char = unpack('P[4]',pack('J',$_[2]));
92-
die "bad 4 char struct" if $f4char ne "JAPH";
76+
my $f4char = unpack('P4',pack(IV_LET,$_[2]));
77+
die "bad 4 char struct \"$f4char\"" if $f4char ne "JAPH";
9378
die "bad float" if $_[3] != 2.5;
9479
die "bad double" if $_[4] != 3.5;
9580
return 70000;
@@ -117,7 +102,7 @@ SKIP: {
117102
$chr = $_[0] & 0xFF; #x64 fill high bits with garbage
118103
die "bad char" if chr($chr) ne 'P';
119104
die "bad unsigned int64" if $_[1] != hex_to_uint64("0x12345678ABCDEF12");
120-
my $f4char = unpack('P[4]',pack('J',$_[2]));
105+
my $f4char = unpack('P4',pack(IV_LET,$_[2]));
121106
die "bad 4 char struct" if $f4char ne "JAPH";
122107
die "bad float" if $_[3] != 2.5;
123108
die "bad double" if $_[4] != 3.5;
@@ -172,15 +157,15 @@ $callback = Win32::API::Callback->new(
172157
$chr = $_[0] & 0xFF;
173158
die "bad char" if chr($chr) ne 'P';
174159
if(PTR_SIZE == 4){
175-
my ($low,$high) = unpack('JJ', $_[1]);
160+
my ($low,$high) = unpack(IV_LET.IV_LET, $_[1]);
176161
die "bad unsigned int64" if $low != 0xABCDEF12;
177162
die "bad unsigned int64" if $high != 0x12345678;
178163
}else{
179164
no warnings 'portable', 'overflow'; #silence on 32 bits
180165
die "bad unsigned int64" if $_[1] != 0x12345678ABCDEF12;
181166
}
182167
my $f4char;
183-
$f4char = unpack('P[4]',pack('J',$_[2]));
168+
$f4char = unpack('P4',pack(IV_LET,$_[2]));
184169
die "bad 4 char struct" if $f4char ne "JAPH";
185170
die "bad float" if $_[3] != 2.5;
186171
die "bad double" if $_[4] != 3.5;
@@ -232,7 +217,7 @@ $callback = Win32::API::Callback->new(
232217
#print Dumper(\@_);
233218
ok(@_ == 0, "@_ should be empty");
234219
if(PTR_SIZE == 4){
235-
return pack('JJ', 0x30004000, 0x80002000);
220+
return pack(IV_LET.IV_LET, 0x30004000, 0x80002000);
236221
}
237222
else{
238223
no warnings 'portable', 'overflow'; #silence on 32 bits
@@ -248,7 +233,7 @@ $result = $function->Call($callback);
248233
{
249234
no warnings 'portable', 'overflow'; #silence on 32 bits
250235
is($result,
251-
PTR_SIZE == 4 ? pack('JJ', 0x30004000, 0x80002000) : 0x8000200030004000
236+
PTR_SIZE == 4 ? pack(IV_LET.IV_LET, 0x30004000, 0x80002000) : 0x8000200030004000
252237
, "do_callback_void_q was successful");
253238
}
254239
#

Callback/t/iat.t

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ $ptrsize = PTR_SIZE;
3737
my $i = 0;
3838
$callback = Win32::API::Callback->new(
3939
sub {
40-
my($low, $hi) = unpack('LL', unpack('P[8]', pack('J', $_[0])));
40+
my($low, $hi) = unpack('LL', unpack('P8', pack(IV_LET , $_[0])));
4141
$hi = 0;
4242
$low = $i;
4343
$i++;
@@ -161,7 +161,7 @@ tco\276\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0PE\0\0L\1\6\0\223\0028P\0
161161
undef($patch); #done let old IATPatch change the GLR for the next call, DESTROY happens
162162
#after the obj was assigned to but before next line
163163
$patch = Win32::API::Callback::IATPatch ->new($callback,
164-
unpack('J', pack('P', $BrokenModule)), 'kernel32.dll', 'QueryPerformanceCounter');
164+
unpack(IV_LET, pack('P', $BrokenModule)), 'kernel32.dll', 'QueryPerformanceCounter');
165165
ok($^E == 193 && ! defined $patch , "IATPatch claims corrupt DLL is corrupt ".($^E+0));
166166
#193 = ERROR_BAD_EXE_FORMAT
167167
$patch = Win32::API::Callback::IATPatch ->new($callback,

Callback/t/threading_fails.t

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ sub cb {
2222
}
2323
my $callback = Win32::API::Callback->new(\&cb, "L", "N");
2424

25+
diag("This might crash");
26+
2527
#$callback->{'code'}, no other way to do it ATM, even though not "public"
2628
my $hnd = $function->Call(0, 0, $callback->{'code'}, 0, 0, 0);
2729
ok($hnd, "CreateThread worked");

Changes

+8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
History of Win32::API perl extension.
22

3+
2013-01-09 Win32::API v0.75 bulk88
4+
- Fixed/added, alpha Perl 5.6.2 support has been added, ::API will compile,
5+
will not crash except for randomly threading_fails.t . Many tests fail due
6+
to prerequities not being met. 00_API.t should pass on 5.6.2 with zero
7+
failures wWITHOUT prereqs. Other tests require Math::Int64 and
8+
Encode::compat.
9+
- Removed, distropref workaround for ActiveState's PPM system (AS fixed it)
10+
311
2012-11-21 Win32::API v0.74 bulk88
412
- Fixed, non threaded Perl fix from Reini Urban
513
- Fixed, Perl 5.8 in Struct.pm syntax error (cpantesters report)

MANIFEST

+1
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,4 @@ Test.pm
7373
TODO
7474
Type.pm
7575
TYPEMAP
76+
typemap56

Test.pm

+2
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ BEGIN {
108108
eval ' sub PTR_LET () { "'
109109
.($Config{ptrsize} == 8 ? 'Q' : 'L').
110110
'" }';
111+
eval 'sub IV_LET () { '.($] <= 5.007002 ? 'L':'J').' }';
112+
eval 'sub IV_SIZE () { '.length(pack(IV_LET(),0)).' }';
111113
package Win32::API::Test;
112114
}
113115

Type.pm

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use strict;
1616
use warnings;
1717
use vars qw( %Known %PackSize %Modifier %Pointer $VERSION @ISA );
1818

19-
$VERSION = '0.66';
19+
$VERSION = '0.67';
2020

2121
use Carp;
2222
BEGIN{
@@ -279,7 +279,7 @@ sub Pack {
279279
else{
280280
if(length($_[2]) < 8){
281281
warn("Win32::API::Call value for 64 bit integer is under 8 bytes long");
282-
$_[2] = pack('a[8]', $_[2]);
282+
$_[2] = pack('a8', $_[2]);
283283
}
284284
}
285285
return;

0 commit comments

Comments
 (0)