Skip to content

Commit

Permalink
implementing changes from code review
Browse files Browse the repository at this point in the history
eliminated a hack created to ensure the result object wasn't cleaned up before Java could consume the results

implementing fixes suggested by chfast

added wrapper methods to EvmcVM and additional tests

removing gradle jar and wrapper.  Added a step to the Makefile and build.gradle to have it automatically download.  Updated Readme

removing evmc-vm.h from repo since it is auto-generated
  • Loading branch information
jrhea committed Dec 2, 2019
1 parent 04badb8 commit f37b69c
Show file tree
Hide file tree
Showing 20 changed files with 667 additions and 901 deletions.
15 changes: 14 additions & 1 deletion bindings/java/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,17 @@ c/build/*
*.dylib
.DS_Store
.gradle
build
build
.classpath
.project
.settings/
java/.classpath
java/.project
java/.settings/
java/bin/
java/hs_err_pid*
gradle/
gradlew
gradlew.bat
c/evmc-vm.h
*.class
22 changes: 0 additions & 22 deletions bindings/java/Dockerfile

This file was deleted.

23 changes: 14 additions & 9 deletions bindings/java/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ OS:=$(shell uname -s | tr '[:upper:]' '[:lower:]')
ifeq ($(OS), linux)
EXT:=so
OS_LFLAGS:=
JAVA_HOME:=$(shell readlink -f /usr/bin/javac | sed "s:/bin/javac::")
JAVA_HOME:=/usr/local/openjdk-11
else ifeq ($(OS), darwin)
EXT:=so
OS_LFLAGS:=-mmacosx-version-min=$(shell defaults read loginwindow SystemVersionStampAsString) -framework CoreFoundation -framework Security
Expand All @@ -17,26 +17,31 @@ CFLAGS = -O2 -fPIC
LFLAGS = -shared
OUT_DIR = ./c/build

build:
gradlew:
gradle setup

build: gradlew
mkdir -p $(OUT_DIR)
gcc $(DEBUG_FLAG) -c $(INCLUDES) -o $(OUT_DIR)/loader.o ../../lib/loader/loader.c
gcc $(DEBUG_FLAG) -c $(INCLUDES) $(JAVA_INCLUDES) -o $(OUT_DIR)/host.o ./c/host.c
gcc $(DEBUG_FLAG) ./c/evmc-vm.c $(INCLUDES) $(JAVA_INCLUDES) $(JAVA_LIBS) $(CFLAGS) $(LFLAGS) -o $(OUT_DIR)/evmc.$(EXT) $(OUT_DIR)/host.o $(OUT_DIR)/loader.o
javac ./java/src/main/java/org/ethereum/evmc/EvmcVm.java -h ./c --class-path ./java/src/main/java -s ./java/build
mv c/org_ethereum_evmc_EvmcVm.h c/evmc-vm.h
gcc $(DEBUG_FLAG) $(CFLAGS) -c $(INCLUDES) -o $(OUT_DIR)/loader.o ../../lib/loader/loader.c
gcc $(DEBUG_FLAG) $(CFLAGS) -c $(INCLUDES) $(JAVA_INCLUDES) -o $(OUT_DIR)/host.o ./c/host.c
gcc $(DEBUG_FLAG) $(CFLAGS) ./c/evmc-vm.c $(INCLUDES) $(JAVA_INCLUDES) $(JAVA_LIBS) $(CFLAGS) $(LFLAGS) -o $(OUT_DIR)/evmc.$(EXT) $(OUT_DIR)/host.o $(OUT_DIR)/loader.o
gcc $(DEBUG_FLAG) -shared ../../examples/example_vm/example_vm.c $(INCLUDES) -o $(OUT_DIR)/example_vm.$(EXT)
mkdir -p ./java/build
./gradlew --no-daemon clean spotlessApply build
#javah -classpath ./java/build/classes/java/main -o ./c/evmc-vm.h org.ethereum.evmc.EvmcVm


debug: DEBUG_FLAG = -D DEBUG

debug: build

c/evmc-vm.h:


test: build
./gradlew --no-daemon test

docker-build:
docker build -t evmc-java .

clean:
rm -rf build
rm -rf ./java/build/
Expand Down
3 changes: 1 addition & 2 deletions bindings/java/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
plugins {
id 'com.diffplug.gradle.spotless' version '3.16.0'
}

apply from: "${rootDir}/wrapper.gradle"
allprojects {
apply plugin: 'java-library'
repositories {
Expand All @@ -23,7 +23,6 @@ allprojects {
trimTrailingWhitespace()
endWithNewline()
googleJavaFormat('1.7')
paddedCell()
}
}
}
Expand Down
150 changes: 59 additions & 91 deletions bindings/java/c/evmc-vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,107 +7,66 @@
#include "evmc-vm.h"
#include "host.h"


JNIEXPORT jint JNICALL Java_org_ethereum_evmc_EvmcVm_test(JNIEnv* jenv, jclass jcls, jobject jbuffer){
struct test_struct{
int one;
long two;
int int1;
int int2;
char three;
long four;
char five[11];
};

struct test_struct *test = (struct test_struct *) (*jenv)->GetDirectBufferAddress(jenv, jbuffer);

struct test_struct *dummy =malloc (sizeof (struct test_struct));
printf("struct: dummy=%p, test=%p\n",dummy,test);
printf("one: dummy=%p, test=%p\n",&dummy->one,&test->one);
printf("two: dummy=%p, test=%p\n",&dummy->two,&test->two);
printf("int1: dummy=%p, test=%p\n",&dummy->int1,&test->int1);
printf("int2: dummy=%p, test=%p\n",&dummy->int2,&test->int2);
printf("three: dummy=%p, test=%p\n",&dummy->three,&test->three);
printf("four: dummy=%p, test=%p\n",&dummy->four, &test->four);
printf("five: dummy=%p, test=%p\n\n",&dummy->five,&test->five);

printf("one=%d\n",test->one);
printf("two=%ld\n",test->two);
printf("int1=%d\n",test->int1);
printf("int2=%d\n",test->int2);
printf("three=%c\n",test->three);
printf("four=%ld\n",test->four);
printf("five=%s\n",test->five);

return 0;


}

JNIEXPORT jint JNICALL Java_org_ethereum_evmc_EvmcVm_init(JNIEnv* jenv, jclass jcls, jstring jfilename)
JNIEXPORT jobject JNICALL Java_org_ethereum_evmc_EvmcVm_init(JNIEnv* jenv, jclass jcls, jstring jfilename)
{
struct evmc_vm *evm;
jint rs = (*jenv)->GetJavaVM(jenv, &jvm);
assert (rs == JNI_OK);

// load the EVM
const char *filename = (*jenv)->GetStringUTFChars(jenv, jfilename, 0);
enum evmc_loader_error_code loader_error;
evm_handle = evmc_load_and_create(filename, &loader_error);
if (evm_handle == NULL || loader_error != EVMC_LOADER_SUCCESS) {
const char *error_msg = evmc_last_error_msg();
printf("EVMC loading error: %s\n", error_msg);
exit(EXIT_FAILURE);
}
(*jenv)->ReleaseStringUTFChars(jenv, jfilename, filename);

// instantiate the EVMC host interface
host = malloc (sizeof (struct evmc_host_interface));
if (host == NULL) {
exit(EXIT_FAILURE);
if(filename != NULL){
enum evmc_loader_error_code loader_error;
evm = evmc_load_and_create(filename, &loader_error);
if (evm == NULL || loader_error != EVMC_LOADER_SUCCESS) {
const char *error_msg = evmc_last_error_msg();
jclass jclazz = (*jenv)->FindClass(jenv, "java/lang/AssertionError");
(*jenv)->ThrowNew(jenv, jclazz, error_msg);
}
(*jenv)->ReleaseStringUTFChars(jenv, jfilename, filename);
} else {
jclass jclazz = (*jenv)->FindClass(jenv, "java/lang/AssertionError");
(*jenv)->ThrowNew(jenv, jclazz, "JNI Error: filename cannot be NULL. \n");
}

host->account_exists = account_exists_fn;
host->get_storage = get_storage_fn;
host->set_storage = set_storage_fn;
host->get_storage = get_storage_fn;
host->get_code_size = get_code_size_fn;
host->get_code_hash = get_code_hash_fn;
host->copy_code = copy_code_fn;
host->selfdestruct = selfdestruct_fn;
host->call = call_fn;
host->get_tx_context = get_tx_context_fn;
host->get_block_hash = get_block_hash_fn;
host->emit_log = emit_log_fn;

return 0;
jobject jresult = (*jenv)->NewDirectByteBuffer(jenv, (void*) evm, sizeof(struct evmc_vm));
assert(jresult != NULL);
return jresult;
}

JNIEXPORT jint JNICALL Java_org_ethereum_evmc_EvmcVm_abi_1version(JNIEnv *jenv, jclass jcls){
return EVMC_ABI_VERSION;
}

JNIEXPORT jstring JNICALL Java_org_ethereum_evmc_EvmcVm_name(JNIEnv *jenv, jclass jcls){
const char *evm_name = evmc_vm_name(evm_handle);
JNIEXPORT jstring JNICALL Java_org_ethereum_evmc_EvmcVm_name(JNIEnv *jenv, jclass jcls, jobject jevm){
struct evmc_vm *evm = (struct evmc_vm *) (*jenv)->GetDirectBufferAddress(jenv, jevm);
assert(evm != NULL);
const char *evm_name = evmc_vm_name(evm);
return (*jenv)->NewStringUTF(jenv, evm_name);
}

JNIEXPORT jstring JNICALL Java_org_ethereum_evmc_EvmcVm_version(JNIEnv *jenv, jclass jcls){
const char *evm_version = evmc_vm_version(evm_handle);
JNIEXPORT jstring JNICALL Java_org_ethereum_evmc_EvmcVm_version(JNIEnv *jenv, jclass jcls, jobject jevm){
struct evmc_vm *evm = (struct evmc_vm *) (*jenv)->GetDirectBufferAddress(jenv, jevm);
assert(evm != NULL);
const char *evm_version = evmc_vm_version(evm);
return (*jenv)->NewStringUTF(jenv, evm_version);
}

JNIEXPORT void JNICALL Java_org_ethereum_evmc_EvmcVm_destroy(JNIEnv *jenv, jclass jcls){
evmc_destroy(evm_handle);
JNIEXPORT void JNICALL Java_org_ethereum_evmc_EvmcVm_destroy(JNIEnv *jenv, jclass jcls, jobject jevm){
struct evmc_vm *evm = (struct evmc_vm *) (*jenv)->GetDirectBufferAddress(jenv, jevm);
assert(evm != NULL);
evmc_destroy(evm);
}

JNIEXPORT jobject JNICALL Java_org_ethereum_evmc_EvmcVm_execute(JNIEnv *jenv, jclass jcls, jint jcontext_index, jint jrev, jobject jmsg, jobject jcode, jint jsize){
jobject jresult;
JNIEXPORT void JNICALL Java_org_ethereum_evmc_EvmcVm_execute(JNIEnv *jenv, jclass jcls, jobject jevm, jint jcontext_index, jint jrev, jobject jmsg, jobject jcode, jint jsize, jobject jresult){
struct evmc_message *cmsg = (struct evmc_message *) (*jenv)->GetDirectBufferAddress(jenv, jmsg);
assert(cmsg != NULL);
const uint8_t * ccode = (uint8_t *) (*jenv)->GetDirectBufferAddress(jenv, jcode);
assert(ccode != NULL);
struct evmc_host_context context = {jcontext_index};
struct evmc_vm *evm = (struct evmc_vm *) (*jenv)->GetDirectBufferAddress(jenv, jevm);
assert(evm != NULL);
#ifdef DEBUG
printf("********************before execute*******************\n");

printf("struct: evmc_message=%p\n",cmsg);
printf("sizeof(evmc_message): %lu\n", sizeof(struct evmc_message));
printf("kind=%p\n",&cmsg->kind);
Expand All @@ -130,32 +89,41 @@ JNIEXPORT jobject JNICALL Java_org_ethereum_evmc_EvmcVm_execute(JNIEnv *jenv, jc
printf("input_size=%zu\n",cmsg->input_size);
printf("value=%s\n\n",cmsg->value.bytes);
#endif
result = evmc_execute(evm_handle,host,&context,jrev,cmsg,ccode,jsize);
jresult = (*jenv)->NewDirectByteBuffer(jenv, (void*) &result, sizeof(struct evmc_result));
const struct evmc_host_interface* host = get_host_interface();
struct evmc_result *result = (struct evmc_result *)(*jenv)->GetDirectBufferAddress(jenv, jresult);
assert(result != NULL);
*result = evmc_execute(evm,host,&context,jrev,cmsg,ccode,jsize);
#ifdef DEBUG
printf("********************after execute*******************\n");
printf("sizeof(evmc_result): %lu\n", sizeof(struct evmc_result));
printf("status_code=%p\n",&result.status_code);
printf("gas_left=%p\n",&result.gas_left);
printf("output_data=%p\n\n",&result.output_data);
printf("status_code=%p\n",&result->status_code);
printf("gas_left=%p\n",&result->gas_left);
printf("output_data=%p\n\n",&result->output_data);

printf("status_code=%d\n",result.status_code);
printf("gas_left=%llu\n",result.gas_left);
printf("output_data=%s\n\n",result.output_data);
printf("status_code=%d\n",result->status_code);
printf("gas_left=%llu\n",result->gas_left);
printf("output_data=%s\n\n",result->output_data);
#endif
return jresult;
}

JNIEXPORT jobject JNICALL Java_org_ethereum_evmc_EvmcVm_get_1capabilities(JNIEnv *jenv, jclass jcls){
evmc_capabilities_flagset capabilities = evm_handle->get_capabilities(evm_handle);
return (*jenv)->NewDirectByteBuffer(jenv, (void*)(uintptr_t)capabilities, sizeof(evmc_capabilities_flagset));
JNIEXPORT jint JNICALL Java_org_ethereum_evmc_EvmcVm_get_1capabilities(JNIEnv *jenv, jclass jcls, jobject jevm){
struct evmc_vm *evm = (struct evmc_vm *) (*jenv)->GetDirectBufferAddress(jenv, jevm);
assert(evm != NULL);
return evm->get_capabilities(evm);
}

JNIEXPORT jint JNICALL Java_org_ethereum_evmc_EvmcVm_set_1option(JNIEnv *jenv, jclass jcls, jstring jname, jstring jvalue){
JNIEXPORT jint JNICALL Java_org_ethereum_evmc_EvmcVm_set_1option(JNIEnv *jenv, jclass jcls, jobject jevm, jstring jname, jstring jvalue){
struct evmc_vm *evm = (struct evmc_vm *) (*jenv)->GetDirectBufferAddress(jenv, jevm);
assert(evm != NULL);
const char *name = (*jenv)->GetStringUTFChars(jenv, jname, 0);
const char *value = (*jenv)->GetStringUTFChars(jenv, jvalue, 0);
enum evmc_set_option_result option_result = evmc_set_option(evm_handle,name,value);
enum evmc_set_option_result option_result = evmc_set_option(evm,name,value);
(*jenv)->ReleaseStringUTFChars(jenv, jname, name);
(*jenv)->ReleaseStringUTFChars(jenv, jvalue, value);
return option_result;
}
}

JNIEXPORT jint JNICALL Java_org_ethereum_evmc_EvmcVm_get_1result_1size(JNIEnv *jenv, jclass jcls){
return sizeof( struct evmc_result );
}

80 changes: 0 additions & 80 deletions bindings/java/c/evmc-vm.h

This file was deleted.

Loading

0 comments on commit f37b69c

Please sign in to comment.