summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--py/bc.h1
-rw-r--r--py/builtinimport.c2
-rw-r--r--py/emitglue.c2
-rw-r--r--py/obj.h1
-rw-r--r--py/objexcept.c43
-rw-r--r--py/py.mk7
-rw-r--r--py/showbc.c18
-rw-r--r--py/vm.c46
-rw-r--r--unix/file.c2
-rw-r--r--unix/modffi.c34
-rw-r--r--unix/modsocket.c8
-rw-r--r--windows/README2
12 files changed, 117 insertions, 49 deletions
diff --git a/py/bc.h b/py/bc.h
index fb672ea03b..964c29f045 100644
--- a/py/bc.h
+++ b/py/bc.h
@@ -13,6 +13,7 @@ typedef struct _mp_exc_stack {
mp_vm_return_kind_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_args, const mp_obj_t *args2, uint n_args2, mp_obj_t *ret);
mp_vm_return_kind_t mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **sp_in_out, mp_exc_stack_t *exc_stack, mp_exc_stack_t **exc_sp_in_out, volatile mp_obj_t inject_exc);
void mp_byte_code_print(const byte *code, int len);
+void mp_byte_code_print2(const byte *code, int len);
// Helper macros to access pointer with least significant bit holding a flag
#define MP_TAGPTR_PTR(x) ((void*)((machine_uint_t)(x) & ~((machine_uint_t)1)))
diff --git a/py/builtinimport.c b/py/builtinimport.c
index 4a2f6510c3..07978e61d7 100644
--- a/py/builtinimport.c
+++ b/py/builtinimport.c
@@ -122,7 +122,7 @@ void do_load(mp_obj_t module_obj, vstr_t *file) {
// TODO handle compile error correctly
mp_locals_set(old_locals);
mp_globals_set(old_globals);
- return;
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_SyntaxError, "Syntax error in imported module"));
}
// complied successfully, execute it
diff --git a/py/emitglue.c b/py/emitglue.c
index 8b1fd97021..dddeea1b57 100644
--- a/py/emitglue.c
+++ b/py/emitglue.c
@@ -159,7 +159,7 @@ mp_obj_t mp_make_function_from_raw_code(mp_raw_code_t *rc, mp_obj_t def_args, mp
}
mp_obj_t mp_make_closure_from_raw_code(mp_raw_code_t *rc, uint n_closed_over, const mp_obj_t *args) {
- DEBUG_OP_printf("make_closure_from_raw_code %p %u %p\n", rc, n_closed_over, argrs);
+ DEBUG_OP_printf("make_closure_from_raw_code %p %u %p\n", rc, n_closed_over, args);
// make function object
mp_obj_t ffun;
if (n_closed_over & 0x100) {
diff --git a/py/obj.h b/py/obj.h
index d62d376ab4..6bb264c1c3 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -351,6 +351,7 @@ mp_obj_t mp_obj_new_float(mp_float_t val);
mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag);
#endif
mp_obj_t mp_obj_new_exception(const mp_obj_type_t *exc_type);
+mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg);
mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, uint n_args, const mp_obj_t *args);
mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const char *msg);
mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char *fmt, ...); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!)
diff --git a/py/objexcept.c b/py/objexcept.c
index 781a00405c..160cf09fd4 100644
--- a/py/objexcept.c
+++ b/py/objexcept.c
@@ -14,11 +14,11 @@
typedef struct _mp_obj_exception_t {
mp_obj_base_t base;
mp_obj_t traceback; // a list object, holding (file,line,block) as numbers (not Python objects); a hack for now
- mp_obj_tuple_t args;
+ mp_obj_tuple_t *args;
} mp_obj_exception_t;
// Instance of MemoryError exception - needed by mp_malloc_fail
-const mp_obj_exception_t mp_const_MemoryError_obj = {{&mp_type_MemoryError}, MP_OBJ_NULL, {{&mp_type_tuple}, 0}};
+const mp_obj_exception_t mp_const_MemoryError_obj = {{&mp_type_MemoryError}, MP_OBJ_NULL, mp_const_empty_tuple};
// Local non-heap memory for allocating an exception when we run out of RAM
STATIC mp_obj_exception_t mp_emergency_exception_obj;
@@ -26,7 +26,7 @@ STATIC mp_obj_exception_t mp_emergency_exception_obj;
// Instance of GeneratorExit exception - needed by generator.close()
// This would belong to objgenerator.c, but to keep mp_obj_exception_t
// definition module-private so far, have it here.
-const mp_obj_exception_t mp_const_GeneratorExit_obj = {{&mp_type_GeneratorExit}, MP_OBJ_NULL, {{&mp_type_tuple}, 0}};
+const mp_obj_exception_t mp_const_GeneratorExit_obj = {{&mp_type_GeneratorExit}, MP_OBJ_NULL, mp_const_empty_tuple};
STATIC void mp_obj_exception_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
mp_obj_exception_t *o = o_in;
@@ -36,15 +36,15 @@ STATIC void mp_obj_exception_print(void (*print)(void *env, const char *fmt, ...
print(env, "%s: ", qstr_str(o->base.type->name));
}
if (kind == PRINT_STR || kind == PRINT_EXC) {
- if (o->args.len == 0) {
+ if (o->args == NULL || o->args->len == 0) {
print(env, "");
return;
- } else if (o->args.len == 1) {
- mp_obj_print_helper(print, env, o->args.items[0], PRINT_STR);
+ } else if (o->args->len == 1) {
+ mp_obj_print_helper(print, env, o->args->items[0], PRINT_STR);
return;
}
}
- tuple_print(print, env, &o->args, kind);
+ tuple_print(print, env, o->args, kind);
}
STATIC mp_obj_t mp_obj_exception_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
@@ -54,35 +54,35 @@ STATIC mp_obj_t mp_obj_exception_make_new(mp_obj_t type_in, uint n_args, uint n_
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "%s does not take keyword arguments", mp_obj_get_type_str(type_in)));
}
- mp_obj_exception_t *o = m_new_obj_var_maybe(mp_obj_exception_t, mp_obj_t, n_args);
+ mp_obj_exception_t *o = m_new_obj_var_maybe(mp_obj_exception_t, mp_obj_t, 0);
if (o == NULL) {
// Couldn't allocate heap memory; use local data instead.
o = &mp_emergency_exception_obj;
// We can't store any args.
n_args = 0;
+ o->args = mp_const_empty_tuple;
+ } else {
+ o->args = mp_obj_new_tuple(n_args, args);
}
o->base.type = type;
o->traceback = MP_OBJ_NULL;
- o->args.base.type = &mp_type_tuple;
- o->args.len = n_args;
- memcpy(o->args.items, args, n_args * sizeof(mp_obj_t));
return o;
}
// Get exception "value" - that is, first argument, or None
mp_obj_t mp_obj_exception_get_value(mp_obj_t self_in) {
mp_obj_exception_t *self = self_in;
- if (self->args.len == 0) {
+ if (self->args->len == 0) {
return mp_const_none;
} else {
- return self->args.items[0];
+ return self->args->items[0];
}
}
STATIC void exception_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
mp_obj_exception_t *self = self_in;
if (attr == MP_QSTR_args) {
- dest[0] = &self->args;
+ dest[0] = self->args;
} else if (self->base.type == &mp_type_StopIteration && attr == MP_QSTR_value) {
dest[0] = mp_obj_exception_get_value(self);
}
@@ -191,6 +191,11 @@ mp_obj_t mp_obj_new_exception(const mp_obj_type_t *exc_type) {
return mp_obj_new_exception_args(exc_type, 0, NULL);
}
+// "Optimized" version for common(?) case of having 1 exception arg
+mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg) {
+ return mp_obj_new_exception_args(exc_type, 1, &arg);
+}
+
mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, uint n_args, const mp_obj_t *args) {
assert(exc_type->make_new == mp_obj_exception_make_new);
return exc_type->make_new((mp_obj_t)exc_type, n_args, 0, args);
@@ -205,20 +210,18 @@ mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char
assert(exc_type->make_new == mp_obj_exception_make_new);
// make exception object
- mp_obj_exception_t *o = m_new_obj_var_maybe(mp_obj_exception_t, mp_obj_t, 1);
+ mp_obj_exception_t *o = m_new_obj_var_maybe(mp_obj_exception_t, mp_obj_t, 0);
if (o == NULL) {
// Couldn't allocate heap memory; use local data instead.
// Unfortunately, we won't be able to format the string...
o = &mp_emergency_exception_obj;
o->base.type = exc_type;
o->traceback = MP_OBJ_NULL;
- o->args.base.type = &mp_type_tuple;
- o->args.len = 0;
+ o->args = mp_const_empty_tuple;
} else {
o->base.type = exc_type;
o->traceback = MP_OBJ_NULL;
- o->args.base.type = &mp_type_tuple;
- o->args.len = 1;
+ o->args = mp_obj_new_tuple(1, NULL);
if (fmt == NULL) {
// no message
@@ -231,7 +234,7 @@ mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char
va_start(ap, fmt);
vstr_vprintf(vstr, fmt, ap);
va_end(ap);
- o->args.items[0] = mp_obj_new_str((byte*)vstr->buf, vstr->len, false);
+ o->args->items[0] = mp_obj_new_str((byte*)vstr->buf, vstr->len, false);
vstr_free(vstr);
}
}
diff --git a/py/py.mk b/py/py.mk
index 5b0dd3d3a8..aa282b3808 100644
--- a/py/py.mk
+++ b/py/py.mk
@@ -7,6 +7,9 @@ HEADER_BUILD = $(BUILD)/genhdr
# file containing qstr defs for the core Python bit
PY_QSTR_DEFS = $(PY_SRC)/qstrdefs.h
+# some code is performance bottleneck and compiled with other optimization options
+CSUPEROPT = -O3
+
# py object files
PY_O_BASENAME = \
nlrx86.o \
@@ -135,8 +138,8 @@ $(PY_BUILD)/emitnthumb.o: py/emitnative.c
$(call compile_c)
# optimising gc for speed; 5ms down to 4ms on pybv2
-$(PY_BUILD)/gc.o: CFLAGS += -O3
+$(PY_BUILD)/gc.o: CFLAGS += $(CSUPEROPT)
# optimising vm for speed, adds only a small amount to code size but makes a huge difference to speed (20% faster)
-$(PY_BUILD)/vm.o: CFLAGS += -O3
+$(PY_BUILD)/vm.o: CFLAGS += $(CSUPEROPT)
diff --git a/py/showbc.c b/py/showbc.c
index 4a8e12e68b..17cb2eadd6 100644
--- a/py/showbc.c
+++ b/py/showbc.c
@@ -28,6 +28,8 @@
ip += sizeof(machine_uint_t); \
} while (0)
+void mp_byte_code_print2(const byte *ip, int len);
+
void mp_byte_code_print(const byte *ip, int len) {
const byte *ip_start = ip;
@@ -71,7 +73,11 @@ void mp_byte_code_print(const byte *ip, int len) {
printf(" bc=" INT_FMT " line=" UINT_FMT "\n", bc, source_line);
}
}
+ mp_byte_code_print2(ip, len - 0);
+}
+void mp_byte_code_print2(const byte *ip, int len) {
+ const byte *ip_start = ip;
machine_uint_t unum;
qstr qstr;
while (ip - ip_start < len) {
@@ -418,15 +424,19 @@ void mp_byte_code_print(const byte *ip, int len) {
printf("MAKE_FUNCTION_DEFARGS " UINT_FMT, unum);
break;
- case MP_BC_MAKE_CLOSURE:
+ case MP_BC_MAKE_CLOSURE: {
DECODE_PTR;
- printf("MAKE_CLOSURE " UINT_FMT, unum);
+ machine_uint_t n_closed_over = *ip++;
+ printf("MAKE_CLOSURE " UINT_FMT " " UINT_FMT, unum, n_closed_over);
break;
+ }
- case MP_BC_MAKE_CLOSURE_DEFARGS:
+ case MP_BC_MAKE_CLOSURE_DEFARGS: {
DECODE_PTR;
- printf("MAKE_CLOSURE_DEFARGS " UINT_FMT, unum);
+ machine_uint_t n_closed_over = *ip++;
+ printf("MAKE_CLOSURE_DEFARGS " UINT_FMT " " UINT_FMT, unum, n_closed_over);
break;
+ }
case MP_BC_CALL_FUNCTION:
DECODE_UINT;
diff --git a/py/vm.c b/py/vm.c
index b1c1719b72..8b4c926def 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -13,7 +13,18 @@
#include "bc.h"
#include "objgenerator.h"
+// With these macros you can tune the maximum number of state slots
+// that will be allocated on the stack. Any function that needs more
+// than this will use the heap.
+#define VM_MAX_STATE_ON_STACK (10)
+#define VM_MAX_EXC_STATE_ON_STACK (4)
+
#define DETECT_VM_STACK_OVERFLOW (0)
+#if 0
+#define TRACE(ip) mp_byte_code_print2(ip, 1);
+#else
+#define TRACE(ip)
+#endif
// Value stack grows up (this makes it incompatible with native C stack, but
// makes sure that arguments to functions are in natural order arg1..argN
@@ -80,20 +91,20 @@ mp_vm_return_kind_t mp_execute_byte_code(const byte *code, const mp_obj_t *args,
ip += 4;
// allocate state for locals and stack
- mp_obj_t temp_state[10];
+ mp_obj_t temp_state[VM_MAX_STATE_ON_STACK];
mp_obj_t *state = &temp_state[0];
#if DETECT_VM_STACK_OVERFLOW
n_state += 1;
#endif
- if (n_state > 10) {
+ if (n_state > VM_MAX_STATE_ON_STACK) {
state = m_new(mp_obj_t, n_state);
}
mp_obj_t *sp = &state[0] - 1;
// allocate state for exceptions
- mp_exc_stack_t exc_state[4];
+ mp_exc_stack_t exc_state[VM_MAX_EXC_STATE_ON_STACK];
mp_exc_stack_t *exc_stack = &exc_state[0];
- if (n_exc_stack > 4) {
+ if (n_exc_stack > VM_MAX_EXC_STATE_ON_STACK) {
exc_stack = m_new(mp_exc_stack_t, n_exc_stack);
}
mp_exc_stack_t *exc_sp = &exc_stack[0] - 1;
@@ -140,19 +151,38 @@ mp_vm_return_kind_t mp_execute_byte_code(const byte *code, const mp_obj_t *args,
}
#endif
+ mp_vm_return_kind_t ret_kind;
switch (vm_return_kind) {
case MP_VM_RETURN_NORMAL:
+ // return value is in *sp
*ret = *sp;
- return MP_VM_RETURN_NORMAL;
+ ret_kind = MP_VM_RETURN_NORMAL;
+ break;
+
case MP_VM_RETURN_EXCEPTION:
+ // return value is in state[n_state - 1]
*ret = state[n_state - 1];
- return MP_VM_RETURN_EXCEPTION;
+ ret_kind = MP_VM_RETURN_EXCEPTION;
+ break;
+
case MP_VM_RETURN_YIELD: // byte-code shouldn't yield
default:
assert(0);
*ret = mp_const_none;
- return MP_VM_RETURN_NORMAL;
+ ret_kind = MP_VM_RETURN_NORMAL;
}
+
+ // free the state if it was allocated on the heap
+ if (n_state > VM_MAX_STATE_ON_STACK) {
+ m_free(state, n_state);
+ }
+
+ // free the exception state if it was allocated on the heap
+ if (n_exc_stack > VM_MAX_EXC_STATE_ON_STACK) {
+ m_free(exc_stack, n_exc_stack);
+ }
+
+ return ret_kind;
}
// fastn has items in reverse order (fastn[0] is local[0], fastn[-1] is local[1], etc)
@@ -168,6 +198,7 @@ mp_vm_return_kind_t mp_execute_byte_code_2(const byte *code_info, const byte **i
#if MICROPY_USE_COMPUTED_GOTO
#include "vmentrytable.h"
#define DISPATCH() do { \
+ TRACE(ip); \
save_ip = ip; \
op = *ip++; \
goto *entry_table[op]; \
@@ -223,6 +254,7 @@ dispatch_loop:
#if MICROPY_USE_COMPUTED_GOTO
DISPATCH();
#else
+ TRACE(ip);
save_ip = ip;
op = *ip++;
diff --git a/unix/file.c b/unix/file.c
index 5bda34013f..041e28e956 100644
--- a/unix/file.c
+++ b/unix/file.c
@@ -106,7 +106,7 @@ STATIC mp_obj_t fdfile_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const
int fd = open(fname, mode, 0644);
if (fd == -1) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", errno));
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT((machine_int_t)errno)));
}
return fdfile_new(fd);
}
diff --git a/unix/modffi.c b/unix/modffi.c
index 83bc2c5454..56ea6ed307 100644
--- a/unix/modffi.c
+++ b/unix/modffi.c
@@ -12,6 +12,22 @@
#include "runtime.h"
#include "binary.h"
+/*
+ * modffi uses character codes to encode a value type, based on "struct"
+ * module type codes, with some extensions and overridings.
+ *
+ * Extra/overridden typecodes:
+ * v - void, can be used only as return type
+ * P - const void*, pointer to read-only memory
+ * p - void*, meaning pointer to a writable memory (note that this
+ * clashes with struct's "p" as "Pascal string").
+ * s - as argument, the same as "p", as return value, causes string
+ * to be allocated and returned, instead of pointer value.
+ *
+ * Note: all constraint specified by typecode can be not enforced at this time,
+ * but may be later.
+ */
+
typedef struct _mp_obj_opaque_t {
mp_obj_base_t base;
void *val;
@@ -63,8 +79,8 @@ STATIC ffi_type *char2ffi_type(char c)
case 'L': return &ffi_type_ulong;
case 'f': return &ffi_type_float;
case 'd': return &ffi_type_double;
- case 'p': // Deprecated - conflicts with struct module
- case 'P':
+ case 'P': // const void*
+ case 'p': // void*
case 's': return &ffi_type_pointer;
case 'v': return &ffi_type_void;
default: return NULL;
@@ -83,7 +99,7 @@ STATIC ffi_type *get_ffi_type(mp_obj_t o_in)
}
// TODO: Support actual libffi type objects
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Unknown type"));
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "Unknown type"));
}
STATIC mp_obj_t return_ffi_value(ffi_arg val, char type)
@@ -129,7 +145,7 @@ STATIC mp_obj_t ffimod_func(uint n_args, const mp_obj_t *args) {
void *sym = dlsym(self->handle, symname);
if (sym == NULL) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", errno));
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT((machine_int_t)errno)));
}
int nparams = MP_OBJ_SMALL_INT_VALUE(mp_obj_len_maybe(args[3]));
mp_obj_ffifunc_t *o = m_new_obj_var(mp_obj_ffifunc_t, ffi_type*, nparams);
@@ -147,7 +163,7 @@ STATIC mp_obj_t ffimod_func(uint n_args, const mp_obj_t *args) {
int res = ffi_prep_cif(&o->cif, FFI_DEFAULT_ABI, nparams, char2ffi_type(*rettype), o->params);
if (res != FFI_OK) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error in ffi_prep_cif"));
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Error in ffi_prep_cif"));
}
return o;
@@ -184,12 +200,12 @@ STATIC mp_obj_t mod_ffi_callback(mp_obj_t rettype_in, mp_obj_t func_in, mp_obj_t
int res = ffi_prep_cif(&o->cif, FFI_DEFAULT_ABI, nparams, char2ffi_type(*rettype), o->params);
if (res != FFI_OK) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error in ffi_prep_cif"));
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Error in ffi_prep_cif"));
}
res = ffi_prep_closure_loc(o->clo, &o->cif, call_py_func, func_in, o->func);
if (res != FFI_OK) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "ffi_prep_closure_loc"));
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "ffi_prep_closure_loc"));
}
return o;
@@ -203,7 +219,7 @@ STATIC mp_obj_t ffimod_var(mp_obj_t self_in, mp_obj_t vartype_in, mp_obj_t symna
void *sym = dlsym(self->handle, symname);
if (sym == NULL) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", errno));
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT((machine_int_t)errno)));
}
mp_obj_ffivar_t *o = m_new_obj(mp_obj_ffivar_t);
o->base.type = &ffivar_type;
@@ -219,7 +235,7 @@ STATIC mp_obj_t ffimod_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const
void *mod = dlopen(fname, RTLD_NOW | RTLD_LOCAL);
if (mod == NULL) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", errno));
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT((machine_int_t)errno)));
}
mp_obj_ffimod_t *o = m_new_obj(mp_obj_ffimod_t);
o->base.type = type_in;
diff --git a/unix/modsocket.c b/unix/modsocket.c
index 6a2ada91f1..b7d167c8ad 100644
--- a/unix/modsocket.c
+++ b/unix/modsocket.c
@@ -33,7 +33,7 @@ STATIC const mp_obj_type_t microsocket_type;
// Helper functions
#define RAISE_ERRNO(err_flag, error_val) \
{ if (err_flag == -1) \
- { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", error_val)); } }
+ { nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT((machine_int_t)error_val))); } }
STATIC mp_obj_socket_t *socket_new(int fd) {
mp_obj_socket_t *o = m_new_obj(mp_obj_socket_t);
@@ -269,7 +269,7 @@ STATIC mp_obj_t mod_socket_inet_aton(mp_obj_t arg) {
const char *s = mp_obj_str_get_str(arg);
struct in_addr addr;
if (!inet_aton(s, &addr)) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Invalid IP address"));
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EINVAL)));
}
return mp_obj_new_int(addr.s_addr);
@@ -282,7 +282,8 @@ STATIC mp_obj_t mod_socket_gethostbyname(mp_obj_t arg) {
const char *s = mp_obj_str_get_str(arg);
struct hostent *h = gethostbyname(s);
if (h == NULL) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", errno));
+ // CPython: socket.herror
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT((machine_int_t)h_errno)));
}
assert(h->h_length == 4);
return mp_obj_new_int(*(int*)*h->h_addr_list);
@@ -314,6 +315,7 @@ STATIC mp_obj_t mod_socket_getaddrinfo(uint n_args, const mp_obj_t *args) {
int res = getaddrinfo(host, serv, NULL/*&hints*/, &addr);
if (res != 0) {
+ // CPython: socket.gaierror
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[addrinfo error %d]", res));
}
assert(addr);
diff --git a/windows/README b/windows/README
index 615ada2012..28940f2c3d 100644
--- a/windows/README
+++ b/windows/README
@@ -4,7 +4,7 @@ It is based on Unix port, and expected to remain so.
To cross-compile under Debian/Ubuntu Linux system:
sudo apt-get install mingw32 mingw32-binutils mingw32-runtime
-make CC=i586-mingw32msvc-gcc
+make CROSS_COMPILE=i586-mingw32msvc-
The port requires additional testing, debugging, and patches. Please
consider to contribute.