This commit is contained in:
2025-06-06 10:31:41 -05:00
parent c570de7f41
commit 5b9f1b8f51
3 changed files with 49 additions and 34 deletions

View File

@@ -285,9 +285,14 @@ function load_actor_config(program) {
var blob = use('blob')
var blob_stone = blob.prototype.stone
var blob_stonep = blob.prototype.stonep;
delete blob.prototype.stone;
delete blob.prototype.stonep;
function deepFreeze(object) {
if (object instanceof blob)
object.stone()
blob_stone.call(object);
// Retrieve the property names defined on object
var propNames = Object.keys(object);
@@ -307,14 +312,9 @@ function deepFreeze(object) {
globalThis.stone = deepFreeze
stone.p = function(object)
{
if (object instanceof blob) {
try {
object.read_logical(0)
return true
} catch(e) {
return false
}
}
if (object instanceof blob)
return blob_stonep.call(object)
return Object.isFrozen(object)
}

View File

@@ -371,6 +371,15 @@ static JSValue js_blob_stone(JSContext *ctx, JSValueConst this_val,
return JS_UNDEFINED;
}
static JSValue js_blob_stonep(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv) {
blob *bd = js2blob(ctx, this_val);
if (!bd) {
return JS_ThrowTypeError(ctx, "stone: not called on a blob");
}
return JS_NewBool(ctx, bd->is_stone);
}
// blob.length getter
// Return number of bits in the blob
static JSValue js_blob_get_length(JSContext *ctx, JSValueConst this_val, int magic) {
@@ -402,6 +411,7 @@ static const JSCFunctionListEntry js_blob_funcs[] = {
// Other methods
JS_CFUNC_DEF("stone", 0, js_blob_stone),
JS_CFUNC_DEF("stonep", 0, js_blob_stonep),
// Length property getter
JS_CGETSET_DEF("length", js_blob_get_length, NULL),

View File

@@ -51,7 +51,7 @@ test("Write and read single bit", function() {
b.write_bit(0);
assertEqual(b.length, 4, "Should have 4 bits after writing");
b.stone(); // Make it stone to read
stone(b); // Make it stone to read
assertEqual(b.read_logical(0), true, "First bit should be true");
assertEqual(b.read_logical(1), false, "Second bit should be false");
assertEqual(b.read_logical(2), true, "Third bit should be true (1)");
@@ -62,7 +62,7 @@ test("Write and read single bit", function() {
test("Out of range read throws error", function() {
var b = new Blob();
b.write_bit(true);
b.stone();
stone(b);
var threw = false;
try {
@@ -88,7 +88,7 @@ test("Write and read numbers", function() {
b.write_number(-42);
b.write_number(0);
b.write_number(1e20);
b.stone();
stone(b);
// Read back the numbers
assertEqual(b.read_number(0), 3.14159, "First number should match");
@@ -103,7 +103,7 @@ test("Write and read text", function() {
b.write_text("Hello");
b.write_text("World");
b.write_text("🎉"); // Unicode test
b.stone();
stone(b);
assertEqual(b.read_text(0), "Hello", "First text should match");
// Note: We need to know bit positions to read subsequent strings
@@ -121,7 +121,7 @@ test("Write and read blobs", function() {
b2.write_bit(false);
assertEqual(b2.length, 4, "Combined blob should have 4 bits");
b2.stone();
stone(b2);
assertEqual(b2.read_logical(0), true);
assertEqual(b2.read_logical(1), false);
assertEqual(b2.read_logical(2), true);
@@ -135,10 +135,10 @@ test("Blob copy constructor", function() {
b1.write_bit(false);
b1.write_bit(true);
b1.write_bit(true);
b1.stone();
stone(b1);
var b2 = new Blob(b1);
b2.stone(); // Need to stone the copy before reading
stone(b2); // Need to stone the copy before reading
assertEqual(b2.length, 4, "Copied blob should have same length");
assertEqual(b2.read_logical(0), true);
assertEqual(b2.read_logical(3), true);
@@ -150,10 +150,10 @@ test("Blob partial copy constructor", function() {
for (var i = 0; i < 10; i++) {
b1.write_bit(i % 2 === 0);
}
b1.stone();
stone(b1);
var b2 = new Blob(b1, 2, 7); // Copy bits 2-6 (5 bits)
b2.stone(); // Need to stone the copy before reading
stone(b2); // Need to stone the copy before reading
assertEqual(b2.length, 5, "Partial copy should have 5 bits");
assertEqual(b2.read_logical(0), true); // bit 2 of original
assertEqual(b2.read_logical(2), true); // bit 4 of original
@@ -164,8 +164,8 @@ test("Create blob with fill", function() {
var b1 = new Blob(8, true); // 8 bits all set to 1
var b2 = new Blob(8, false); // 8 bits all set to 0
b1.stone();
b2.stone();
stone(b1);
stone(b2);
for (var i = 0; i < 8; i++) {
assertEqual(b1.read_logical(i), true, "Bit " + i + " should be true");
@@ -182,7 +182,7 @@ test("Create blob with random function", function() {
return sequence[index++] ? 1 : 0;
});
b.stone();
stone(b);
for (var i = 0; i < 5; i++) {
assertEqual(b.read_logical(i), sequence[i], "Bit " + i + " should match sequence");
}
@@ -197,7 +197,7 @@ test("Write pad and check padding", function() {
b.write_pad(8); // Pad to 8-bit boundary
assertEqual(b.length, 8, "Should be padded to 8 bits");
b.stone();
stone(b);
assert(b['pad?'](3, 8), "Should detect valid padding at position 3");
assert(!b['pad?'](2, 8), "Should detect invalid padding at position 2");
@@ -209,10 +209,10 @@ test("Read blob from stone blob", function() {
for (var i = 0; i < 16; i++) {
b1.write_bit(i % 3 === 0);
}
b1.stone();
stone(b1);
var b2 = b1.read_blob(4, 12); // Read bits 4-11 (8 bits)
b2.stone(); // Need to stone the read blob before reading from it
stone(b2); // Need to stone the read blob before reading from it
assertEqual(b2.length, 8, "Read blob should have 8 bits");
// Check the pattern
@@ -224,7 +224,7 @@ test("Read blob from stone blob", function() {
test("Stone blob is immutable", function() {
var b = new Blob();
b.write_bit(true);
b.stone();
stone(b);
var threw = false;
try {
@@ -235,13 +235,18 @@ test("Stone blob is immutable", function() {
assert(threw, "Writing to stone blob should throw error");
});
// Test 15: Multiple stone calls
test("Multiple stone calls are safe", function() {
// Test 15: Multiple stone calls and stone.p check
test("Multiple stone calls are safe and stone.p works", function() {
var b = new Blob();
b.write_bit(true);
b.stone();
b.stone(); // Should be safe to call again
assert(!stone.p(b), "Blob should not be a stone before stone() call");
stone(b);
assert(stone.p(b), "Blob should be a stone after stone() call");
stone(b); // Should be safe to call again
assertEqual(b.read_logical(0), true, "Blob data should remain intact");
// Verify blob.stone is not available
assert(b.stone === undefined, "blob.stone should not be available as a method");
});
// Test 16: Invalid constructor arguments
@@ -282,11 +287,11 @@ test("Complex data round-trip", function() {
b.write_number(-999.999);
var originalLength = b.length;
b.stone();
stone(b);
// Verify we can create a copy
var b2 = new Blob(b);
b2.stone(); // Need to stone the copy before reading
stone(b2); // Need to stone the copy before reading
assertEqual(b2.length, originalLength, "Copy should have same length");
assertEqual(b2.read_text(0), "Test", "First text should match");
});
@@ -310,7 +315,7 @@ test("Large blob handling", function() {
}
assertEqual(b.length, testSize, "Should have " + testSize + " bits");
b.stone();
stone(b);
// Verify pattern
assertEqual(b.read_logical(0), true, "Bit 0 should be true");
@@ -372,7 +377,7 @@ test("Non-stone blob read methods should throw", function() {
test("Empty text write and read", function() {
var b = new Blob();
b.write_text("");
b.stone();
stone(b);
assertEqual(b.read_text(0), "", "Empty string should round-trip");
});
@@ -380,7 +385,7 @@ test("Empty text write and read", function() {
test("Invalid read positions", function() {
var b = new Blob();
b.write_number(42);
b.stone();
stone(b);
var threw = false;
try {