Compiler exceptions
This commit is contained in:
@@ -16,6 +16,9 @@ uses
|
||||
Myc.Ast.Compiler.Binder;
|
||||
|
||||
type
|
||||
// Exception specific to specialization errors (e.g. internal compilation failures)
|
||||
ESpecializerException = class(EAstException);
|
||||
|
||||
IAstSpecializer = interface(IAstVisitor)
|
||||
function Execute(const RootNode: IAstNode): IAstNode;
|
||||
end;
|
||||
@@ -90,6 +93,12 @@ constructor TStaticSpecializer.Create(
|
||||
);
|
||||
begin
|
||||
inherited Create;
|
||||
if not Assigned(AMonomorphCache) then
|
||||
raise ESpecializerException.Create('MonomorphCache cannot be nil.');
|
||||
if not Assigned(AFunctionRegistry) then
|
||||
raise ESpecializerException.Create('FunctionRegistry cannot be nil.');
|
||||
// CompileFunc can be nil if no recursion is supported, but usually required.
|
||||
|
||||
FMonomorphCache := AMonomorphCache;
|
||||
FFunctionRegistry := AFunctionRegistry;
|
||||
FCompileFunc := ACompileFunc;
|
||||
@@ -178,7 +187,6 @@ begin
|
||||
if FMonomorphCache.TryGetFunction(key, specializedMethod) then
|
||||
begin
|
||||
// 4a. Cache Hit (Environment)
|
||||
// Propagate IsPure flag from cache to AST node
|
||||
Result :=
|
||||
TAst.FunctionCall(
|
||||
newCallee,
|
||||
@@ -198,7 +206,6 @@ begin
|
||||
// 5a. Cache Hit (RTL)
|
||||
FMonomorphCache.Add(key, specializedMethod);
|
||||
|
||||
// Propagate IsPure flag from RTL definition to AST node
|
||||
Result :=
|
||||
TAst.FunctionCall(
|
||||
newCallee,
|
||||
@@ -228,17 +235,21 @@ begin
|
||||
end;
|
||||
|
||||
// 6a. Compile func with KNOWN TYPES
|
||||
// This recursively triggers Bind -> Check -> Specialize -> Purity Inference for the callee body!
|
||||
if not Assigned(FCompileFunc) then
|
||||
raise ESpecializerException.Create('Cannot specialize user function: Compiler callback is missing.');
|
||||
|
||||
var compiled := FCompileFunc(funcDef, argTypes);
|
||||
|
||||
// Safety check: The recursive compiler MUST produce a valid function pointer
|
||||
if not Assigned(compiled.Func) then
|
||||
raise ESpecializerException.CreateFmt('Internal Error: Failed to compile specialization for "%s"', [funcName]);
|
||||
|
||||
// 6b. Store in cache
|
||||
// Get the return type from the *full function type* returned by Compile
|
||||
var returnType := compiled.StaticType.Signatures[0].ReturnType;
|
||||
specializedMethod := TSpecializedMethod.Create(compiled.Func, returnType, compiled.IsPure);
|
||||
FMonomorphCache.Add(key, specializedMethod);
|
||||
|
||||
// 6c. Return the new node
|
||||
// Propagate the inferred IsPure flag to the AST node
|
||||
Result := TAst.FunctionCall(newCallee, newArgs, returnType, Node.IsTailCall, compiled.Func, compiled.IsPure);
|
||||
exit;
|
||||
end;
|
||||
|
||||
Reference in New Issue
Block a user