Skip to content

Commit

Permalink
[K/N][runtime] Renamed object tags
Browse files Browse the repository at this point in the history
  • Loading branch information
homuroll authored and Space Team committed Jan 29, 2025
1 parent bfbfac6 commit 959272b
Show file tree
Hide file tree
Showing 17 changed files with 48 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ internal class StackLocalsManagerImpl(

val objectHeader = structGep(type, stackSlot, 0, "objHeader")
val typeInfo = codegen.typeInfoForAllocation(irClass)
setTypeInfoForLocalObject(runtime.objHeaderType, objectHeader, typeInfo)
setTypeInfoForStackObject(runtime.objHeaderType, objectHeader, typeInfo)
val gcRootSetSlot = createRootSetSlot()
StackLocal(null, irClass, stackSlot, objectHeader, gcRootSetSlot)
}
Expand Down Expand Up @@ -477,7 +477,7 @@ internal class StackLocalsManagerImpl(
val arraySlot = LLVMBuildAlloca(builder, arrayType, "")!!
// Set array size in ArrayHeader.
val arrayHeaderSlot = structGep(arrayType, arraySlot, 0, "arrayHeader")
setTypeInfoForLocalObject(runtime.arrayHeaderType, arrayHeaderSlot, typeInfo)
setTypeInfoForStackObject(runtime.arrayHeaderType, arrayHeaderSlot, typeInfo)
val sizeField = structGep(runtime.arrayHeaderType, arrayHeaderSlot, 1, "count_")
store(count, sizeField)

Expand Down Expand Up @@ -541,9 +541,9 @@ internal class StackLocalsManagerImpl(
}
}

private fun setTypeInfoForLocalObject(headerType: LLVMTypeRef, header: LLVMValueRef, typeInfoPointer: LLVMValueRef) = with(functionGenerationContext) {
private fun setTypeInfoForStackObject(headerType: LLVMTypeRef, header: LLVMValueRef, typeInfoPointer: LLVMValueRef) = with(functionGenerationContext) {
val typeInfo = structGep(headerType, header, 0, "typeInfoOrMeta_")
// Set tag OBJECT_TAG_PERMANENT_CONTAINER | OBJECT_TAG_NONTRIVIAL_CONTAINER.
// Set tag OBJECT_TAG_STACK.
val typeInfoValue = intToPtr(or(ptrToInt(typeInfoPointer, codegen.intPtrType),
codegen.immThreeIntPtrType), kTypeInfoPtr)
store(typeInfoValue, typeInfo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ private fun ConstPointer.addBits(llvm: CodegenLlvmHelpers, type: LLVMTypeRef, bi
internal class KotlinStaticData(override val generationState: NativeGenerationState, override val llvm: CodegenLlvmHelpers, module: LLVMModuleRef) : ContextUtils, StaticData(module, llvm) {
private val stringLiterals = mutableMapOf<String, ConstPointer>()

// Must match OBJECT_TAG_PERMANENT_CONTAINER in C++.
// Must match OBJECT_TAG_PERMANENT in C++.
private fun permanentTag(typeInfo: ConstPointer): ConstPointer {
return typeInfo.addBits(llvm, kTypeInfoPtr, 1)
}
Expand Down
6 changes: 3 additions & 3 deletions kotlin-native/runtime/src/gc/common/cpp/MarkAndSweepUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ void processFieldInMark(void* state, ObjHeader* object, ObjHeader* field) noexce
}
if constexpr (!Traits::kAllowHeapToStackRefs) {
if (object->heap()) {
RuntimeAssert(!field->local(), "Heap object %p references stack object %p[typeInfo=%p]", object, field, field->type_info());
RuntimeAssert(!field->stack(), "Heap object %p references stack object %p[typeInfo=%p]", object, field, field->type_info());
}
}
}
Expand Down Expand Up @@ -76,8 +76,8 @@ template <typename Traits>
void processExtraObjectData(GCHandle::GCMarkScope& markHandle, typename Traits::MarkQueue& markQueue, mm::ExtraObjectData& extraObjectData, ObjHeader* object) noexcept {
if (auto weakReference = extraObjectData.GetRegularWeakReferenceImpl()) {
RuntimeAssert(
weakReference->heap(), "Weak reference must be a heap object. object=%p weak=%p permanent=%d local=%d", object,
weakReference, weakReference->permanent(), weakReference->local());
weakReference->heap(), "Weak reference must be a heap object. object=%p weak=%p permanent=%d stack=%d", object,
weakReference, weakReference->permanent(), weakReference->stack());
// Do not schedule RegularWeakReferenceImpl but process it right away.
// This will skip markQueue interaction.
if (Traits::tryMark(weakReference)) {
Expand Down
4 changes: 2 additions & 2 deletions kotlin-native/runtime/src/gc/common/cpp/TracingGCTest.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class GlobalPermanentObjectHolder : private Pinned {
public:
explicit GlobalPermanentObjectHolder(mm::ThreadData& threadData) {
mm::GlobalsRegistry::Instance().RegisterStorageForGlobal(&threadData, &global_);
global_->typeInfoOrMeta_ = setPointerBits(global_->typeInfoOrMeta_, OBJECT_TAG_PERMANENT_CONTAINER);
global_->typeInfoOrMeta_ = setPointerBits(global_->typeInfoOrMeta_, OBJECT_TAG_PERMANENT);
RuntimeAssert(global_->permanent(), "Must be permanent");
}

Expand Down Expand Up @@ -572,7 +572,7 @@ TYPED_TEST_P(TracingGCTest, PermanentObjects) {
GlobalObjectHolder global2{threadData};
test_support::Object<Payload> permanentObject{typeHolder.typeInfo()};
permanentObject.header()->typeInfoOrMeta_ =
setPointerBits(permanentObject.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT_CONTAINER);
setPointerBits(permanentObject.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT);
RuntimeAssert(permanentObject.header()->permanent(), "Must be permanent");

global1->field1 = permanentObject.header();
Expand Down
22 changes: 11 additions & 11 deletions kotlin-native/runtime/src/main/cpp/ExceptionsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ TEST(ExceptionTest, ProcessUnhandledException_WithHook) {
test_support::TypeInfoHolder typeHolder{test_support::TypeInfoHolder::ObjectBuilder<Payload>().setSuperType(theThrowableTypeInfo)};
kotlin::RunInNewThread([&typeHolder]() {
Object exception(typeHolder.typeInfo());
exception.header()->typeInfoOrMeta_ = setPointerBits(exception.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT_CONTAINER);
exception.header()->typeInfoOrMeta_ = setPointerBits(exception.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT);
exception->value = 42;
auto reportUnhandledExceptionMock = ScopedReportUnhandledExceptionMock();
auto Kotlin_runUnhandledExceptionHookMock = ScopedKotlin_runUnhandledExceptionHookMock();
Expand All @@ -58,7 +58,7 @@ TEST(ExceptionDeathTest, ProcessUnhandledException_NoHook) {
test_support::TypeInfoHolder typeHolder{test_support::TypeInfoHolder::ObjectBuilder<Payload>().setSuperType(theThrowableTypeInfo)};
kotlin::RunInNewThread([&typeHolder]() {
Object exception(typeHolder.typeInfo());
exception.header()->typeInfoOrMeta_ = setPointerBits(exception.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT_CONTAINER);
exception.header()->typeInfoOrMeta_ = setPointerBits(exception.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT);
exception->value = 42;
auto reportUnhandledExceptionMock = ScopedReportUnhandledExceptionMock();
auto Kotlin_runUnhandledExceptionHookMock = ScopedKotlin_runUnhandledExceptionHookMock();
Expand All @@ -78,10 +78,10 @@ TEST(ExceptionDeathTest, ProcessUnhandledException_WithFailingHook) {
test_support::TypeInfoHolder typeHolder{test_support::TypeInfoHolder::ObjectBuilder<Payload>().setSuperType(theThrowableTypeInfo)};
kotlin::RunInNewThread([&typeHolder]() {
Object exception(typeHolder.typeInfo());
exception.header()->typeInfoOrMeta_ = setPointerBits(exception.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT_CONTAINER);
exception.header()->typeInfoOrMeta_ = setPointerBits(exception.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT);
exception->value = 42;
Object hookException(typeHolder.typeInfo());
hookException.header()->typeInfoOrMeta_ = setPointerBits(hookException.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT_CONTAINER);
hookException.header()->typeInfoOrMeta_ = setPointerBits(hookException.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT);
hookException->value = 13;
auto reportUnhandledExceptionMock = ScopedReportUnhandledExceptionMock();
auto Kotlin_runUnhandledExceptionHookMock = ScopedKotlin_runUnhandledExceptionHookMock();
Expand All @@ -100,10 +100,10 @@ TEST(ExceptionDeathTest, ProcessUnhandledException_WithTerminatingFailingHook) {
test_support::TypeInfoHolder typeHolder{test_support::TypeInfoHolder::ObjectBuilder<Payload>().setSuperType(theThrowableTypeInfo)};
kotlin::RunInNewThread([&typeHolder]() {
Object exception(typeHolder.typeInfo());
exception.header()->typeInfoOrMeta_ = setPointerBits(exception.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT_CONTAINER);
exception.header()->typeInfoOrMeta_ = setPointerBits(exception.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT);
exception->value = 42;
Object hookException(typeHolder.typeInfo());
hookException.header()->typeInfoOrMeta_ = setPointerBits(hookException.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT_CONTAINER);
hookException.header()->typeInfoOrMeta_ = setPointerBits(hookException.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT);
hookException->value = 13;
auto reportUnhandledExceptionMock = ScopedReportUnhandledExceptionMock();
auto Kotlin_runUnhandledExceptionHookMock = ScopedKotlin_runUnhandledExceptionHookMock();
Expand All @@ -122,7 +122,7 @@ TEST(ExceptionDeathTest, TerminateWithUnhandledException) {
test_support::TypeInfoHolder typeHolder{test_support::TypeInfoHolder::ObjectBuilder<Payload>().setSuperType(theThrowableTypeInfo)};
kotlin::RunInNewThread([&typeHolder]() {
Object exception(typeHolder.typeInfo());
exception.header()->typeInfoOrMeta_ = setPointerBits(exception.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT_CONTAINER);
exception.header()->typeInfoOrMeta_ = setPointerBits(exception.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT);
exception->value = 42;
auto reportUnhandledExceptionMock = ScopedReportUnhandledExceptionMock();
auto Kotlin_runUnhandledExceptionHookMock = ScopedKotlin_runUnhandledExceptionHookMock();
Expand All @@ -139,7 +139,7 @@ TEST(ExceptionDeathTest, TerminateWithUnhandledException) {
TEST(ExceptionDeathTest, TerminateHandler_WithHook) {
test_support::TypeInfoHolder typeHolder{test_support::TypeInfoHolder::ObjectBuilder<Payload>().setSuperType(theThrowableTypeInfo)};
Object exception(typeHolder.typeInfo());
exception.header()->typeInfoOrMeta_ = setPointerBits(exception.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT_CONTAINER);
exception.header()->typeInfoOrMeta_ = setPointerBits(exception.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT);
exception->value = 42;
auto reportUnhandledExceptionMock = ScopedReportUnhandledExceptionMock();
auto Kotlin_runUnhandledExceptionHookMock = ScopedKotlin_runUnhandledExceptionHookMock();
Expand Down Expand Up @@ -179,7 +179,7 @@ TEST(ExceptionDeathTest, TerminateHandler_WithHook) {
TEST(ExceptionDeathTest, TerminateHandler_NoHook) {
test_support::TypeInfoHolder typeHolder{test_support::TypeInfoHolder::ObjectBuilder<Payload>().setSuperType(theThrowableTypeInfo)};
Object exception(typeHolder.typeInfo());
exception.header()->typeInfoOrMeta_ = setPointerBits(exception.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT_CONTAINER);
exception.header()->typeInfoOrMeta_ = setPointerBits(exception.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT);
exception->value = 42;
auto reportUnhandledExceptionMock = ScopedReportUnhandledExceptionMock();
auto Kotlin_runUnhandledExceptionHookMock = ScopedKotlin_runUnhandledExceptionHookMock();
Expand Down Expand Up @@ -221,10 +221,10 @@ TEST(ExceptionDeathTest, TerminateHandler_NoHook) {
TEST(ExceptionDeathTest, TerminateHandler_WithFailingHook) {
test_support::TypeInfoHolder typeHolder{test_support::TypeInfoHolder::ObjectBuilder<Payload>().setSuperType(theThrowableTypeInfo)};
Object exception(typeHolder.typeInfo());
exception.header()->typeInfoOrMeta_ = setPointerBits(exception.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT_CONTAINER);
exception.header()->typeInfoOrMeta_ = setPointerBits(exception.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT);
exception->value = 42;
Object hookException(typeHolder.typeInfo());
hookException.header()->typeInfoOrMeta_ = setPointerBits(hookException.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT_CONTAINER);
hookException.header()->typeInfoOrMeta_ = setPointerBits(hookException.header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT);
hookException->value = 13;
auto reportUnhandledExceptionMock = ScopedReportUnhandledExceptionMock();
auto Kotlin_runUnhandledExceptionHookMock = ScopedKotlin_runUnhandledExceptionHookMock();
Expand Down
2 changes: 1 addition & 1 deletion kotlin-native/runtime/src/main/cpp/KString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ extern "C" KRef CreatePermanentStringFromCString(const char* nullTerminatedUTF8)
size_t arraySize = headerSize + count * sizeof(char16_t);

auto header = (ObjHeader*)std::calloc(arraySize, 1);
header->typeInfoOrMeta_ = setPointerBits((TypeInfo *)theStringTypeInfo, OBJECT_TAG_PERMANENT_CONTAINER);
header->typeInfoOrMeta_ = setPointerBits((TypeInfo *)theStringTypeInfo, OBJECT_TAG_PERMANENT);
header->array()->count_ = count;
utf8::with_replacement::utf8to16(nullTerminatedUTF8, end, StringUtf16Data(header));
return header;
Expand Down
22 changes: 11 additions & 11 deletions kotlin-native/runtime/src/main/cpp/Memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@
#include "Utils.hpp"

typedef enum {
// Must match to permTag() in Kotlin.
OBJECT_TAG_PERMANENT_CONTAINER = 1 << 0,
OBJECT_TAG_NONTRIVIAL_CONTAINER = 1 << 1,
// Keep in sync with immTypeInfoMask in Kotlin.
OBJECT_TAG_MASK = (1 << 2) - 1
OBJECT_TAG_HEAP = 0,
OBJECT_TAG_PERMANENT = 1, // Must match to permanentTag() in Kotlin.
OBJECT_TAG_STACK = 3,
// Keep in sync with immTypeInfoMask in Kotlin.
OBJECT_TAG_MASK = (1 << 2) - 1
} ObjectTag;

struct ArrayHeader;
Expand Down Expand Up @@ -96,10 +96,8 @@ struct ObjHeader {
void* CasAssociatedObject(void* expectedObj, void* obj);
#endif

inline bool local() const {
unsigned bits = getPointerBits(typeInfoOrMetaRelaxed(), OBJECT_TAG_MASK);
return (bits & (OBJECT_TAG_PERMANENT_CONTAINER | OBJECT_TAG_NONTRIVIAL_CONTAINER)) ==
(OBJECT_TAG_PERMANENT_CONTAINER | OBJECT_TAG_NONTRIVIAL_CONTAINER);
inline bool stack() const {
return getPointerBits(typeInfoOrMetaRelaxed(), OBJECT_TAG_MASK) == OBJECT_TAG_STACK;
}

// Unsafe cast to ArrayHeader. Use carefully!
Expand All @@ -108,10 +106,12 @@ struct ObjHeader {
const ArrayHeader* array() const { return reinterpret_cast<const ArrayHeader*>(this); }

inline bool permanent() const {
return hasPointerBits(typeInfoOrMetaRelaxed(), OBJECT_TAG_PERMANENT_CONTAINER);
return getPointerBits(typeInfoOrMetaRelaxed(), OBJECT_TAG_MASK) == OBJECT_TAG_PERMANENT;
}

inline bool heap() const { return getPointerBits(typeInfoOrMetaRelaxed(), OBJECT_TAG_MASK) == 0; }
inline bool heap() const {
return getPointerBits(typeInfoOrMetaRelaxed(), OBJECT_TAG_MASK) == OBJECT_TAG_HEAP;
}

static MetaObjHeader* createMetaObject(ObjHeader* object);
static void destroyMetaObject(ObjHeader* object);
Expand Down
4 changes: 2 additions & 2 deletions kotlin-native/runtime/src/main/cpp/Runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,8 @@ KBoolean Kotlin_Debugging_isPermanent(KRef obj) {
return obj->permanent();
}

RUNTIME_NOTHROW KBoolean Kotlin_Debugging_isLocal(KRef obj) {
return obj->local();
RUNTIME_NOTHROW KBoolean Kotlin_Debugging_isStack(KRef obj) {
return obj->stack();
}

static void CallInitGlobalAwaitInitialized(uintptr_t* state) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ package kotlin.native.internal
import kotlin.native.internal.escapeAnalysis.Escapes

/*
* Internal utilities for debugging K/N compiler and runtime.
* Internal utilities for debugging/testing K/N compiler and runtime.
*/

@OptIn(kotlin.native.runtime.NativeRuntimeApi::class)
Expand All @@ -22,9 +22,9 @@ public object Debugging {
@GCUnsafeCall("Kotlin_Debugging_isPermanent")
@InternalForKotlinNative
@Escapes.Nothing
public external fun Any.isPermanent() : Boolean
public external fun Any.isPermanent(): Boolean

@GCUnsafeCall("Kotlin_Debugging_isLocal")
@GCUnsafeCall("Kotlin_Debugging_isStack")
@InternalForKotlinNative
@Escapes.Nothing
public external fun Any.isLocal() : Boolean
public external fun Any.isStack(): Boolean
2 changes: 1 addition & 1 deletion kotlin-native/runtime/src/mm/cpp/ExternalRCRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ mm::ExternalRCRefImpl::ExternalRCRefImpl(mm::ExternalRCRefRegistry& registry, KR
RuntimeAssert(obj != nullptr, "Creating ExternalRCRefImpl for null object");
RuntimeAssert(rc >= 0, "Creating ExternalRCRefImpl with negative rc %d", rc);
// Runtime tests occasionally use sentinel values under 8 for opaque objects
RuntimeAssert(reinterpret_cast<uintptr_t>(obj) < 8u || !obj->local(), "Creating ExternalRCRefImpl to a stack-allocated object %p", obj);
RuntimeAssert(reinterpret_cast<uintptr_t>(obj) < 8u || !obj->stack(), "Creating ExternalRCRefImpl to a stack-allocated object %p", obj);

if (rc > 0) {
registry.insertIntoRootsHead(*this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ struct HeapObject : test_support::Object<Payload> {

struct PermanentObject : test_support::Object<Payload> {
PermanentObject() noexcept : Object(typeInfoHolder.typeInfo()) {
header()->typeInfoOrMeta_ = setPointerBits(header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT_CONTAINER);
header()->typeInfoOrMeta_ = setPointerBits(header()->typeInfoOrMeta_, OBJECT_TAG_PERMANENT);
RuntimeAssert(header()->permanent(), "Must be permanent");
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12123,10 +12123,10 @@ final fun (kotlin/Any).kotlin.native.concurrent/ensureNeverFrozen() // kotlin.na
final fun (kotlin/Any).kotlin.native.internal/collectReferenceFieldValues(): kotlin.collections/List<kotlin/Any> // kotlin.native.internal/collectReferenceFieldValues|[email protected](){}[0]

// Targets: [native]
final fun (kotlin/Any).kotlin.native.internal/isLocal(): kotlin/Boolean // kotlin.native.internal/isLocal|isLocal@kotlin.Any(){}[0]
final fun (kotlin/Any).kotlin.native.internal/isPermanent(): kotlin/Boolean // kotlin.native.internal/isPermanent|isPermanent@kotlin.Any(){}[0]

// Targets: [native]
final fun (kotlin/Any).kotlin.native.internal/isPermanent(): kotlin/Boolean // kotlin.native.internal/isPermanent|isPermanent@kotlin.Any(){}[0]
final fun (kotlin/Any).kotlin.native.internal/isStack(): kotlin/Boolean // kotlin.native.internal/isStack|isStack@kotlin.Any(){}[0]

// Targets: [native]
final fun (kotlin/Any?).kotlin.native/identityHashCode(): kotlin/Int // kotlin.native/identityHashCode|[email protected]?(){}[0]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class A {

fun f(x: Int): Int {
val a = A()
assertTrue(a.isLocal())
assertTrue(a.isStack())
return a.f(x)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import kotlin.native.internal.*

fun box(): String {
val s = String()
assertTrue(s.isLocal())
assertTrue(s.isStack())

return "OK"
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class A {

fun f(x: Int): Int {
val a = A()
assertFalse(a.isLocal())
assertFalse(a.isStack())
return a.f(x)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import kotlin.native.internal.*

fun box(): String {
val s = String()
assertFalse(s.isLocal())
assertFalse(s.isStack())

return "OK"
}
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ private class ExtTestDataFile(
) {
args.add("-Xverify-ir-visibility")
}
args += "-opt-in=kotlin.native.internal.InternalForKotlinNative" // for `Any.isPermanent()` and `Any.isLocal()`
args += "-opt-in=kotlin.native.internal.InternalForKotlinNative" // for `Any.isPermanent()` and `Any.isStack()`
args += "-opt-in=kotlin.native.internal.InternalForKotlinNativeTests" // for ReflectionPackageName
val freeCInteropArgs = structure.directives.listValues(FREE_CINTEROP_ARGS.name)
.orEmpty().flatMap { it.split(" ") }
Expand Down

0 comments on commit 959272b

Please sign in to comment.