-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtypemap
153 lines (137 loc) · 4.16 KB
/
typemap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
TYPEMAP
Pvoid_t T_PVOID
PWord_t T_WORD_PTR
UWord_t T_UWORD
IWord_t T_IWORD
Str T_STR
INPUT
T_STR
($var.ptr) = SvPV($arg,($var.length));
if ( SvUTF8($arg) ) {
/* TODO: handle warning properly if there's an embedded null
in the input string. Right now, ordinary %s interpolation
will halt. */
warn(\"Dropping UTF8 flag for '%s'\",
$var.ptr);
}
T_PVOID
/* It should never, ever happen that I get pointers that could
suffer truncation because Judy always allocates everything and
that's at the native size instead of perl's long long. */
$var = (Pvoid_t)(SvOK($arg) ? (Word_t)SvUV($arg) : 0);
T_WORD_PTR
/* It should never, ever happen that I get pointers that could
suffer truncation because Judy always allocates everything and
that's at the native size instead of perl's long long. */
$var = INT2PTR($type,SvUV($arg));
T_IWORD
/* Accept:
- IV that fits in (long int).
- IV that requires more bits that fit in (long int). Truncate
it to LONG_MAX. Throw a warning.
- UV that fits in (long int) without using the sign bit.
- UV that fits in (long int) using the sign bit. Truncate it to
LONG_MAX and throw a warning.
- UV that doesn't fit in (long int). Truncate it to LONG_MAX
and throw a warning.
- Cast everything else to IV or NV and apply the above rules.
*/
if ( SvUOK($arg) ) {
if ( SvUV($arg) > LONG_MAX ) {
$var = LONG_MAX;
warn(\"Truncating %\"UVuf\" to %ld because your number is larger than fits in a signed integer\",
SvUV($arg), LONG_MAX);
}
else {
$var = (long int)SvIV($arg);
}
}
else {
if (LONGSIZE == IVSIZE) {
assert( LONG_MIN <= SvIV($arg) && SvIV($arg) <= LONG_MAX );
$var = SvIV($arg);
} else {
if ( SvIV($arg) > LONG_MAX ) {
$var = LONG_MAX;
warn(\"Truncating %\"IVdf\" to %ld because your number is larger than fits in a signed integer\",
SvIV($arg), LONG_MAX);
}
else if ( SvIV($arg) < LONG_MIN ) {
$var = LONG_MIN;
warn(\"Truncating %\"IVdf\" to %ld because your number is smaller than fits in a signed integer\",
SvIV($arg), LONG_MIN);
}
else {
$var = SvIV($arg);
}
}
}
T_UWORD
/* Accept:
- IV that's -1.
- IV that's negative, coerce to 0 and warn.
- IV/UV that fits in (unsigned long int)
- IV/UV that requires more bits than fit in (unsigned long
int). Truncate it and throw a warning.
- Cast everything else to UV and apply the above rules
*/
if ( SvIOK($arg) && SvIV($arg) < 0 ) {
if ( SvIV($arg) == -1 ) {
$var = -1;
}
else {
$var = 0;
warn(\"Coercing %\"IVdf\" to 0. Can't use negative values as keys.\",
SvIV($arg));
}
}
else {
if (LONGSIZE == UVSIZE) {
$var = SvUV($arg);
}
else {
if (SvUV($arg) > ULONG_MAX) {
$var = LONG_MAX;
warn(\"Truncating %\"UVuf\" to %lu because your number is larger than fits in an unsigned integer\",
SvUV($arg), ULONG_MAX);
}
else {
$var = SvUV($arg);
}
}
}
OUTPUT
T_STR
SvUPGRADE($arg,SVt_PV);
sv_setpvn(
$arg,
$var.ptr,
$var.length ? $var.length : strlen( $var.ptr )
);
T_PVOID
SvUPGRADE($arg,SVt_IV);
if ( (unsigned long int)$var > LONG_MAX ) {
sv_setuv($arg,PTR2UV($var));
}
else {
sv_setiv($arg,PTR2IV($var));
}
T_IWORD
SvUPGRADE($arg,SVt_IV);
sv_setiv($arg, (signed long int)$var);
T_UWORD
SvUPGRADE($arg,SVt_IV);
if ( $var > LONG_MAX ) {
sv_setuv($arg,PTR2UV($var));
}
else {
sv_setiv($arg,PTR2IV($var));
}
T_WORD_PTR
SvUPGRADE($arg,SVt_IV);
if ( (unsigned long int)$var > LONG_MAX ) {
sv_setuv($arg,PTR2UV($var));
}
else {
sv_setiv($arg,PTR2IV($var));
}