From ecdeeab90fc523ec324d8394bb442d1ab9fa44c2 Mon Sep 17 00:00:00 2001 From: Daniel Hails Date: Fri, 7 Sep 2018 11:24:12 +0100 Subject: [PATCH] Generate IR code for caller functions --- .../Runtime/IRCallerCapabilityChecks.swift | 134 ++++++++++-------- 1 file changed, 78 insertions(+), 56 deletions(-) diff --git a/Sources/IRGen/Runtime/IRCallerCapabilityChecks.swift b/Sources/IRGen/Runtime/IRCallerCapabilityChecks.swift index 3e518944..09725e3c 100644 --- a/Sources/IRGen/Runtime/IRCallerCapabilityChecks.swift +++ b/Sources/IRGen/Runtime/IRCallerCapabilityChecks.swift @@ -1,57 +1,79 @@ // - // IRCallerCapabilityChecks.swift - // IRGen - // - // Created by Hails, Daniel R on 11/07/2018. - // - - import AST - - /// Checks whether the caller of a function has appropriate caller capabilities. - struct IRCallerCapabilityChecks { - static let postfix: String = "CallerCheck" - static let varName: String = "_flint" + postfix - - var variableName: String - var callerCapabilities: [CallerCapability] - let revert: Bool - - init(callerCapabilities: [CallerCapability], revert: Bool = true, variableName: String = varName) { - self.variableName = variableName - self.callerCapabilities = callerCapabilities - self.revert = revert - } - - func rendered(enclosingType: RawTypeIdentifier, environment: Environment) -> String { - let checks = callerCapabilities.compactMap { callerCapability -> String? in - guard !callerCapability.isAny else { return nil } - - let type = environment.type(of: callerCapability.identifier.name, enclosingType: enclosingType) - let offset = environment.propertyOffset(for: callerCapability.name, enclosingType: enclosingType)! - - switch type { - case .fixedSizeArrayType(_, let size): - return (0.. String { + let checks = callerCapabilities.compactMap { callerCapability -> String? in + guard !callerCapability.isAny else { return nil } + + let type = environment.type(of: callerCapability.identifier.name, enclosingType: enclosingType) + let offset = environment.propertyOffset(for: callerCapability.name, enclosingType: enclosingType) + let functionContext = FunctionContext(environment: environment, scopeContext: ScopeContext(), enclosingTypeName: enclosingType, isInStructFunction: false) + + switch type { + case .functionType(parameters: [], result: .basicType(.address)): + var identifier = callerCapability.identifier + let name = Mangler.mangleFunctionName(identifier.name, parameterTypes: [], enclosingType: enclosingType) + identifier.identifierToken.kind = .identifier(name) + let functionCall = IRFunctionCall(functionCall: FunctionCall(identifier: identifier, arguments: [], closeBracketToken: .init(kind: .punctuation(.closeBracket), sourceLocation: .DUMMY), isAttempted: false)) + let check = "eq(caller(), \(functionCall.rendered(functionContext: functionContext)))" + return "\(variableName) := add(\(variableName), \(check))" + case .functionType(parameters: [.basicType(.address)], result: .basicType(.bool)): + var identifier = callerCapability.identifier + let name = Mangler.mangleFunctionName(identifier.name, parameterTypes: [.basicType(.address)], enclosingType: enclosingType) + identifier.identifierToken.kind = .identifier(name) + let functionCall = IRFunctionCall(functionCall: FunctionCall(identifier: identifier, arguments: [FunctionArgument(.rawAssembly("caller()", resultType: .basicType(.address)))], closeBracketToken: .init(kind: .punctuation(.closeBracket), sourceLocation: .DUMMY), isAttempted: false)) + let check = "\(functionCall.rendered(functionContext: functionContext))" + return "\(variableName) := add(\(variableName), \(check))" + case .fixedSizeArrayType(_, let size): + return (0..