From d33ad3749a59583488625e12df9d3073a6a83a32 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Fri, 30 Oct 2015 15:36:37 +0000 Subject: [PATCH] Added stix_shallowcopy(). added some code for bigint operations --- stix/kernel/Apex.st | 10 +- stix/kernel/test-005.st | 7 +- stix/lib/bigint.c | 316 ++++++++++++++++++++++++++++++++++++---- stix/lib/exec.c | 59 +++++++- stix/lib/gc.c | 114 ++++++++++----- stix/lib/main.c | 5 +- stix/lib/obj.c | 28 ++-- stix/lib/stix-prv.h | 4 +- stix/lib/stix.h | 10 ++ 9 files changed, 463 insertions(+), 90 deletions(-) diff --git a/stix/kernel/Apex.st b/stix/kernel/Apex.st index 0da1317..e31f22d 100644 --- a/stix/kernel/Apex.st +++ b/stix/kernel/Apex.st @@ -66,6 +66,14 @@ ^self. } + ## ------------------------------------------------------- + ## ------------------------------------------------------- + #method shallowCopy + { + + self primitiveFailed. + } + ## ------------------------------------------------------- ## ------------------------------------------------------- @@ -107,7 +115,6 @@ self error: 'out of range'. } - #method(#class) basicAt: anInteger { @@ -177,6 +184,7 @@ ^true. } + ## ------------------------------------------------------- ## ------------------------------------------------------- " diff --git a/stix/kernel/test-005.st b/stix/kernel/test-005.st index 8924100..405e577 100644 --- a/stix/kernel/test-005.st +++ b/stix/kernel/test-005.st @@ -241,6 +241,9 @@ ffi close. " + +" +PROCESS TESTING | p | '000000000000000000' dump. ## p := [ | 'xxxxxxxxxxx' dump. 'yyyyyyyyyy' dump. ^10. ] newProcess. @@ -252,7 +255,8 @@ '222222222222222222' dump. '333333333333333333' dump. '444444444444444444' dump. - +" + (-2305843009213693952 - 1) dump. " FFI isNil dump. FFI notNil dump. @@ -261,6 +265,7 @@ nil class dump. nil class class class dump. " + } } diff --git a/stix/lib/bigint.c b/stix/lib/bigint.c index fbdb0cc..a64457a 100644 --- a/stix/lib/bigint.c +++ b/stix/lib/bigint.c @@ -1,13 +1,144 @@ +/* + * $Id$ + * + Copyright (c) 2014-2015 Chung, Hyung-Hwan. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #include "stix-prv.h" -/*static normalize_integer (*/ +#define MAKE_WORD(hw1,hw2) ((stix_oow_t)(hw1) | (stix_oow_t)(hw2) << STIX_OOHW_BITS) -static stix_oop_t normalize (stix_t* stix, stix_oop_t z) +static STIX_INLINE int is_integer (stix_t* stix, stix_oop_t oop) { + stix_oop_t c; + + c = STIX_CLASSOF(stix,oop); + +/* TODO: is it better to introduct a special integer mark into the class itself */ + return c == stix->_small_integer || + c == stix->_large_positive_integer || + c == stix->_large_negative_integer; +} + +static STIX_INLINE stix_oop_t make_bigint_with_ooi (stix_t* stix, stix_ooi_t i) +{ + stix_oohw_t hw[2]; + stix_oow_t w; + + if (i >= 0) + { + w = i; + hw[0] = w & STIX_LBMASK(stix_oow_t,STIX_OOHW_BITS); + hw[1] = w >> STIX_OOHW_BITS; + return stix_instantiate (stix, stix->_large_positive_integer, &hw, (hw[1] > 0? 2: 1)); + } + else + { + w = -i; + hw[0] = w & STIX_LBMASK(stix_oow_t,STIX_OOHW_BITS); + hw[1] = w >> STIX_OOHW_BITS; + return stix_instantiate (stix, stix->_large_negative_integer, &hw, (hw[1] > 0? 2: 1)); + } +} + +static STIX_INLINE stix_oow_t count_effective_digits (stix_oop_t oop) +{ + stix_oow_t i; + + for (i = STIX_OBJ_GET_SIZE(oop); i > 1; ) + { + --i; + if (((stix_oop_halfword_t)oop)->slot[i] != 0) return i + 1; + } + + return 1; +} + +static STIX_INLINE stix_oop_t clone_bigint (stix_t* stix, stix_oop_t oop, stix_oow_t count) +{ + stix_oop_t z; + stix_oow_t i; + + STIX_ASSERT (STIX_OOP_IS_POINTER(oop)); + if (count <= 0) count = STIX_OBJ_GET_SIZE(oop); + + stix_pushtmp (stix, &oop); + z = stix_instantiate (stix, STIX_OBJ_GET_CLASS(oop), STIX_NULL, count); + stix_poptmp (stix); + if (!z) return STIX_NULL; + + for (i = 0; i < count; i++) + { + ((stix_oop_halfword_t)z)->slot[i] = ((stix_oop_halfword_t)oop)->slot[i]; + } return z; } +static stix_oop_t normalize_bigint (stix_t* stix, stix_oop_t oop) +{ + stix_oow_t count; + + STIX_ASSERT (STIX_OOP_IS_POINTER(oop)); + count = count_effective_digits (oop); + if (count == 1) + { + if (STIX_OBJ_GET_CLASS(oop) == stix->_large_positive_integer) + { + return STIX_OOP_FROM_SMINT(((stix_oop_halfword_t)oop)->slot[0]); + } + else + { + STIX_ASSERT (STIX_OBJ_GET_CLASS(oop) == stix->_large_negative_integer); + return STIX_OOP_FROM_SMINT(-(stix_oow_t)((stix_oop_halfword_t)oop)->slot[0]); + } + } + else if (count == 2) + { + stix_oow_t w; + + w = MAKE_WORD (((stix_oop_halfword_t)oop)->slot[0], ((stix_oop_halfword_t)oop)->slot[1]); + if (STIX_OBJ_GET_CLASS(oop) == stix->_large_positive_integer) + { + if (w <= STIX_SMINT_MAX) return STIX_OOP_FROM_SMINT(w); + } + else + { + STIX_ASSERT (STIX_OBJ_GET_CLASS(oop) == stix->_large_negative_integer); + /*if (w <= -STIX_SMINT_MIN) */ + if (w <= ((stix_oow_t)STIX_SMINT_MAX + 1)) return STIX_OOP_FROM_SMINT(-(stix_ooi_t)w); + } + } + + if (STIX_OBJ_GET_SIZE(oop) == count) + { + /* no compaction is needed. return it as it is */ + return oop; + } + + return clone_bigint (stix, oop, count); +} + + static STIX_INLINE int is_less_unsigned_array (const stix_oohw_t* x, stix_oow_t xs, const stix_oohw_t* y, stix_oow_t ys) { stix_oow_t i; @@ -59,7 +190,7 @@ static STIX_INLINE stix_oow_t add_unsigned_array (const stix_oohw_t* x, stix_oow carry = w >> STIX_OOHW_BITS; z[i] = w & STIX_LBMASK(stix_oow_t, STIX_OOHW_BITS); } - + for (; i < xs; i++) { w = (stix_oow_t)x[i] + carry; @@ -72,7 +203,6 @@ static STIX_INLINE stix_oow_t add_unsigned_array (const stix_oohw_t* x, stix_oow return i; } - static STIX_INLINE stix_oow_t subtract_unsigned_array (const stix_oohw_t* x, stix_oow_t xs, const stix_oohw_t* y, stix_oow_t ys, stix_oohw_t* z) { stix_oow_t i, w; @@ -118,7 +248,7 @@ static STIX_INLINE stix_oow_t subtract_unsigned_array (const stix_oohw_t* x, sti static stix_oop_t add_unsigned_integers (stix_t* stix, stix_oop_t x, stix_oop_t y) { stix_oohw_t* a, * b; - stix_oow_t as, bs, zs, ks; + stix_oow_t as, bs, zs; stix_oop_t z; as = STIX_OBJ_GET_SIZE(x); @@ -141,12 +271,7 @@ static stix_oop_t add_unsigned_integers (stix_t* stix, stix_oop_t x, stix_oop_t b = ((stix_oop_halfword_t)x)->slot; } - ks = add_unsigned_array (a, as, b, bs, ((stix_oop_halfword_t)z)->slot); - if (ks <= zs) - { - /*normalize;*/ - } - + add_unsigned_array (a, as, b, bs, ((stix_oop_halfword_t)z)->slot); return z; } @@ -154,6 +279,8 @@ static stix_oop_t subtract_unsigned_integers (stix_t* stix, stix_oop_t x, stix_o { stix_oop_t z; + STIX_ASSERT (!is_less(stix, x, y)); + stix_pushtmp (stix, &x); stix_pushtmp (stix, &y); z = stix_instantiate (stix, stix->_large_positive_integer, STIX_NULL, STIX_OBJ_GET_SIZE(x)); @@ -166,48 +293,175 @@ static stix_oop_t subtract_unsigned_integers (stix_t* stix, stix_oop_t x, stix_o return z; } - -stix_oop_t stix_addbigints (stix_t* stix, stix_oop_t x, stix_oop_t y) +stix_oop_t stix_addints (stix_t* stix, stix_oop_t x, stix_oop_t y) { stix_oop_t z; - if (STIX_OBJ_GET_CLASS(x) != STIX_OBJ_GET_CLASS(y)) + if (STIX_OOP_IS_SMINT(x) && STIX_OOP_IS_SMINT(y)) { - if (STIX_OBJ_GET_CLASS(x) == stix->_large_negative_integer) - z = stix_subbigints (stix, y, x); - else - z = stix_subbigints (stix, x, y); + stix_ooi_t i; + /* no integer overflow/underflow must occur as the possible integer + * range is narrowed by the tag bits used */ + i = STIX_OOP_TO_SMINT(x) + STIX_OOP_TO_SMINT(y); + if (STIX_OOI_IN_SMINT_RANGE(i)) return STIX_OOP_FROM_SMINT(i); + + return make_bigint_with_ooi (stix, i); } else { - z = add_unsigned_integers (stix, x, y); + stix_ooi_t v; + int neg; + + if (STIX_OOP_IS_SMINT(x)) + { + if (!is_integer(stix,y)) goto oops_einval; + + v = STIX_OOP_TO_SMINT(x); + if (v == 0) return y; + + stix_pushtmp (stix, &y); + x = make_bigint_with_ooi (stix, v); + stix_poptmp (stix); + + if (!x) return STIX_NULL; + } + else if (STIX_OOP_IS_SMINT(y)) + { + if (!is_integer(stix,x)) goto oops_einval; + + v = STIX_OOP_TO_SMINT(y); + if (v == 0) return x; + + stix_pushtmp (stix, &x); + y = make_bigint_with_ooi (stix, v); + stix_poptmp (stix); + + if (!y) return STIX_NULL; + } + else + { + if (!is_integer(stix,x)) goto oops_einval; + if (!is_integer(stix,y)) goto oops_einval; + } + + if (STIX_OBJ_GET_CLASS(x) != STIX_OBJ_GET_CLASS(y)) + { + if (STIX_OBJ_GET_CLASS(x) == stix->_large_negative_integer) + { + /* x is negative, y is positive */ + z = stix_subints (stix, y, x); + } + else + { + /* x is positive, y is negative */ + z = stix_subints (stix, x, y); + } + if (!z) return STIX_NULL; + } + else + { + /* both are positive or negative */ + neg = (STIX_OBJ_GET_CLASS(x) == stix->_large_negative_integer); + z = add_unsigned_integers (stix, x, y); + if (!z) return STIX_NULL; + if (neg) STIX_OBJ_SET_CLASS(z, stix->_large_negative_integer); + } } - return normalize(stix, z); + return normalize_bigint (stix, z); + +oops_einval: + stix->errnum = STIX_EINVAL; + return STIX_NULL; } -#if 0 -stix_subbigints (stix_t* stix, stix_oop_t x, stix_oop_t y) +stix_oop_t stix_subints (stix_t* stix, stix_oop_t x, stix_oop_t y) { -/* TOOD: ensure both are LargeIntgers */ + stix_oop_t z; - if (STIX_OBJ_GET_CLASS(x) != STIX_OBJ_GET_CLASS(y)) + if (STIX_OOP_IS_SMINT(x) && STIX_OOP_IS_SMINT(y)) { - z = add_unsigned (stix, x, y); + stix_ooi_t i; + /* no integer overflow/underflow must occur as the possible integer + * range is narrowed by the tag bits used */ + i = STIX_OOP_TO_SMINT(x) - STIX_OOP_TO_SMINT(y); + if (STIX_OOI_IN_SMINT_RANGE(i)) return STIX_OOP_FROM_SMINT(i); + + return make_bigint_with_ooi (stix, i); } else { - if (is_less_unsigned (x, y)) + stix_ooi_t v; + int neg; + + if (STIX_OOP_IS_SMINT(x)) { - z = subtract_unsigned (stix, y, x); /* get the opposite sign of x; */ + if (!is_integer(stix,y)) goto oops_einval; + + v = STIX_OOP_TO_SMINT(x); + if (v == 0) + { + /* switch the sign to the opposite and return it */ + neg = (STIX_OBJ_GET_CLASS(y) == stix->_large_negative_integer); + z = clone_bigint (stix, y, 0); + if (!neg) STIX_OBJ_SET_CLASS(z, stix->_large_negative_integer); + return z; + } + + stix_pushtmp (stix, &y); + x = make_bigint_with_ooi (stix, v); + if (!x) return STIX_NULL; + stix_poptmp (stix); + } + else if (STIX_OOP_IS_SMINT(y)) + { + if (!is_integer(stix,x)) goto oops_einval; + + v = STIX_OOP_TO_SMINT(y); + if (v == 0) return x; + + stix_pushtmp (stix, &x); + y = make_bigint_with_ooi (stix, v); + if (!y) return STIX_NULL; + stix_poptmp (stix); } else { - - z = subtract_unsigned (stix, x, y); /* take x's sign */ + if (!is_integer(stix,x)) goto oops_einval; + if (!is_integer(stix,y)) goto oops_einval; + } + + if (STIX_OBJ_GET_CLASS(x) != STIX_OBJ_GET_CLASS(y)) + { + neg = (STIX_OBJ_GET_CLASS(x) == stix->_large_negative_integer); + z = add_unsigned_integers (stix, x, y); + if (!z) return STIX_NULL; + if (neg) STIX_OBJ_SET_CLASS(z, stix->_large_negative_integer); + } + else + { + /* both are positive or negative */ + if (is_less_unsigned (x, y)) + { + neg = (STIX_OBJ_GET_CLASS(x) == stix->_large_negative_integer); + z = subtract_unsigned_integers (stix, y, x); + if (!z) return STIX_NULL; + if (!neg) STIX_OBJ_SET_CLASS(z, stix->_large_negative_integer); + } + else + { + neg = (STIX_OBJ_GET_CLASS(x) == stix->_large_negative_integer); + z = subtract_unsigned_integers (stix, x, y); /* take x's sign */ + if (!z) return STIX_NULL; + if (neg) STIX_OBJ_SET_CLASS(z, stix->_large_negative_integer); + } } } - return normalize (stix, z); + return normalize_bigint (stix, z); + +oops_einval: + stix->errnum = STIX_EINVAL; + return STIX_NULL; } -#endif + diff --git a/stix/lib/exec.c b/stix/lib/exec.c index 113ec07..c43bee0 100644 --- a/stix/lib/exec.c +++ b/stix/lib/exec.c @@ -620,6 +620,22 @@ static int prim_basic_new_with_size (stix_t* stix, stix_ooi_t nargs) return 1; /* success */ } +static int prim_shallow_copy (stix_t* stix, stix_ooi_t nargs) +{ + stix_oop_t rcv, obj; + + STIX_ASSERT (nargs == 0); + + rcv = ACTIVE_STACK_GETTOP (stix); + + obj = stix_shallowcopy (stix, rcv); + if (!obj) return -1; + + /* emulate 'pop receiver' and 'push result' */ + ACTIVE_STACK_SETTOP (stix, obj); + return 1; /* success */ +} + static int prim_basic_size (stix_t* stix, stix_ooi_t nargs) { stix_oop_t rcv; @@ -704,8 +720,6 @@ static int prim_basic_at_put (stix_t* stix, stix_ooi_t nargs) STIX_ASSERT (nargs == 2); -/* TODO: disallow change of some key kernel objects */ - rcv = ACTIVE_STACK_GET(stix, stix->sp - 2); if (!STIX_OOP_IS_POINTER(rcv)) { @@ -730,6 +744,14 @@ static int prim_basic_at_put (stix_t* stix, stix_ooi_t nargs) return 0; } + if (STIX_OBJ_GET_CLASS(rcv) == stix->_symbol) + { +/* TODO: disallow change of some key kernel objects???? */ + /* TODO: is it better to introduct a read-only mark in the object header instead of this class check??? */ + /* read-only object */ /* TODO: DEVISE A WAY TO PASS a proper error from the primitive handler to STIX */ + return 0; + } + /* [NOTE] basicAt: and basicAt:put: used a 1-based index. */ idx = idx - 1; @@ -987,16 +1009,18 @@ printf ("PRIMITVE VALUE RECEIVER IS NOT A BLOCK CONTEXT\n"); static int prim_integer_add (stix_t* stix, stix_ooi_t nargs) { - stix_ooi_t tmp; - stix_oop_t rcv, arg; + stix_oop_t rcv, arg, res; STIX_ASSERT (nargs == 1); rcv = ACTIVE_STACK_GET(stix, stix->sp - 1); arg = ACTIVE_STACK_GET(stix, stix->sp); +#if 0 if (STIX_OOP_IS_SMINT(rcv) && STIX_OOP_IS_SMINT(arg)) { + stix_ooi_t tmp; + tmp = STIX_OOP_TO_SMINT(rcv) + STIX_OOP_TO_SMINT(arg); /* TODO: check overflow. if so convert it to LargeInteger */ @@ -1007,20 +1031,31 @@ static int prim_integer_add (stix_t* stix, stix_ooi_t nargs) /* TODO: handle LargeInteger */ return 0; + +#else + res = stix_addints (stix, rcv, arg); + if (!res) return -1; /* hard failure */ + + ACTIVE_STACK_POP (stix); + ACTIVE_STACK_SETTOP (stix, res); + return 1; +#endif + } static int prim_integer_sub (stix_t* stix, stix_ooi_t nargs) { - stix_ooi_t tmp; - stix_oop_t rcv, arg; + stix_oop_t rcv, arg, res; STIX_ASSERT (nargs == 1); rcv = ACTIVE_STACK_GET(stix, stix->sp - 1); arg = ACTIVE_STACK_GET(stix, stix->sp); +#if 0 if (STIX_OOP_IS_SMINT(rcv) && STIX_OOP_IS_SMINT(arg)) { + stix_ooi_t tmp; tmp = STIX_OOP_TO_SMINT(rcv) - STIX_OOP_TO_SMINT(arg); /* TODO: check overflow. if so convert it to LargeInteger */ @@ -1031,6 +1066,14 @@ static int prim_integer_sub (stix_t* stix, stix_ooi_t nargs) /* TODO: handle LargeInteger */ return 0; +#else + res = stix_subints (stix, rcv, arg); + if (!res) return -1; /* hard failure */ + + ACTIVE_STACK_POP (stix); + ACTIVE_STACK_SETTOP (stix, res); + return 1; +#endif } static int prim_integer_mul (stix_t* stix, stix_ooi_t nargs) @@ -1547,11 +1590,13 @@ static prim_t primitives[] = { 0, prim_basic_new, "_basic_new" }, { 1, prim_basic_new_with_size, "_basic_new_with_size" }, - { 0, prim_basic_size, "_basic_size" }, + { 0, prim_shallow_copy, "_shallow_copy" }, + { 0, prim_basic_size, "_basic_size" }, { 1, prim_basic_at, "_basic_at" }, { 2, prim_basic_at_put, "_basic_at_put" }, + { -1, prim_block_value, "_block_value" }, { -1, prim_block_new_process, "_block_new_process" }, diff --git a/stix/lib/gc.c b/stix/lib/gc.c index 0bdee01..568043c 100644 --- a/stix/lib/gc.c +++ b/stix/lib/gc.c @@ -83,6 +83,48 @@ static void compact_symbol_table (stix_t* stix, stix_oop_t _nil) stix->symtab->tally = STIX_OOP_FROM_SMINT(tally); } + +static STIX_INLINE stix_oow_t get_payload_bytes (stix_t* stix, stix_oop_t oop) +{ + stix_oow_t nbytes_aligned; + +#if defined(STIX_USE_OBJECT_TRAILER) + if (STIX_OBJ_GET_FLAGS_TRAILER(oop)) + { + stix_oow_t nbytes; + + /* only an OOP object can have the trailer. + * + * | _flags | + * | _size | <-- if it's 3 + * | _class | + * | X | + * | X | + * | X | + * | Y | <-- it may exist if EXTRA is set in _flags. + * | Z | <-- if TRAILER is set, it is the number of bytes in the trailer + * | | | | | + */ + STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(oop) == STIX_OBJ_TYPE_OOP); + STIX_ASSERT (STIX_OBJ_GET_FLAGS_UNIT(oop) == STIX_SIZEOF(stix_oow_t)); + STIX_ASSERT (STIX_OBJ_GET_FLAGS_EXTRA(oop) == 0); /* no 'extra' for an OOP object */ + + nbytes = STIX_OBJ_BYTESOF(oop) + STIX_SIZEOF(stix_oow_t) + \ + (stix_oow_t)((stix_oop_oop_t)oop)->slot[STIX_OBJ_GET_SIZE(oop)]; + nbytes_aligned = STIX_ALIGN (nbytes, STIX_SIZEOF(stix_oop_t)); + } + else + { +#endif + /* calculate the payload size in bytes */ + nbytes_aligned = STIX_ALIGN (STIX_OBJ_BYTESOF(oop), STIX_SIZEOF(stix_oop_t)); +#if defined(STIX_USE_OBJECT_TRAILER) + } +#endif + + return nbytes_aligned; +} + stix_oop_t stix_moveoop (stix_t* stix, stix_oop_t oop) { #if defined(STIX_SUPPORT_GC_DURING_IGNITION) @@ -104,39 +146,7 @@ stix_oop_t stix_moveoop (stix_t* stix, stix_oop_t oop) stix_oow_t nbytes_aligned; stix_oop_t tmp; -#if defined(STIX_USE_OBJECT_TRAILER) - if (STIX_OBJ_GET_FLAGS_TRAILER(oop)) - { - stix_oow_t nbytes; - - /* only an OOP object can have the trailer. - * - * | _flags | - * | _size | <-- if it's 3 - * | _class | - * | X | - * | X | - * | X | - * | Y | <-- it may exist if EXTRA is set in _flags. - * | Z | <-- if TRAILER is set, it is the number of bytes in the trailer - * | | | | | - */ - STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(oop) == STIX_OBJ_TYPE_OOP); - STIX_ASSERT (STIX_OBJ_GET_FLAGS_UNIT(oop) == STIX_SIZEOF(stix_oow_t)); - STIX_ASSERT (STIX_OBJ_GET_FLAGS_EXTRA(oop) == 0); /* no 'extra' for an OOP object */ - - nbytes = STIX_OBJ_BYTESOF(oop) + STIX_SIZEOF(stix_oow_t) + \ - (stix_oow_t)((stix_oop_oop_t)oop)->slot[STIX_OBJ_GET_SIZE(oop)]; - nbytes_aligned = STIX_ALIGN (nbytes, STIX_SIZEOF(stix_oop_t)); - } - else - { -#endif - /* calculate the payload size in bytes */ - nbytes_aligned = STIX_ALIGN (STIX_OBJ_BYTESOF(oop), STIX_SIZEOF(stix_oop_t)); -#if defined(STIX_USE_OBJECT_TRAILER) - } -#endif + nbytes_aligned = get_payload_bytes (stix, oop); /* allocate space in the new heap */ tmp = stix_allocheapmem (stix, stix->newheap, STIX_SIZEOF(stix_obj_t) + nbytes_aligned); @@ -380,3 +390,41 @@ void stix_poptmps (stix_t* stix, stix_oow_t count) STIX_ASSERT (stix->tmp_count >= count); stix->tmp_count -= count; } + + +stix_oop_t stix_shallowcopy (stix_t* stix, stix_oop_t oop) +{ + if (STIX_OOP_IS_POINTER(oop) && STIX_OBJ_GET_CLASS(oop) != stix->_symbol) + { +#if 0 + stix_oop_t z; + stix_oop_class_t c; + + c = (stix_oop_class_t)STIX_OBJ_GET_CLASS(oop); + stix_pushtmp (stix, &oop); + z = stix_instantiate (stix, (stix_oop_t)c, STIX_NULL, STIX_OBJ_GET_SIZE(oop) - STIX_CLASS_SPEC_NAMED_INSTVAR(STIX_OOP_TO_SMINT(c->spec))); + stix_poptmp(stix); + + if (!z) return z; + + /* copy the payload */ + STIX_MEMCPY (z + 1, oop + 1, get_payload_bytes(stix, oop)); + + return z; +#else + stix_oop_t z; + stix_oow_t total_bytes; + + total_bytes = STIX_SIZEOF(stix_obj_t) + get_payload_bytes(stix, oop); + + stix_pushtmp (stix, &oop); + z = stix_allocbytes (stix, total_bytes); + stix_poptmp(stix); + + STIX_MEMCPY (z, oop, total_bytes); + return z; +#endif + } + + return oop; +} diff --git a/stix/lib/main.c b/stix/lib/main.c index b1e8f4e..41e163c 100644 --- a/stix/lib/main.c +++ b/stix/lib/main.c @@ -382,11 +382,12 @@ int main (int argc, char* argv[]) stix_vmprim_t vmprim; int i; - printf ("Stix 1.0.0 - max named %lu max indexed %lu max class %lu max classinst %lu\n", + printf ("Stix 1.0.0 - max named %lu max indexed %lu max class %lu max classinst %lu smintmax %ld smintmax %ld\n", (unsigned long int)STIX_MAX_NAMED_INSTVARS, (unsigned long int)STIX_MAX_INDEXED_INSTVARS(STIX_MAX_NAMED_INSTVARS), (unsigned long int)STIX_MAX_CLASSVARS, - (unsigned long int)STIX_MAX_CLASSINSTVARS); + (unsigned long int)STIX_MAX_CLASSINSTVARS, + (long)STIX_SMINT_MAX, (long)STIX_SMINT_MIN); #if !defined(macintosh) diff --git a/stix/lib/obj.c b/stix/lib/obj.c index 3fcb695..4c9babb 100644 --- a/stix/lib/obj.c +++ b/stix/lib/obj.c @@ -109,7 +109,7 @@ stix_oop_t stix_allocoopobjwithtrailer (stix_t* stix, stix_oow_t size, const sti } #endif -static stix_oop_t alloc_numeric_array (stix_t* stix, const void* ptr, stix_oow_t len, stix_obj_type_t type, stix_oow_t unit, int extra) +static STIX_INLINE stix_oop_t alloc_numeric_array (stix_t* stix, const void* ptr, stix_oow_t len, stix_obj_type_t type, stix_oow_t unit, int extra) { /* allocate a variable object */ @@ -155,19 +155,16 @@ stix_oop_t stix_alloccharobj (stix_t* stix, const stix_ooch_t* ptr, stix_oow_t l return alloc_numeric_array (stix, ptr, len, STIX_OBJ_TYPE_CHAR, STIX_SIZEOF(stix_ooch_t), 1); } -/* -TODO: extra bits must be set ... -stix_oop_t stix_allocmbcharobj (stix_t* stix, const stix_ooch_t* ptr, stix_oow_t len) -{ - return alloc_numeric_array (stix, ptr, len, STIX_OBJ_TYPE_MBCHAR, STIX_SIZEOF(stix_ooch_t), 1); -} -*/ - stix_oop_t stix_allocbyteobj (stix_t* stix, const stix_oob_t* ptr, stix_oow_t len) { return alloc_numeric_array (stix, ptr, len, STIX_OBJ_TYPE_BYTE, STIX_SIZEOF(stix_oob_t), 0); } +stix_oop_t stix_allochalfwordobj (stix_t* stix, const stix_oohw_t* ptr, stix_oow_t len) +{ + return alloc_numeric_array (stix, ptr, len, STIX_OBJ_TYPE_HALFWORD, STIX_SIZEOF(stix_oohw_t), 0); +} + stix_oop_t stix_allocwordobj (stix_t* stix, const stix_oow_t* ptr, stix_oow_t len) { return alloc_numeric_array (stix, ptr, len, STIX_OBJ_TYPE_WORD, STIX_SIZEOF(stix_oow_t), 0); @@ -227,7 +224,7 @@ stix_oop_t stix_instantiate (stix_t* stix, stix_oop_t _class, const void* vptr, case STIX_OBJ_TYPE_OOP: /* both the fixed part(named instance variables) and * the variable part(indexed instance variables) are allowed. */ - oop = stix_allocoopobj(stix, named_instvar + vlen); + oop = stix_allocoopobj (stix, named_instvar + vlen); STIX_ASSERT (vptr == STIX_NULL); /* @@ -243,15 +240,19 @@ stix_oop_t stix_instantiate (stix_t* stix, stix_oop_t _class, const void* vptr, break; case STIX_OBJ_TYPE_CHAR: - oop = stix_alloccharobj(stix, vptr, vlen); + oop = stix_alloccharobj (stix, vptr, vlen); break; case STIX_OBJ_TYPE_BYTE: - oop = stix_allocbyteobj(stix, vptr, vlen); + oop = stix_allocbyteobj (stix, vptr, vlen); + break; + + case STIX_OBJ_TYPE_HALFWORD: + oop = stix_allochalfwordobj (stix, vptr, vlen); break; case STIX_OBJ_TYPE_WORD: - oop = stix_allocwordobj(stix, vptr, vlen); + oop = stix_allocwordobj (stix, vptr, vlen); break; default: @@ -343,3 +344,4 @@ einval: } #endif + diff --git a/stix/lib/stix-prv.h b/stix/lib/stix-prv.h index cb16378..9f1c18c 100644 --- a/stix/lib/stix-prv.h +++ b/stix/lib/stix-prv.h @@ -1038,13 +1038,13 @@ int stix_utf8toucs ( /* ========================================================================= */ /* bigint.c */ /* ========================================================================= */ -stix_oop_t stix_addbigints ( +stix_oop_t stix_addints ( stix_t* stix, stix_oop_t x, stix_oop_t y ); -stix_oop_t stix_subbigints ( +stix_oop_t stix_subints ( stix_t* stix, stix_oop_t x, stix_oop_t y diff --git a/stix/lib/stix.h b/stix/lib/stix.h index 611c98c..266640a 100644 --- a/stix/lib/stix.h +++ b/stix/lib/stix.h @@ -794,6 +794,11 @@ STIX_EXPORT void stix_gc ( stix_t* stix ); +STIX_EXPORT stix_oow_t stix_getpayloadbytes ( + stix_t* stix, + stix_oop_t oop +); + /** * The stix_instantiate() function creates a new object of the class * \a _class. The size of the fixed part is taken from the information @@ -810,6 +815,11 @@ STIX_EXPORT stix_oop_t stix_instantiate ( stix_oow_t vlen ); +STIX_EXPORT stix_oop_t stix_shallowcopy ( + stix_t* stix, + stix_oop_t oop +); + /** * The stix_ignite() function creates key initial objects. */