Runtime: add method dispatch for array/string/dict/number (.len, .push, .pop, .keys, .values, .has, .toInt) Stdlib: delete global len/push/pop/keys/values/has Tests/docs/examples: migrate to method style; add tests/test_builtin_methods_style.bob All tests pass Breaking: global len/push/pop/keys/values/has removed; use methods instead Parser/AST: add class/extends/extension/super, field initializers Runtime: shared methods with this injection; classParents/classTemplates; super resolution; ownerClass/currentClass; extension lookup order Builtins: method dispatch for array/string/dict/number (.len/.push/.pop/.keys/.values/.has/.toInt); remove global forms Tests/docs/examples: add/refresh for classes, inheritance, super, polymorphism; migrate to method style; all tests pass VS Code extension: update grammar/readme/snippets for new features
113 lines
4.2 KiB
Plaintext
113 lines
4.2 KiB
Plaintext
// Memory leak test: Mixed type scenarios and edge cases
|
|
// Test combinations and edge cases that might cause leaks
|
|
|
|
print("=== Mixed Type Memory Leak Tests ===");
|
|
print("Initial memory: " + memoryUsage() + " MB");
|
|
|
|
// Test 1: Functions with collection captures
|
|
print("Test 1: Functions capturing collections");
|
|
var funcWithCollections = [];
|
|
for (var i = 0; i < 50000; i++) {
|
|
var capturedArray = [i, i+1, i+2, "data" + i];
|
|
var capturedDict = {"id": i, "values": [i*2, i*3]};
|
|
|
|
funcWithCollections.push(func() {
|
|
// Capture both collections
|
|
var localArray = capturedArray;
|
|
var localDict = capturedDict;
|
|
return func() {
|
|
return localArray.len() + localDict.len();
|
|
};
|
|
});
|
|
}
|
|
print("Created " + funcWithCollections.len() + " functions with collection captures");
|
|
print("Memory: " + memoryUsage() + " MB");
|
|
input("Press Enter to clear function collections...");
|
|
funcWithCollections = [];
|
|
print("Memory after clear: " + memoryUsage() + " MB");
|
|
input("Cleared. Check memory usage...");
|
|
|
|
// Test 2: Collections containing functions and other collections
|
|
print("Test 2: Collections with mixed content");
|
|
var mixedContent = [];
|
|
for (var i = 0; i < 30000; i++) {
|
|
mixedContent.push([
|
|
func() { return i; }, // Function
|
|
[i, i+1, func() { return i*2; }], // Array with function
|
|
{"value": i, "func": func() { return i*3; }}, // Dict with function
|
|
"string" + i, // String
|
|
i * 1.5, // Number
|
|
i % 2 == 0 // Boolean
|
|
]);
|
|
}
|
|
print("Created " + mixedContent.len() + " mixed content collections");
|
|
print("Memory: " + memoryUsage() + " MB");
|
|
input("Press Enter to clear mixed content...");
|
|
mixedContent = none;
|
|
print("Memory after clear: " + memoryUsage() + " MB");
|
|
input("Cleared. Check memory usage...");
|
|
|
|
// Test 3: Property assignment patterns
|
|
print("Test 3: Property assignment patterns");
|
|
var propObjects = [];
|
|
for (var i = 0; i < 100000; i++) {
|
|
var obj = {"base": i};
|
|
// Dynamic property assignment
|
|
obj["prop" + i] = func() { return i; };
|
|
obj["nested"] = {"deep": {"value": i}};
|
|
obj["array"] = [1, 2, 3];
|
|
obj["array"][0] = func() { return i * 2; };
|
|
|
|
propObjects.push(obj);
|
|
}
|
|
print("Created " + propObjects.len() + " objects with dynamic properties");
|
|
print("Memory: " + memoryUsage() + " MB");
|
|
input("Press Enter to clear property objects...");
|
|
propObjects = "cleared";
|
|
print("Memory after clear: " + memoryUsage() + " MB");
|
|
input("Cleared. Check memory usage...");
|
|
|
|
// Test 4: Type reassignment chains
|
|
print("Test 4: Type reassignment chains");
|
|
var typeChains = [];
|
|
for (var i = 0; i < 200000; i++) {
|
|
typeChains.push(i);
|
|
}
|
|
print("Memory after number array: " + memoryUsage() + " MB");
|
|
input("Created number array. Press Enter to convert to functions...");
|
|
|
|
// Reassign all elements to functions
|
|
for (var i = 0; i < typeChains.len(); i++) {
|
|
typeChains[i] = func() { return i; };
|
|
}
|
|
print("Memory after function conversion: " + memoryUsage() + " MB");
|
|
input("Converted to functions. Press Enter to convert to dicts...");
|
|
|
|
// Reassign all elements to dicts
|
|
for (var i = 0; i < typeChains.len(); i++) {
|
|
typeChains[i] = {"id": i, "func": func() { return i; }};
|
|
}
|
|
print("Memory after dict conversion: " + memoryUsage() + " MB");
|
|
input("Converted to dicts. Press Enter to clear...");
|
|
typeChains = none;
|
|
print("Memory after clear: " + memoryUsage() + " MB");
|
|
input("Cleared. Check memory usage...");
|
|
|
|
// Test 5: Rapid allocation/deallocation
|
|
print("Test 5: Rapid allocation/deallocation");
|
|
for (var round = 0; round < 10; round++) {
|
|
var temp = [];
|
|
for (var i = 0; i < 100000; i++) {
|
|
temp.push([
|
|
func() { return i; },
|
|
{"data": [i, i+1, func() { return i*2; }]}
|
|
]);
|
|
}
|
|
print("Round " + round + ": Created " + temp.len() + " items, Memory: " + memoryUsage() + " MB");
|
|
temp = none; // Clear immediately
|
|
if (round % 2 == 1) print("After clear round " + round + ": " + memoryUsage() + " MB");
|
|
}
|
|
print("Final memory after all cycles: " + memoryUsage() + " MB");
|
|
input("Completed rapid allocation cycles. Check memory usage...");
|
|
|
|
print("=== Mixed Type Tests Complete ==="); |