diff --git a/runtime/build.gradle b/runtime/build.gradle new file mode 100644 index 00000000000..9ec91384345 --- /dev/null +++ b/runtime/build.gradle @@ -0,0 +1,58 @@ +// TODO: consider using some Gradle plugins to build and test + +def srcDir = 'src/main/cpp' +def objDir = "$buildDir/bitcode" +def outFile = "$buildDir/runtime.bc" + +task compile(type: Exec) { + doFirst { + new File(objDir).mkdirs() + } + + inputs.dir srcDir + outputs.dir objDir + + workingDir objDir + + executable "$llvmInstallPath/bin/clang" + args '-std=c++11' + + args '-c', '-emit-llvm' + + args fileTree(srcDir).include('**/*.cpp') +} + +task build(type: Exec) { + dependsOn compile + + inputs.dir objDir + outputs.file outFile + + executable "$llvmInstallPath/bin/llvm-link" + args '-o', outFile + + doFirst { + args fileTree(objDir).include('**/*.bc') + } +} + +task test { + dependsOn build + + doLast { + exec { + commandLine "$llvmInstallPath/bin/clang", 'src/test/c/main.c', '-c', '-emit-llvm', '-o', "$buildDir/main.bc" + } + exec { + commandLine "$llvmInstallPath/bin/clang++", outFile, "$buildDir/main.bc", '-o', "$buildDir/main" + } + exec { + workingDir buildDir + commandLine './main' + } + } +} + +task clean << { + delete buildDir +} diff --git a/runtime/src/main/cpp/TypeInfo.cpp b/runtime/src/main/cpp/TypeInfo.cpp new file mode 100644 index 00000000000..3e9919a3c02 --- /dev/null +++ b/runtime/src/main/cpp/TypeInfo.cpp @@ -0,0 +1,9 @@ +#include +#include "TypeInfo.h" + +extern "C" { + int lookupField(TypeInfo* info, NameHash nameSignature) { + assert(false); // not implemented yet + return -1; + } +} \ No newline at end of file diff --git a/runtime/src/main/cpp/TypeInfo.h b/runtime/src/main/cpp/TypeInfo.h new file mode 100644 index 00000000000..8df39fa4705 --- /dev/null +++ b/runtime/src/main/cpp/TypeInfo.h @@ -0,0 +1,39 @@ +#ifndef RUNTIME_TYPEINFO_H +#define RUNTIME_TYPEINFO_H + +#include + +// All names in system are stored as hashes (or maybe, for debug builds, +// as pointers to uniqued C strings containing names?). +typedef int64_t NameHash; + +// An element of sorted by hash in-place array representing methods. +struct MethodTableRecord { + NameHash nameSignature; + void* methodEntryPoint; +}; + +// An element of sorted by hash in-place array representing field offsets. +struct FieldTableRecord { + NameHash nameSignature; + int fieldOffset; +}; + +// This struct represents runtime type information and by itself is compile time +// constant. +struct TypeInfo { + NameHash name; + int size; + const TypeInfo* superType; + const int* objOffsets; + int objOffsetsCount; + TypeInfo* const* implementedInterfaces; + int implementedInterfacesCount; + const MethodTableRecord* methods; + int methodsCount; + const FieldTableRecord* fields; + int fieldsCount; +}; + + +#endif //RUNTIME_TYPEINFO_H diff --git a/runtime/src/main/cpp/launcher.cpp b/runtime/src/main/cpp/launcher.cpp new file mode 100644 index 00000000000..cc2d10187d1 --- /dev/null +++ b/runtime/src/main/cpp/launcher.cpp @@ -0,0 +1,6 @@ +extern "C" void kotlinNativeMain(); + +int main() { + kotlinNativeMain(); + return 0; +} \ No newline at end of file diff --git a/runtime/src/test/c/main.c b/runtime/src/test/c/main.c new file mode 100644 index 00000000000..07e58d74dab --- /dev/null +++ b/runtime/src/test/c/main.c @@ -0,0 +1,6 @@ +#include +#include + +void kotlinNativeMain() { + // nothing to test yet +} diff --git a/settings.gradle b/settings.gradle index f904ffb1584..fbd1ea6cbcd 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,3 +3,4 @@ include ':Interop:StubGenerator' include ':Interop:Runtime' include ':InteropExample' include ':backend.native' +include ':runtime'