Skip to content

Commit e63b30e

Browse files
committed
[ffi] add primitiveFFIIntegerAtPut
1 parent 7a14dc1 commit e63b30e

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

vm.plugins.ffi.js

+27
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,33 @@ Object.extend(Squeak.Primitives.prototype,
424424
}
425425
return this.popNandPushIfOK(argCount + 1, result);
426426
},
427+
ffi_primitiveFFIIntegerAtPut: function(argCount) {
428+
var data = this.ffiDataFromStack(4),
429+
byteOffset = this.stackInteger(3),
430+
value = this.stackSigned53BitInt(2), // good up to int32 / uint32
431+
byteSize = this.stackInteger(1),
432+
isSigned = this.stackBoolean(0);
433+
if (!this.success) return false;
434+
byteOffset--; // 1-based indexing
435+
if (byteOffset < 0 || byteSize < 1 || byteSize > 8 ||
436+
(byteSize & (byteSize - 1)) !== 0) return false;
437+
if (byteSize === 4) {
438+
if (( isSigned && (value < -0x80000000 || value > 0x7FFFFFFF)) ||
439+
(!isSigned && (value < 0 || value > 0xFFFFFFFF))) return false;
440+
if (data instanceof Uint32Array) {
441+
data[byteOffset] = value >>> 0; // storage is always unsigned
442+
} else if (data instanceof Uint8Array) {
443+
new DataView(data.buffer).setUint32(data.byteOffset + byteOffset, value >>> 0, true);
444+
} else {
445+
this.vm.warnOnce("FFI: expected Uint32Array, got " + typeof data);
446+
return false;
447+
}
448+
} else {
449+
this.vm.warnOnce("FFI: unimplemented integer type size: " + byteSize + " signed: " + isSigned);
450+
return false;
451+
}
452+
return this.popNandPushIfOK(argCount + 1, value);
453+
},
427454
ffi_primitiveFFIDoubleAtPut: function(argCount) {
428455
var data = this.ffiDataFromStack(2),
429456
byteOffset = this.stackInteger(1),

0 commit comments

Comments
 (0)