From 206ba4dbfb3afa30cf9835d30edf625c5a89907d Mon Sep 17 00:00:00 2001 From: Aviv Palivoda Date: Sun, 21 Apr 2019 17:20:33 +0300 Subject: [PATCH 1/5] Change socket to new args style --- vm/src/stdlib/socket.rs | 200 +++++++++++++++++----------------------- 1 file changed, 83 insertions(+), 117 deletions(-) diff --git a/vm/src/stdlib/socket.rs b/vm/src/stdlib/socket.rs index 9d7a703e1f..96d3829709 100644 --- a/vm/src/stdlib/socket.rs +++ b/vm/src/stdlib/socket.rs @@ -7,9 +7,10 @@ use std::ops::Deref; use crate::function::PyFuncArgs; use crate::obj::objbytes; +use crate::obj::objbytes::PyBytesRef; use crate::obj::objint; -use crate::obj::objsequence::get_elements; use crate::obj::objstr; +use crate::obj::objtuple::PyTupleRef; use crate::pyobject::{PyObjectRef, PyRef, PyResult, PyValue, TryFromObject}; use crate::vm::VirtualMachine; @@ -167,88 +168,94 @@ fn get_socket<'a>(obj: &'a PyObjectRef) -> impl Deref + 'a { type SocketRef = PyRef; -fn socket_new( - cls: PyClassRef, - family: AddressFamily, - kind: SocketKind, - vm: &VirtualMachine, -) -> PyResult { - Socket::new(family, kind).into_ref_with_type(vm, cls) -} +impl SocketRef { + fn new( + cls: PyClassRef, + family: AddressFamily, + kind: SocketKind, + vm: &VirtualMachine, + ) -> PyResult { + Socket::new(family, kind).into_ref_with_type(vm, cls) + } -fn socket_connect(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!( - vm, - args, - required = [(zelf, None), (address, Some(vm.ctx.tuple_type()))] - ); + fn connect(self, address: PyTupleRef, vm: &VirtualMachine) -> PyResult { + let address_string = get_address_string(vm, address)?; - let address_string = get_address_string(vm, address)?; - - let socket = get_socket(zelf); - - match socket.socket_kind { - SocketKind::Stream => match TcpStream::connect(address_string) { - Ok(stream) => { - socket - .con - .borrow_mut() - .replace(Connection::TcpStream(stream)); - Ok(vm.get_none()) + match self.socket_kind { + SocketKind::Stream => match TcpStream::connect(address_string) { + Ok(stream) => { + self.con.borrow_mut().replace(Connection::TcpStream(stream)); + Ok(vm.get_none()) + } + Err(s) => Err(vm.new_os_error(s.to_string())), + }, + SocketKind::Dgram => { + if let Some(Connection::UdpSocket(con)) = self.con.borrow().as_ref() { + match con.connect(address_string) { + Ok(_) => Ok(vm.get_none()), + Err(s) => Err(vm.new_os_error(s.to_string())), + } + } else { + Err(vm.new_type_error("".to_string())) + } } - Err(s) => Err(vm.new_os_error(s.to_string())), - }, - SocketKind::Dgram => { - if let Some(Connection::UdpSocket(con)) = socket.con.borrow().as_ref() { - match con.connect(address_string) { - Ok(_) => Ok(vm.get_none()), + } + } + + fn bind(self, address: PyTupleRef, vm: &VirtualMachine) -> PyResult { + let address_string = get_address_string(vm, address)?; + + match self.socket_kind { + SocketKind::Stream => match TcpListener::bind(address_string) { + Ok(stream) => { + self.con + .borrow_mut() + .replace(Connection::TcpListener(stream)); + Ok(vm.get_none()) + } + Err(s) => Err(vm.new_os_error(s.to_string())), + }, + SocketKind::Dgram => match UdpSocket::bind(address_string) { + Ok(dgram) => { + self.con.borrow_mut().replace(Connection::UdpSocket(dgram)); + Ok(vm.get_none()) + } + Err(s) => Err(vm.new_os_error(s.to_string())), + }, + } + } + + fn sendto(self, bytes: PyBytesRef, address: PyTupleRef, vm: &VirtualMachine) -> PyResult { + let address_string = get_address_string(vm, address)?; + + match self.socket_kind { + SocketKind::Dgram => { + if let Some(v) = self.con.borrow().as_ref() { + return match v.send_to(&bytes, address_string) { + Ok(_) => Ok(vm.get_none()), + Err(s) => Err(vm.new_os_error(s.to_string())), + }; + } + // Doing implicit bind + match UdpSocket::bind("0.0.0.0:0") { + Ok(dgram) => match dgram.send_to(&bytes, address_string) { + Ok(_) => { + self.con.borrow_mut().replace(Connection::UdpSocket(dgram)); + Ok(vm.get_none()) + } + Err(s) => Err(vm.new_os_error(s.to_string())), + }, Err(s) => Err(vm.new_os_error(s.to_string())), } - } else { - Err(vm.new_type_error("".to_string())) } + _ => Err(vm.new_not_implemented_error("".to_string())), } } } -fn socket_bind(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!( - vm, - args, - required = [(zelf, None), (address, Some(vm.ctx.tuple_type()))] - ); - - let address_string = get_address_string(vm, address)?; - - let socket = get_socket(zelf); - - match socket.socket_kind { - SocketKind::Stream => match TcpListener::bind(address_string) { - Ok(stream) => { - socket - .con - .borrow_mut() - .replace(Connection::TcpListener(stream)); - Ok(vm.get_none()) - } - Err(s) => Err(vm.new_os_error(s.to_string())), - }, - SocketKind::Dgram => match UdpSocket::bind(address_string) { - Ok(dgram) => { - socket - .con - .borrow_mut() - .replace(Connection::UdpSocket(dgram)); - Ok(vm.get_none()) - } - Err(s) => Err(vm.new_os_error(s.to_string())), - }, - } -} - -fn get_address_string(vm: &VirtualMachine, address: &PyObjectRef) -> Result { +fn get_address_string(vm: &VirtualMachine, address: PyTupleRef) -> Result { let args = PyFuncArgs { - args: get_elements(address).to_vec(), + args: address.elements.borrow().to_vec(), kwargs: vec![], }; arg_check!( @@ -365,47 +372,6 @@ fn socket_send(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { Ok(vm.get_none()) } -fn socket_sendto(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!( - vm, - args, - required = [ - (zelf, None), - (bytes, Some(vm.ctx.bytes_type())), - (address, Some(vm.ctx.tuple_type())) - ] - ); - let address_string = get_address_string(vm, address)?; - - let socket = get_socket(zelf); - - match socket.socket_kind { - SocketKind::Dgram => { - if let Some(v) = socket.con.borrow().as_ref() { - return match v.send_to(&objbytes::get_value(&bytes), address_string) { - Ok(_) => Ok(vm.get_none()), - Err(s) => Err(vm.new_os_error(s.to_string())), - }; - } - // Doing implicit bind - match UdpSocket::bind("0.0.0.0:0") { - Ok(dgram) => match dgram.send_to(&objbytes::get_value(&bytes), address_string) { - Ok(_) => { - socket - .con - .borrow_mut() - .replace(Connection::UdpSocket(dgram)); - Ok(vm.get_none()) - } - Err(s) => Err(vm.new_os_error(s.to_string())), - }, - Err(s) => Err(vm.new_os_error(s.to_string())), - } - } - _ => Err(vm.new_not_implemented_error("".to_string())), - } -} - fn socket_close(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { arg_check!(vm, args, required = [(zelf, None)]); @@ -452,16 +418,16 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { let ctx = &vm.ctx; let socket = py_class!(ctx, "socket", ctx.object(), { - "__new__" => ctx.new_rustfunc(socket_new), - "connect" => ctx.new_rustfunc(socket_connect), + "__new__" => ctx.new_rustfunc(SocketRef::new), + "connect" => ctx.new_rustfunc(SocketRef::connect), "recv" => ctx.new_rustfunc(socket_recv), "send" => ctx.new_rustfunc(socket_send), - "bind" => ctx.new_rustfunc(socket_bind), + "bind" => ctx.new_rustfunc(SocketRef::bind), "accept" => ctx.new_rustfunc(socket_accept), "listen" => ctx.new_rustfunc(socket_listen), "close" => ctx.new_rustfunc(socket_close), "getsockname" => ctx.new_rustfunc(socket_getsockname), - "sendto" => ctx.new_rustfunc(socket_sendto), + "sendto" => ctx.new_rustfunc(SocketRef::sendto), "recvfrom" => ctx.new_rustfunc(socket_recvfrom), "fileno" => ctx.new_rustfunc(socket_fileno), }); From 9954361df9fc7565efeaddf1d57ceeaca7567b29 Mon Sep 17 00:00:00 2001 From: Aviv Palivoda Date: Sun, 21 Apr 2019 17:28:41 +0300 Subject: [PATCH 2/5] Move more socket methods to new arg style --- vm/src/stdlib/socket.rs | 99 +++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 58 deletions(-) diff --git a/vm/src/stdlib/socket.rs b/vm/src/stdlib/socket.rs index 96d3829709..dc165d3162 100644 --- a/vm/src/stdlib/socket.rs +++ b/vm/src/stdlib/socket.rs @@ -9,6 +9,7 @@ use crate::function::PyFuncArgs; use crate::obj::objbytes; use crate::obj::objbytes::PyBytesRef; use crate::obj::objint; +use crate::obj::objint::PyIntRef; use crate::obj::objstr; use crate::obj::objtuple::PyTupleRef; use crate::pyobject::{PyObjectRef, PyRef, PyResult, PyValue, TryFromObject}; @@ -251,6 +252,43 @@ impl SocketRef { _ => Err(vm.new_not_implemented_error("".to_string())), } } + + fn listen(self, _num: PyIntRef, _vm: &VirtualMachine) -> () {} + + fn accept(self, vm: &VirtualMachine) -> PyResult { + let ret = match self.con.borrow_mut().as_mut() { + Some(v) => v.accept(), + None => return Err(vm.new_type_error("".to_string())), + }; + + let (tcp_stream, addr) = match ret { + Ok((socket, addr)) => (socket, addr), + Err(s) => return Err(vm.new_os_error(s.to_string())), + }; + + let socket = Socket { + address_family: self.address_family, + socket_kind: self.socket_kind, + con: RefCell::new(Some(Connection::TcpStream(tcp_stream))), + } + .into_ref(vm); + + let addr_tuple = get_addr_tuple(vm, addr)?; + + Ok(vm.ctx.new_tuple(vec![socket.into_object(), addr_tuple])) + } + + fn recv(self, bufsize: PyIntRef, vm: &VirtualMachine) -> PyResult { + let mut buffer = vec![0u8; bufsize.as_bigint().to_usize().unwrap()]; + match self.con.borrow_mut().as_mut() { + Some(v) => match v.read_exact(&mut buffer) { + Ok(_) => (), + Err(s) => return Err(vm.new_os_error(s.to_string())), + }, + None => return Err(vm.new_type_error("".to_string())), + }; + Ok(vm.ctx.new_bytes(buffer)) + } } fn get_address_string(vm: &VirtualMachine, address: PyTupleRef) -> Result { @@ -274,61 +312,6 @@ fn get_address_string(vm: &VirtualMachine, address: PyTupleRef) -> Result PyResult { - arg_check!( - vm, - args, - required = [(_zelf, None), (_num, Some(vm.ctx.int_type()))] - ); - Ok(vm.get_none()) -} - -fn socket_accept(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!(vm, args, required = [(zelf, None)]); - - let socket = get_socket(zelf); - - let ret = match socket.con.borrow_mut().as_mut() { - Some(v) => v.accept(), - None => return Err(vm.new_type_error("".to_string())), - }; - - let (tcp_stream, addr) = match ret { - Ok((socket, addr)) => (socket, addr), - Err(s) => return Err(vm.new_os_error(s.to_string())), - }; - - let socket = Socket { - address_family: socket.address_family, - socket_kind: socket.socket_kind, - con: RefCell::new(Some(Connection::TcpStream(tcp_stream))), - } - .into_ref(vm); - - let addr_tuple = get_addr_tuple(vm, addr)?; - - Ok(vm.ctx.new_tuple(vec![socket.into_object(), addr_tuple])) -} - -fn socket_recv(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!( - vm, - args, - required = [(zelf, None), (bufsize, Some(vm.ctx.int_type()))] - ); - let socket = get_socket(zelf); - - let mut buffer = vec![0u8; objint::get_value(bufsize).to_usize().unwrap()]; - match socket.con.borrow_mut().as_mut() { - Some(v) => match v.read_exact(&mut buffer) { - Ok(_) => (), - Err(s) => return Err(vm.new_os_error(s.to_string())), - }, - None => return Err(vm.new_type_error("".to_string())), - }; - Ok(vm.ctx.new_bytes(buffer)) -} - fn socket_recvfrom(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { arg_check!( vm, @@ -420,11 +403,11 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { let socket = py_class!(ctx, "socket", ctx.object(), { "__new__" => ctx.new_rustfunc(SocketRef::new), "connect" => ctx.new_rustfunc(SocketRef::connect), - "recv" => ctx.new_rustfunc(socket_recv), + "recv" => ctx.new_rustfunc(SocketRef::recv), "send" => ctx.new_rustfunc(socket_send), "bind" => ctx.new_rustfunc(SocketRef::bind), - "accept" => ctx.new_rustfunc(socket_accept), - "listen" => ctx.new_rustfunc(socket_listen), + "accept" => ctx.new_rustfunc(SocketRef::accept), + "listen" => ctx.new_rustfunc(SocketRef::listen), "close" => ctx.new_rustfunc(socket_close), "getsockname" => ctx.new_rustfunc(socket_getsockname), "sendto" => ctx.new_rustfunc(SocketRef::sendto), From 1f733932558611219a09f843469cc4fe2b37b34b Mon Sep 17 00:00:00 2001 From: Aviv Palivoda Date: Sun, 21 Apr 2019 17:35:20 +0300 Subject: [PATCH 3/5] Move more socket methods to new arg style --- vm/src/stdlib/socket.rs | 201 +++++++++++++++++----------------------- 1 file changed, 85 insertions(+), 116 deletions(-) diff --git a/vm/src/stdlib/socket.rs b/vm/src/stdlib/socket.rs index dc165d3162..4082fca4f0 100644 --- a/vm/src/stdlib/socket.rs +++ b/vm/src/stdlib/socket.rs @@ -3,10 +3,8 @@ use std::io; use std::io::Read; use std::io::Write; use std::net::{SocketAddr, TcpListener, TcpStream, ToSocketAddrs, UdpSocket}; -use std::ops::Deref; use crate::function::PyFuncArgs; -use crate::obj::objbytes; use crate::obj::objbytes::PyBytesRef; use crate::obj::objint; use crate::obj::objint::PyIntRef; @@ -163,10 +161,6 @@ impl Socket { } } -fn get_socket<'a>(obj: &'a PyObjectRef) -> impl Deref + 'a { - obj.payload::().unwrap() -} - type SocketRef = PyRef; impl SocketRef { @@ -226,33 +220,6 @@ impl SocketRef { } } - fn sendto(self, bytes: PyBytesRef, address: PyTupleRef, vm: &VirtualMachine) -> PyResult { - let address_string = get_address_string(vm, address)?; - - match self.socket_kind { - SocketKind::Dgram => { - if let Some(v) = self.con.borrow().as_ref() { - return match v.send_to(&bytes, address_string) { - Ok(_) => Ok(vm.get_none()), - Err(s) => Err(vm.new_os_error(s.to_string())), - }; - } - // Doing implicit bind - match UdpSocket::bind("0.0.0.0:0") { - Ok(dgram) => match dgram.send_to(&bytes, address_string) { - Ok(_) => { - self.con.borrow_mut().replace(Connection::UdpSocket(dgram)); - Ok(vm.get_none()) - } - Err(s) => Err(vm.new_os_error(s.to_string())), - }, - Err(s) => Err(vm.new_os_error(s.to_string())), - } - } - _ => Err(vm.new_not_implemented_error("".to_string())), - } - } - fn listen(self, _num: PyIntRef, _vm: &VirtualMachine) -> () {} fn accept(self, vm: &VirtualMachine) -> PyResult { @@ -289,6 +256,86 @@ impl SocketRef { }; Ok(vm.ctx.new_bytes(buffer)) } + + fn recvfrom(self, bufsize: PyIntRef, vm: &VirtualMachine) -> PyResult { + let mut buffer = vec![0u8; bufsize.as_bigint().to_usize().unwrap()]; + let ret = match self.con.borrow().as_ref() { + Some(v) => v.recv_from(&mut buffer), + None => return Err(vm.new_type_error("".to_string())), + }; + + let addr = match ret { + Ok((_size, addr)) => addr, + Err(s) => return Err(vm.new_os_error(s.to_string())), + }; + + let addr_tuple = get_addr_tuple(vm, addr)?; + + Ok(vm.ctx.new_tuple(vec![vm.ctx.new_bytes(buffer), addr_tuple])) + } + + fn send(self, bytes: PyBytesRef, vm: &VirtualMachine) -> PyResult { + match self.con.borrow_mut().as_mut() { + Some(v) => match v.write(&bytes) { + Ok(_) => (), + Err(s) => return Err(vm.new_os_error(s.to_string())), + }, + None => return Err(vm.new_type_error("".to_string())), + }; + Ok(vm.get_none()) + } + + fn sendto(self, bytes: PyBytesRef, address: PyTupleRef, vm: &VirtualMachine) -> PyResult { + let address_string = get_address_string(vm, address)?; + + match self.socket_kind { + SocketKind::Dgram => { + if let Some(v) = self.con.borrow().as_ref() { + return match v.send_to(&bytes, address_string) { + Ok(_) => Ok(vm.get_none()), + Err(s) => Err(vm.new_os_error(s.to_string())), + }; + } + // Doing implicit bind + match UdpSocket::bind("0.0.0.0:0") { + Ok(dgram) => match dgram.send_to(&bytes, address_string) { + Ok(_) => { + self.con.borrow_mut().replace(Connection::UdpSocket(dgram)); + Ok(vm.get_none()) + } + Err(s) => Err(vm.new_os_error(s.to_string())), + }, + Err(s) => Err(vm.new_os_error(s.to_string())), + } + } + _ => Err(vm.new_not_implemented_error("".to_string())), + } + } + + fn close(self, vm: &VirtualMachine) -> PyResult { + self.con.borrow_mut().take(); + Ok(vm.get_none()) + } + + fn fileno(self, vm: &VirtualMachine) -> PyResult { + let fileno = match self.con.borrow_mut().as_mut() { + Some(v) => v.fileno(), + None => return Err(vm.new_type_error("".to_string())), + }; + Ok(vm.ctx.new_int(fileno)) + } + + fn getsockname(self, vm: &VirtualMachine) -> PyResult { + let addr = match self.con.borrow().as_ref() { + Some(v) => v.local_addr(), + None => return Err(vm.new_type_error("".to_string())), + }; + + match addr { + Ok(addr) => get_addr_tuple(vm, addr), + Err(s) => Err(vm.new_os_error(s.to_string())), + } + } } fn get_address_string(vm: &VirtualMachine, address: PyTupleRef) -> Result { @@ -312,84 +359,6 @@ fn get_address_string(vm: &VirtualMachine, address: PyTupleRef) -> Result PyResult { - arg_check!( - vm, - args, - required = [(zelf, None), (bufsize, Some(vm.ctx.int_type()))] - ); - - let socket = get_socket(zelf); - - let mut buffer = vec![0u8; objint::get_value(bufsize).to_usize().unwrap()]; - let ret = match socket.con.borrow().as_ref() { - Some(v) => v.recv_from(&mut buffer), - None => return Err(vm.new_type_error("".to_string())), - }; - - let addr = match ret { - Ok((_size, addr)) => addr, - Err(s) => return Err(vm.new_os_error(s.to_string())), - }; - - let addr_tuple = get_addr_tuple(vm, addr)?; - - Ok(vm.ctx.new_tuple(vec![vm.ctx.new_bytes(buffer), addr_tuple])) -} - -fn socket_send(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!( - vm, - args, - required = [(zelf, None), (bytes, Some(vm.ctx.bytes_type()))] - ); - let socket = get_socket(zelf); - - match socket.con.borrow_mut().as_mut() { - Some(v) => match v.write(&objbytes::get_value(&bytes)) { - Ok(_) => (), - Err(s) => return Err(vm.new_os_error(s.to_string())), - }, - None => return Err(vm.new_type_error("".to_string())), - }; - Ok(vm.get_none()) -} - -fn socket_close(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!(vm, args, required = [(zelf, None)]); - - let socket = get_socket(zelf); - socket.con.borrow_mut().take(); - Ok(vm.get_none()) -} - -fn socket_fileno(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!(vm, args, required = [(zelf, None)]); - - let socket = get_socket(zelf); - - let fileno = match socket.con.borrow_mut().as_mut() { - Some(v) => v.fileno(), - None => return Err(vm.new_type_error("".to_string())), - }; - Ok(vm.ctx.new_int(fileno)) -} - -fn socket_getsockname(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!(vm, args, required = [(zelf, None)]); - let socket = get_socket(zelf); - - let addr = match socket.con.borrow().as_ref() { - Some(v) => v.local_addr(), - None => return Err(vm.new_type_error("".to_string())), - }; - - match addr { - Ok(addr) => get_addr_tuple(vm, addr), - Err(s) => Err(vm.new_os_error(s.to_string())), - } -} - fn get_addr_tuple(vm: &VirtualMachine, addr: SocketAddr) -> PyResult { let port = vm.ctx.new_int(addr.port()); let ip = vm.ctx.new_str(addr.ip().to_string()); @@ -404,15 +373,15 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { "__new__" => ctx.new_rustfunc(SocketRef::new), "connect" => ctx.new_rustfunc(SocketRef::connect), "recv" => ctx.new_rustfunc(SocketRef::recv), - "send" => ctx.new_rustfunc(socket_send), + "send" => ctx.new_rustfunc(SocketRef::send), "bind" => ctx.new_rustfunc(SocketRef::bind), "accept" => ctx.new_rustfunc(SocketRef::accept), "listen" => ctx.new_rustfunc(SocketRef::listen), - "close" => ctx.new_rustfunc(socket_close), - "getsockname" => ctx.new_rustfunc(socket_getsockname), + "close" => ctx.new_rustfunc(SocketRef::close), + "getsockname" => ctx.new_rustfunc(SocketRef::getsockname), "sendto" => ctx.new_rustfunc(SocketRef::sendto), - "recvfrom" => ctx.new_rustfunc(socket_recvfrom), - "fileno" => ctx.new_rustfunc(socket_fileno), + "recvfrom" => ctx.new_rustfunc(SocketRef::recvfrom), + "fileno" => ctx.new_rustfunc(SocketRef::fileno), }); py_module!(vm, "socket", { From b61cd6f011d79ea2c2583ab39113309dbf070a78 Mon Sep 17 00:00:00 2001 From: Aviv Palivoda Date: Sun, 21 Apr 2019 17:44:41 +0300 Subject: [PATCH 4/5] Simplify return values --- vm/src/stdlib/socket.rs | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/vm/src/stdlib/socket.rs b/vm/src/stdlib/socket.rs index 4082fca4f0..25edf7a65a 100644 --- a/vm/src/stdlib/socket.rs +++ b/vm/src/stdlib/socket.rs @@ -173,21 +173,21 @@ impl SocketRef { Socket::new(family, kind).into_ref_with_type(vm, cls) } - fn connect(self, address: PyTupleRef, vm: &VirtualMachine) -> PyResult { + fn connect(self, address: PyTupleRef, vm: &VirtualMachine) -> PyResult<()> { let address_string = get_address_string(vm, address)?; match self.socket_kind { SocketKind::Stream => match TcpStream::connect(address_string) { Ok(stream) => { self.con.borrow_mut().replace(Connection::TcpStream(stream)); - Ok(vm.get_none()) + Ok(()) } Err(s) => Err(vm.new_os_error(s.to_string())), }, SocketKind::Dgram => { if let Some(Connection::UdpSocket(con)) = self.con.borrow().as_ref() { match con.connect(address_string) { - Ok(_) => Ok(vm.get_none()), + Ok(_) => Ok(()), Err(s) => Err(vm.new_os_error(s.to_string())), } } else { @@ -197,7 +197,7 @@ impl SocketRef { } } - fn bind(self, address: PyTupleRef, vm: &VirtualMachine) -> PyResult { + fn bind(self, address: PyTupleRef, vm: &VirtualMachine) -> PyResult<()> { let address_string = get_address_string(vm, address)?; match self.socket_kind { @@ -206,14 +206,14 @@ impl SocketRef { self.con .borrow_mut() .replace(Connection::TcpListener(stream)); - Ok(vm.get_none()) + Ok(()) } Err(s) => Err(vm.new_os_error(s.to_string())), }, SocketKind::Dgram => match UdpSocket::bind(address_string) { Ok(dgram) => { self.con.borrow_mut().replace(Connection::UdpSocket(dgram)); - Ok(vm.get_none()) + Ok(()) } Err(s) => Err(vm.new_os_error(s.to_string())), }, @@ -274,7 +274,7 @@ impl SocketRef { Ok(vm.ctx.new_tuple(vec![vm.ctx.new_bytes(buffer), addr_tuple])) } - fn send(self, bytes: PyBytesRef, vm: &VirtualMachine) -> PyResult { + fn send(self, bytes: PyBytesRef, vm: &VirtualMachine) -> PyResult<()> { match self.con.borrow_mut().as_mut() { Some(v) => match v.write(&bytes) { Ok(_) => (), @@ -282,17 +282,17 @@ impl SocketRef { }, None => return Err(vm.new_type_error("".to_string())), }; - Ok(vm.get_none()) + Ok(()) } - fn sendto(self, bytes: PyBytesRef, address: PyTupleRef, vm: &VirtualMachine) -> PyResult { + fn sendto(self, bytes: PyBytesRef, address: PyTupleRef, vm: &VirtualMachine) -> PyResult<()> { let address_string = get_address_string(vm, address)?; match self.socket_kind { SocketKind::Dgram => { if let Some(v) = self.con.borrow().as_ref() { return match v.send_to(&bytes, address_string) { - Ok(_) => Ok(vm.get_none()), + Ok(_) => Ok(()), Err(s) => Err(vm.new_os_error(s.to_string())), }; } @@ -301,7 +301,7 @@ impl SocketRef { Ok(dgram) => match dgram.send_to(&bytes, address_string) { Ok(_) => { self.con.borrow_mut().replace(Connection::UdpSocket(dgram)); - Ok(vm.get_none()) + Ok(()) } Err(s) => Err(vm.new_os_error(s.to_string())), }, @@ -312,9 +312,8 @@ impl SocketRef { } } - fn close(self, vm: &VirtualMachine) -> PyResult { + fn close(self, _vm: &VirtualMachine) -> () { self.con.borrow_mut().take(); - Ok(vm.get_none()) } fn fileno(self, vm: &VirtualMachine) -> PyResult { From cb322019047ede2014e848e1b7d06d213b1de8fb Mon Sep 17 00:00:00 2001 From: Aviv Palivoda Date: Mon, 22 Apr 2019 00:18:19 +0300 Subject: [PATCH 5/5] Add Address --- vm/src/stdlib/socket.rs | 61 +++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/vm/src/stdlib/socket.rs b/vm/src/stdlib/socket.rs index 25edf7a65a..edab574b38 100644 --- a/vm/src/stdlib/socket.rs +++ b/vm/src/stdlib/socket.rs @@ -4,11 +4,9 @@ use std::io::Read; use std::io::Write; use std::net::{SocketAddr, TcpListener, TcpStream, ToSocketAddrs, UdpSocket}; -use crate::function::PyFuncArgs; use crate::obj::objbytes::PyBytesRef; -use crate::obj::objint; use crate::obj::objint::PyIntRef; -use crate::obj::objstr; +use crate::obj::objstr::PyStringRef; use crate::obj::objtuple::PyTupleRef; use crate::pyobject::{PyObjectRef, PyRef, PyResult, PyValue, TryFromObject}; use crate::vm::VirtualMachine; @@ -173,8 +171,8 @@ impl SocketRef { Socket::new(family, kind).into_ref_with_type(vm, cls) } - fn connect(self, address: PyTupleRef, vm: &VirtualMachine) -> PyResult<()> { - let address_string = get_address_string(vm, address)?; + fn connect(self, address: Address, vm: &VirtualMachine) -> PyResult<()> { + let address_string = address.get_address_string(); match self.socket_kind { SocketKind::Stream => match TcpStream::connect(address_string) { @@ -197,8 +195,8 @@ impl SocketRef { } } - fn bind(self, address: PyTupleRef, vm: &VirtualMachine) -> PyResult<()> { - let address_string = get_address_string(vm, address)?; + fn bind(self, address: Address, vm: &VirtualMachine) -> PyResult<()> { + let address_string = address.get_address_string(); match self.socket_kind { SocketKind::Stream => match TcpListener::bind(address_string) { @@ -285,8 +283,8 @@ impl SocketRef { Ok(()) } - fn sendto(self, bytes: PyBytesRef, address: PyTupleRef, vm: &VirtualMachine) -> PyResult<()> { - let address_string = get_address_string(vm, address)?; + fn sendto(self, bytes: PyBytesRef, address: Address, vm: &VirtualMachine) -> PyResult<()> { + let address_string = address.get_address_string(); match self.socket_kind { SocketKind::Dgram => { @@ -337,25 +335,34 @@ impl SocketRef { } } -fn get_address_string(vm: &VirtualMachine, address: PyTupleRef) -> Result { - let args = PyFuncArgs { - args: address.elements.borrow().to_vec(), - kwargs: vec![], - }; - arg_check!( - vm, - args, - required = [ - (host, Some(vm.ctx.str_type())), - (port, Some(vm.ctx.int_type())) - ] - ); +struct Address { + host: String, + port: usize, +} - Ok(format!( - "{}:{}", - objstr::get_value(host), - objint::get_value(port).to_string() - )) +impl Address { + fn get_address_string(self) -> String { + format!("{}:{}", self.host, self.port.to_string()) + } +} + +impl TryFromObject for Address { + fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult { + let tuple = PyTupleRef::try_from_object(vm, obj)?; + if tuple.elements.borrow().len() != 2 { + Err(vm.new_type_error("Address tuple should have only 2 values".to_string())) + } else { + Ok(Address { + host: PyStringRef::try_from_object(vm, tuple.elements.borrow()[0].clone())? + .value + .to_string(), + port: PyIntRef::try_from_object(vm, tuple.elements.borrow()[1].clone())? + .as_bigint() + .to_usize() + .unwrap(), + }) + } + } } fn get_addr_tuple(vm: &VirtualMachine, addr: SocketAddr) -> PyResult {