[K/N] Treat DEF files as regular test source, compiled with cinterop
^KT-61259
This commit is contained in:
committed by
Space Team
parent
2530cba82a
commit
0b0ba3160f
-8
@@ -1,8 +0,0 @@
|
||||
---
|
||||
int (*arrayPointer)[1];
|
||||
|
||||
int globalArray[3] = {1, 2, 3};
|
||||
|
||||
struct StructWithArrayPtr {
|
||||
int (*arrayPointer)[1];
|
||||
};
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const char* name();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
#include <string>
|
||||
#include "auxiliarySources.aux.h"
|
||||
|
||||
static std::string _name = "Hello from C++";
|
||||
|
||||
const char* name() {
|
||||
return _name.c_str();
|
||||
}
|
||||
-2
@@ -1,2 +0,0 @@
|
||||
# The def file is empty intentianally
|
||||
# `auxiliarySources.aux.h` is meant to be included via `-header` option of cinterop tool
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import auxiliarySources.*
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
fun main() {
|
||||
assertEquals(name()!!.toKString(), "Hello from C++")
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
---
|
||||
enum B2 {
|
||||
ZERO, ONE, TWO, THREE
|
||||
};
|
||||
|
||||
enum E : short {
|
||||
A, B
|
||||
};
|
||||
|
||||
struct __attribute__((packed)) S {
|
||||
long long x1 : 1;
|
||||
enum B2 x2 : 2;
|
||||
unsigned short x3 : 3;
|
||||
unsigned int x4 : 4;
|
||||
int x5 : 5;
|
||||
long long x6 : 63;
|
||||
enum E x7: 2;
|
||||
_Bool x8 : 1;
|
||||
struct { int x9:4; };
|
||||
};
|
||||
|
||||
static long long getX1(struct S* s) { return s->x1; }
|
||||
static enum B2 getX2(struct S* s) { return s->x2; }
|
||||
static unsigned short getX3(struct S* s) { return s->x3; }
|
||||
static unsigned int getX4(struct S* s) { return s->x4; }
|
||||
static int getX5(struct S* s) { return s->x5; }
|
||||
static long long getX6(struct S* s) { return s->x6; }
|
||||
static enum E getX7(struct S* s) { return s->x7; }
|
||||
static _Bool getX8(struct S* s) { return s->x8; }
|
||||
static int getX9(struct S* s) { return s->x9; }
|
||||
Vendored
-78
@@ -1,78 +0,0 @@
|
||||
|
||||
|
||||
---
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
struct S {
|
||||
int x;
|
||||
};
|
||||
|
||||
static int getX(struct S (*callback)(void)) {
|
||||
return callback().x;
|
||||
}
|
||||
|
||||
static void applyCallback(struct S s, void (*callback)(struct S)) {
|
||||
callback(s);
|
||||
}
|
||||
|
||||
static struct S makeS(int x, ...) {
|
||||
return (struct S){ x };
|
||||
}
|
||||
|
||||
enum E {
|
||||
ZERO, ONE, TWO
|
||||
};
|
||||
|
||||
static enum E makeE(int ordinal, ...) {
|
||||
return ordinal;
|
||||
}
|
||||
|
||||
struct Args {
|
||||
char a1;
|
||||
char a2;
|
||||
short a3;
|
||||
int a4;
|
||||
long long a5;
|
||||
float a6;
|
||||
double a7;
|
||||
void* a8;
|
||||
unsigned char a9;
|
||||
unsigned short a10;
|
||||
unsigned int a11;
|
||||
unsigned long long a12;
|
||||
enum E a13;
|
||||
struct S a14;
|
||||
void* a15;
|
||||
};
|
||||
|
||||
static struct Args getVarargs(int ignore, ...) {
|
||||
va_list args;
|
||||
va_start(args, ignore);
|
||||
|
||||
struct Args result = {
|
||||
va_arg(args, char),
|
||||
va_arg(args, char),
|
||||
va_arg(args, short),
|
||||
va_arg(args, int),
|
||||
va_arg(args, long long),
|
||||
va_arg(args, double),
|
||||
va_arg(args, double),
|
||||
va_arg(args, void*),
|
||||
va_arg(args, unsigned char),
|
||||
va_arg(args, unsigned short),
|
||||
va_arg(args, unsigned int),
|
||||
va_arg(args, unsigned long long),
|
||||
va_arg(args, enum E),
|
||||
va_arg(args, struct S),
|
||||
va_arg(args, void*)
|
||||
};
|
||||
|
||||
va_end(args);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int sum(int first, int second) {
|
||||
return first + second;
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
enum E {
|
||||
A, B, C
|
||||
};
|
||||
Vendored
-11
@@ -1,11 +0,0 @@
|
||||
---
|
||||
struct StructDeclared;
|
||||
struct StructDefined { int x; };
|
||||
|
||||
int useStructDeclared(struct StructDeclared* declared) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int useStructDefined(struct StructDefined* defined) {
|
||||
return -2;
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
headerFilter = NOTHING
|
||||
---
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef int (*atoiPtrType)(const char*);
|
||||
|
||||
static atoiPtrType getAtoiPtr() {
|
||||
return &atoi;
|
||||
}
|
||||
|
||||
static void __printInt(int x) {
|
||||
printf("%d\n", x);
|
||||
}
|
||||
|
||||
static void* __getPrintIntPtr() {
|
||||
return &__printInt;
|
||||
}
|
||||
|
||||
typedef void* (*getPrintIntPtrPtrType)(void);
|
||||
|
||||
static getPrintIntPtrPtrType getGetPrintIntPtrPtr() {
|
||||
return &__getPrintIntPtr;
|
||||
}
|
||||
|
||||
static double __add(double x, double y) {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
typedef double (*addPtrType)(double, double);
|
||||
|
||||
static addPtrType getAddPtr() {
|
||||
return &__add;
|
||||
}
|
||||
|
||||
static int __doubleToInt(double x) {
|
||||
return (int) x;
|
||||
}
|
||||
|
||||
typedef int (*doubleToIntPtrType)(double);
|
||||
|
||||
static doubleToIntPtrType getDoubleToIntPtr() {
|
||||
return &__doubleToInt;
|
||||
}
|
||||
|
||||
static _Bool __isIntPositive(int x) {
|
||||
return x > 0;
|
||||
}
|
||||
|
||||
typedef _Bool (*isIntPositivePtrType)(int);
|
||||
|
||||
static isIntPositivePtrType getIsIntPositivePtr() {
|
||||
return &__isIntPositive;
|
||||
}
|
||||
|
||||
static unsigned int getMaxUInt(void) {
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
static typeof(&getMaxUInt) getMaxUIntGetter() {
|
||||
return &getMaxUInt;
|
||||
}
|
||||
|
||||
typedef int (*longSignatureFunctionPtrType)(
|
||||
int, int, int, int, int, int, int, int, int, int, int, int,
|
||||
int, int, int, int, int, int, int, int, int, int, int
|
||||
);
|
||||
|
||||
typedef int (*notSoLongSignatureFunctionPtrType)(
|
||||
int, int, int, int, int, int, int, int, int, int, int,
|
||||
int, int, int, int, int, int, int, int, int, int, int
|
||||
);
|
||||
|
||||
static int longSignatureFunction(
|
||||
int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, int p9, int p10, int p11, int p12,
|
||||
int p13, int p14, int p15, int p16, int p17, int p18, int p19, int p20, int p21, int p22, int p23
|
||||
) {
|
||||
return 42;
|
||||
}
|
||||
|
||||
static int notSoLongSignatureFunction(
|
||||
int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, int p9, int p10, int p11, int p12,
|
||||
int p13, int p14, int p15, int p16, int p17, int p18, int p19, int p20, int p21, int p22
|
||||
) {
|
||||
return 42;
|
||||
}
|
||||
|
||||
static longSignatureFunctionPtrType getLongSignatureFunctionPtr() {
|
||||
return &longSignatureFunction;
|
||||
}
|
||||
|
||||
static notSoLongSignatureFunctionPtrType getNotSoLongSignatureFunctionPtr() {
|
||||
return ¬SoLongSignatureFunction;
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
// OUT_DATA_FILE: funptr.out
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import funptr.*
|
||||
import kotlin.test.*
|
||||
|
||||
typealias NotSoLongSignatureFunction = (
|
||||
Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int,
|
||||
Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
|
||||
) -> Int
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val atoiPtr = getAtoiPtr()!!
|
||||
|
||||
val getPrintIntPtrPtr = getGetPrintIntPtrPtr()!!
|
||||
val printIntPtr = getPrintIntPtrPtr()!!.reinterpret<CFunction<(Int) -> Unit>>()
|
||||
|
||||
val fortyTwo = memScoped {
|
||||
atoiPtr("42".cstr.getPointer(memScope))
|
||||
}
|
||||
|
||||
printIntPtr(fortyTwo)
|
||||
|
||||
printIntPtr(
|
||||
getDoubleToIntPtr()!!(
|
||||
getAddPtr()!!(5.1, 12.2)
|
||||
)
|
||||
)
|
||||
|
||||
val isIntPositivePtr = getIsIntPositivePtr()!!
|
||||
|
||||
printIntPtr(isIntPositivePtr(42).ifThenOneElseZero())
|
||||
printIntPtr(isIntPositivePtr(-42).ifThenOneElseZero())
|
||||
|
||||
assertEquals(getMaxUIntGetter()!!(), UInt.MAX_VALUE)
|
||||
|
||||
val longSignaturePtr: COpaquePointer? = getLongSignatureFunctionPtr()
|
||||
val notSoLongSignaturePtr: CPointer<CFunction<NotSoLongSignatureFunction>>? = getNotSoLongSignatureFunctionPtr()
|
||||
printIntPtr(notSoLongSignaturePtr!!.invoke(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
|
||||
printIntPtr(notSoLongSignatureFunction(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
fun Boolean.ifThenOneElseZero() = if (this) 1 else 0
|
||||
@@ -1,33 +0,0 @@
|
||||
---
|
||||
const int g1 = 42;
|
||||
|
||||
int g2 = 17;
|
||||
|
||||
struct S {
|
||||
int x;
|
||||
} g3 = { 128 };
|
||||
|
||||
int g4[2] = { 13, 14 };
|
||||
|
||||
int g5[2][2] = { 15, 16, 17, 18 };
|
||||
|
||||
struct S* const g6 = &g3;
|
||||
|
||||
void foo() {
|
||||
// Test that local vars are not treated as global ones.
|
||||
float g1;
|
||||
}
|
||||
|
||||
// Test non-compilable variable:
|
||||
typedef int MyInt;
|
||||
MyInt g7;
|
||||
#define g7 bad macro
|
||||
|
||||
// Test property name mangling:
|
||||
struct g1 {};
|
||||
struct g1_ {};
|
||||
|
||||
typedef void* voidptr;
|
||||
_Pragma("clang assume_nonnull begin")
|
||||
const voidptr g8 = 0x1, g9 = 0x2;
|
||||
_Pragma("clang assume_nonnull end")
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Forward declaration.
|
||||
struct S;
|
||||
extern struct S s;
|
||||
|
||||
const char* getContent(struct S* s);
|
||||
void setContent(struct S* s, const char* name);
|
||||
|
||||
union U;
|
||||
extern union U u;
|
||||
|
||||
double getDouble(union U* u);
|
||||
void setDouble(union U* u, double value);
|
||||
|
||||
// Global array of unknown size.
|
||||
extern char array[];
|
||||
|
||||
|
||||
int arrayLength();
|
||||
void setArrayValue(char* array, char value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
#include <string>
|
||||
#include "incompleteTypes.aux.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
struct S {
|
||||
std::string name;
|
||||
};
|
||||
|
||||
S s = {
|
||||
.name = "initial"
|
||||
};
|
||||
|
||||
void setContent(struct S* s, const char* name) {
|
||||
// Note that copy here is intentional: we use it as a workaround
|
||||
// for short lifetime of copy of the passed Kotlin string.
|
||||
s->name = name;
|
||||
}
|
||||
|
||||
const char* getContent(struct S* s) {
|
||||
return s->name.c_str();
|
||||
}
|
||||
|
||||
union U {
|
||||
float f;
|
||||
double d;
|
||||
};
|
||||
|
||||
void setDouble(union U* u, double value) {
|
||||
u->d = value;
|
||||
}
|
||||
|
||||
double getDouble(union U* u) {
|
||||
return u->d;
|
||||
}
|
||||
|
||||
union U u = {
|
||||
.d = 0.0
|
||||
};
|
||||
|
||||
char array[5] = { 0, 0, 0, 0, 0 };
|
||||
|
||||
void setArrayValue(char* array, char value) {
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
array[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
int arrayLength() {
|
||||
return sizeof(array) / sizeof(char);
|
||||
}
|
||||
|
||||
}
|
||||
-2
@@ -1,2 +0,0 @@
|
||||
# The def file is empty intentianally
|
||||
# `incompleteTypes.aux.h` is meant to be included via `-header` option of cinterop tool
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import incompleteTypes.*
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
|
||||
fun main() {
|
||||
assertNotNull(s.ptr)
|
||||
assertNotNull(u.ptr)
|
||||
assertNotNull(array)
|
||||
|
||||
assertEquals("initial", getContent(s.ptr)?.toKString())
|
||||
setContent(s.ptr, "yo")
|
||||
val ptr = getContent(s.ptr)
|
||||
assertEquals("yo", ptr?.toKString())
|
||||
|
||||
assertEquals(0.0, getDouble(u.ptr))
|
||||
setDouble(u.ptr, Double.MIN_VALUE)
|
||||
assertEquals(Double.MIN_VALUE, getDouble(u.ptr))
|
||||
|
||||
for (i in 0 until arrayLength()) {
|
||||
assertEquals(0x0, array[i])
|
||||
}
|
||||
setArrayValue(array, 0x1)
|
||||
for (i in 0 until arrayLength()) {
|
||||
assertEquals(0x1, array[i])
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
strictEnums = bcm2835FunctionSelect
|
||||
---
|
||||
enum bcm2835FunctionSelect {
|
||||
BCM2835_GPIO_FSEL_INPT = 0x00, BCM2835_GPIO_FSEL_OUTP = 0x01, BCM2835_GPIO_FSEL_ALT0 = 0x04, BCM2835_GPIO_FSEL_ALT1 = 0x05,
|
||||
BCM2835_GPIO_FSEL_ALT2 = 0x06, BCM2835_GPIO_FSEL_ALT3 = 0x07, BCM2835_GPIO_FSEL_ALT4 = 0x03, BCM2835_GPIO_FSEL_ALT5 = 0x02,
|
||||
BCM2835_GPIO_FSEL_MASK = 0x07
|
||||
};
|
||||
@@ -1,7 +0,0 @@
|
||||
import kt43265.*
|
||||
import kotlin.test.*
|
||||
|
||||
@kotlinx.cinterop.ExperimentalForeignApi
|
||||
fun main() {
|
||||
assertEquals(bcm2835FunctionSelect.BCM2835_GPIO_FSEL_ALT3, bcm2835FunctionSelect.BCM2835_GPIO_FSEL_MASK)
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
---
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
typedef struct {
|
||||
int d;
|
||||
} TestStruct;
|
||||
|
||||
typedef struct {
|
||||
void (*f)(TestStruct data);
|
||||
} ThreadData;
|
||||
|
||||
void *dispatch(void *rawArg) {
|
||||
ThreadData *arg = rawArg;
|
||||
arg->f((TestStruct) {.d = 1});
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void invokeFromThread(void (*f)(TestStruct data)) {
|
||||
pthread_t thread_id;
|
||||
ThreadData *threadData = malloc(sizeof(ThreadData));
|
||||
threadData->f = f;
|
||||
pthread_create(&thread_id, NULL, dispatch, (void *) threadData);
|
||||
pthread_join(thread_id, NULL);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
#define KFILE "FILE:" __FILE__
|
||||
#define KLINE "LINE:" __LINE__
|
||||
#define KTIME "TIME:" __TIME__
|
||||
#define KDATE "DATE:" __DATE__
|
||||
#define KFILENAME "NAME:" __FILE_NAME__
|
||||
#define KBASEFILE "BASE:" __BASE_FILE__
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
compilerOpts = -fmodules
|
||||
---
|
||||
#define KFILE "FILE:" __FILE__
|
||||
#define KLINE "LINE:" __LINE__
|
||||
#define KTIME "TIME:" __TIME__
|
||||
#define KDATE "DATE:" __DATE__
|
||||
#define KFILENAME "NAME:" __FILE_NAME__
|
||||
#define KBASEFILE "BASE:" __BASE_FILE__
|
||||
@@ -1,2 +0,0 @@
|
||||
language = Objective-C
|
||||
headers = kt63048.h
|
||||
@@ -1,7 +0,0 @@
|
||||
#import "Foundation/NSString.h"
|
||||
#import "Foundation/NSObject.h"
|
||||
|
||||
@interface WithClassProperty : NSObject
|
||||
-(instancetype) init;
|
||||
@property (class, readonly, copy) NSString * stringProperty;
|
||||
@end
|
||||
@@ -1,6 +0,0 @@
|
||||
#import "kt63048.h"
|
||||
|
||||
@implementation WithClassProperty : NSObject
|
||||
-(instancetype) init {}
|
||||
+ (NSString *) stringProperty { return @"153"; }
|
||||
@end
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
#include "leakMemoryWithRunningThreadUnchecked.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
extern "C" void test_RunInNewThread(void (*f)()) {
|
||||
std::atomic<bool> haveRun(false);
|
||||
std::thread t([f, &haveRun]() {
|
||||
f();
|
||||
haveRun = true;
|
||||
while (true) {}
|
||||
});
|
||||
t.detach();
|
||||
while (!haveRun) {}
|
||||
}
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
package leakMemoryWithRunningThreadUnchecked
|
||||
|
||||
---
|
||||
|
||||
void test_RunInNewThread(void (*)());
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void test_RunInNewThread(void (*)());
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
const char* empty() { return ""; }
|
||||
const char* foo() { return "foo"; }
|
||||
const char* kuku() { return "куку"; }
|
||||
const char* invalid_utf8() { return "\x85\xAF"; }
|
||||
const char* zero_in_the_middle() { return "before zero\0after zero"; }
|
||||
+15
-1
@@ -1,6 +1,20 @@
|
||||
// MODULE: cinterop
|
||||
// FILE: carrayPointers.def
|
||||
---
|
||||
int (*arrayPointer)[1];
|
||||
|
||||
int globalArray[3] = {1, 2, 3};
|
||||
|
||||
struct StructWithArrayPtr {
|
||||
int (*arrayPointer)[1];
|
||||
};
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import arrayPointers.*
|
||||
import carrayPointers.*
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// FREE_CINTEROP_ARGS: -header auxiliaryCppSources.h
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: auxiliaryCppSources.def
|
||||
# The def file is intentionally empty
|
||||
# `auxiliaryCppSources.h` is meant to be included via `-header` free arg of cinterop tool
|
||||
|
||||
// FILE: auxiliaryCppSources.h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const char* name();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// FILE: auxiliaryCppSources.cpp
|
||||
#include <string>
|
||||
#include "auxiliaryCppSources.h"
|
||||
|
||||
static std::string _name = "Hello from C++";
|
||||
|
||||
const char* name() {
|
||||
return _name.c_str();
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import auxiliaryCppSources.*
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
fun main() {
|
||||
assertEquals(name()!!.toKString(), "Hello from C++")
|
||||
}
|
||||
+36
@@ -4,6 +4,42 @@
|
||||
*/
|
||||
// May need disabling when gcSchedulerType=aggressive . since it may be too slow
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: bitfields.def
|
||||
---
|
||||
enum B2 {
|
||||
ZERO, ONE, TWO, THREE
|
||||
};
|
||||
|
||||
enum E : short {
|
||||
A, B
|
||||
};
|
||||
|
||||
struct __attribute__((packed)) S {
|
||||
long long x1 : 1;
|
||||
enum B2 x2 : 2;
|
||||
unsigned short x3 : 3;
|
||||
unsigned int x4 : 4;
|
||||
int x5 : 5;
|
||||
long long x6 : 63;
|
||||
enum E x7: 2;
|
||||
_Bool x8 : 1;
|
||||
struct { int x9:4; };
|
||||
};
|
||||
|
||||
static long long getX1(struct S* s) { return s->x1; }
|
||||
static enum B2 getX2(struct S* s) { return s->x2; }
|
||||
static unsigned short getX3(struct S* s) { return s->x3; }
|
||||
static unsigned int getX4(struct S* s) { return s->x4; }
|
||||
static int getX5(struct S* s) { return s->x5; }
|
||||
static long long getX6(struct S* s) { return s->x6; }
|
||||
static enum E getX7(struct S* s) { return s->x7; }
|
||||
static _Bool getX8(struct S* s) { return s->x8; }
|
||||
static int getX9(struct S* s) { return s->x9; }
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import bitfields.*
|
||||
+82
-1
@@ -2,11 +2,92 @@
|
||||
* Copyright 2010-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
// MODULE: cinterop
|
||||
// FILE: ccallbacksAndVarargs.def
|
||||
---
|
||||
#include <stdarg.h>
|
||||
|
||||
struct S {
|
||||
int x;
|
||||
};
|
||||
|
||||
static int getX(struct S (*callback)(void)) {
|
||||
return callback().x;
|
||||
}
|
||||
|
||||
static void applyCallback(struct S s, void (*callback)(struct S)) {
|
||||
callback(s);
|
||||
}
|
||||
|
||||
static struct S makeS(int x, ...) {
|
||||
return (struct S){ x };
|
||||
}
|
||||
|
||||
enum E {
|
||||
ZERO, ONE, TWO
|
||||
};
|
||||
|
||||
static enum E makeE(int ordinal, ...) {
|
||||
return ordinal;
|
||||
}
|
||||
|
||||
struct Args {
|
||||
char a1;
|
||||
char a2;
|
||||
short a3;
|
||||
int a4;
|
||||
long long a5;
|
||||
float a6;
|
||||
double a7;
|
||||
void* a8;
|
||||
unsigned char a9;
|
||||
unsigned short a10;
|
||||
unsigned int a11;
|
||||
unsigned long long a12;
|
||||
enum E a13;
|
||||
struct S a14;
|
||||
void* a15;
|
||||
};
|
||||
|
||||
static struct Args getVarargs(int ignore, ...) {
|
||||
va_list args;
|
||||
va_start(args, ignore);
|
||||
|
||||
struct Args result = {
|
||||
va_arg(args, char),
|
||||
va_arg(args, char),
|
||||
va_arg(args, short),
|
||||
va_arg(args, int),
|
||||
va_arg(args, long long),
|
||||
va_arg(args, double),
|
||||
va_arg(args, double),
|
||||
va_arg(args, void*),
|
||||
va_arg(args, unsigned char),
|
||||
va_arg(args, unsigned short),
|
||||
va_arg(args, unsigned int),
|
||||
va_arg(args, unsigned long long),
|
||||
va_arg(args, enum E),
|
||||
va_arg(args, struct S),
|
||||
va_arg(args, void*)
|
||||
};
|
||||
|
||||
va_end(args);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int sum(int first, int second) {
|
||||
return first + second;
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.*
|
||||
import callbacksAndVarargs.*
|
||||
import ccallbacksAndVarargs.*
|
||||
|
||||
fun main() {
|
||||
testStructCallbacks()
|
||||
+11
-1
@@ -2,10 +2,20 @@
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
// MODULE: cinterop
|
||||
// FILE: cenums.def
|
||||
---
|
||||
enum E {
|
||||
A, B, C
|
||||
};
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
// !LANGUAGE: +EnumEntries
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import enums.*
|
||||
import cenums.*
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
|
||||
+20
-1
@@ -1,7 +1,26 @@
|
||||
// This test mostly checks frontend behaviour.
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: cForwardDeclarations.def
|
||||
---
|
||||
struct StructDeclared;
|
||||
struct StructDefined { int x; };
|
||||
|
||||
int useStructDeclared(struct StructDeclared* declared) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int useStructDefined(struct StructDefined* defined) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import forwardDeclarations.*
|
||||
import cForwardDeclarations.*
|
||||
import cnames.structs.StructDeclared
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
@@ -0,0 +1,149 @@
|
||||
// OUTPUT_DATA_FILE: funptr.out
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: cfunptr.def
|
||||
headerFilter = NOTHING
|
||||
---
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef int (*atoiPtrType)(const char*);
|
||||
|
||||
static atoiPtrType getAtoiPtr() {
|
||||
return &atoi;
|
||||
}
|
||||
|
||||
static void __printInt(int x) {
|
||||
printf("%d\n", x);
|
||||
}
|
||||
|
||||
static void* __getPrintIntPtr() {
|
||||
return &__printInt;
|
||||
}
|
||||
|
||||
typedef void* (*getPrintIntPtrPtrType)(void);
|
||||
|
||||
static getPrintIntPtrPtrType getGetPrintIntPtrPtr() {
|
||||
return &__getPrintIntPtr;
|
||||
}
|
||||
|
||||
static double __add(double x, double y) {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
typedef double (*addPtrType)(double, double);
|
||||
|
||||
static addPtrType getAddPtr() {
|
||||
return &__add;
|
||||
}
|
||||
|
||||
static int __doubleToInt(double x) {
|
||||
return (int) x;
|
||||
}
|
||||
|
||||
typedef int (*doubleToIntPtrType)(double);
|
||||
|
||||
static doubleToIntPtrType getDoubleToIntPtr() {
|
||||
return &__doubleToInt;
|
||||
}
|
||||
|
||||
static _Bool __isIntPositive(int x) {
|
||||
return x > 0;
|
||||
}
|
||||
|
||||
typedef _Bool (*isIntPositivePtrType)(int);
|
||||
|
||||
static isIntPositivePtrType getIsIntPositivePtr() {
|
||||
return &__isIntPositive;
|
||||
}
|
||||
|
||||
static unsigned int getMaxUInt(void) {
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
static typeof(&getMaxUInt) getMaxUIntGetter() {
|
||||
return &getMaxUInt;
|
||||
}
|
||||
|
||||
typedef int (*longSignatureFunctionPtrType)(
|
||||
int, int, int, int, int, int, int, int, int, int, int, int,
|
||||
int, int, int, int, int, int, int, int, int, int, int
|
||||
);
|
||||
|
||||
typedef int (*notSoLongSignatureFunctionPtrType)(
|
||||
int, int, int, int, int, int, int, int, int, int, int,
|
||||
int, int, int, int, int, int, int, int, int, int, int
|
||||
);
|
||||
|
||||
static int longSignatureFunction(
|
||||
int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, int p9, int p10, int p11, int p12,
|
||||
int p13, int p14, int p15, int p16, int p17, int p18, int p19, int p20, int p21, int p22, int p23
|
||||
) {
|
||||
return 42;
|
||||
}
|
||||
|
||||
static int notSoLongSignatureFunction(
|
||||
int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, int p9, int p10, int p11, int p12,
|
||||
int p13, int p14, int p15, int p16, int p17, int p18, int p19, int p20, int p21, int p22
|
||||
) {
|
||||
return 42;
|
||||
}
|
||||
|
||||
static longSignatureFunctionPtrType getLongSignatureFunctionPtr() {
|
||||
return &longSignatureFunction;
|
||||
}
|
||||
|
||||
static notSoLongSignatureFunctionPtrType getNotSoLongSignatureFunctionPtr() {
|
||||
return ¬SoLongSignatureFunction;
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import cfunptr.*
|
||||
import kotlin.test.*
|
||||
|
||||
typealias NotSoLongSignatureFunction = (
|
||||
Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int,
|
||||
Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int
|
||||
) -> Int
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val atoiPtr = getAtoiPtr()!!
|
||||
|
||||
val getPrintIntPtrPtr = getGetPrintIntPtrPtr()!!
|
||||
val printIntPtr = getPrintIntPtrPtr()!!.reinterpret<CFunction<(Int) -> Unit>>()
|
||||
|
||||
val fortyTwo = memScoped {
|
||||
atoiPtr("42".cstr.getPointer(memScope))
|
||||
}
|
||||
|
||||
printIntPtr(fortyTwo)
|
||||
|
||||
printIntPtr(
|
||||
getDoubleToIntPtr()!!(
|
||||
getAddPtr()!!(5.1, 12.2)
|
||||
)
|
||||
)
|
||||
|
||||
val isIntPositivePtr = getIsIntPositivePtr()!!
|
||||
|
||||
printIntPtr(isIntPositivePtr(42).ifThenOneElseZero())
|
||||
printIntPtr(isIntPositivePtr(-42).ifThenOneElseZero())
|
||||
|
||||
assertEquals(getMaxUIntGetter()!!(), UInt.MAX_VALUE)
|
||||
|
||||
val longSignaturePtr: COpaquePointer? = getLongSignatureFunctionPtr()
|
||||
val notSoLongSignaturePtr: CPointer<CFunction<NotSoLongSignatureFunction>>? = getNotSoLongSignatureFunctionPtr()
|
||||
printIntPtr(notSoLongSignaturePtr!!.invoke(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
|
||||
printIntPtr(notSoLongSignatureFunction(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
fun Boolean.ifThenOneElseZero() = if (this) 1 else 0
|
||||
+41
-1
@@ -2,10 +2,50 @@
|
||||
* Copyright 2010-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: cglobals.def
|
||||
---
|
||||
const int g1 = 42;
|
||||
|
||||
int g2 = 17;
|
||||
|
||||
struct S {
|
||||
int x;
|
||||
} g3 = { 128 };
|
||||
|
||||
int g4[2] = { 13, 14 };
|
||||
|
||||
int g5[2][2] = { 15, 16, 17, 18 };
|
||||
|
||||
struct S* const g6 = &g3;
|
||||
|
||||
void foo() {
|
||||
// Test that local vars are not treated as global ones.
|
||||
float g1;
|
||||
}
|
||||
|
||||
// Test non-compilable variable:
|
||||
typedef int MyInt;
|
||||
MyInt g7;
|
||||
#define g7 bad macro
|
||||
|
||||
// Test property name mangling:
|
||||
struct g1 {};
|
||||
struct g1_ {};
|
||||
|
||||
typedef void* voidptr;
|
||||
_Pragma("clang assume_nonnull begin")
|
||||
const voidptr g8 = 0x1, g9 = 0x2;
|
||||
_Pragma("clang assume_nonnull end")
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class, kotlin.experimental.ExperimentalNativeApi::class)
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import globals.*
|
||||
import cglobals.*
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
assert(g1__ == 42)
|
||||
@@ -0,0 +1,122 @@
|
||||
// FREE_CINTEROP_ARGS: -header library.h
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: library.def
|
||||
# The def file is intentionally empty
|
||||
# `library.h` is meant to be included via `-header` option of cinterop tool
|
||||
|
||||
// FILE: library.h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Forward declaration.
|
||||
struct S;
|
||||
extern struct S s;
|
||||
|
||||
const char* getContent(struct S* s);
|
||||
void setContent(struct S* s, const char* name);
|
||||
|
||||
union U;
|
||||
extern union U u;
|
||||
|
||||
double getDouble(union U* u);
|
||||
void setDouble(union U* u, double value);
|
||||
|
||||
// Global array of unknown size.
|
||||
extern char array[];
|
||||
|
||||
|
||||
int arrayLength();
|
||||
void setArrayValue(char* array, char value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// FILE: library.cpp
|
||||
#include <string>
|
||||
#include "library.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
struct S {
|
||||
std::string name;
|
||||
};
|
||||
|
||||
S s = {
|
||||
.name = "initial"
|
||||
};
|
||||
|
||||
void setContent(struct S* s, const char* name) {
|
||||
// Note that copy here is intentional: we use it as a workaround
|
||||
// for short lifetime of copy of the passed Kotlin string.
|
||||
s->name = name;
|
||||
}
|
||||
|
||||
const char* getContent(struct S* s) {
|
||||
return s->name.c_str();
|
||||
}
|
||||
|
||||
union U {
|
||||
float f;
|
||||
double d;
|
||||
};
|
||||
|
||||
void setDouble(union U* u, double value) {
|
||||
u->d = value;
|
||||
}
|
||||
|
||||
double getDouble(union U* u) {
|
||||
return u->d;
|
||||
}
|
||||
|
||||
union U u = {
|
||||
.d = 0.0
|
||||
};
|
||||
|
||||
char array[5] = { 0, 0, 0, 0, 0 };
|
||||
|
||||
void setArrayValue(char* array, char value) {
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
array[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
int arrayLength() {
|
||||
return sizeof(array) / sizeof(char);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import library.*
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
|
||||
fun main() {
|
||||
assertNotNull(s.ptr)
|
||||
assertNotNull(u.ptr)
|
||||
assertNotNull(array)
|
||||
|
||||
assertEquals("initial", getContent(s.ptr)?.toKString())
|
||||
setContent(s.ptr, "yo")
|
||||
val ptr = getContent(s.ptr)
|
||||
assertEquals("yo", ptr?.toKString())
|
||||
|
||||
assertEquals(0.0, getDouble(u.ptr))
|
||||
setDouble(u.ptr, Double.MIN_VALUE)
|
||||
assertEquals(Double.MIN_VALUE, getDouble(u.ptr))
|
||||
|
||||
for (i in 0 until arrayLength()) {
|
||||
assertEquals(0x0, array[i])
|
||||
}
|
||||
setArrayValue(array, 0x1)
|
||||
for (i in 0 until arrayLength()) {
|
||||
assertEquals(0x1, array[i])
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// MODULE: cinterop
|
||||
// FILE: kt43265.def
|
||||
strictEnums = bcm2835FunctionSelect
|
||||
---
|
||||
enum bcm2835FunctionSelect {
|
||||
BCM2835_GPIO_FSEL_INPT = 0x00, BCM2835_GPIO_FSEL_OUTP = 0x01, BCM2835_GPIO_FSEL_ALT0 = 0x04, BCM2835_GPIO_FSEL_ALT1 = 0x05,
|
||||
BCM2835_GPIO_FSEL_ALT2 = 0x06, BCM2835_GPIO_FSEL_ALT3 = 0x07, BCM2835_GPIO_FSEL_ALT4 = 0x03, BCM2835_GPIO_FSEL_ALT5 = 0x02,
|
||||
BCM2835_GPIO_FSEL_MASK = 0x07
|
||||
};
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
import kt43265.*
|
||||
import kotlin.test.*
|
||||
|
||||
@kotlinx.cinterop.ExperimentalForeignApi
|
||||
fun main() {
|
||||
assertEquals(bcm2835FunctionSelect.BCM2835_GPIO_FSEL_ALT3, bcm2835FunctionSelect.BCM2835_GPIO_FSEL_MASK)
|
||||
}
|
||||
+31
@@ -1,3 +1,34 @@
|
||||
// MODULE: cinterop
|
||||
// FILE: kt44283.def
|
||||
---
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
typedef struct {
|
||||
int d;
|
||||
} TestStruct;
|
||||
|
||||
typedef struct {
|
||||
void (*f)(TestStruct data);
|
||||
} ThreadData;
|
||||
|
||||
void *dispatch(void *rawArg) {
|
||||
ThreadData *arg = rawArg;
|
||||
arg->f((TestStruct) {.d = 1});
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void invokeFromThread(void (*f)(TestStruct data)) {
|
||||
pthread_t thread_id;
|
||||
ThreadData *threadData = malloc(sizeof(ThreadData));
|
||||
threadData->f = f;
|
||||
pthread_create(&thread_id, NULL, dispatch, (void *) threadData);
|
||||
pthread_join(thread_id, NULL);
|
||||
}
|
||||
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class)
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
+14
@@ -1,3 +1,17 @@
|
||||
// MODULE: cinterop
|
||||
// FILE: kt54284.def
|
||||
---
|
||||
#define KFILE "FILE:" __FILE__
|
||||
#define KLINE "LINE:" __LINE__
|
||||
#define KTIME "TIME:" __TIME__
|
||||
#define KDATE "DATE:" __DATE__
|
||||
#define KFILENAME "NAME:" __FILE_NAME__
|
||||
#define KBASEFILE "BASE:" __BASE_FILE__
|
||||
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import kt54284.*
|
||||
import kotlin.test.*
|
||||
+14
@@ -1,3 +1,17 @@
|
||||
// MODULE: cinterop
|
||||
// FILE: kt54284_fmodules.def
|
||||
compilerOpts = -fmodules
|
||||
---
|
||||
#define KFILE "FILE:" __FILE__
|
||||
#define KLINE "LINE:" __LINE__
|
||||
#define KTIME "TIME:" __TIME__
|
||||
#define KDATE "DATE:" __DATE__
|
||||
#define KFILENAME "NAME:" __FILE_NAME__
|
||||
#define KBASEFILE "BASE:" __BASE_FILE__
|
||||
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
import kotlinx.cinterop.*
|
||||
import kt54284_fmodules.*
|
||||
import kotlin.test.*
|
||||
+26
@@ -1,3 +1,29 @@
|
||||
// MODULE: cinterop
|
||||
// FILE: kt63048.def
|
||||
language = Objective-C
|
||||
headers = kt63048.h
|
||||
|
||||
// FILE: kt63048.h
|
||||
#import "Foundation/NSString.h"
|
||||
#import "Foundation/NSObject.h"
|
||||
|
||||
@interface WithClassProperty : NSObject
|
||||
-(instancetype) init;
|
||||
@property (class, readonly, copy) NSString * stringProperty;
|
||||
@end
|
||||
|
||||
|
||||
// FILE: kt63048.m
|
||||
#import "kt63048.h"
|
||||
|
||||
@implementation WithClassProperty : NSObject
|
||||
-(instancetype) init {}
|
||||
+ (NSString *) stringProperty { return @"153"; }
|
||||
@end
|
||||
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class, kotlin.experimental.ExperimentalObjCName::class)
|
||||
|
||||
import kt63048.*
|
||||
+37
@@ -1,3 +1,40 @@
|
||||
// MODULE: cinterop
|
||||
// FILE: leakMemoryWithRunningThreadUnchecked.def
|
||||
package leakMemoryWithRunningThreadUnchecked
|
||||
---
|
||||
void test_RunInNewThread(void (*)());
|
||||
|
||||
// FILE: leakMemoryWithRunningThreadUnchecked.h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void test_RunInNewThread(void (*)());
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// FILE: leakMemoryWithRunningThreadUnchecked.cpp
|
||||
#include "leakMemoryWithRunningThreadUnchecked.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
extern "C" void test_RunInNewThread(void (*f)()) {
|
||||
std::atomic<bool> haveRun(false);
|
||||
std::thread t([f, &haveRun]() {
|
||||
f();
|
||||
haveRun = true;
|
||||
while (true) {}
|
||||
});
|
||||
t.detach();
|
||||
while (!haveRun) {}
|
||||
}
|
||||
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(
|
||||
kotlin.experimental.ExperimentalNativeApi::class,
|
||||
kotlin.native.runtime.NativeRuntimeApi::class,
|
||||
+12
@@ -1,3 +1,15 @@
|
||||
// MODULE: cinterop
|
||||
// FILE: toKString.def
|
||||
---
|
||||
const char* empty() { return ""; }
|
||||
const char* foo() { return "foo"; }
|
||||
const char* kuku() { return "куку"; }
|
||||
const char* invalid_utf8() { return "\x85\xAF"; }
|
||||
const char* zero_in_the_middle() { return "before zero\0after zero"; }
|
||||
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import toKString.*
|
||||
Reference in New Issue
Block a user