Skip to content

Commit

Permalink
Minor code improvements (#552)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcauberer committed May 17, 2024
1 parent ecaa09d commit c0e405d
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 74 deletions.
2 changes: 1 addition & 1 deletion .run/spice.run.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="spice" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="build -O2 -d ../../media/test-project/test.spice" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="spice" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="spice">
<configuration default="false" name="spice" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="run -O0 -d ../../media/test-project/test.spice" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="spice" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="spice">
<envs>
<env name="LLVM_ADDITIONAL_FLAGS" value="-lole32 -lws2_32" />
<env name="LLVM_BUILD_INCLUDE_DIR" value="$PROJECT_DIR$/../llvm-project-latest/build/include" />
Expand Down
51 changes: 11 additions & 40 deletions media/test-project/test.spice
Original file line number Diff line number Diff line change
@@ -1,42 +1,13 @@
import "std/os/thread";

f<int> fib(int n) {
if n <= 2 { return 1; }
return fib(n - 1) + fib(n - 2);
}

f<int> main() {
int threadCount = 8;
Thread[8] threads = [];
for unsigned int i = 0; i < threadCount; i++ {
threads[i] = Thread(p() {
int res = fib(30);
printf("Thread returned with result: %d\n", res);
});
Thread& thread = threads[i];
thread.run();
}
printf("Started all threads. Waiting for results ...\n");
for unsigned int i = 0; i < threadCount; i++ {
Thread& thread = threads[i];
thread.join();
}
printf("Program finished");
}

/*import "bootstrap/util/block-allocator";
import "bootstrap/util/memory";

type ASTNode struct {
int value
}

public p ASTNode.dtor() {
printf("Dtor called!");
}
import "std/os/env";
import "bootstrap/ast/ast-nodes";
import "bootstrap/lexer/lexer";
import "bootstrap/parser/parser";

f<int> main() {
DefaultMemoryManager defaultMemoryManager;
IMemoryManager* memoryManager = &defaultMemoryManager;
BlockAllocator<ASTNode> allocator = BlockAllocator<ASTNode>(memoryManager, 10l);
}*/
String filePath = getEnv("SPICE_STD_DIR") + "/../test/test-files/bootstrap-compiler/standalone-parser-test/test-file.spice";
Lexer lexer = Lexer(filePath.getRaw());
Parser parser = Parser(lexer);
ASTEntryNode* ast = parser.parse();
assert ast != nil<ASTEntryNode*>;
printf("All assertions passed!\n");
}
16 changes: 14 additions & 2 deletions src-bootstrap/global/global-resource-manager.spice
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import "std/type/byte";
import "std/data/vector";
import "std/data/unordered-map";
import "std/time/timer";
import "std/io/filepath";

// Own imports
import "../global/runtime-module-manager";
Expand All @@ -25,7 +26,7 @@ public const string LTO_FILE_NAME = "lto-module";
*/
public type GlobalResourceManager struct {
public llvm::Context context
public llvm::IRBuilder builder
public llvm::IRBuilder builder = llvm::IRBuilder(context)
public llvm::Module ltoModule
public llvm::TargetMachine targetMachine
public DefaultMemoryManager memoryManager
Expand All @@ -39,6 +40,7 @@ public type GlobalResourceManager struct {
public RuntimeModuleManager runtimeModuleManager
public Timer totalTimer
public ErrorManager errorManager
public bool abortCompilation = false
unsigned long nextCustomTypeId = BYTE_MAX_VALUE + 1 // Start at 256 because all primitive types come first
}

Expand Down Expand Up @@ -77,7 +79,9 @@ public p GlobalResourceManager.ctor(const CliOptions& cliOptions) {
}

public p GlobalResourceManager.dtor() {
// Shutdown LLVM
// Cleanup all statics
// ToDo: Implement
// Cleanup all LLVM statics
llvm::llvm_shutdown();
}

Expand All @@ -96,4 +100,12 @@ public f<heap SourceFile*> GlobalResourceManager.createSourceFile(SourceFile* pa

public f<unsigned long> GlobalResourceManager.getNextCustomTypeId() {
return nextCustomTypeId++;
}

public f<unsigned long> GlobalResourceManager.getTotalLineCount() {
unsigned long totalLineCount = 0l;
foreach const SourceFile* sourceFile : sourceFiles {
totalLineCount += sourceFile.value.getLineCount();
}
return totalLineCount;
}
25 changes: 15 additions & 10 deletions src-bootstrap/source-file.spice
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Imports
import "std/text/print";
import "std/data/pair";
import "std/io/filepath";
import "./driver";
import "./global/global-resource-manager";
import "./ast/ast-nodes";
Expand All @@ -11,15 +12,15 @@ type CompileStageType enum {
PARSER,
CST_VISUALIZER,
AST_BUILDER,
AST_OPTIMIZER,
AST_VISUALIZER,
IMPORT_COLLECTOR,
SYMBOL_TABLE_BUILDER,
TYPE_CHECKER_PRE,
TYPE_CHECKER_POST,
IR_GENERATOR,
IR_OPTIMIZER,
OBJECT_EMITTER
OBJECT_EMITTER,
FINISHED
}

type CompileStageIOType enum {
Expand All @@ -44,7 +45,6 @@ type TimerOutput struct {
unsigned long irGenerator = 0l
unsigned long irOptimizer = 0l
unsigned long objectEmitter = 0l
unsigned long executionEngine = 0l
}

/**
Expand All @@ -57,16 +57,17 @@ type CompilerOutput struct {
String irString
String irOptString
String asmString
String typesString
Vector<CompilerWarning> warnings
TimerOutput times
}

type NameRegistryEntry struct {
String name
unsigned long typeId // Set for structs, interfaces and enums
SymbolTableEntry* targetEntry
Scope* targetScope
SymbolTableEntry* importEntry
String predecessorName
SymbolTableEntry* importEntry = nil<SymbolTableEntry*>
}

/**
Expand All @@ -75,22 +76,26 @@ type NameRegistryEntry struct {
public type SourceFile struct {
public String name
public String fileName
public String filePath
public FilePath filePath
public String fileDir
public String objectFilePath
public bool stdFile = false
public bool mainFile = true
public bool alwaysKeepSymbolsOnNameCollision = false
public bool ignoreWarnings = false
public CompileStageType previousStage = CompileStageType::NONE
public CompilerOutput compilerOutput
public SourceFile* parent
public String cacheKey
public bool restoredFromCache = false
public EntryNode ast
public Scope globalScope
public EntryNode* ast = nil<EntryNode*>
public heap Scope* globalScope
//public llvm::Module llvmModule
public Map<String, Pair<SourceFile, const ASTNode*>> dependencies
public Vector<const SourceFile*> dependants
public Map<String, NameRegistryEntry> exportedNameRegistry
public Vector<const Function*> testFunctions

GlobalResourceManager& resourceManager
CliOptions& cliOptions
unsigned short importedRuntimeModules = 0s
unsigned short totalTypeCheckerRuns = 0s
}
Expand Down
31 changes: 28 additions & 3 deletions src-bootstrap/util/block-allocator.spice
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,21 @@ import "std/os/system";
import "../util/memory";

type Base dyn;
type T dyn;

public type BlockAllocator<Base> struct {
IMemoryManager* memoryManager
IMemoryManager& memoryManager
Vector<byte*> memoryBlocks
Vector<Base*> allocatedObjects
unsigned long blockSize
unsigned long offsetInBlock = 0l
}

public p BlockAllocator.ctor(IMemoryManager* memoryManager, unsigned long blockSize = 0l) {
public p BlockAllocator.ctor(IMemoryManager& memoryManager, unsigned long blockSize = 0l) {
this.memoryManager = memoryManager;
this.blockSize = blockSize == 0l ? (unsigned long) getPageSize() : blockSize;
// We do not allow allocating objects that exceed the block size
assert sizeof(type Base) <= this.blockSize;
// Allocate the first block
this.allocateNewBlock();
}
Expand All @@ -30,12 +33,34 @@ public p BlockAllocator.dtor() {
this.allocatedObjects.clear();

// Free all memory blocks
foreach byte* block : this.memoryBlocks {
foreach heap byte* block : this.memoryBlocks {
this.memoryManager.deallocate(block);
}
this.memoryBlocks.clear();
}

public f<T*> BlockAllocator.allocate<T>(const T& obj) {
// We do not allow allocating objects that exceed the block size
const unsigned long objSize = sizeof(type T);
assert objSize <= this.blockSize;

// Check if we need a new block
if this.offsetInBlock + objSize > this.blockSize {
this.allocateNewBlock();
}

// Construct object at the offset address
heap byte* destAddr = this.memoryBlocks.back();
unsafe {
destAddr += this.offsetInBlock;
}
T* ptr = sPlacementNew<T>(destAddr, obj);

// Update offset to be ready to store the next object
this.offsetInBlock += objSize;
return ptr;
}

public p BlockAllocator.allocateNewBlock() {
// Allocate new block
heap byte* ptr = this.memoryManager.allocate(this.blockSize);
Expand Down
2 changes: 1 addition & 1 deletion src/SourceFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ class SourceFile {
const CliOptions &cliOptions;
BS::synced_stream &tout;
uint8_t importedRuntimeModules = 0;
unsigned short totalTypeCheckerRuns = 0;
uint8_t totalTypeCheckerRuns = 0;

// Private methods
bool haveAllDependantsBeenTypeChecked() const;
Expand Down
5 changes: 5 additions & 0 deletions src/ast/ASTNodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,11 @@ class ASTNode {

virtual std::vector<std::vector<const Function *>> *getOpFctPointers() { // LCOV_EXCL_LINE
assert_fail("The given node does not overload the getOpFctPointers function"); // LCOV_EXCL_LINE
return nullptr; // LCOV_EXCL_LINE
} // LCOV_EXCL_LINE
[[nodiscard]] virtual const std::vector<std::vector<const Function *>> *getOpFctPointers() const { // LCOV_EXCL_LINE
assert_fail("The given node does not overload the getOpFctPointers function"); // LCOV_EXCL_LINE
return nullptr; // LCOV_EXCL_LINE
} // LCOV_EXCL_LINE

virtual void customItemsInitialization(size_t) {} // Noop
Expand Down Expand Up @@ -131,14 +133,17 @@ class ASTNode {

[[nodiscard]] virtual std::vector<Function *> *getFctManifestations(const std::string &) { // LCOV_EXCL_LINE
assert_fail("Must be called on a FctDefNode, ProcDefNode, ExtDeclNode, StructDefNode or SignatureNode"); // LCOV_EXCL_LINE
return nullptr; // LCOV_EXCL_LINE
} // LCOV_EXCL_LINE

[[nodiscard]] virtual std::vector<Struct *> *getStructManifestations() { // LCOV_EXCL_LINE
assert_fail("Must be called on a StructDefNode"); // LCOV_EXCL_LINE
return nullptr; // LCOV_EXCL_LINE
} // LCOV_EXCL_LINE

[[nodiscard]] virtual std::vector<Interface *> *getInterfaceManifestations() { // LCOV_EXCL_LINE
assert_fail("Must be called on a InterfaceDefNode"); // LCOV_EXCL_LINE
return nullptr; // LCOV_EXCL_LINE
} // LCOV_EXCL_LINE

[[nodiscard]] virtual bool isFctOrProcDef() const { return false; }
Expand Down
2 changes: 1 addition & 1 deletion src/util/CodeLoc.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ struct CodeLoc {
CodeLoc(const antlr4::Token *token, size_t startIdx, size_t stopIdx, SourceFile *sourceFile = nullptr)
: sourceFile(sourceFile), sourceInterval(startIdx, stopIdx), line(token->getLine()),
col(token->getCharPositionInLine() + 1){};
CodeLoc(size_t line, size_t col, SourceFile *sourceFile = nullptr) : sourceFile(sourceFile), line(line), col(col) {}
CodeLoc(uint32_t line, uint32_t col, SourceFile *sourceFile = nullptr) : sourceFile(sourceFile), line(line), col(col) {}

// Public members
SourceFile *sourceFile = nullptr;
Expand Down
6 changes: 3 additions & 3 deletions std/runtime/memory_rt.spice
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,12 @@ public f<heap T*> sNew<T>(const T& val) {
* @param val The value to put into the heap-allocated memory
* @return A pointer to the heap-allocated instance
*/
public f<heap T*> sPlacementNew<T>(heap byte* ptr, const T& val) {
public f<T*> sPlacementNew<T>(heap byte* ptr, const T& val) {
unsafe {
// Copy the value into the heap-allocated memory
sCopy((heap byte*) &val, (heap byte*) ptr, sizeof(type T));
sCopy((heap byte*) &val, ptr, sizeof(type T));
return (T*) ptr;
}
return ptr;
}

/**
Expand Down
20 changes: 10 additions & 10 deletions test/test-files/std/os/thread-pool/source.spice
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,43 @@ import "std/time/delay";
f<int> main() {
ThreadPool tp = ThreadPool(3s);
tp.enqueue(p() [[async]] {
delay(50);
delay(10);
printf("Hello from task 1\n");
});
tp.enqueue(p() [[async]] {
delay(100);
delay(20);
printf("Hello from task 2\n");
});
tp.enqueue(p() [[async]] {
delay(150);
delay(30);
printf("Hello from task 3\n");
});
tp.enqueue(p() [[async]] {
delay(200);
delay(40);
printf("Hello from task 4\n");
});
tp.enqueue(p() [[async]] {
delay(250);
delay(50);
printf("Hello from task 5\n");
});
tp.enqueue(p() [[async]] {
delay(300);
delay(60);
printf("Hello from task 6\n");
});
tp.enqueue(p() [[async]] {
delay(350);
delay(70);
printf("Hello from task 7\n");
});
tp.enqueue(p() [[async]] {
delay(400);
delay(80);
printf("Hello from task 8\n");
});
tp.enqueue(p() [[async]] {
delay(450);
delay(90);
printf("Hello from task 9\n");
});
tp.enqueue(p() [[async]] {
delay(500);
delay(100);
printf("Hello from task 10\n");
});
tp.start();
Expand Down

0 comments on commit c0e405d

Please sign in to comment.