--- 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"