Skip to content

ARCHIVE

Daniil Tiganov edited this page Aug 4, 2019 · 2 revisions

NOTE

SWAN started out as a UCOSP W2018 project, so this archive mostly consists of meeting notes, reports, etc. from that group.


Page: 2017.09.25

  • a walk through the WALA codebase
  • com.ibm.wala.cast.tree.CAstNode
  • mapping instructions in Swift IL (SIL) to different types of CAstNode
  • Control flow: wrap the target statement of a goto in a LABEL_STMT
  • Most of what we need is in the CAstWrapper.h. If not, we can add it and recompile to get the new libcast.so/dynlib
  • Next thing to do: take a couple of operations and translate the WALA CAst for.
  • Tricky examples: binary addition in Swift is a method call, but in WALA, it is an expression.

Page: 2017.10.03

  • Jeff will look into hooking our code into the compiler after the Guaranteed Optimization Passes and Diagnostic Passes and before the General SIL Optimization Passes.
  • This will hopefully simplify all these calls we see for simple expressions such as 3 + 7.
  • Lydia + Chen worked on string concatenation.

Page: 2017.10.10

  • Chen and Lydia: all operations on Strings are translated into function calls.
  • // : asking about built-in statements in WALA.
  • Julian: look into CAstOperator. You'll find things like union, concat.
  • Roony + Yaser: not enough time to put in the project this last week (which is fine btw :))
  • Yaser: is there an STL for Swift?
  • Julian: there is, but we'd like to represent simple things like integer + as simple expressions.

Page: Cadence Report Format

Cadence Report

Date:

Word Done:
  • What you did this past week
Difficulties:
  • What you were stuck on, struggled with, or have questions about
Learned:
  • What you learned
Next Week:
  • What you plan to do this upcoming week

Page: Chen

Email

We are currently working on translating the binary operators in Swift to their corresponding representations in WALA. Attached is the SIL output we obtained from compiling this Swift code:

var a = true && false

We understand that && and || are special binary operators, as they involve short-circuitings. However, the output is very confusing and beyond what we would expect for a simple implementation of the short-circuiting mechanism. Our current understanding is that:

  1. The TryApplyInst calls Swift.Bool.|| infix(). This function takes a boolean value as input. When the boolean is true, it does nothing. When the boolean is false, it throws an exception. Essentially, it "guesses" whether the input can be the result of ||.
  2. TryApplyInst jumps to different basic blocks depending on whether or not an exception is thrown.

We are not sure about:

  1. Why and how closures are involved
  2. What "@error Error" means
  3. Why and how ThinToThickFunctionInst is involved
  4. Why TryApplyInst jumps to UnreachableInst when an exception is thrown
  5. Why there are more than one SILFunctions involved

At your convenience, we think it will be most helpful if you can explain all the SIL instructions in the attached file line by line, in plain English.

Cadence Report Date: Oct 30, 2017

Past Week:
  • I worked on separating built-in unary/binary operators to regular functions.
Difficulties: - What you were stuck on, struggled with, or have questions about
  • In an ApplyInst instance, the "arguments" can sometimes be confusing. For example, in the following code:
var a = ~2

The unary operator ~ (sometimes? not always?) has three arguments: a GlobalAddrInst, an integer, and a metatype. I am not sure why GlobalAddrInst is passed to this function application.

Learned: - What you learned
  • I handled the difficulty discussed above by:
    • In an unary operation, only use the second last argument
    • In a binary operation, only use the second and third last argument
Next Week: - What you plan to do this upcoming week
  • I'm going to discuss this with Miss Wu.

Cadence Report Date: Oct 23, 2017

Past Week:
  • I basically finished half of the ApplyInst. A CAst can be built if there is a call to a "real" function, and all the argument CAst nodes have been created. However, if there is really a call to a built-in unary/binary operator, I cannot separate it from the regular function calls yet.
  • I took a quick look to (global) variable declaration & definition & usage.
  • I worked on if statements.
Difficulties: - What you were stuck on, struggled with, or have questions about
  • It is not easy to separate calls to built-in unary/binary operators to regular functions.
Learned: - What you learned
  • The swift ASTNode appears to have some information about whether the node is a built-in unary/binary operator (in class Decl). I probably have to somehow retrieve a Decl* from a SILFunction*. (I can do this now with Jeff's help)
  • Global variables are declared and definied using 3 instructions: AllocGlobalInst, GlobalAddrInst, StoreInst. They are used via a couple of "Access Instruction"s.
  • SILFunction is a chunk of SIL code that can be called. It is also a container of SILBasicBlocks. A SILBasicBlock is a container of SILInstructions.
Next Week: - What you plan to do this upcoming week
  • I'm going to continue working on separating built-in binary/unary operators with regular fuction calls
  • I may become less productive this upcoming week, as I have some course projects to do. I will see what else I can do after finishing my course projects.

Cadence Report Date: Oct 16, 2017

Past Week:
  • I separated the giant switch statement into a separated class: InstrKindInfoGetter. CMakeLists are updated to reflect this change.
  • I created a hash map to store the CAst nodes created in WALAWalker. The key is a pointer to a SILInstruction, and the value is a reference to a CAst node.
  • In ApplyInst, I figured out how to fetch the original SILInstruction for each argument. This allows me to lookup the hash map I created when I am building the apply function node.
Difficulties: - What you were stuck on, struggled with, or have questions about
  • It was the first time that I had modified a CMakeList file. When I first created a new class, I did not know I had to update the CMakeList file. Therefore, the compilation was not successful initially.
  • I spent most of the time deciding the type of the key in my hash map. The key must be accessible from a SILInstruction instance, which is a extremely complex class. I spent a lot of time figuring out what are the relationships among SILInstruction, SILValue, ValueBase, etc.
Learned: - What you learned
  • I understand now how to modify CMakeList when I want to create a new source file, or delete an existing one.
  • For an ApplyInst instance, I can obatin its arguments through: castInst->getArgument(i). The return value is of type SILValue. SILValue is a wrapper around a ValueBase pointer. I can get the underlying ValueBase pointer through: SILValue::getOpaqueValue(). The class SILInstruction is inherited from the calss ValueBase. It turns out that from castInst->getArgument(i)->getOpaqueValue(), I can obtain the original SILInstruction that creates this argument.
Next Week: - What you plan to do this upcoming week
  • I realized (actualy two weeks ago) that I was progressing very very slow in this project. This is partly because I always have a lot of other districtions: sometimes GRE, sometimes TOEFL, sometimes job interview, and sometimes assignments and exams. This is pretty bad. Lydia and I decided that we should set up some fixed time each week to work together: Tuesday after the meeting, and Saturday afternoon.
  • Next week I am going to finish the ApplyInst. Lydia and I are still waiting for the code for generating integer literal CAst nodes. They are required since most functions we encounter so far take integers as (part of) input.

Cadence Report Date: Oct 9, 2017

I don't want to lie here... I did not do anything related to our project in the past week.

Cadence Report Date: Oct 2, 2017

Past Week:

I apologize for my low productivity last week. I had a GRE test on Oct 1 (Sunday), so I spent most of my time preparing for this. Essentially, what I have done are:

  1. I wrote some new tests for the string literals. The results are good. The existing code passes these tests perfectly.
  2. I made some attempts in supporting string operations. When I compile the following swift code:
var str = "a" + "b"

three ApplyInst are generated. Two string constructors, and one "+" function. When I compile the following code:

func appendA(str : String) -> String {
	return str + "A"
}

var str = "a" + "b"
var appendedStr = appendA(str: str)

I get the additional ApplyInst generated for my user-defined function, which takes a string as input as well. I can trace the ApplyInst in "case ValueKind::ApplyInst" in the gaint switch statement. However, I have trouble obatining useful information from that instruction object. (Please see my second and thrid point in "Difficulities")

Difficulties: - What you were stuck on, struggled with, or have questions about
  1. In the swift compiler, a string literal can have encoding "UTF16". From my understanding, a plain text source file can have either UTF8 or UTF16 for its entire content. However, the swift compiler seems to have trouble with UTF16 encoded source files (even the released official version). Meanwhile, it treats East Asian characters in an UTF8 encoded file as UTF16 characters.
  2. In swift, all string operations are translated into function calls. However, in WALA, some of them are treated as built-in statements. Where can I find a list of all built-in statements in WALA?
  3. How can I know whether the callee is a built-in WALA statement from an ApplyInst object? An object for string concatination looks like this, where %10 and %16 are string constructors, and %0 and %1 are string objects:
<< ApplyInst >>
	[ARG] #0:   %11 = apply %10(%6, %7, %8, %9) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %18
	[ARG] #1:   %17 = apply %16(%12, %13, %14, %15) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %18
	[ARG] #2:   %5 = metatype $@thin String.Type                // user: %18
Learned: - What you learned
  1. In "case ValueKind::ApplyInst", I believe we only need to worry about built-in WALA statements now. Everything else should be translated into WALA as regular function calls. This can be done without understanding the types of the arguments, return value, and functionality.
Next Week: - What you plan to do this upcoming week
  1. I will try to look into WALA and find exactly what are the built-in statements.
  2. Once I find the list for the built-in statements, I will continue working on those related to strings.

Page: Classes and Methods of Interest

WALA Integration

WALAWalker

  • swift/include/swift/WALASupport/WALAWalker.h
    • declarations of utility methods for parsing and performing semantic analysis on modules
  • swift/lib/WALASupport/WalaWalker.cpp
    • WalaWalker implementation
    • WalaWalker::print_object(JNIEnv *java_env, jobject object)
    • WalaWalker::foo()
      • instances JNIEnv
      • calls print_object
    • WalaWalker::print(SILModule &SM)
      • exploratory test function for working with SILModule

FrontendTool

  • swift/include/swift/FrontendTool/FrontendTool.h
    • high-level API for interacting with basic frontend tool operation
  • swift/lib/FrontendTool/FrontendTool.cpp
    • entrypoint for swift -frontend functionality; core compiler functionality along with additional tools for demonstration and testing purposes
    • WalaWalker integration lines 705-709

SIL

performSilGeneration()

  • Called from FrontendTool.cpp to create SIL
  • Calls SILModule::constructSIL -> implementation in lib/SILGen/SILGen.cpp:1391

SILModule

  • FunctionListType = llvm::ilist<SILFunction>
  • method: getTypeLowering(SILType t) -> const Lowering::TypeLowering
    • look up the TypeLowering for a SILType
  • method: *getSwiftModule() -> ModuleDecl
  • method: &getASTContext() -> ASTContext
  • method: &getSourceManager() -> SourceManager
  • method: getAssociatedContext() -> DeclContext
    • gets Swift DeclContext associated with the SIL module
  • method: getFunctions() -> iterator_range<iterator>
    • returns {functions.begin(), functions.end()}
  • method: getFunctionList() -> FunctionListType
    • begin() gets functions.begin()
    • end() gets functions.end()
  • method: dump()
  • method: dump(const char *fileName, bool Verbose = false, bool PrintASTDecls = false)
  • method: print(raw_ostream &OS, bool Verbose = false, ModuleDecl *M = nullptr, bool ShouldSort = false, bool PrintASTDecls = true)

SILFunction

  • base class: llvm::ilist_node<SILFunction>, SILAllocated<SILFunction>
  • BlockListType = llvm::iplist<SILBasicBlock>
  • method: &getModule() -> SILModule
  • method: getLoweredType() -> SILType
  • method: getLoweredFunctionType() -> CanSILFunctionType
  • method: getConventions() -> SILFunctionConventions
  • method: isNoReturnFunction() -> bool
  • method: canBeDeleted() -> bool
  • method: getRefCount() -> unsigned
    • number of entities referring to this function other than the SILModule
  • method: isInlined() -> bool
  • method: isZombie() -> bool
  • method: getRepresentation() -> SILFunctionTypeRepresentation
    • calling convention used by this entry point
  • method: hasSelfParam() -> bool
  • method: getName() -> StringRef
    • gets mangled name
  • method: hasName(const char *Name) -> bool
    • getName() == Name
  • method: isExternalDeclaration() -> bool
  • method: isDefinition() -> bool
  • method: getLinkage() -> SILLinkage
  • method: isAvailableExternally() -> bool
  • method: isPossiblyUsedExternally() -> bool
  • method: isExternallyUsedSymbol() -> bool
  • method: *getDeclContext() -> DeclContext
  • method: getSemanticAttrs() -> ArrayRef<std::string>
  • method: getLocation() -> SILLocation
  • method: isBare() -> IsBare_t
    • enum: IsNotBare, IsBare
  • method: isTransparent() -> IsTransparent_t
    • enum: IsNotTransparent, IsTransparent
  • method: isSerialized() -> IsSerialized_t
  • method: isThunk() -> IsThunk_t
    • enum: IsNotThunk, IsThunk, IsReabstractedThunk
  • method: getSubclassScope() -> SubclassScope
  • method: getEffectsKind() -> EffectsKind
  • Block List Access:
    • method: &getBlocks() -> BlockListType
    • method: empty() -> bool
    • method: begin() -> iterator
    • method: end() -> iterator
    • method: size() -> unsigned
    • method: findReturnBB() -> iterator
      • find unique BB containing return if exists; else return end
    • method: findThrowBB() -> iterator
      • find unique BB containing throw if exists; else return end
  • Misc:
    • dump(), dump(bool Verbose)
    • print(raw_ostream &OS, bool Verbose = false)
    • printName(raw_ostream &OS)
      • pretty-print SILFunction's name with SIL syntax, '@function_mangled_name'

SILBasicBlock

  • using InstListType = llvm::iplist<SILInstruction>
  • method: *getParent() -> SILFunction
  • method: `&getModule() -> SILModule
  • using iterator = InstListType::iterator (const, reverse, const_reverse)
    • begin() -> iterator
    • end() -> iterator
    • rbegin() -> reverse_iterator
    • rend() -> reverse_iterator
    • empty() -> bool
  • using arg_iterator = std::vector<SILArgument *>::iterator
    • args_begin() -> arg_iterator
    • args_end() -> arg_iterator
    • getArguments() -> ArrayRef<SILArgument *>
    • getFunctionArguments() -> TransformArrayRef<std::function<SILFunctionArgument *(SILArgument *)>>
    • getNumArguments() -> unsigned
    • getArgument(unsigned i) -> SILArgument
  • method: isEntry() -> bool
    • if BB is entry BB of its parent
  • method: isNoReturn() -> bool
    • if BB ends in an unreachable or an apply of a no-return apply or builtin
  • method: isTrampoline() -> bool
    • if instruction only contains a branch
  • method: dump()
    • pretty-print the SILBasicBlock
  • method: print(llvm::raw_ostream &OS)
    • pretty-print to designated stream
  • method: printAsOperand(raw_ostream &OS, bool PrintType = true)

SILInstruction

  • method: *getParent() -> SILBasicBlock
  • method: *getFunction() -> SILFunction
  • method: &getModule() -> SILModule
  • method: getLoc() -> SILLocation
    • instruction's source location (ASTNode)
  • method: getAllOperands() -> MutableArrayRef<Operand>
  • method: getTypeDependentOperands() -> MutableArrayRef<Operand>
  • method: getNumOperands() -> unsigned
  • method: getNumTypeDependentOperands() -> unsigned
  • method: getOperand(unsigned Num) -> SILValue
  • method: getMemoryBehavior() -> MemoryBehavior
    • enum: None, MayRead, MayWrite, MayReadWrite, MayHaveSideEffects
  • method: getReleasingBehavior() -> ReleasingBehavior
    • enum: DoesNotRelease, MayRelease
  • method: mayRelease() -> bool
  • method: mayReleaseOrReadRefCount() -> bool
  • method: mayTrap() -> bool
    • if instruction can abort program in some manner
  • method: isIdenticalTo(const SILInstruction *RHS) -> bool
  • method: isIdenticalTo(const SILInstruction *RHS, OpCmp opEqual) -> bool
  • method: mayHaveSideEffects() -> bool
  • method: mayWriteToMemory() -> bool
  • method: mayReadFromMemory() -> bool
  • method: mayReadOrWriteMemory() -> bool
  • method: *clone(SILInstruction *InsertPt = nullptr)
    • create copy which retains all operands and other info. If insertion point specified, inserted before; otherwise returned with no parent
  • method: destroy(SILInstruction *I)
    • calls destructor, does not deallocate
  • method: combineMemoryBehavior(SILInstruction::MemoryBehavior B1, SILInstruction::MemoryBehavior B2) -> MemoryBehavior
  • swift/include/swift/SIL/SILInstruction.h defines many many more classes derived from SILInstruction

SILLocation

  • struct DebugLoc: unsigned Line, unsigned Column, StringRef Filename
  • method: isNull() -> bool
  • method: isASTNode() -> bool
  • method: isSILFile() -> bool
  • method: isDebugInfoLoc() -> bool
  • method: isInTopLevel() -> bool
  • method: hasDebugLoc() -> bool
  • method: getKind() -> LocationKind
    • enum: NoneKind, RegularKind, ReturnKind, ImplicitReturnKind, InlinedKind, MandatoryInlinedKind, CleanupKind, ArtificialUnreachableKind
  • method: getStorageKind() -> StorageKind
    • enum: UnknownKind, ASTNodeKind, SILFileKind, DebugInfoKind
  • method: getDebugSourceLoc() -> SourceLoc
  • method: getSourceLoc() -> SourceLoc
  • method: getStartSourceLoc() -> SourceLoc
  • method: getEndSourceLoc() -> SourceLoc
  • method: getSourceRange() -> SourceRange
  • method: decode(SourceLoc loc, const SourceManager &SM) -> DebugLoc
    • extract the line, col, and filename
  • method: decodeDebugLoc(const SourceManager &SM) -> DebugLoc
    • return the decoded debug location
  • method: dump(const SourceManager &SM)
  • method: print(raw_ostream &OS, const SourceManager &SM)
  • Also defines RegularLocation, ReturnLocation, ImplicitReturnLocation, InlinedLocation, MandatoryInlinedLocation, CleanupLocation, ArtificialUnreachableLocation, SILDebugScope

Other

SourceManager

  • Manages and owns source buffers
  • method: &getLLVMSourceMgr() -> llvm::SourceMgr
  • method: findBufferContaining(SourceLoc loc) -> unsigned (buffer ID)
  • method: getIdentifierForBuffer(unsigned BufferID) -> StringRef
  • method: getRangeForBuffer(unsigned BufferID) -> CharSourceRange
  • method: getLineAndColumn(SourceLoc loc, unsigned BufferID = 0) -> std::pair<unsigned, unsigned>
  • method: getLineNumber(SourceLoc loc, unsigned BufferID = 0) -> unsigned
  • method: getEntireTextForBuffer(unsigned BufferID) -> StringRef

DeclContext

  • semantic construct that a declaration belongs to, such as the enclosing AbstractClosureExpr or declaration
  • method: getParentModule() -> ModuleDecl
    • returns the parent context that contains this context
  • method: getASTContext() -> ASTContext
    • gets ASTContext by walking up to the enclosing module and returning its ASTContext
  • method: walkContext(ASTWalker &walker) -> bool
  • method: dumpContext()

ASTNode

  • method: getKind() -> ASTNodeKind
  • method: getChildren() -> ArrayRef<MarkupASTNode *>
  • method: classOf(const MarkupASTNode *N) -> bool

Page: Lydia

Cadence Report Date: 2017.12.05

Past Week:

  1. I finished the translation of logic AND and logic OR.
  2. I went through the implementation ForIn Loop in swift and tried to translate reading and writing of array.

Difficulties:

  1. I don’t know what the right CAST should be, especially the construction of array.
  2. There are 4 different types of CAstNode ARRAY_LITERAL ARRAY_REF OBJECT_LITERAL OBJECT_REF I don’t know which one should I use.

Learned:

  1. I understand the distinction between "let" and "var". Using "let" means the declared object is a constant so it can not be modified afterwords.
var names = [“Anna”, “Alex”, “Brian”, “Jack”]
for name in names {
    // We can't change the value of name!
    print(name)
}

However, if we declare the iterator in ForIn Loop as a variable, we are able to modify it in the loop.

var names = ["Anna", "Alex", "Brian", "Jack"]
for var name in names {
         name = "a "+name
}
  1. I find that for the code:
 var names = [“Anna”, “Alex”, “Brian”, “Jack”]

swift firstly allocate uninitialized array and assign string to corresponding address, the it initialized this array and assign this array to variable “names”.

Cadence Report Date: 2017.11.23

Past Week:

  1. I tried to implement translation of logic AND and logic OR.

Difficulties:

  1. In my opinion, "TryApplyInst" corresponds to "try" and "catch" structure in c language. However, in this case, there is no "catchInst" but only ""TryApplyInst", so I have no idea about how to translate this instruction into two part.
  2. TryApplyInst calls Swift.Bool.&& infix() in this case, and its arguments are the first bool literal and a function reference which creates the second bool. This function is created while compiling swift code, so I am not very clear what the final CAST should be look like.

Learned:

  • For those functions created during compilation, we can find their definition code through the address of SILFunction.
  • TryApplyInst will has two destination Basic Block. When the funciton returns, control resumes in either the normal destination (if it returns with "return") or the error destination (if it returns with "throw").

Next Week:

  • I will finish the translation of logic AND and logic OR.

Cadence Report Date: 2017.11.15

Past Week:

  1. I supplemented some functions for the handler of "BranchInst" so that it will create an ASSIGN node while binding given values to arguments for destination basic block.
  2. I implemented the expression of "ReturnInst" in CAST.

Difficulties:

  • The difficulty I met this week has been resolved with the help of Julian and Chen.

Learned:

  • I test a special case in which return instructions are in if-else statements. By carefully reading the SIL file generated by it, I found that "branchInst" will bind given values to arguments of destination basic block and the return instruction in destination block will regard its argument as return value.
func use_ints(num1: Int, num2: Int, num3: Int) -> Int{
    var num4 = num1 + num2
    if (num1 < 5 ) {
        return (num4 - num3)
    } else {
        return (num4 * num3)
    }
}

var t = use_ints(num1: 1, num2: 2, num3: 3);

The CAST is like below:

FOO: 1836019240:BLOCK
  LABEL_STMT
    "BLOCK #0"
    ASSIGN
      VAR
        "num4"
      BINARY_EXPR
        "+"
        VAR
          "num1"
        VAR
          "num2"
  IF_STMT
    CALL
      FUNCTION_EXPR
        "Swift.Bool._getBuiltinLogicValue() -> Builtin.Int1"
      BINARY_EXPR
        "<"
        VAR
          "num1"
        CALL
          FUNCTION_EXPR
            "Swift.Int.init(_builtinIntegerLiteral: Builtin.Int2048) -> Swift.Int"
          "5"
    GOTO
      "BLOCK #1"
    GOTO
      "BLOCK #2"

FOO: 325040804:BLOCK
  LABEL_STMT
    "BLOCK #1"
    ASSIGN
      VAR
        "argument0"
      BINARY_EXPR
        "-"
        VAR
          "num4"
        VAR
          "num3"
  GOTO
    "BLOCK #3"

FOO: 1173230247:BLOCK
  LABEL_STMT
    "BLOCK #2"
    ASSIGN
      VAR
        "argument0"
      BINARY_EXPR
        "*"
        VAR
          "num4"
        VAR
          "num3"
  GOTO
    "BLOCK #3"

FOO: 856419764:BLOCK
  LABEL_STMT
    "BLOCK #3"
    RETURN
      VAR
        "argument0"

Next Week:

  • I plan to help Chen to deal with the implicit closure.

Cadence Report Date: 2017.11.08

Past Week:

  1. I finished the work of expressing arguments normally in user-defined functions.
  2. I implemented the expression of local variables in user-defined functions.

Difficulties:

  • When I declare a local variable in the function with a value assigned to it, I found that there is no SILInstrunction "ASSIGN", but "StoreInst" instead. However, this instruction can be used as many situations such as storing stack pointer while allocating new space. I modify the handler of "StoreInst" so that it will create a "ASSIGN" node if the destination is variable. Till now, all test cases can work well but I ma not sure whether this measure is appropriate enough.

Learned:

  • I learned how the swift compiler works to deal with the passing of parameters and allocating for local variables.

Next Week:

  1. I will implement the return instruction in CAST.
  2. I plan to go through expression of enumeration and loop of swift in CAST.

Cadence Report Date: 2017.10.30

Past Week:

  1. I modified the switch statement in WALAWalker so that some previously unhandled cases are now being processed. (CopyValueInst, DestroyValueInst, BeginBorrowInst, DebugValueInst)
  2. I tried to resolve the problem that expression of function's arguments in CAST but I have not finished yet.

Difficulties:

When an used-defined function is called, its arguments can't be presented well as below:

func add_str(op1:String,op2:String) -> String{
    return (op1+op2)
}

its CAST tree is like this:

  LABEL_STMT
    "BLOCK #0"
    BINARY_EXPR
      "+"
      (null)
      (null)

When I checked its arguments' address in <> and I found that there is no instructions to create CAST nodes for them. So I wonder how to express arguments of a function no matter whether it is called.

Learned:

  • I learned that debug_value in SIL is to indicates that the value of a declaration with loadable type has changed value to the specified operand. *I learned that load_borrow instruction in SIL creates a borrowed scope in which a read-only borrow value %1 can be used to read the value stored in %0.

Next Week:

  • I will continue working on expressing arguments of user-defined functions in CAST.

Cadence Report Date: 2017.10.23

Past Week:

  1. I worked on a part of if statement.
  2. I finished the implementation of reading and writing variables.
  3. I tested some cases and found that I might mix up the difference between expression and statement. In somehow the tree-like output looks very strange and I tried to figure out the problem.

Difficulties:

The problem is that if I set FUNCTION_EXPR as a child of block statement, when I test the below code:

var a = ""
if (true) {
        a = a + "x"
} else {
        a = a + "y"
}
a = a + "z"

The tree structure returned will present FUNCTION_EXPR twice, such as below:

FOO: 1836019240:BLOCK
  LABEL_STMT
    "BLOCK #1"
    FUNCTION_EXPR
      "static Swift.String.+ infix(Swift.String, Swift.String) -> Swift.String"
  FUNCTION_EXPR
    "Swift.String.init(_builtinStringLiteral: Builtin.RawPointer, utf8CodeUnitCount: Builtin.Word, isASCII: Builtin.Int1) -> Swift.String"
  BINARY_EXPR
    "+"
    VAR
      "_T08nodetest1aSSvp"
    CALL
      FUNCTION_EXPR
        "Swift.String.init(_builtinStringLiteral: Builtin.RawPointer, utf8CodeUnitCount: Builtin.Word, isASCII: Builtin.Int1) -> Swift.String"
      "x"
      "1"
      "-1"
  ASSIGN
    VAR
      "_T08nodetest1aSSvp"
    BINARY_EXPR
      "+"
      VAR
        "_T08nodetest1aSSvp"
      CALL
        FUNCTION_EXPR
          "Swift.String.init(_builtinStringLiteral: Builtin.RawPointer, utf8CodeUnitCount: Builtin.Word, isASCII: Builtin.Int1) -> Swift.String"
        "x"
        "1"
        "-1"
  GOTO
    "BLOCK #3"

But if I remove FUNCTION_EXPR from block statement's children, when I test the below code:

func add_str(op1:String,op2:String) -> String{
        return (op1+op2)
}

var c = add_str(op1:"qwe",op2:"weq")

it only returns

FOO: 2133927002:BLOCK
  LABEL_STMT
    "BLOCK #0"
    "0"

That's what I am confused about.

Learned:

  1. Global variables are declared and definied using 3 instructions: AllocGlobalInst, GlobalAddrInst, StoreInst. They are read through instructions "Begin Access" "Load Inst" and "End Access", they are written through "Begin Access", "Assign Inst' and "End Access".
  2. The AST structure of reading variables is Node(var) with variable's name as child node, and the ASTs structure of writing values into variables is Node(Assign) with Node(Var)and Node(expression) as children.
  3. I found that a SILBasicBlock is a container of SILInstructions because I'm able to retrieve all instructions in a block from a SILBasicBlock.

Next Week:

  • I'm going to finish work on variables and distinct clear between expression and statement.
  • I'm going to help Chen's work on separating built-in binary/unary operators with regular function calls.

Cadence Report Date: 2017.10.17

Past Week:

  1. I made some tests on makeNode() functions and found the relationship between constant numbers such as "1" and their AST means. For example, if I want to create an CAST node whose syntax is "LOOP", I can call makeNode(3). But obviously speaking, it is not practical to use simple constants because there are too many operators and node types.
  2. At the beginning, I insisted that using SILValue as the key for hash map which stores CAST nodes. So I spent a lot of time detecting the relationship between SILInstruction, SILValue and Valuebase and trying to find out a method which can fetch SILValue from SILInstruction. What made me raise the idea that we can use SILValue as the key is that: firstly, through getArgument() I can get SILValue of all arguments of a function call; secondly, for each CAST node created, there must be an SILInstruction corresponding to it. However, after exploring and analyzing, I found using SILValue may not be a good idea. Thanks to the help of Jeff, I found that the address of SILInstruction is as same as that of ValueBase stored in SILValue. Consequently, a hash map using the address of SILInstruction is much more practical.
  3. Based on what I have done above, I implemented a simple CAST tree with "FUNC_STMT" as root node and its arguments as children. What's more, there are many different makeNode() functions which connect different number of children to their parent node. Therefore, I store fetched argument node in a vector so for a specific number of arguments, I can call the corresponding function.
  4. In order to build simple CAST tree, I need integer node as child node. Since the other group has not been done on their work, I just write a little code on integer literal so that I can continue my test.

Difficulties:

  1. It is impractical to use constants as the parameters for makeNode() function, but I can't find a valid way to use macro instead. It seems that macros of all operators and node types have been written well but when the program is ran, it returns "unknown" instead of right type of the node.
  2. By printing all arguments of a function call, I found there are more arguments than what I imagine before, such as metatype argument which is the last argument for all function calls. Therefore, I am not sure which and what arguments should be connected to the function node.
  3. Based on the output, I found that the function name is pretty long. Since I need to create different function nodes according to the type of function, it will be a matter to extract useful function name from those long strings.

Learned:

  1. It is very important to select an appropriate key for hash map, so I think the huge time Chen and I spent on discussing and testing different key candidates is worthy. Moreover, during exploring this great amount of code, I know much better about the relation between SILInstruction, SILValue, SILType and Valuebase. SILValue is a wrapper around a ValueBase pointer. The underlying ValueBase pointer can be gotten through: SILValue::getOpaqueValue(). The class SILInstruction is inherited from the calss ValueBase. Beacuse of that, getting value of SILInstruction is practical.

Next Week:

  1. Chen and I have decided to set Tuesday afternoon and Saturday afternoon as our regular programming day. So I maintain that our efficiency will be boost up.
  2. I will solve the problem of nonavailability in macro use for function makeNode().
  3. I will start on distinguishing different function call based on their names.

Cadence Report Date: 2017.10.09

####Past week: Since I got a Mac, I tried to install swift and WALA on my own machine. Although there were several difficulties, fortunately I built them successfully with the help of Julian and Jeff. According to my well configured environment, it is much easier for me to modify code and run test. Based on what I have done last week, I tried more tests on operations of string such as string equality and self-defined string concatenation. These tests told me that operations of string in swift are all function calls and they have quite complex structure, so it might not be very east to translate string operation in swift into expression node in WALA AST. As I have known from our meetings, I was aware that, for example, we should create an OP_ADD node and two constant nodes for string concatenation for WALA. Consequently, I attempted to detect the add operation in swift text and call makeNode function based on that. But it doesn't success until now.

Difficulties:

The problem is that I can't find a method to detect there is a string operation in swift code. In the file WALAWalker, we have a switch branch whose name is "ApplyInst", all expressions and function calls are dealt with this branch, so a effective way to distinct string operation from other instructions is needed in translating them into WALA node. However, there is no direct way to print out the name of the callee or what the function does. Too many wraps are there that I have no idea about what some data structures, such as SILValue, SILFunction and SILType really are. so it is difficult to confirm whether this instruction is string operation or not.

Learned:

when I ran test on string equality, I found that we can see some interesting results. What I run is the following code:

let spain = "España"
let tilde = "\u{303}"
let country = "Espan" + "\(tilde)" + "a"
if country == spain {
  print("Matched!")       // "Matched!\n"
}

Since I print all standard output I can get, I found that the name of function can be printed out, some function names are listed as following:

[OPER]:   // function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
  %30 = function_ref @_T0S2SBp21_builtinStringLiteral_Bw17utf8CodeUnitCountBi1_7isASCIItcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %31
[OPER]:   // function_ref _allocateUninitializedArray<A>(_:)
  %35 = function_ref @_T0s27_allocateUninitializedArraySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %36
[OPER]:   // function_ref static String.+ infix(_:_:)
  %24 = function_ref @_T0SS1poiS2S_SStFZ : $@convention(method) (@owned String, @owned String, @thin String.Type) -> @owned String // user: %83
 [OPER]:   // function_ref static String.== infix(_:_:)
  %93 = function_ref @_T0SS2eeoiSbSS_SStFZ : $@convention(method) (@owned String, @owned String, @thin String.Type) -> Bool // user: %97

As we can see from the function reference, String.init is the function used to assign value to a string variable, String.+ represents string concatenation, and String.== represents string comparison. Consequently, what I need to do is find the member function which can give me the reference name of function. With those names, I can deal with different string operations.

Next week:

I will continue my work on translating function call in swift to expression node in WALA and find an effective way to detect the details of instruction.

Cadence Report Date: 2017.10.02

Past Week:

Firstly, since I can't build swift and WALA on my own machine and there is some problems with my private key for server, testing my code is impossible for me. Based on this situation, I didn't do much coding in the past week. Instead, I watched some videos about SIL and WALA offered in the reference link. Secondly, Chen and I spent a lot of time on transforming binary addition of swift from method call into expression in WALA, but we didn't make a big progress on it. Currently, we only get aware of the sequence of method calls when we use binary addition in swift and the difference between calling a self-defined function and calling binary addition directly.

Difficulties:

In the beginning, I have a misunderstanding about the requirement of the transformation on binary addition. It cost me some time on detecting the structure of "SILFunction" and the definition of "ValueType". I made some attempts on printing the type of arguments but I failed. After discussion with Chen, we found the critical problem is to understand the expression structure of WALA and to transform method call in swift to expression in WALA. Consequently, I think what I need to do next week is understanding the expression in WALA and implementing the transformation.

Learned:

During the test, I found that three functions will be called while calling binary addition of two strings. For example "a"+"b": [1] Assign "a" to a temporary variable; [2] Assign "b" to a temporary variable; [3] Concatenate "a" and "b", and assign the value to a variable; I have learned a compiler course in school but this process is different from what I learned in the class. In my opinion, the third step is to store concatenating result into a temporary variable and there should be the forth step assigning the value of temporary variable to the variable we declared. However, the program only prints the above three steps and this makes me very curious.

Next Week:

As I have mentioned above, I can't do any attempts on my own because I can't get access to the server. I believe it will be more convenient after the problem with the public key of server is fixed. Therefore, I plan to learn expression in WALA and implement the transformation between swift's method call and WALA's expression.


Page: Meeting 2017 07 31

Via Skype, 2017-07-31 1400T

On the Call:

  • Karim Ali (UAlberta)
  • Jeff Cho (UAlberta)
  • Devin Coughlin (Apple)
  • Julian Dolby (IBM)

Notes:

Using some combination of AST and SIL

  • Where is a good place to look?
  • FrontendTool - do we want WALA to be a frontend observer?

The hook is currently at performSema() in performCompile() [the function that does everything]

  • Devin: We can just move it, shouldn't be an issue
  • Julian: If we move it too far, we might need to change the linking stuff?
  • performedSILGeneration() - reasonable place to hook into [~line 709]

Should we hook in at SILGen or canonical SIL?

  • Devin: It does make a difference

  • SILGen gets you the generated SIL, but before any of the SIL diagnostics have run

  • Also gets it before some optimizations have been done - guaranteed inlining, for example is the important one

  • If no interprocedural analysis, some benefit to doing it after guaranteed inlining

  • Julian: for WALA to be useful, focus will be on analyses that are interprocedural. Devin agrees.

  • User-facing diagnostics: the earlier they are in the pipeline, the easier they are to understand, the less likely they are to be confusing when e.g. dead code elimination removes something

  • Less predictable diagnostics, less predictable analysis

  • Julian: probably cleaner to think about that being done under WALA's control - dead code elimination, constant folding, etc.

  • Julian: around observer->perform SIL generation? Seems like a good place to put it

Take a look at: swift/lib/SILOptimizer/PassManager/PassPipeline.cpp

  • Devin: mandatory pipeline, all the stuff that happens as part of converting raw SIL to canonical SIL -> place to look at to see what we're missing if we're working over raw SIL (how they're different)

  • We do track where something was inlined from, but not edges (source location: where it came from, but not the steps by which it came to be)

  • Julian: we should probably look at raw SIL then (around FrontendTool:709 as prev. indicated)

  • Devin: initialization vs. declaration are different in the language, e.g. important for destructors/allocation

  • Devin: this early in the pipeline, there will be some invalid programs that won't have been rejected yet

  • Julian: That's fine, that's not WALA's business

  • Julian: we have this SM object - (Devin: SILModule?) - do we need...

  • Devin: this SM is a collection of functions, each instruction should have a SIL location and those instructions should then have links back to the AST, an expression or statement or declaration

  • Julian: use the AST to understand (...) but when it comes to the actual stuff the code is doing, rely on SIL because a lot of the work is already done for us

  • Devin: you're going to have to deal with two levels of types, SIL (lowered) and AST notion of types

  • Julian: should we consider working with the lowered types?

  • Devin: that's likely to cause you pain, but might not get consistent results out if you're always going up to the AST level. Where this matters a lot -> things like tuples. Could try AST until it breaks, then go down to SIL level.

  • Julian: AST, we'd see it as a tuple, at SIL we'd see it more representation oriented. So it'd be nice to avoid thinking about representation if we can.

  • Closure conversion - use SIL?

  • Use AST until it fails, then look at SIL

Example of finding non-localized strings

  • Devin: Write a super-simple interprocedural example of how you can get this wrong
  • Then something that shows how to do it correctly, then remove one of the correct examples - then can we find it would be the test

AST: not a lot of documentation; read all the headers, -dumpAST flag to dump what Swift thinks the AST is for a particular code

TO DO:

  • Move the hook
  • Pass the SM object into it
  • Start looking around
  • Maybe for us to poke around and see what we can do and schedule another call
  • Email is probably the best (for asking questions etc to Devin)
  • Figure out the poking-around stuff, ask Julian when it comes to how to make it talk nice with WALA

Page: Meeting 2017 08 09

Via Skype, 2017-08-09 1030T

On the call:

  • Karim Ali (UAlberta)
  • Jeff Cho (UAlberta)
  • Julian Dolby (IBM)

Notes:

Why go SIL -> WALACAst instead of from the AST?

  • Bytecode in SIL, Apple has done a bunch of lowering, e.g. closures, lexical scoping - we can either hack into the WALA support for that or with SIL they have compiled a bunch of stuff away
  • This would simplify the process of getting this to work; so it's going to be a very flat AST working with SIL
  • What we want to work on is translating SIL to WALACAst
  • One thing to keep in mind: the SIL IR is somewhat analogous to bytecode, somewhat bytecode-ish, somewhat IR-ish; in that sense, it fits somewhat with WALA's Java bytecode heritage

Why hook directly into Swift Compiler instead of working from a SIL dump?

  • Swift SIL dumps are not designed to be machine-read; not reliable
  • Can't read it back in, Noah tried and it wasn't consumed
  • Noah tried to create some grammar on the WALA side but couldn't get it working, not well defined and keeps changing quite a bit

Examples of what we want to be able to pull out from a basic output from a simple program:

  • Types
  • List of functions
  • Name/label
  • SIL

Look at SIL dump, figure out what things are "reverse-engineer", add support for it as a testcase into WALA, and keep adding more and more functionality

  • GOTOs and labels
  • SIL dump won't be SSA but not a big deal - will turn into SSA during CAst
  • Simple translation of low level operations is all we need
  • Find however they represent source locations and dump those out too
  • **Source location: line number, beginning ending, line numbers, column numbers, character offsets, local variables
  • We can annotate the WALACAst with this information

TODO:

  • Break down the SILModule into more atomic pieces (SILBasicBlock, individual operations)
  • Find source location information for these pieces and find ways to pass it to WALACAst
  • Don't worry for now about going back up to AST from SILModule - we will worry about this when typing fails
  • For next week, hope to have the ability to print out more granular pieces and source location tagging

Page: Meeting 2017 08 30

Via Skype, 2017-08-30 1030T

On the Call:

  • Karim Ali (UAlberta)
  • Jeff Cho (UAlberta)
  • Julian Dolby (IBM)

Notes:

Jeff: compiling -x for Xcodeproject doesn't work - fails out on Java something

  • test suite fails with a massive amount of errors, probably something Java related as well

Find the end of the range (Source location information)

  • Highlight a called region, for example
  • A position in WALA is a range

Julian: preference is to keep as much of the logic as possible in Java

  • Have the C++ code essentially hand information in to create objects
  • Use the C++ code to create CAst trees that could be handed in to Java rather than trying to call back and forth
  • Lowest level information that's workable, pass into Java
  • Create JVM, load WALA into the JVM, create the data structures that WALA needs, hand those to WALA, then we won't need C++ past that point
  • Once the data structures are created, call analysis in WALA or something

Julian: Try to merge everything from the WALA branch and make sure we can do everything to merge Java

Try creating a few CAstnodes with some of these things as constants

  • Or: if I can figure out how to get the range thing, Julian will turn them into CAst positions

For each instruction, we need to understand what it's doing, what its operands are, and what its result is

  • SIL uses some notion of local registers?
  • Its operands as register numbers
  • What it's doing: like what the function is? Assigning, reading a local variable, object field reference, invoke, object creation, etc.
  • Look at: interface CAst node, has a bunch of static variables, the name of which is describing what it does - IF, object Ref, block, scope, If Expression, etc.

Don't worry about building Basic Blocks - we can just build sequences of instructions and put in GOTOs where we need them, and WALA should take care of building CFGs for us

For WALA, a basic block is a basic block - any time there's an exception, WALA breaks it down, whereas for a compiler, there might be "side exits"

For conditionals, let's see if we can get the BasicBlock's first instruction if we can - where does control flow go is what we want to know


Page: Meeting 2017 09 24

Via Skype, 2017-08-30 1030R

On the Call:

  • Karim Ali (UAlberta)
  • Yaser Alkayale (UCOSP - Dalhousie)
  • Jeff Cho (UAlberta)
  • Julian Dolby (IBM)
  • Ronny Mondal (UCOSP - Brock)
  • Chen Song (UCOSP - SFU)
  • Lydia Wu (UCOSP - SFU)

Work Log

  • Karim will set up Wiki workspaces for everyone to continually update their progress and project work for the weekly meetings
  • Yaser proposes a format for tracking which he will send out over the Slack

Project Assignments

  • Karim and Jeff will go over the ValueKinds that require support and add them as Issues in swift-wala. Everyone can pick a task, assign it to themselves, work on it, and keep notes
  • Very large instruction set for Swift - 170ish, but it is still fewer than Java bytecode - various different types for Java, eg half a dozen load instructions
  • Maybe working on tasks in groups of two? Could be difficult for coordination. Perhaps a solution is working on similar types of instructions so they can still bounce ideas off each other but don't need to work in parallel
  • Whomever is adding support for whichever instruction type, also writes the unit tests for them
  • WALA Casts have particular ways of handling control flow - Julian should walk people through existing ways that the frontend currently handles that. A Doodle will go out for scheduling this info session
  • Function calls will also be more involved in terms of sending to WALA - representing the function references, figure out what makes the most sense
  • Branching instructions - on WALA, labeled instructions set as jump targets, for example. Hopefully can still keep it as a one way flow of information from compiler to WALA instead of passing back info about what nodes correspond to what SIL Basic Block
  • Send Slack invites for wala-swift (done)
  • Swift type system, class hierarchy, etc - look at Java frontend as an example; this requires a different node structure, CastType (next week info session with Julian)
  • Start with simple type support for the time being, learn WALA concepts as we go, then add support for more complex stuff like load and store and branch

Weekly Meetings

  • Karim will send out a Doodle for scheduling weekly meetings and we'll pick something that works for the most people
  • We could possibly split meetings (Julian meets with east, Karim/Jeff meet with west) but this is not preferable

Page: Suggestions

Hi Karim, Chen’s suggestions were:

  • image for distributing Swift-WALA build
  • emphasize C++ knowledge and experience
  • emphasize compiler theory
  • emphasize program analysis knowledge and experience
  • de-emphasize Swift knowledge
  • de-emphasize LLVM knowledge
  • de-emphasize Java knowledge and experience
  • biweekly plans for students

My augments to these suggestions:

  • An image is tricky - too much virtualization overhead, streaming in codebase updates, etc. Having the build instructions and a set-up server instance is my suggestion as discussed
  • Definitely emphasizing C++ knowledge/experience is a massive component, unless we’re looking for both people who can work at the compiler level and at the Swift level (e.g. different teams like we have now). I would suggest in terms of C++ having a piece of code or a few examples of complex code as baseline examples for things students should be able to explain in detail what it’s doing and why to consider themselves proficient
  • Maybe instead of Java knowledge, we should put in a note about JNI, since that will be more useful than direct Java knowledge. Students probably don’t need to have experience using JNI but should familiarize themselves with it.
  • Biweekly plans are also difficult because students will be at different levels/working on different things, I think. What could be good, though, is using the Github project board for progress tracking and task allocation.

Page: UCOSP W2018 Starting Email

Hey everyone!

Welcome to Winter semester! We’ve got some stuff for you to work on, tinker with, and research from now until the Code Sprint so that we all have a common base from which to start.

So as you know, the project entails working with the Swift compiler (C++) and enabling static analysis by instantiating a JVM (through JNI) and passing calls to WALA (Java) where we build our WALA CAst (WALA Common Abstract Syntax Tree). This requires some knowledge of how the Swift compiler works, how Swift’s internal representation works (Swift Intermediate Language - SIL), Swift types and features, and WALA usage. To this end, I’ve gathered some references and resources for you to familiarize yourself with in order to get an idea of the Swift and LLVM side of the house (read the whole email through before you start diving into these!):

Please be aware that while these videos and posts will give you a good idea of the underlying systems powering Swift, SIL, and LLVM, some of the specific information is now deprecated as Swift language and compiler are under continuous development. You can see Apple’s SIL documentation at https://github.com/apple/swift/blob/master/docs/SIL.rst - a page that’s handy to have bookmarked.

You should all now be added to themaplelab on Github, and you should have access to our swift repo as well as our swift-wala repo (ignore wala-swift for now; it’s older stuff that isn’t currently relevant). The Wiki that we’re using for project tracking and information is on swift-wala, and we’ll be setting up a Project board there for tasks and tracking as well. What we want to get you guys started doing before Code Sprint is building WALA, Swift, and Swift-WALA. It sounds trivial, but it can take a while, and you can end up with some frustrating errors in the process! I recommend working on getting set up with WALA and Swift (in that order), checking out some of those links above while downloading and compiling, and jumping on the Slack to ask any questions if you run into issues.

The WALA and Swift-WALA build help are at: https://github.com/themaplelab/swift-wala/wiki/Getting-Started

Once that’s complete, the Swift Compiler for WALA Integration build help is at: https://github.com/themaplelab/swift-wala/wiki/Install-Notes (our current branch of swift is wala-merge, not wala or wala-next; this will be merged back to wala once validation is complete, we’re still in-progress for getting up to date with Apple’s latest changes since the last UCOSP semester). Please note after you pull the wala-merge branch that if you are building on macOS, you may need to comment out InstrKindInfoGetter::get() in order for it to compile successfully. We’re working on that at the moment, as you may have seen from the chatter on #general.

Once you’re built, or as you build, depending on how long the process takes you, you may want to look at some files of interest to get some bearings on the project thus far. In particular:

- swift/lib/WALASupport/
  * WALAWalker.cpp: the overarching structure that links in to the Swift compiler
  * InstrKindInfoGetter.cpp: where we’re doing the bulk of handling of SILInstructions to CAst
  * BasicBlockLabeller and SymbolTable are helpers for WALAWalker/InstrKindInfoGetter

- swift/include/swift/
  * SIL/SILBasicBlock.h
  * SIL/SILFunction.h
  * SIL/SILInstruction.h
  * SIL/SILValue.h
  * SIL/SILLocation.h

Please let us know as you run into issues or have questions so we can help you out right away! While it’s valuable to problem-solve things and figure out how all the pieces come together, I think it’s more important to get to the start state of having everything built so that you can problem-solve what’s really important for this semester, the continuation of the project and adding support for more types and analyses, so we don’t want you to get stuck on the build process.

I think that’s more than enough to get you started for now - please keep in touch over Slack (or email as needed) and keep us up to date on your progress! I know I’ve front-loaded you with a firehose of stuff, so just take it one step at a time and you shouldn’t have any issues getting built and tested. Good luck, and again don’t hesitate to say something on Slack if you run into any issues! I’ll be following up in a little bit once your workspaces are set up on our server to get you access and send instructions on how to connect.

Jeff


Page: Yaser

Yaser Alkayale

Tuesday Dec 12, 2017

What was done?

  • Mutating and non-mutating functions. Basically if a function is mutating, it has the ability to modify instance variables of a class.
  • typealias keyword. It has similar behaviour to typedef in C++;
  • associatedtype allows us to have more flexibility in the types of instance variables that we can have when implementing a protocol.
  • hopefully comprehensive testing of the most common array functions
  • Very simple import statement
  • Using the super keyword to access superclass variables.
  • using "inout" keyword to pass variables by reference and allowing them to be modified.
  • Creating a generic function with inout keyword to modify different types.
  • Using "where" clauses to allow us to have specialized extensions and specialized for loops.

Where I am stuck?

  • No where :)

What was learned?

  • Everything mentioned in the done section was well researched.

What is planned for next week?

  • Enjoy the break!

Tuesday Dec 5, 2017

What was done?

Implemented testcases the following features:
  • didSet and willSet which are two functions that get executed around the time a variable is being set
  • the required keyword which required the user to use a given initializer so that a protocol is guaranteed to be implemented properly.
  • final keyword which doesn't allow a class to be inherited by anything else.
  • Failable initializers are probably the coolest feature so far. It allows us to return a nil pointer if an object could not be created within the constructor. Most other languages I know force you to construct an object once a constructor is called but Swift doesn't.
  • nil coalescing operator is syntactic sugar to allow us to set a variable to something and set it to something else if the firsr thing is nil.
  • static keyword is very similar to most other languages.
  • private and public vars
  • multicase switch statements
  • numeric operations were added to test what kind of optimization the compiler does before moving to the SIL stage.

Where I am stuck?

  • What is? @IBOutlet var imageView: UIImageView!

What was learned?

  • Learnt about all the different cases up

What is planned for next week?

Tuesday Nov 28, 2017

What was done?

  • Added ten test cases
  • Tested extensions of structures
  • Special switch statement where variables are bound within a case
  • Tested fileprivate keyword where an object is only instantiable within the file it is written in
  • toString for objects using the CustomStringConvertible
  • Testing localized structs within other structs. This helps us create extra functionality that cannot be used outside

Where I am stuck?

  • How do I compile multiple files and have them access elements from each other using commandline.
  • what is this var dreamDidChange: ((Dream) -> Void)?

What was learned?

  • toString in Swift is actually just a property names "description", and the compiler searches for it when printing out an object (struct or class) CustomStringConvertible is needed to be extended
  • An extension is basically a way for us to add extra functionality into a struct or a class

What is planned for next week?

-Finish the last ten test cases of the semester! -

===================================================================

Tuesday Nov 21, 2017

What was done?

  • Removed the file from the app which was added by accident to the wala-next branch.
  • Watched video explaining the project and the ideas behind it.
  • Cleaned up test cases from the previous week by adding more meaningful header comments and splitting some test cases out so that they are more explicit in what they are testing

Where I am stuck?

  • Picking the exact next class to work on continues to be a challenge, but I believe that I am on the right track.

What was learned?

  • The code for the App is available online for anyone to download. I was super scared for including a file from the app in the project, but now it is removed.
  • Local reasoning is the idea that the data structures we create should be localized to our specific needs.
  • Composition is the idea to not use inheritance and try and use specific instances of a given class in our local code. This helps us not worry about dependencies for neither super nor subclasses.
  • We can create protocols and get any class to extend them using the extension semantics. This is very important as we can modify classes from other libraries to ensure that they implement given functionality so that we can use them in our program and avoid major bugs.
  • Xcode is the best tool to navigate the files because it adds a lot of structure to the files and folders that are not found in a simple system viewer.

What is planned for next week?

  • Add 10 more testcases that would allow us to catch the bugs that are in the code.

===================================================================

Tuesday Nov 14, 2017

What was done?

  • Provided test cases for switch statements that take simple integers
  • Provided test cases for switch statements that take enum values
  • Switch statements with a tuple as the switch value
  • Switch statements with derived type by switching on localized enum within a different struct
  • Created functions to overload operators for a given class/struct
  • Variable initialization within a struct using a switch statement. Very cool syntactic sugar provided by swift!

Where I am stuck?

  • What should I prioritize next? Should I just go to the next file, or is there one in particular I should look at?
  • Can I get some feedback on the test cases? Are they good? or should I do something differently.

What was learned?

  • Function input parameters have a lot of things not found in different languages. A variable can have two names one for the function to use and one to be used when calling the function. That is very cool, but can be confusing.
  • Never knew variables could be initialized like this using an "anonymous" switch statement. I find it fascinating!
  • Derived types for switches with enums makes it so much easier and less cluttered.

What is planned for next week?

  • Continue working on as many files as I can.

===================================================================

Tuesday Nov 17, 2017

What was done?

  • Went over the iPhone application provided by Kareem
  • Fixed bugs found in the application
  • Fixed XCode certificate and signing problems
  • Loaded the App onto the iphone and simulator
  • Created generic testCases for classes and string intropolation found in the testFiles folder

Where I am stuck?

  • Not sure what type of testCases to work on from here.

What was learned?

  • I learnt a lot more about Swift syntax and how it deals with classes.
  • Learnt the problems that arise with XCode and how to fix some of them
  • Learned how to navigate an XCode project

What is planned for next week?

  • Disect the code provided by Karim and add test cases that will cover pretty much everything in it.

===================================================================

Tuesday Oct 31, 2017

What was done?

Where I am stuck?

  • Going over the lexical structure, there are a lot of variations as to how Swift can accept things. For instance, Strings can be read with single quotes or triple quotes for longer strings. This in theory should not affect the SIL code that we receive because the parser should deal with them the same way. For this I am not sure, if we should test different input types, or that would not matter for that analysis.
  • Still trying to wrap my head around the code to make changes to the C++ codebase.
  • Added the testFiles directory
  • Made sure to name the test-cases properly so that we can group them and go through them easily with regex expressions.

What was learned?

  • I learned about the lexical structure of the Swift programming language.
  • Learned the problems in testing compilers as there are different stages of the compilation process. This leads us to needing specialized cases so that we can test the proper part of the analyzer.

What is planned for next week?

  • Contact Lydia and Chen to check with them about what we should test next after the literals.
  • Complete 20 more testFiles for next week.

===================================================================

Tuesday Oct 24, 2017

What was done?

  • Figured out how to recompile iteratively using Ninja rather than using the compile script.
  • Recompiled the code from scratch multiple times.
  • Spent over 5 hours going over the code and was unable to make any meaningful changes.

Where I am stuck?

  • Still was unable to add any code to the C++ codebase.
  • Trying to print out the different outputs to see the SIL structure and other outputs

What was learned?

  • Learnt about the function that are being connected with the C++ code through the Java code.
  • Have a much better understanding of the higher level design of the Swift compiler code.

What is planned for next week?

  • Start writing a minimum of 10 test-cases for the next week.
  • Contact Chen to go over the code with him and ask him the questions I'm stuck on.
  • Still unsure why we are getting exceptions when running swiftc. Where is it coming from? Should it be suppressed?

===================================================================

Tuesday Oct 17, 2017

What was done?

  • Added one untested function to support Integer literals.
  • Struggled understanding the codebase in both the Java and C++ side of things.
  • Looked up a lot about the swift codebase itself and worked on understanding Lidya and Chen's code.

Where I am stuck?

  • Recompiling Swift was taking too long. Understanding the code is still a challenge.

What was learned?

  • Adding code to the codebase is not the easiest. There are a lot of unknown parts of the system.
  • Rigorous testing of the specific parts added will be needed.

What is planned for next week?

  • Figure out how to recompile only the needed parts rather than recompiling everything from scratch.

===================================================================

Tuesday Oct 10, 2017

What was done?

  • I added onto Chen's code and created dummy methods for a couple of the AST Instructions
  • Studied more on AST format and Swift Syntax
  • Started collaborating with Ronny properly and now have set weekly time for collaboration.
  • Recompiled Swift (For some reason recompiling took over 2 hours, even though it was not a clean build. I believe the reason could do with updating my MacOS or a substantial commit to the wala-next branch (unlikely))

Where I am stuck?

-I am not sure how we would deal with single-threaded deadlock situations. -A little unclear on how to print the AST in a readable format -Trying to print things from C++ is not printing anything during compileTime, or rinTime. Where does the printing go?????

What was learned?

-Swift may run into deadlock situations even in single-threaded applications. This is due to cases where two variables are pointing to the same space in memory and at least one of them is trying to modify that memory. Swift guarantees that these situations give either compile-time or runtime errors.

What is planned for next week?

  • Meet with Ronny on Thursday (virtually) for 2 hours to do "pair programming" -Get unstuck on all of my points above. -Finish a minimum of 3 functions to parse 3 different instructions
===================================================================

Sept 24, 2017

What was done?

Added support for IntegerLiterals. Found this resource that is written by Apple which includes explanations for the Swift instructions that we are trying to translate into WALA nodes. https://github.com/apple/swift/blob/master/docs/SIL.rst Read more about Swift syntax and semantics.

Where I am stuck?

Trying to understand the codebase in detail has definitely been a challenge. The lack of documentation has made it more difficult to understand different architectural decisions of the project. This will get a lot better as I get more used to the constructs and the code-base.

What was learned?

I learned how LLVM has different stages for compiling SIL which broke down source code into different abstractions. Each of these abstractions had their own pros and cons and are each useful in their own respective ways. While the implementation this week relies on the SIL representation without any optimization, it might be better to get one of the other representations of the code.

I also learned more about jobjects and how java is connecting to the C++ code-base which is making it possible for them to communication.

Another thing is that Swift does not have many primitive operations in its SIL representation that we are working on. Most of the instructions are very low level memoryAddress operations, and function calls.

What is planned for next week?

More collaboration with Jeff so that we can possibly change the implementation to get more meaningful data structures from LLVM. Another thing is that I will keep in mind to make as good documentation as possible as we go. If I understand any part well, I will make sure to document it so that others who pick up the project will have the ability to get started on it more efficiently.

Clone this wiki locally