Commit 7ee6a039 authored by Tommy Olofsson's avatar Tommy Olofsson
Browse files

Merge branch 'vx_c_copy' into vx

parents 05f371e2 695926ba
......@@ -40,9 +40,12 @@ aspect C_CodeGenEnv {
private int indent;
public final int depth;
private C_printer printer;
public final int nestedLevel;
private boolean rootIsPointer;
private int rootLevel;
private C_env(String qualid, String lcName, String rawPrefix,
int indent, int depth, C_printer printer) {
int indent, int depth, C_printer printer, int nestedLevel) {
this.qualid = qualid;
this.lcName = lcName;
this.rawPrefix = rawPrefix;
......@@ -54,6 +57,7 @@ aspect C_CodeGenEnv {
this.indent = indent;
this.depth = depth;
this.printer = printer;
this.nestedLevel = nestedLevel;
}
public C_env(String qualid, String lcName, String rawPrefix,
......@@ -69,16 +73,22 @@ aspect C_CodeGenEnv {
this.depth = 0;
this.indent = 0;
this.printer = new C_printer(out);
this.nestedLevel = 0;
}
public C_env(String qualid, String lcName, String rawPrefix,
int indent, int depth, C_printer printer) {
this(qualid, lcName, rawPrefix, indent, depth, printer, 0);
}
public C_env nestArray(String suffix) {
return new C_env(qualid + suffix, lcName, rawPrefix,
indent, depth + 1, printer);
indent, depth + 1, printer, nestedLevel + 1);
}
public C_env nestStruct(String suffix) {
return new C_env(qualid + suffix, lcName, rawPrefix,
indent, depth, printer);
indent, depth, printer, nestedLevel + 1);
}
public void indent() {
......@@ -101,6 +111,19 @@ aspect C_CodeGenEnv {
printer.println(this, s);
}
public C_env setPointer() {
rootIsPointer = true;
rootLevel = nestedLevel;
return this;
}
public String memberAccessor() {
return (rootIsPointer && (nestedLevel == rootLevel)) ? "->" : ".";
}
public String accessor() {
return (rootIsPointer && (nestedLevel == rootLevel)) ? "*" : "";
}
}
public C_env ArrayType.C_Nest(C_env env) {
......@@ -110,7 +133,7 @@ aspect C_CodeGenEnv {
}
public C_env FixedArrayType.C_Nest(C_env env) {
String index = ".a";
String index = env.memberAccessor() + "a";
for (int i = 0 ; i < getNumExp() ; i++) {
index += "[i_" + env.depth + "_" + i + "]";
}
......@@ -118,7 +141,7 @@ aspect C_CodeGenEnv {
}
public C_env VariableArrayType.C_Nest(C_env env) {
return env.nestArray(".a[i_" + env.depth + "]");
return env.nestArray(env.memberAccessor() + "a[i_" + env.depth + "]");
}
......@@ -195,6 +218,8 @@ aspect C_CodeGen {
getDecl(i).C_emitDecoderDeclaration(env);
getDecl(i).C_emitEncoderDeclaration(env);
getDecl(i).C_emitSizeofDeclaration(env);
getDecl(i).C_emitCopyDeclaration(env);
getDecl(i).C_emitCopyDeallocationDeclaration(env);
env.println("");
}
C_emitConstructorDeclaration(env);
......@@ -211,6 +236,8 @@ aspect C_CodeGen {
getDecl(i).C_emitEncoderRegisterHandler(env);
getDecl(i).C_emitEncoderIoctl(env);
getDecl(i).C_emitSizeof(env);
getDecl(i).C_emitCopy(env);
getDecl(i).C_emitCopyDeallocation(env);
}
C_emitConstructor(env);
}
......@@ -405,7 +432,7 @@ aspect C_Limit {
}
public String VariableSize.C_getLimit(C_env env, int i) {
return env.qualid + ".n_" + i;
return env.qualid + env.memberAccessor() + "n_" + i;
}
}
......@@ -653,6 +680,259 @@ aspect C_Decoder {
}
aspect C_copy {
private void SampleDecl.C_emitCopyFunctionParam(C_env env_src, String src,
String dst)
{
env_src.println("void labcomm_copy_" + env_src.prefix + getName() + "(");
env_src.indent();
env_src.println("struct labcomm_memory *mem,");
env_src.println(env_src.prefix + getName() + " *" + dst + ",");
env_src.println(env_src.prefix + getName() + " *" + src);
env_src.unindent();
env_src.print(")");
}
public void Decl.C_emitCopyDeclaration(C_env env) {
}
public void SampleDecl.C_emitCopyDeclaration(C_env env) {
C_emitCopyFunctionParam(env, "src", "dst");
env.println(";");
}
public void Decl.C_emitCopy(C_env env) {
throw new Error(this.getClass().getName() +
".C_emitCopy(C_env env)" +
" not declared");
}
public void TypeDecl.C_emitCopy(C_env env) {
}
public void SampleDecl.C_emitCopy(C_env env) {
final String dst = "dst";
final String src = "src";
C_env env_src = env.nestStruct(src).setPointer();
C_env env_dst = env.nestStruct(dst).setPointer();
C_emitCopyFunctionParam(env_src, src, dst);
env_src.println("");
env_src.println("{");
env_src.indent();
getType().C_emitCopy(env_src, env_dst);
env_src.unindent();
env_src.println("}");
}
public void Type.C_emitCopy(C_env env_src, C_env env_dst) {
throw new Error(this.getClass().getName() +
".C_emitCopy(C_env env)" +
" not declared");
}
public void VoidType.C_emitCopy(C_env env_src, C_env env_dst) {
}
public void PrimType.C_emitCopy(C_env env_src, C_env env_dst) {
if (C_isDynamic()) {
env_src.println(String.format(
"%s%s = labcomm_memory_alloc(mem, 1, strlen(%s%s)+1);",
env_dst.accessor(), env_dst.qualid,
env_src.accessor(), env_src.qualid));
env_src.println(String.format(
"memcpy(%s%s, %s%s, strlen(%s%s)+1);",
env_dst.accessor(), env_dst.qualid,
env_src.accessor(), env_src.qualid,
env_src.accessor(), env_src.qualid));
} else {
env_src.println(env_dst.accessor() + env_dst.qualid + " = " +
env_src.accessor() + env_src.qualid + ";");
}
}
public void UserType.C_emitCopy(C_env env_src, C_env env_dst) {
lookupType(getName()).getType().C_emitCopy(env_src, env_dst);
}
public void StructType.C_emitCopy(C_env env_src, C_env env_dst) {
for (int i = 0 ; i < getNumField() ; i++) {
getField(i).C_emitCopy(env_src, env_dst);
}
}
public void ArrayType.C_emitCopy(C_env env_src, C_env env_dst) {
C_emitCopyDecodeLimit(env_src, env_dst);
C_emitCopyArrayAllocate(env_src, env_dst);
env_src.println("{");
env_src.indent();
C_emitLoopVariables(env_src);
for (int i = 0 ; i < getNumExp() ; i++) {
String iterator = "i_" + env_src.depth + "_" + i;
env_src.println("for (" + iterator + " = 0" +
" ; " +
iterator + " < " + getExp(i).C_getLimit(env_src, i) +
" ; " +
iterator + "++) {");
env_src.indent();
}
C_emitCalcIndex(env_src);
getType().C_emitCopy(C_Nest(env_src), C_Nest(env_dst));
for (int i = getNumExp() - 1 ; i >= 0 ; i--) {
env_src.unindent();
env_src.println("}");
}
env_src.unindent();
env_src.println("}");
}
public void Field.C_emitCopy(C_env env_src, C_env env_dst) {
String fnam = env_src.memberAccessor() + getName();
getType().C_emitCopy(env_src.nestStruct(fnam), env_dst.nestStruct(fnam));
}
public void Exp.C_emitCopyDecodeLimit(C_env env_src, C_env env_dst, int i) {
// Ordinary array has no length-member.
}
public void VariableSize.C_emitCopyDecodeLimit(C_env env_src, C_env env_dst, int i) {
String src = env_src.qualid + env_src.memberAccessor() + "n_" + i;
String dst = env_dst.qualid + env_dst.memberAccessor() + "n_" + i;
env_src.println(dst + " = " + src + ";");
}
public void ArrayType.C_emitCopyDecodeLimit(C_env env_src, C_env env_dst) {
for (int i = 0 ; i < getNumExp() ; i++) {
getExp(i).C_emitCopyDecodeLimit(env_src, env_dst, i);
}
}
public void ArrayType.C_emitCopyArrayAllocate(C_env env_src, C_env env_dst) {
}
public void VariableArrayType.C_emitCopyArrayAllocate(C_env env_src,
C_env env_dst)
{
env_src.print(env_dst.qualid + env_dst.memberAccessor() +
"a = labcomm_memory_alloc(mem, 1, sizeof(" +
env_src.qualid + env_src.memberAccessor() + "a[0])");
for (int i = 0 ; i < getNumExp() ; i++) {
env_src.print(" * " + getExp(i).C_getLimit(env_src, i));
}
env_dst.println(");");
}
// Code for deallocation of dynamically allocated data in a copy.
private void SampleDecl.C_emitCopyDeallocationFunctionParam(C_env env,
String par)
{
env.println("void labcomm_copy_free_" + env.prefix + getName() + "(");
env.indent();
env.println("struct labcomm_memory *mem,");
env.println(env.prefix + getName() + " *" + par);
env.unindent();
env.print(")");
}
public void Decl.C_emitCopyDeallocationDeclaration(C_env env) {
}
public void SampleDecl.C_emitCopyDeallocationDeclaration(C_env env) {
C_emitCopyDeallocationFunctionParam(env, "c");
env.println(";");
}
public void Decl.C_emitCopyDeallocation(C_env env) {
throw new Error(this.getClass().getName() +
".C_emitCopy(C_env env)" +
" not declared");
}
public void TypeDecl.C_emitCopyDeallocation(C_env env) {
}
public void SampleDecl.C_emitCopyDeallocation(C_env env) {
String par = "par";
env = env.nestStruct(par).setPointer();
C_emitCopyDeallocationFunctionParam(env, par);
env.println("");
env.println("{");
env.indent();
getType().C_emitCopyDeallocation(env);
env.unindent();
env.println("}");
}
public void Type.C_emitCopyDeallocation(C_env env) {
throw new Error(this.getClass().getName() +
".C_emitCopyDeallocation(C_env env)" +
" not declared");
}
public void VoidType.C_emitCopyDeallocation(C_env env) {
}
public void PrimType.C_emitCopyDeallocation(C_env env) {
if (C_isDynamic()) {
env.println("labcomm_memory_free(mem, 1, " +
env.accessor() + env.qualid + ");");
}
}
public void UserType.C_emitCopyDeallocation(C_env env) {
if (C_isDynamic()) {
lookupType(getName()).getType().C_emitCopyDeallocation(env);
}
}
public void StructType.C_emitCopyDeallocation(C_env env) {
if (C_isDynamic()) {
for (int i = 0 ; i < getNumField() ; i++) {
getField(i).C_emitCopyDeallocation(env);
}
}
}
public void ArrayType.C_emitCopyDeallocation(C_env env) {
if (getType().C_isDynamic()) {
env.println("{");
env.indent();
C_emitLoopVariables(env);
for (int i = 0 ; i < getNumExp() ; i++) {
String iterator = "i_" + env.depth + "_" + i;
env.println("for (" + iterator + " = 0" +
" ; " +
iterator + " < " + getExp(i).C_getLimit(env, i) +
" ; " +
iterator + "++) {");
env.indent();
}
C_emitCalcIndex(env);
getType().C_emitCopyDeallocation(C_Nest(env));
for (int i = 0 ; i < getNumExp() ; i++) {
env.unindent();
env.println("}");
}
env.unindent();
env.println("}");
}
}
public void VariableArrayType.C_emitCopyDeallocation(C_env env) {
super.C_emitCopyDeallocation(env);
env.println("labcomm_memory_free(mem, 1, " +
env.qualid + env.memberAccessor() + "a);");
}
public void Field.C_emitCopyDeallocation(C_env env) {
getType().C_emitCopyDeallocation(env.nestStruct(env.memberAccessor()
+ getName()));
}
}
aspect C_DecoderIoctl {
public void Decl.C_emitDecoderIoctl(C_env env) {
......
.PHONY: all
all:
echo To be done...
$(MAKE) -C twoway all
......
......@@ -5,10 +5,12 @@ java -jar ../../compiler/labComm.jar --java=gen --c=gen/simple.c --h=gen/simple.
javac -cp ../../lib/java:. gen/*.java Encoder.java Decoder.java
gcc -Wall -Werror -I. -I../../lib/c -L../../lib/c \
gcc -Wall -Werror -Wno-unused-function \
-I. -I../../lib/c -L../../lib/c \
-o example_encoder example_encoder.c gen/simple.c \
-llabcomm -Tlabcomm.linkscript
gcc -Wall -Werror -I . -I ../../lib/c -L../../lib/c \
gcc -Wall -Werror -Wno-unused-function \
-I . -I ../../lib/c -L../../lib/c \
-o example_decoder example_decoder.c gen/simple.c \
-llabcomm -Tlabcomm.linkscript
......
......@@ -2,7 +2,7 @@ TARGETS=client server
LABCOMM_JAR=../../compiler/labComm.jar
LABCOMM=java -jar $(LABCOMM_JAR)
CFLAGS=-O3 -g -Wall -Werror -I../../lib/c -I.
CFLAGS=-O3 -g -Wall -Werror -I../../lib/c -I. -Wno-unused-function
all: $(TARGETS:%=gen/%)
......
......@@ -18,6 +18,13 @@ else ifeq ($(UNAME_S),Darwin)
LDFLAGS=-L.
LDLIBS=-llabcomm
MAKESHARED=clang -o $1 -shared -Wl,-install_name,$2 $3 -lc
else ifneq ($(findstring CYGWIN,$(UNAME_S)),)
CFLAGS=-std=c99 -g -Wall -Werror -O3 -I. -Itest
CC=$(CROSS_COMPILE)gcc
LD=$(CROSS_COMPILE)ld
LDFLAGS=-L.
LDLIBS=-llabcomm -lrt
ALL_DEPS:=$(filter-out %.so.1, $(ALL_DEPS)) # No -fPIC supported in windows?
else
$(error Unknown system $(UNAME_S))
endif
......@@ -49,6 +56,7 @@ TESTS=test_labcomm_basic_type_encoding test_labcomm_generated_encoding \
test_signature_numbers \
test_labcomm \
test_labcomm_pthread_scheduler \
test_labcomm_copy
#
#FIXME: test_labcomm test_labcomm_errors
TEST_DIR=test
......@@ -133,6 +141,7 @@ clean:
$(RM) test/testdata/gen/*.[cho]
$(RM) test/gen/*.[cho]
$(RM) $(TEST_DIR)/test_labcomm
$(RM) $(TEST_DIR)/test_labcomm_copy
distclean: clean
$(RM) liblabcomm.so.1
......@@ -150,6 +159,7 @@ $(TEST_DIR)/test_signature_numbers.c: $(TEST_DIR)/gen/another_encoding.h
$(TEST_DIR)/test_signature_numbers.c: $(TEST_DIR)/gen/generated_encoding.h
$(TEST_DIR)/test_signature_numbers: $(TEST_DIR)/gen/another_encoding.o
$(TEST_DIR)/test_signature_numbers: $(TEST_DIR)/gen/generated_encoding.o
$(TEST_DIR)/test_labcomm_copy: $(TEST_DIR)/gen/generated_encoding.o $(TEST_DIR)/gen/test_sample.o $(TEST_DIR)/gen/more_types.o
labcomm_fd_reader.o: labcomm_private.h
labcomm_fd_writer.o: labcomm_private.h
labcomm_dynamic_buffer_writer.o: labcomm_private.h
sample string S;
sample int A[8];
sample struct {
string s1;
string s2;
} NS;
sample string AS[_];
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <err.h>
#include "labcomm.h"
#include "labcomm_private.h"
#include "labcomm_default_error_handler.h"
#include "labcomm_default_memory.h"
#include "labcomm_default_scheduler.h"
#include "labcomm_fd_writer.h"
#include "labcomm_fd_reader.h"
#include "test/gen/generated_encoding.h"
#include "test/gen/test_sample.h"
#include "test/gen/more_types.h"
#define DATA_FILE "copy_test.dat"
static void handle_s1(generated_encoding_S1 *v, void *context)
{
labcomm_copy_generated_encoding_S1(labcomm_default_memory, context, v);
}
static void handle_b(generated_encoding_B *v, void *context)
{
labcomm_copy_generated_encoding_B(labcomm_default_memory, context, v);
}
static void handle_i(generated_encoding_I *v, void *context)
{
labcomm_copy_generated_encoding_I(labcomm_default_memory, context, v);
}
static void handle_p(generated_encoding_P *v, void *context)
{
labcomm_copy_generated_encoding_P(labcomm_default_memory, context, v);
}
static void handle_test_var(test_sample_test_var *v, void *context)
{
labcomm_copy_test_sample_test_var(labcomm_default_memory, context, v);
}
static void handle_a(more_types_A *v, void *context)
{
labcomm_copy_more_types_A(labcomm_default_memory, context, v);
}
static void handle_s(more_types_S *v, void *context)
{
labcomm_copy_more_types_S(labcomm_default_memory, context, v);
}
static void handle_ns(more_types_NS *v, void *context)
{
labcomm_copy_more_types_NS(labcomm_default_memory, context, v);
}
static void handle_as(more_types_AS *v, void *context)
{
labcomm_copy_more_types_AS(labcomm_default_memory, context, v);
}
int main(int argc, char **argv)
{
struct labcomm_encoder *encoder;
struct labcomm_decoder *decoder;
int fd;
generated_encoding_S1 s1;
generated_encoding_S1 cache_s1;
generated_encoding_B b;
generated_encoding_B cache_b;
generated_encoding_I I;
generated_encoding_I cache_I;
generated_encoding_P p;
generated_encoding_P cache_p;
test_sample_test_var test_var;
test_sample_test_var cache_test_var;
more_types_A a;
more_types_A cache_a;
more_types_S s;
more_types_S cache_s = NULL;
more_types_NS ns;
more_types_NS cache_ns;
more_types_AS as;
more_types_AS cache_as;
fd = open(DATA_FILE, O_RDWR | O_CREAT | O_TRUNC, 0644);
if (fd == -1)
err(1, "open()");
encoder =
labcomm_encoder_new(labcomm_fd_writer_new(labcomm_default_memory, fd, 0),
labcomm_default_error_handler,
labcomm_default_memory,
labcomm_default_scheduler);
labcomm_encoder_register_generated_encoding_S1(encoder);
s1.i = 1;
labcomm_encode_generated_encoding_S1(encoder, &s1);
labcomm_encoder_register_generated_encoding_B(encoder);
b = 2;
labcomm_encode_generated_encoding_B(encoder, &b);
labcomm_encoder_register_generated_encoding_I(encoder);
I.n_0 = 3;
I.a = calloc(I.n_0, sizeof(I.a[0]));
I.a[0] = 4;
I.a[1] = 5;
I.a[2] = 6;
labcomm_encode_generated_encoding_I(encoder, &I);
labcomm_encoder_register_generated_encoding_P(encoder);
p.n_0 = 7;
p.a = calloc(p.n_0, sizeof(p.a[0]));
for (int i = 0; i < p.n_0; i++)
p.a[i].i = 8 + i;
labcomm_encode_generated_encoding_P(encoder, &p);
labcomm_encoder_register_test_sample_test_var(encoder);
test_var.n_0 = 2;
test_var.n_1 = 7;
test_var.a = calloc(test_var.n_0 * test_var.n_1, sizeof(*test_var.a));
for (int i = 0; i < test_var.n_0; i++)
for (int j = 0; j < test_var.n_1; j++)
test_var.a[i] = 10 * i + j;
labcomm_encode_test_sample_test_var(encoder, &test_var);
labcomm_encoder_register_more_types_A(encoder);
for (int i = 0; i < sizeof(a.a) / sizeof(a.a[0]); i++)
a.a[i] = i;
labcomm_encode_more_types_A(encoder, &a);
labcomm_encoder_register_more_types_S(encoder);
s = "this is a string";
labcomm_encode_more_types_S(encoder, &s);
labcomm_encoder_register_more_types_NS(encoder);
ns.s1 = "this is a string";
ns.s2 = "this is a another string";
labcomm_encode_more_types_NS(encoder, &ns);
labcomm_encoder_register_more_types_AS(encoder);
as.n_0 = 3;
as.a = calloc(as.n_0, sizeof(as.a[0]));
as.a[0] = "string 0";
as.a[1] = "string 1";
as.a[2] = "string 2";
labcomm_encode_more_types_AS(encoder, &as);
labcomm_encoder_free(encoder);
encoder = NULL;
lseek(fd, 0, SEEK_SET);
decoder =
labcomm_decoder_new(labcomm_fd_reader_new(labcomm_default_memory, fd, 0),
labcomm_default_error_handler,
labcomm_default_memory,
labcomm_default_scheduler);
labcomm_decoder_register_generated_encoding_S1(decoder, handle_s1, &cache_s1);
labcomm_decoder_register_generated_encoding_B(decoder, handle_b, &cache_b);
labcomm_decoder_register_generated_encoding_I(decoder, handle_i, &cache_I);
labcomm_decoder_register_generated_encoding_P(decoder, handle_p, &cache_p);
labcomm_decoder_register_test_sample_test_var(decoder, handle_test_var,
&cache_test_var);
labcomm_decoder_register_more_types_A(decoder, handle_a, &cache_a);
labcomm_decoder_register_more_types_S(decoder, handle_s, &cache_s);
labcomm_decoder_register_more_types_NS(decoder, handle_ns, &cache_ns);
labcomm_decoder_register_more_types_AS(decoder, handle_as, &cache_as);
while (labcomm_decoder_decode_one(decoder) > 0) ;
assert(cache_s1.i == s1.i);
puts("S1 copied ok");
assert(cache_b == b);
puts("B copied ok");
assert(cache_I.n_0 == I.n_0);
assert(cache_I.a[0] == I.a[0]);
assert(cache_I.a[1] == I.a[1]);
assert(cache_I.a[2] == I.a[2]);
free(I.a);
puts("I copied ok");
assert(cache_p.n_0 == p.n_0);
for (int i = 0; i < p.n_0; i++)
assert(cache_p.a[i].i == p.a[i].i);
free(p.a);
puts("P copied ok");
assert(cache_test_var.n_0 == test_var.n_0);
assert(cache_test_var.n_1 == test_var.n_1);