authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-05-13 09:23:03-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-05-13 09:54:56-07:00
log8e3ab28be95de4faca64d5abab21f1948f71510b
treee7a1a0c73840e846d19260d412601cb93c608775
parent774ec1f88992667529a7b3c149b59b68eb4f2c59

ability to cast maybe pointer to isize/usize

also ability to put noalias on maybe pointer

4 files changed, 48 insertions(+), 7 deletions(-)

src/analyze.cpp+13-4
...@@ -4168,6 +4168,16 @@ static TypeTableEntry *resolve_cast(CodeGen *g, BlockContext *context, AstNode *...@@ -4168,6 +4168,16 @@ static TypeTableEntry *resolve_cast(CodeGen *g, BlockContext *context, AstNode *
4168 return wanted_type;4168 return wanted_type;
4169}4169}
41704170
4171static bool type_is_codegen_pointer(TypeTableEntry *type) {
4172 if (type->id == TypeTableEntryIdPointer) return true;
4173 if (type->id == TypeTableEntryIdFn) return true;
4174 if (type->id == TypeTableEntryIdMaybe) {
4175 if (type->data.maybe.child_type->id == TypeTableEntryIdPointer) return true;
4176 if (type->data.maybe.child_type->id == TypeTableEntryIdFn) return true;
4177 }
4178 return false;
4179}
4180
4171static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,4181static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
4172 AstNode *node)4182 AstNode *node)
4173{4183{
...@@ -4207,7 +4217,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B...@@ -4207,7 +4217,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
42074217
4208 // explicit cast from pointer to isize or usize4218 // explicit cast from pointer to isize or usize
4209 if ((wanted_type_canon == g->builtin_types.entry_isize || wanted_type_canon == g->builtin_types.entry_usize) &&4219 if ((wanted_type_canon == g->builtin_types.entry_isize || wanted_type_canon == g->builtin_types.entry_usize) &&
4210 actual_type_canon->id == TypeTableEntryIdPointer)4220 type_is_codegen_pointer(actual_type_canon))
4211 {4221 {
4212 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpPtrToInt, false);4222 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpPtrToInt, false);
4213 }4223 }
...@@ -6193,9 +6203,8 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {...@@ -6193,9 +6203,8 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
6193 AstNodeParamDecl *param_decl = &param_decl_node->data.param_decl;6203 AstNodeParamDecl *param_decl = &param_decl_node->data.param_decl;
6194 TypeTableEntry *type = unwrapped_node_type(param_decl->type);6204 TypeTableEntry *type = unwrapped_node_type(param_decl->type);
61956205
6196 if (param_decl->is_noalias && type->id != TypeTableEntryIdPointer) {6206 if (param_decl->is_noalias && !type_is_codegen_pointer(type)) {
6197 add_node_error(g, param_decl_node,6207 add_node_error(g, param_decl_node, buf_sprintf("noalias on non-pointer parameter"));
6198 buf_sprintf("noalias on non-pointer parameter"));
6199 }6208 }
62006209
6201 if (fn_type->data.fn.fn_type_id.is_extern && type->id == TypeTableEntryIdStruct) {6210 if (fn_type->data.fn.fn_type_id.is_extern && type->id == TypeTableEntryIdStruct) {
src/codegen.cpp+1-1
...@@ -3923,7 +3923,7 @@ static void do_code_gen(CodeGen *g) {...@@ -3923,7 +3923,7 @@ static void do_code_gen(CodeGen *g) {
3923 TypeTableEntry *param_type = info->type;3923 TypeTableEntry *param_type = info->type;
3924 LLVMValueRef argument_val = LLVMGetParam(fn_table_entry->fn_value, gen_index);3924 LLVMValueRef argument_val = LLVMGetParam(fn_table_entry->fn_value, gen_index);
3925 bool param_is_noalias = param_node->data.param_decl.is_noalias;3925 bool param_is_noalias = param_node->data.param_decl.is_noalias;
3926 if (param_type->id == TypeTableEntryIdPointer && param_is_noalias) {3926 if (param_is_noalias) {
3927 LLVMAddAttribute(argument_val, LLVMNoAliasAttribute);3927 LLVMAddAttribute(argument_val, LLVMNoAliasAttribute);
3928 }3928 }
3929 if ((param_type->id == TypeTableEntryIdPointer && (param_type->data.pointer.is_const || fn_table_entry->is_pure)) ||3929 if ((param_type->id == TypeTableEntryIdPointer && (param_type->data.pointer.is_const || fn_table_entry->is_pure)) ||
std/linux.zig+2-2
...@@ -402,7 +402,7 @@ pub fn recvmsg(fd: i32, msg: &arch.msghdr, flags: i32) -> isize {...@@ -402,7 +402,7 @@ pub fn recvmsg(fd: i32, msg: &arch.msghdr, flags: i32) -> isize {
402}402}
403403
404pub fn recvfrom(fd: i32, noalias buf: &u8, len: isize, flags: i32,404pub fn recvfrom(fd: i32, noalias buf: &u8, len: isize, flags: i32,
405 noalias addr: &sockaddr, noalias alen: &socklen_t) -> isize405 noalias addr: ?&sockaddr, noalias alen: ?&socklen_t) -> isize
406{406{
407 arch.syscall6(arch.SYS_recvfrom, fd, isize(buf), len, flags, isize(addr), isize(alen))407 arch.syscall6(arch.SYS_recvfrom, fd, isize(buf), len, flags, isize(addr), isize(alen))
408}408}
...@@ -419,7 +419,7 @@ pub fn listen(fd: i32, backlog: i32) -> isize {...@@ -419,7 +419,7 @@ pub fn listen(fd: i32, backlog: i32) -> isize {
419 arch.syscall2(arch.SYS_listen, fd, backlog)419 arch.syscall2(arch.SYS_listen, fd, backlog)
420}420}
421421
422pub fn sendto(fd: i32, buf: &const u8, len: isize, flags: i32, addr: &const sockaddr, alen: socklen_t) -> isize {422pub fn sendto(fd: i32, buf: &const u8, len: isize, flags: i32, addr: ?&const sockaddr, alen: socklen_t) -> isize {
423 arch.syscall6(arch.SYS_sendto, fd, isize(buf), len, flags, isize(addr), isize(alen))423 arch.syscall6(arch.SYS_sendto, fd, isize(buf), len, flags, isize(addr), isize(alen))
424}424}
425425
std/net.zig+32
...@@ -6,10 +6,42 @@ pub error SigInterrupt;...@@ -6,10 +6,42 @@ pub error SigInterrupt;
6pub error Unexpected;6pub error Unexpected;
7pub error Io;7pub error Io;
8pub error TimedOut;8pub error TimedOut;
9pub error ConnectionReset;
10pub error NoMem;
11pub error NotSocket;
912
10struct Connection {13struct Connection {
11 socket_fd: i32,14 socket_fd: i32,
1215
16 pub fn send(c: Connection, buf: []const u8) -> %isize {
17 const send_ret = linux.sendto(c.socket_fd, buf.ptr, buf.len, 0, null, 0);
18 const send_err = linux.get_errno(send_ret);
19 switch (send_err) {
20 0 => return send_ret,
21 errno.EINVAL => unreachable{},
22 errno.EFAULT => unreachable{},
23 errno.ECONNRESET => return error.ConnectionReset,
24 errno.EINTR => return error.SigInterrupt,
25 // TODO there are more possible errors
26 else => return error.Unexpected,
27 }
28 }
29
30 pub fn recv(c: Connection, buf: []u8) -> %isize {
31 const recv_ret = linux.recvfrom(c.socket_fd, buf.ptr, buf.len, 0, null, null);
32 const recv_err = linux.get_errno(recv_ret);
33 switch (recv_err) {
34 0 => return recv_ret,
35 errno.EINVAL => unreachable{},
36 errno.EFAULT => unreachable{},
37 errno.ENOTSOCK => return error.NotSocket,
38 errno.EINTR => return error.SigInterrupt,
39 errno.ENOMEM => return error.NoMem,
40 // TODO more error values
41 else => return error.Unexpected,
42 }
43 }
44
13 pub fn close(c: Connection) -> %void {45 pub fn close(c: Connection) -> %void {
14 switch (linux.get_errno(linux.close(c.socket_fd))) {46 switch (linux.get_errno(linux.close(c.socket_fd))) {
15 0 => return,47 0 => return,