OLD | NEW |
1 #!/usr/bin/env perl | 1 #!/usr/bin/env perl |
2 # Copyright 2009 The Go Authors. All rights reserved. | 2 # Copyright 2009 The Go Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style | 3 # Use of this source code is governed by a BSD-style |
4 # license that can be found in the LICENSE file. | 4 # license that can be found in the LICENSE file. |
5 | 5 |
6 # This program reads a file containing function prototypes | 6 # This program reads a file containing function prototypes |
7 # (like syscall_darwin.go) and generates system call bodies. | 7 # (like syscall_darwin.go) and generates system call bodies. |
8 # The prototypes are marked by lines beginning with "//sys" | 8 # The prototypes are marked by lines beginning with "//sys" |
9 # and read like func declarations if //sys is replaced by func, but: | 9 # and read like func declarations if //sys is replaced by func, but: |
10 # * The parameter lists must give a name for each argument. | 10 # * The parameter lists must give a name for each argument. |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 foreach my $p (@out) { | 125 foreach my $p (@out) { |
126 my ($name, $type) = parseparam($p); | 126 my ($name, $type) = parseparam($p); |
127 if($type eq "error") { | 127 if($type eq "error") { |
128 $errvar = $name; | 128 $errvar = $name; |
129 last; | 129 last; |
130 } | 130 } |
131 } | 131 } |
132 | 132 |
133 # Prepare arguments to Syscall. | 133 # Prepare arguments to Syscall. |
134 my @args = (); | 134 my @args = (); |
| 135 my @uses = (); |
135 my $n = 0; | 136 my $n = 0; |
136 foreach my $p (@in) { | 137 foreach my $p (@in) { |
137 my ($name, $type) = parseparam($p); | 138 my ($name, $type) = parseparam($p); |
138 if($type =~ /^\*/) { | 139 if($type =~ /^\*/) { |
139 push @args, "uintptr(unsafe.Pointer($name))"; | 140 push @args, "uintptr(unsafe.Pointer($name))"; |
140 } elsif($type eq "string" && $errvar ne "") { | 141 } elsif($type eq "string" && $errvar ne "") { |
141 $text .= "\tvar _p$n *byte\n"; | 142 $text .= "\tvar _p$n *byte\n"; |
142 $text .= "\t_p$n, $errvar = BytePtrFromString($name)\n"; | 143 $text .= "\t_p$n, $errvar = BytePtrFromString($name)\n"; |
143 $text .= "\tif $errvar != nil {\n\t\treturn\n\t}\n"; | 144 $text .= "\tif $errvar != nil {\n\t\treturn\n\t}\n"; |
144 push @args, "uintptr(unsafe.Pointer(_p$n))"; | 145 push @args, "uintptr(unsafe.Pointer(_p$n))"; |
| 146 push @uses, "use(unsafe.Pointer(_p$n))"; |
145 $n++; | 147 $n++; |
146 } elsif($type eq "string") { | 148 } elsif($type eq "string") { |
147 print STDERR "$ARGV:$.: $func uses string arguments, but
has no error return\n"; | 149 print STDERR "$ARGV:$.: $func uses string arguments, but
has no error return\n"; |
148 $text .= "\tvar _p$n *byte\n"; | 150 $text .= "\tvar _p$n *byte\n"; |
149 $text .= "\t_p$n, _ = BytePtrFromString($name)\n"; | 151 $text .= "\t_p$n, _ = BytePtrFromString($name)\n"; |
150 push @args, "uintptr(unsafe.Pointer(_p$n))"; | 152 push @args, "uintptr(unsafe.Pointer(_p$n))"; |
| 153 push @uses, "use(unsafe.Pointer(_p$n))"; |
151 $n++; | 154 $n++; |
152 } elsif($type =~ /^\[\](.*)/) { | 155 } elsif($type =~ /^\[\](.*)/) { |
153 # Convert slice into pointer, length. | 156 # Convert slice into pointer, length. |
154 # Have to be careful not to take address of &a[0] if len
== 0: | 157 # Have to be careful not to take address of &a[0] if len
== 0: |
155 # pass dummy pointer in that case. | 158 # pass dummy pointer in that case. |
156 # Used to pass nil, but some OSes or simulators reject w
rite(fd, nil, 0). | 159 # Used to pass nil, but some OSes or simulators reject w
rite(fd, nil, 0). |
157 $text .= "\tvar _p$n unsafe.Pointer\n"; | 160 $text .= "\tvar _p$n unsafe.Pointer\n"; |
158 $text .= "\tif len($name) > 0 {\n\t\t_p$n = unsafe.Point
er(\&${name}[0])\n\t}"; | 161 $text .= "\tif len($name) > 0 {\n\t\t_p$n = unsafe.Point
er(\&${name}[0])\n\t}"; |
159 $text .= " else {\n\t\t_p$n = unsafe.Pointer(&_zero)\n\t
}"; | 162 $text .= " else {\n\t\t_p$n = unsafe.Pointer(&_zero)\n\t
}"; |
160 $text .= "\n"; | 163 $text .= "\n"; |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 } | 274 } |
272 if($reg ne "e1" || $plan9) { | 275 if($reg ne "e1" || $plan9) { |
273 $body .= "\t$name = $type($reg)\n"; | 276 $body .= "\t$name = $type($reg)\n"; |
274 } | 277 } |
275 } | 278 } |
276 if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") { | 279 if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") { |
277 $text .= "\t$call\n"; | 280 $text .= "\t$call\n"; |
278 } else { | 281 } else { |
279 $text .= "\t$ret[0], $ret[1], $ret[2] := $call\n"; | 282 $text .= "\t$ret[0], $ret[1], $ret[2] := $call\n"; |
280 } | 283 } |
| 284 foreach my $use (@uses) { |
| 285 $text .= "\t$use\n"; |
| 286 } |
281 $text .= $body; | 287 $text .= $body; |
282 ········ | 288 ········ |
283 if ($plan9 && $ret[2] eq "e1") { | 289 if ($plan9 && $ret[2] eq "e1") { |
284 $text .= "\tif int32(r0) == -1 {\n"; | 290 $text .= "\tif int32(r0) == -1 {\n"; |
285 $text .= "\t\terr = e1\n"; | 291 $text .= "\t\terr = e1\n"; |
286 $text .= "\t}\n"; | 292 $text .= "\t}\n"; |
287 } elsif ($do_errno) { | 293 } elsif ($do_errno) { |
288 $text .= "\tif e1 != 0 {\n"; | 294 $text .= "\tif e1 != 0 {\n"; |
289 $text .= "\t\terr = e1\n"; | 295 $text .= "\t\terr = e1\n"; |
290 $text .= "\t}\n"; | 296 $text .= "\t}\n"; |
(...skipping 13 matching lines...) Expand all Loading... |
304 // $cmdline | 310 // $cmdline |
305 // MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT | 311 // MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT |
306 | 312 |
307 package syscall | 313 package syscall |
308 | 314 |
309 import "unsafe" | 315 import "unsafe" |
310 | 316 |
311 $text | 317 $text |
312 EOF | 318 EOF |
313 exit 0; | 319 exit 0; |
OLD | NEW |