Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test types that use native.CArray #90

Merged
merged 5 commits into from
Jul 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions bindgen/TypeTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,10 @@ std::shared_ptr<Type> TypeTranslator::translate(const clang::QualType &qtpe,
if (typeEquals(tpe, avoid)) {
// This is a type that we want to avoid the usage.
// Êxample: A struct that has a pointer to itself
uint64_t size = ctx->getTypeSize(tpe);
uint64_t sizeInBits = ctx->getTypeSize(tpe);
assert(sizeInBits % 8 == 0);
return std::make_shared<ArrayType>(
std::make_shared<PrimitiveType>("Byte"), size);
std::make_shared<PrimitiveType>("Byte"), sizeInBits / 8);
}

if (tpe->isFunctionPointerType()) {
Expand Down
4 changes: 3 additions & 1 deletion bindgen/ir/IR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,9 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &s, const IR &ir) {
s << "object " << ir.libName << "Helpers {\n";

for (const auto &st : ir.structs) {
s << "\n" << st->generateHelperClass();
if (st->hasHelperMethods()) {
s << "\n" << st->generateHelperClass();
}
}

for (const auto &u : ir.unions) {
Expand Down
6 changes: 2 additions & 4 deletions bindgen/ir/Struct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,8 @@ std::shared_ptr<TypeDef> Struct::generateTypeDef() {
}

std::string Struct::generateHelperClass() const {
if (!hasHelperMethods()) {
/* struct is empty or represented as an array */
return "";
}
assert(hasHelperMethods());
/* struct is not empty and not represented as an array */
std::stringstream s;
std::string type = getAliasType();
s << " implicit class " << type << "_ops(val p: native.Ptr[" << type
Expand Down
10 changes: 6 additions & 4 deletions bindgen/visitor/TreeVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,9 @@ void TreeVisitor::handleUnion(clang::RecordDecl *record, std::string name) {
std::vector<Field *> fields;

for (const clang::FieldDecl *field : record->fields()) {
uint64_t sizeInBytes = astContext->getTypeSize(field->getType()) / 8;
maxSize = std::max(maxSize, sizeInBytes);
uint64_t sizeInBits = astContext->getTypeSize(field->getType());
assert(sizeInBits % 8 == 0);
maxSize = std::max(maxSize, sizeInBits / 8);
std::string fname = field->getNameAsString();
std::shared_ptr<Type> ftype =
typeTranslator.translate(field->getType(), &name);
Expand Down Expand Up @@ -152,9 +153,10 @@ void TreeVisitor::handleStruct(clang::RecordDecl *record, std::string name) {
llvm::errs().flush();
}

uint64_t sizeInBits = astContext->getTypeSize(record->getTypeForDecl());
assert(sizeInBits % 8 == 0);
std::shared_ptr<Type> alias =
ir.addStruct(name, std::move(fields),
astContext->getTypeSize(record->getTypeForDecl()));
ir.addStruct(name, std::move(fields), sizeInBits / 8);

typeTranslator.addAlias("struct " + name, alias);
}
Expand Down
10 changes: 10 additions & 0 deletions tests/samples/Struct.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,13 @@ point_s getPoint() {
point->y = 20;
return point;
}

int getBigStructSize() { return sizeof(struct bigStruct); }

char getCharFromAnonymousStruct(struct structWithAnonymousStruct *s) {
return s->anonymousStruct.c;
}

char getIntFromAnonymousStruct(struct structWithAnonymousStruct *s) {
return s->anonymousStruct.i;
}
40 changes: 40 additions & 0 deletions tests/samples/Struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,43 @@ struct point {
typedef struct point *point_s;

point_s getPoint();

struct bigStruct {
long one;
char two;
int three;
float four;
double five;
point_s six;
int seven;
int eight;
int nine;
int ten;
int eleven;
int twelve;
int thirteen;
int fourteen;
int fifteen;
int sixteen;
int seventeen;
int eighteen;
int nineteen;
int twenty;
int twentyOne;
int twentyTwo;
int twentyThree;
};

int getBigStructSize();

struct structWithAnonymousStruct {
int a;
struct {
char c;
int i;
} anonymousStruct;
};

char getCharFromAnonymousStruct(struct structWithAnonymousStruct *s);

char getIntFromAnonymousStruct(struct structWithAnonymousStruct *s);
14 changes: 14 additions & 0 deletions tests/samples/Struct.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ import scala.scalanative.native._
object Struct {
type struct_point = native.CStruct2[native.CInt, native.CInt]
type point_s = native.Ptr[struct_point]
type struct_bigStruct = native.CArray[Byte, native.Nat.Digit[native.Nat._1, native.Nat.Digit[native.Nat._1, native.Nat._2]]]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, so this doesn't the helper with getters and setters. We should probably create a ticket for that.

type struct_structWithAnonymousStruct = native.CStruct2[native.CInt, native.CArray[Byte, native.Nat._8]]
def getPoint(): native.Ptr[struct_point] = native.extern
def getBigStructSize(): native.CInt = native.extern
def getCharFromAnonymousStruct(s: native.Ptr[struct_structWithAnonymousStruct]): native.CChar = native.extern
def getIntFromAnonymousStruct(s: native.Ptr[struct_structWithAnonymousStruct]): native.CChar = native.extern
}

import Struct._
Expand All @@ -23,4 +28,13 @@ object StructHelpers {
}

def struct_point()(implicit z: native.Zone): native.Ptr[struct_point] = native.alloc[struct_point]

implicit class struct_structWithAnonymousStruct_ops(val p: native.Ptr[struct_structWithAnonymousStruct]) extends AnyVal {
def a: native.CInt = !p._1
def a_=(value: native.CInt):Unit = !p._1 = value
def anonymousStruct: native.CArray[Byte, native.Nat._8] = !p._2
def anonymousStruct_=(value: native.CArray[Byte, native.Nat._8]):Unit = !p._2 = value
}

def struct_structWithAnonymousStruct()(implicit z: native.Zone): native.Ptr[struct_structWithAnonymousStruct] = native.alloc[struct_structWithAnonymousStruct]
}
2 changes: 2 additions & 0 deletions tests/samples/Union.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
void setIntValue(union values *v) { v->i = 10; }

void setLongValue(union values *v) { v->l = 10000000000; }

int getUnionSize() { return sizeof(union values); }
2 changes: 2 additions & 0 deletions tests/samples/Union.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ union values {
void setIntValue(union values *v);

void setLongValue(union values *v);

int getUnionSize();
1 change: 1 addition & 0 deletions tests/samples/Union.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ object Union {
type union_values = native.CArray[Byte, native.Nat._8]
def setIntValue(v: native.Ptr[union_values]): Unit = native.extern
def setLongValue(v: native.Ptr[union_values]): Unit = native.extern
def getUnionSize(): native.CInt = native.extern
}

import Union._
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.scalanative.bindgen.samples

import utest._
import scala.scalanative.native._
import org.scalanative.bindgen.samples.StructHelpers._

object StructTests extends TestSuite {
Expand All @@ -9,6 +10,29 @@ object StructTests extends TestSuite {
val point = Struct.getPoint()
assert(point.x == 10)
assert(point.y == 20)

point.x_=(11)
assert(point.x == 11)
}

'bigStructSize - {
assert(Struct.getBigStructSize() == sizeof[Struct.struct_bigStruct])
}

'innerAnonymousStruct - {
type struct_anonymousStruct = CStruct2[CChar, CInt]
Zone { implicit zone =>
val anonymousStruct: Ptr[struct_anonymousStruct] = alloc[struct_anonymousStruct]
!anonymousStruct._1 = 'a'
!anonymousStruct._2 = 42

val structWithAnonymousStruct = struct_structWithAnonymousStruct()
val array = anonymousStruct.cast[Ptr[CArray[Byte, Nat._8]]]
!structWithAnonymousStruct._2 = !array

assert('a' == Struct.getCharFromAnonymousStruct(structWithAnonymousStruct))
assert(42 == Struct.getIntFromAnonymousStruct(structWithAnonymousStruct))
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ object UnionTests extends TestSuite {
val tests = Tests {
'getValues - {
Zone {implicit zone =>
val structPtr = alloc[Union.union_values]
Union.setIntValue(structPtr)
assert(!structPtr.i == 10)
Union.setLongValue(structPtr)
assert(!structPtr.l == 10000000000L)
val unionPtr = alloc[Union.union_values]
Union.setIntValue(unionPtr)
assert(!unionPtr.i == 10)
Union.setLongValue(unionPtr)
assert(!unionPtr.l == 10000000000L)
}
}

'unionSize - {
assert(Union.getUnionSize() == sizeof[Union.union_values])
}
}
}