From 9ee7d9e1100acfc6f8d2d9a61fc2dc0aa1eebddc Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Thu, 27 Apr 2017 15:40:04 +0000 Subject: [PATCH] touched up raw memory access primitives --- moo/kernel/Mill.moo | 2 +- moo/lib/bigint.c | 31 +++-- moo/lib/exec.c | 300 +++++++++++++++++++++++++++++++++----------- 3 files changed, 251 insertions(+), 82 deletions(-) diff --git a/moo/kernel/Mill.moo b/moo/kernel/Mill.moo index 1fb0c73..2924556 100644 --- a/moo/kernel/Mill.moo +++ b/moo/kernel/Mill.moo @@ -338,7 +338,7 @@ a := System _malloc(200). i := 0. while (i < 26) { - a putUint8(i, ($A asInteger + i)). + a putUint32(i, ($A asInteger + i)). i := i + 1. }. while (i > 0) diff --git a/moo/lib/bigint.c b/moo/lib/bigint.c index 671af48..f2bd3aa 100644 --- a/moo/lib/bigint.c +++ b/moo/lib/bigint.c @@ -233,17 +233,12 @@ MOO_INLINE static int is_bigint (moo_t* moo, moo_oop_t x) { moo_oop_class_t c; - /*MOO_ASSERT (moo, MOO_OOP_IS_POINTER(x));*/ if (!MOO_OOP_IS_POINTER(x)) return 0; /* TODO: is it better to introduce a special integer mark into the class itself */ /* TODO: or should it check if it's a subclass, subsubclass, subsubsubclass, etc of a large_integer as well? */ c = MOO_OBJ_GET_CLASS(x); - - if (c == moo->_large_positive_integer || - c == moo->_large_negative_integer) return 1; - - return 0; + return (c == moo->_large_positive_integer || c == moo->_large_negative_integer); } MOO_INLINE int moo_isint (moo_t* moo, moo_oop_t x) @@ -257,7 +252,7 @@ static MOO_INLINE int bigint_to_oow (moo_t* moo, moo_oop_t num, moo_oow_t* w) { MOO_ASSERT (moo, MOO_OOP_IS_POINTER(num)); MOO_ASSERT (moo, MOO_OBJ_GET_CLASS(num) == moo->_large_positive_integer || - MOO_OBJ_GET_CLASS(num) == moo->_large_negative_integer); + MOO_OBJ_GET_CLASS(num) == moo->_large_negative_integer); #if (MOO_LIW_BITS == MOO_OOW_BITS) MOO_ASSERT (moo, MOO_OBJ_GET_SIZE(num) >= 1); @@ -283,6 +278,7 @@ static MOO_INLINE int bigint_to_oow (moo_t* moo, moo_oop_t num, moo_oow_t* w) # error UNSUPPORTED LIW BIT SIZE #endif + moo->errnum = MOO_ERANGE; return 0; /* not convertable */ } @@ -346,8 +342,25 @@ int moo_inttoooi (moo_t* moo, moo_oop_t x, moo_ooi_t* i) int n; n = moo_inttooow (moo, x, &w); - if (n < 0) *i = -w; - else if (n > 0) *i = w; + if (n < 0) + { + MOO_ASSERT (moo, MOO_TYPE_MAX(moo_ooi_t) + MOO_TYPE_MIN(moo_ooi_t) == -1); /* assume 2's complement */ + if (w > (moo_oow_t)MOO_TYPE_MAX(moo_ooi_t) + 1) + { + moo->errnum = MOO_ERANGE; /* not convertable. number too small */ + return 0; + } + *i = -w; + } + else if (n > 0) + { + if (w > MOO_TYPE_MAX(moo_ooi_t)) + { + moo->errnum = MOO_ERANGE; /* not convertable. number too big */ + return 0; + } + *i = w; + } return n; } diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 2225a52..89333a9 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -1470,6 +1470,8 @@ static MOO_INLINE moo_pfrc_t pf_basic_new (moo_t* moo, moo_ooi_t nargs) return MOO_PF_FAILURE; } +/* TOOD: check if _class is set to be instantiatable... if not MOO_EPERM */ + if (nargs >= 1) { szoop = MOO_STACK_GETARG(moo, nargs, 0); @@ -3003,51 +3005,208 @@ static moo_pfrc_t pf_smptr_free (moo_t* moo, moo_ooi_t nargs) } -#define FETCH_RAW_INT(var,rawptr,offset,size) \ - switch (size) \ - { \ - case 1: var = *(moo_int8_t*)&rawptr[offset]; break; \ - case 2: var = *(moo_int16_t*)&rawptr[offset]; break; \ - case 4: var = *(moo_int32_t*)&rawptr[offset]; break; \ - case 8: var = *(moo_int64_t*)&rawptr[offset]; break; \ - default: var = *(moo_int8_t*)&rawptr[offset]; break; \ +#pragma pack(1) +struct st_int8_t { moo_int8_t v; }; +struct st_int16_t { moo_int16_t v; }; +struct st_int32_t { moo_int32_t v; }; + +struct st_uint8_t { moo_uint8_t v; }; +struct st_uint16_t { moo_uint16_t v; }; +struct st_uint32_t { moo_uint32_t v; }; + +#if defined(MOO_HAVE_UINT64_T) +struct st_int64_t { moo_int64_t v; }; +struct st_uint64_t { moo_uint64_t v; }; +#endif +#if defined(MOO_HAVE_UINT128_T) +struct st_int128_t { moo_int128_t v; }; +struct st_uint128_t { moo_uint128_t v; }; +#endif +#pragma pack() + + +static MOO_INLINE moo_oop_t _fetch_raw_int (moo_t* moo, moo_int8_t* rawptr, moo_oow_t offset, int size) +{ + moo_ooi_t v; + + switch (size) + { + case 1: + v = ((struct st_int8_t*)&rawptr[offset])->v; + break; + + case 2: + v = ((struct st_int16_t*)&rawptr[offset])->v; + break; + + case 4: + v = ((struct st_int32_t*)&rawptr[offset])->v; + break; + + #if defined(MOO_HAVE_INT64_T) && (MOO_SIZEOF_OOW_T >= MOO_SIZEOF_INT64_T) + case 8: + v = ((struct st_int64_t*)&rawptr[offset])->v; + break; + #endif + + #if defined(MOO_HAVE_INT128_T) && (MOO_SIZEOF_OOW_T >= MOO_SIZEOF_INT128_T) + case 16: + v = ((struct st_int128_t*)&rawptr[offset])->v; + break; + #endif + + default: + moo->errnum = MOO_EINVAL; + return MOO_NULL; } -#define FETCH_RAW_UINT(var,rawptr,offset,size) \ - switch (size) \ - { \ - case 1: var = *(moo_uint8_t*)&rawptr[offset]; break; \ - case 2: var = *(moo_uint16_t*)&rawptr[offset]; break; \ - case 4: var = *(moo_uint32_t*)&rawptr[offset]; break; \ - case 8: var = *(moo_uint64_t*)&rawptr[offset]; break; \ - default: var = *(moo_uint8_t*)&rawptr[offset]; break; \ + return moo_ooitoint (moo, v); +} + + +static MOO_INLINE moo_oop_t _fetch_raw_uint (moo_t* moo, moo_uint8_t* rawptr, moo_oow_t offset, int size) +{ + moo_oow_t v; + + switch (size) + { + case 1: + v = ((struct st_uint8_t*)&rawptr[offset])->v; + break; + + case 2: + v = ((struct st_uint16_t*)&rawptr[offset])->v; + break; + + case 4: + v = ((struct st_uint32_t*)&rawptr[offset])->v; + break; + + #if defined(MOO_HAVE_UINT64_T) && (MOO_SIZEOF_OOW_T >= MOO_SIZEOF_UINT64_T) + case 8: + v = ((struct st_uint64_t*)&rawptr[offset])->v; + break; + #endif + + #if defined(MOO_HAVE_UINT128_T) && (MOO_SIZEOF_OOW_T >= MOO_SIZEOF_UINT128_T) + case 16: + v = ((struct st_uint128_t*)&rawptr[offset])->v; + break; + #endif + + default: + moo->errnum = MOO_EINVAL; + return MOO_NULL; } -#define STORE_RAW_INT(value,rawptr,offset,size) \ - switch (size) \ - { \ - case 1: *(moo_int8_t*)&rawptr[offset] = value; break; \ - case 2: *(moo_int16_t*)&rawptr[offset] = value; break; \ - case 4: *(moo_int32_t*)&rawptr[offset] = value; break; \ - case 8: *(moo_int64_t*)&rawptr[offset] = value; break; \ - default: *(moo_int8_t*)&rawptr[offset] = value; break; \ + return moo_oowtoint (moo, v); +} + +static MOO_INLINE int _store_raw_int (moo_t* moo, moo_uint8_t* rawptr, moo_oow_t offset, int size, moo_oop_t voop) +{ + moo_ooi_t w, max, min; + + if (moo_inttoooi (moo, voop, &w) == 0) return -1; + + /* assume 2's complement */ + max = (moo_ooi_t)(~(moo_oow_t)0 >> ((MOO_SIZEOF_OOW_T - size) * 8 + 1)); + min = -max - 1; +MOO_DEBUG2 (moo, "MAX = %zd MIN = %zd\n", max, min); + + if (w > max || w < min) + { + moo->errnum = MOO_ERANGE; + return -1; } -#define STORE_RAW_UINT(value,rawptr,offset,size) \ - switch (size) \ - { \ - case 1: *(moo_uint8_t*)&rawptr[offset] = value; break; \ - case 2: *(moo_uint16_t*)&rawptr[offset] = value; break; \ - case 4: *(moo_uint32_t*)&rawptr[offset] = value; break; \ - case 8: *(moo_uint64_t*)&rawptr[offset] = value; break; \ - default: *(moo_uint8_t*)&rawptr[offset] = value; break; \ + switch (size) + { + case 1: + ((struct st_int8_t*)&rawptr[offset])->v = w; + return 0; + + case 2: + ((struct st_int16_t*)&rawptr[offset])->v = w; + return 0; + + case 4: + ((struct st_int32_t*)&rawptr[offset])->v = w; + return 0; + + #if defined(MOO_HAVE_INT64_T) && (MOO_SIZEOF_OOW_T >= MOO_SIZEOF_INT64_T) + case 8: + ((struct st_int64_t*)&rawptr[offset])->v = w; + return 0; + #endif + + #if defined(MOO_HAVE_INT128_T) && (MOO_SIZEOF_OOW_T >= MOO_SIZEOF_INT128_T) + case 16: + ((struct st_int128_t*)&rawptr[offset])->v = w; + return 0; + #endif } + moo->errnum = MOO_EINVAL; + return -1; +} + +static MOO_INLINE int _store_raw_uint (moo_t* moo, moo_uint8_t* rawptr, moo_oow_t offset, int size, moo_oop_t voop) +{ + int n; + moo_oow_t w, max; + + + if ((n = moo_inttooow (moo, voop, &w)) <= -1) + { + if (n <= -1) moo->errnum = MOO_ERANGE; + return -1; + } + + max = (~(moo_oow_t)0 >> ((MOO_SIZEOF_OOW_T - size) * 8)); +MOO_DEBUG2 (moo, "MAX = %zx %zx\n", max, max); + if (w > max) + { + moo->errnum = MOO_ERANGE; + return -1; + } + + + switch (size) + { + case 1: + ((struct st_uint8_t*)&rawptr[offset])->v = w; + return 0; + + case 2: + ((struct st_uint16_t*)&rawptr[offset])->v = w; + return 0; + + case 4: + ((struct st_uint32_t*)&rawptr[offset])->v = w; + return 0; + + #if defined(MOO_HAVE_UINT64_T) && (MOO_SIZEOF_OOW_T >= MOO_SIZEOF_UINT64_T) + case 8: + ((struct st_uint64_t*)&rawptr[offset])->v = w; + return 0; + #endif + + #if defined(MOO_HAVE_UINT128_T) && (MOO_SIZEOF_OOW_T >= MOO_SIZEOF_UINT128_T) + case 16: + ((struct st_uint128_t*)&rawptr[offset])->v = w; + return 0; + #endif + } + + moo->errnum = MOO_EINVAL; + return -1; +} + + static moo_pfrc_t _get_system_int (moo_t* moo, moo_ooi_t nargs, int size) { - moo_uint8_t* rawptr; + moo_int8_t* rawptr; moo_oow_t offset; - moo_ooi_t value; moo_oop_t tmp; MOO_ASSERT (moo, nargs == 2); @@ -3063,10 +3222,8 @@ static moo_pfrc_t _get_system_int (moo_t* moo, moo_ooi_t nargs, int size) return MOO_PF_SUCCESS; } - FETCH_RAW_INT (value, rawptr, offset, size); - - tmp = moo_ooitoint (moo, value); - if (!tmp) + tmp = _fetch_raw_int (moo, rawptr, offset, size); + if (!tmp) { MOO_STACK_SETRETTOERRNUM (moo, nargs); return MOO_PF_SUCCESS; @@ -3080,7 +3237,6 @@ static moo_pfrc_t _get_system_uint (moo_t* moo, moo_ooi_t nargs, int size) { moo_uint8_t* rawptr; moo_oow_t offset; - moo_oow_t value; moo_oop_t tmp; MOO_ASSERT (moo, nargs == 2); @@ -3096,9 +3252,7 @@ static moo_pfrc_t _get_system_uint (moo_t* moo, moo_ooi_t nargs, int size) return MOO_PF_SUCCESS; } - FETCH_RAW_UINT (value, rawptr, offset, size); - - tmp = moo_oowtoint (moo, value); + tmp = _fetch_raw_uint (moo, rawptr, offset, size); if (!tmp) { MOO_STACK_SETRETTOERRNUM (moo, nargs); @@ -3153,7 +3307,6 @@ static moo_pfrc_t _put_system_int (moo_t* moo, moo_ooi_t nargs, int size) { moo_uint8_t* rawptr; moo_oow_t offset; - moo_ooi_t value; moo_oop_t tmp; MOO_ASSERT (moo, nargs == 3); @@ -3162,10 +3315,13 @@ static moo_pfrc_t _put_system_int (moo_t* moo, moo_ooi_t nargs, int size) if (MOO_OOP_IS_SMPTR(tmp)) rawptr = MOO_OOP_TO_SMPTR(tmp); else if (moo_inttooow (moo, tmp, (moo_oow_t*)&rawptr) <= 0) goto einval; - if (moo_inttooow(moo, MOO_STACK_GETARG(moo, nargs, 1), &offset) <= 0 || - moo_inttoooi(moo, MOO_STACK_GETARG(moo, nargs, 2), &value) <= 0) goto einval; + if (moo_inttooow(moo, MOO_STACK_GETARG(moo, nargs, 1), &offset) <= 0) goto einval; - STORE_RAW_INT (value, rawptr, offset, size); + if (_store_raw_int (moo, rawptr, offset, size, MOO_STACK_GETARG(moo, nargs, 2)) <= -1) + { + MOO_STACK_SETRETTOERRNUM (moo, nargs); + return MOO_PF_SUCCESS; + } MOO_STACK_SETRETTORCV (moo, nargs); return MOO_PF_SUCCESS; @@ -3179,7 +3335,6 @@ static moo_pfrc_t _put_system_uint (moo_t* moo, moo_ooi_t nargs, int size) { moo_uint8_t* rawptr; moo_oow_t offset; - moo_oow_t value; moo_oop_t tmp; MOO_ASSERT (moo, nargs == 3); @@ -3188,10 +3343,13 @@ static moo_pfrc_t _put_system_uint (moo_t* moo, moo_ooi_t nargs, int size) if (MOO_OOP_IS_SMPTR(tmp)) rawptr = MOO_OOP_TO_SMPTR(tmp); else if (moo_inttooow (moo, tmp, (moo_oow_t*)&rawptr) <= 0) goto einval; - if (moo_inttooow(moo, MOO_STACK_GETARG(moo, nargs, 1), &offset) <= 0 || - moo_inttooow(moo, MOO_STACK_GETARG(moo, nargs, 2), &value) <= 0) goto einval; + if (moo_inttooow(moo, MOO_STACK_GETARG(moo, nargs, 1), &offset) <= 0) goto einval; - STORE_RAW_UINT (value, rawptr, offset, size); + if (_store_raw_uint (moo, rawptr, offset, size, MOO_STACK_GETARG(moo, nargs, 2)) <= -1) + { + MOO_STACK_SETRETTOERRNUM (moo, nargs); + return MOO_PF_SUCCESS; + } MOO_STACK_SETRETTORCV (moo, nargs); return MOO_PF_SUCCESS; @@ -3245,9 +3403,8 @@ static moo_pfrc_t pf_system_put_uint64 (moo_t* moo, moo_ooi_t nargs) static moo_pfrc_t _get_smptr_int (moo_t* moo, moo_ooi_t nargs, int size) { moo_oop_t rcv; - moo_uint8_t* rawptr; + moo_int8_t* rawptr; moo_oow_t offset; - moo_ooi_t value; moo_oop_t result; MOO_ASSERT (moo, nargs == 1); @@ -3267,12 +3424,10 @@ static moo_pfrc_t _get_smptr_int (moo_t* moo, moo_ooi_t nargs, int size) rawptr = MOO_OOP_TO_SMPTR(rcv); - FETCH_RAW_INT (value, rawptr, offset, size); - - result = moo_ooitoint (moo, value); + result = _fetch_raw_int (moo, rawptr, offset, size); if (!result) { - MOO_STACK_SETRETTOERRNUM(moo, nargs); + MOO_STACK_SETRETTOERRNUM (moo, nargs); return MOO_PF_SUCCESS; } @@ -3285,7 +3440,6 @@ static moo_pfrc_t _get_smptr_uint (moo_t* moo, moo_ooi_t nargs, int size) moo_oop_t rcv; moo_uint8_t* rawptr; moo_oow_t offset; - moo_oow_t value; moo_oop_t result; MOO_ASSERT (moo, nargs == 1); @@ -3305,9 +3459,7 @@ static moo_pfrc_t _get_smptr_uint (moo_t* moo, moo_ooi_t nargs, int size) rawptr = MOO_OOP_TO_SMPTR(rcv); - FETCH_RAW_UINT (value, rawptr, offset, size); - - result = moo_oowtoint (moo, value); + result = _fetch_raw_uint (moo, rawptr, offset, size); if (!result) { MOO_STACK_SETRETTOERRNUM(moo, nargs); @@ -3362,7 +3514,6 @@ static moo_pfrc_t _put_smptr_int (moo_t* moo, moo_ooi_t nargs, int size) { moo_uint8_t* rawptr; moo_oow_t offset; - moo_ooi_t value; moo_oop_t tmp; MOO_ASSERT (moo, nargs == 2); @@ -3370,20 +3521,23 @@ static moo_pfrc_t _put_smptr_int (moo_t* moo, moo_ooi_t nargs, int size) tmp = MOO_STACK_GETRCV(moo, nargs); if (!MOO_OOP_IS_SMPTR(tmp)) { - moo->errnum = MOO_EMSGRCV; - return MOO_PF_HARD_FAILURE; + MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EMSGRCV); + return MOO_PF_SUCCESS; } rawptr = MOO_OOP_TO_SMPTR(tmp); - if (moo_inttooow(moo, MOO_STACK_GETARG(moo, nargs, 0), &offset) <= 0 || - moo_inttoooi(moo, MOO_STACK_GETARG(moo, nargs, 1), &value) <= 0) + if (moo_inttooow(moo, MOO_STACK_GETARG(moo, nargs, 0), &offset) <= 0) { MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL); return MOO_PF_SUCCESS; } - STORE_RAW_INT (value, rawptr, offset, size); + if (_store_raw_int (moo, rawptr, offset, size, MOO_STACK_GETARG(moo, nargs, 1)) <= -1) + { + MOO_STACK_SETRETTOERRNUM (moo, nargs); + return MOO_PF_SUCCESS; + } MOO_STACK_SETRETTORCV (moo, nargs); return MOO_PF_SUCCESS; @@ -3393,7 +3547,6 @@ static moo_pfrc_t _put_smptr_uint (moo_t* moo, moo_ooi_t nargs, int size) { moo_uint8_t* rawptr; moo_oow_t offset; - moo_oow_t value; moo_oop_t tmp; MOO_ASSERT (moo, nargs == 2); @@ -3401,20 +3554,23 @@ static moo_pfrc_t _put_smptr_uint (moo_t* moo, moo_ooi_t nargs, int size) tmp = MOO_STACK_GETRCV(moo, nargs); if (!MOO_OOP_IS_SMPTR(tmp)) { - moo->errnum = MOO_EMSGRCV; - return MOO_PF_HARD_FAILURE; + MOO_STACK_SETRETTOERRNUM (moo, MOO_EMSGRCV); + return MOO_PF_SUCCESS; } rawptr = MOO_OOP_TO_SMPTR(tmp); - if (moo_inttooow(moo, MOO_STACK_GETARG(moo, nargs, 0), &offset) <= 0 || - moo_inttooow(moo, MOO_STACK_GETARG(moo, nargs, 1), &value) <= 0) + if (moo_inttooow(moo, MOO_STACK_GETARG(moo, nargs, 0), &offset) <= 0) { MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL); return MOO_PF_SUCCESS; } - STORE_RAW_UINT (value, rawptr, offset, size); + if (_store_raw_uint (moo, rawptr, offset, size, MOO_STACK_GETARG(moo, nargs, 1)) <= -1) + { + MOO_STACK_SETRETTOERRNUM (moo, nargs); + return MOO_PF_SUCCESS; + } MOO_STACK_SETRETTORCV (moo, nargs); return MOO_PF_SUCCESS;