diff -r 20f96b340a4d -r 711de6b11ff1 UninterpretedBytes.st --- a/UninterpretedBytes.st Thu May 10 21:05:57 2018 +0200 +++ b/UninterpretedBytes.st Thu May 10 21:26:56 2018 +0200 @@ -3494,51 +3494,48 @@ "get a pointer starting at byteIndex as ExternalAddress. The byteIndex is a smalltalk index (i.e. 1-based). Only aligned accesses are allowed. - The pointer is of native cpu's size (4 or 8 bytes)" + The pointer is of native cpu's size (4 or 8 bytes). + This returns an external adress." + + |failReason| %{ if (__isSmallInteger(byteIndex)) { - unsigned char *cp; - INT sz; - - __fetchBytePointerAndSize__(self, &cp, &sz); - if (cp) { - INT idx = __smallIntegerVal(byteIndex) - 1; - char *pointer; - - if ((idx >= 0) && ((idx+(sizeof(pointer)-1)) < sz)) { - cp += idx; - /* - * aligned - */ - if (((INT)cp & (sizeof(pointer)-1)) == 0) { - pointer = ((char **)cp)[0]; - RETURN (__MKEXTERNALADDRESS(pointer)); - } else { -#if 0 - printf("cp UNALIGNED (%"_lx_")\n", (INT)cp); -#endif - } - } else { -#if 0 - printf("idx(%"_ld_")+(sizeof(pointer)-1) (%d) >= sz (%"_ld_")\n", - idx, (int)(sizeof(pointer)-1), sz); -#endif - } - } else { -#if 0 - printf("cp is NULL\n"); -#endif - } + unsigned char *cp; + INT sz; + + __fetchBytePointerAndSize__(self, &cp, &sz); + if (cp) { + INT idx = __smallIntegerVal(byteIndex) - 1; + char *pointer; + + if ((idx >= 0) && ((idx+(sizeof(pointer)-1)) < sz)) { + cp += idx; + /* + * aligned + */ + if (((INT)cp & (sizeof(pointer)-1)) == 0) { + pointer = ((char **)cp)[0]; + RETURN (__MKEXTERNALADDRESS(pointer)); + } + // fprintf(stderr, "cp UNALIGNED (%"_lx_")\n", (INT)cp); + failReason = @symbol(unaligned); + } else { + // fprintf(stderr, "idx(%"_ld_")+(sizeof(pointer)-1) (%d) >= sz (%"_ld_")\n", + // idx, (int)(sizeof(pointer)-1), sz); + failReason = @symbol(invalidIndex); + } + } else { + // fprintf(stderr, "cp is NULL\n"); + failReason = @symbol(nullPointer); + } } else { -#if 0 - printf("bad index\n"); -#endif + // fprintf(stderr, "non integer index\n"); + failReason = @symbol(invalidIndex); } bad:; %}. - - self primitiveFailed. + ^ self reportError:failReason with:byteIndex " |b| @@ -3564,49 +3561,63 @@ The pointer is of native cpu's size (4 or 8 bytes). The value may be either an ExternalAddress, ExternalBytes or an Integer" + |failReason| + %{ OBJ *pointer; if (__isExternalAddressLike(value)) { - pointer = __externalAddressVal(value); + pointer = __externalAddressVal(value); } else if (__isExternalBytesLike(value)) { - pointer = __externalBytesVal(value); - if (pointer == (OBJ *)0) - pointer = 0; + pointer = __externalBytesVal(value); + if (pointer == (OBJ *)0) + pointer = 0; } else if (value == nil) { - pointer = 0; + pointer = 0; } else if (__isSmallInteger(value)) { - pointer = (OBJ *)__intVal(value); + pointer = (OBJ *)__intVal(value); } else { - if ((pointer = (OBJ *)__unsignedLongIntVal(value)) == 0) { - goto bad; - } + if ((pointer = (OBJ *)__unsignedLongIntVal(value)) == 0) { + // fprintf(stderr, "not a largeInt\n"); + failReason = @symbol(badValue); + goto bad; + } } if (__isSmallInteger(byteIndex)) { - unsigned char *cp; - INT sz; - - __fetchBytePointerAndSize__(self, &cp, &sz); - if (cp) { - INT idx = __smallIntegerVal(byteIndex) - 1; - - if ((idx >= 0) && ((idx+(sizeof(pointer)-1)) < sz)) { - cp += idx; - /* - * aligned - */ - if (((INT)cp & (sizeof(pointer)-1)) == 0) { - ((char **)cp)[0] = (char *) pointer; - RETURN (value); - } - } - } + unsigned char *cp; + INT sz; + + __fetchBytePointerAndSize__(self, &cp, &sz); + if (cp) { + INT idx = __smallIntegerVal(byteIndex) - 1; + + if ((idx >= 0) && ((idx+(sizeof(pointer)-1)) < sz)) { + cp += idx; + /* + * aligned + */ + if (((INT)cp & (sizeof(pointer)-1)) == 0) { + ((char **)cp)[0] = (char *) pointer; + RETURN (value); + } + // fprintf(stderr, "cp unaligned\n"); + failReason = @symbol(unaligned); + } else { + // fprintf(stderr, "idx out of bounds\n"); + failReason = @symbol(invalidIndex); + } + } else { + // fprintf(stderr, "cp is null\n"); + failReason = @symbol(nullPointer); + } + } else { + // fprintf(stderr, "byteIndex not a smallInt\n"); + failReason = @symbol(invalidIndex); } bad:; %}. - - self primitiveFailed. + ^ self reportError:failReason with:byteIndex " |b| @@ -3626,41 +3637,45 @@ The pointer is of native cpu's size (4 or 8 bytes). This returns an int with sizeof the machines's native pointer (4 or 8 bytes)" + |failReason| %{ if (__isSmallInteger(byteIndex)) { - unsigned char *cp; - INT sz; - - __fetchBytePointerAndSize__(self, &cp, &sz); - if (cp) { - INT idx = __smallIntegerVal(byteIndex) - 1; - char *pointer; - - if ((idx >= 0) && ((idx+(sizeof(pointer)-1)) < sz)) { - cp += idx; - /* - * aligned - */ - if (((INT)cp & (sizeof(pointer)-1)) == 0) { - pointer = ((char **)cp)[0]; - RETURN (__MKUINT((INT)(pointer))); - } else { - // printf("cp UNALIGNED (%"_lx_")\n", (INT)cp); - } - } else { - // printf("idx(%"_ld_")+(sizeof(pointer)-1) (%d) >= sz (%"_ld_")\n", - // idx, (int)(sizeof(pointer)-1), sz); - } - } else { - // printf("cp is NULL\n"); - } + unsigned char *cp; + INT sz; + + __fetchBytePointerAndSize__(self, &cp, &sz); + if (cp) { + INT idx = __smallIntegerVal(byteIndex) - 1; + char *pointer; + + if ((idx >= 0) && ((idx+(sizeof(pointer)-1)) < sz)) { + cp += idx; + /* + * aligned + */ + if (((INT)cp & (sizeof(pointer)-1)) == 0) { + pointer = ((char **)cp)[0]; + RETURN (__MKUINT((INT)(pointer))); + } + // printf("cp UNALIGNED (%"_lx_")\n", (INT)cp); + failReason = @symbol(unaligned); + } else { + // printf("idx(%"_ld_")+(sizeof(pointer)-1) (%d) >= sz (%"_ld_")\n", + // idx, (int)(sizeof(pointer)-1), sz); + failReason = @symbol(invalidIndex); + } + } else { + // fprintf(stderr, "cp is NULL\n"); + failReason = @symbol(nullPointer); + } } else { - // printf("bad index\n"); + // fprintf(stderr, "non integer index\n"); + failReason = @symbol(invalidIndex); } bad:; %}. - self primitiveFailed. + ^ self reportError:failReason with:byteIndex " |b| @@ -5029,6 +5044,21 @@ !UninterpretedBytes methodsFor:'private'! +reportError:failReason with:parameter + "common helper" + + (failReason == #invalidIndex) ifTrue:[ + ^ self indexNotIntegerOrOutOfBounds:parameter + ]. + failReason == #nullPointer ifTrue:[ + ^ self error:'free or unallocated object referenced' + ]. + failReason == #unaligned ifTrue:[ + ^ self error:'unaligned index'. + ]. + self primitiveFailed:failReason. +! + slowReplaceBytesFrom:startArg to:stopArg with:sourceBytes startingAt:sourceIndex "fallback if primitive code fails"