Skip to content

Commit

Permalink
dlopen,dlsym,dlcloseの追加。拡張ライブラリが作れるようになりました。
Browse files Browse the repository at this point in the history
  • Loading branch information
ab25cq committed Sep 15, 2017
1 parent 934f7f8 commit 3d43ce8
Show file tree
Hide file tree
Showing 17 changed files with 1,196 additions and 947 deletions.
17 changes: 17 additions & 0 deletions File.clc
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@ class System
CLOCK_PROCESS_CPUTIME_ID: static int;
CLOCK_THREAD_CPUTIME_ID: static int;

RTLD_LAZY:static int;
RTLD_NOW:static int;
RTLD_GLOBAL:static int;
RTLD_LOCAL:static int;
RTLD_NODELETE:static int;
RTLD_NOLOAD:static int;
RTLD_DEEPBIND:static int;

RTLD_DEFAULT: static pointer;
RTLD_NEXT: static pointer;

def initialize_file_system(): static native;

def initialize(): static {
Expand Down Expand Up @@ -122,6 +133,12 @@ class System
def clock_getres(clk_id:clockid_t, res:timespec): static native throws Exception;
def clock_gettime(clk_id:clockid_t, tp:timespec): static native throws Exception;
def clock_settime(clk_id:clockid_t, tp:timespec): static native throws Exception;

def dlopen(path:String, flags:int): static native pointer throws Exception;
def dlclose(handle:pointer): static native int throws Exception;
def dlsym(handle:pointer, symbol:String): static native pointer throws Exception;

def put_fun_to_hash_for_native_method(path:String, fun_name:String, native_method:pointer): static native;
}

class timespec
Expand Down
3 changes: 3 additions & 0 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -341,4 +341,7 @@ test:
./cclover2 code/command.cl && ./clover2 code/command.clo
./cclover2 code/closure.cl && ./clover2 code/closure.clo
./cclover2 code/anonymous.cl && ./clover2 code/anonymous.clo
gcc -shared -Wl,-soname=libExtTest.so.1 -o libExtTest.so.1.0.0 -I src/ -I . -fPIC ext/hello.c
ln -fs libExtTest.so.1.0.0 libExtTest.so
./cclover2 -class code/ext.clc && ./cclover2 code/ext.cl && ./clover2 code/ext.clo

80 changes: 80 additions & 0 deletions abc
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
==13176== Memcheck, a memory error detector
==13176== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==13176== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==13176== Command: ./clover2 code/stack.clo
==13176==
==13176== Invalid read of size 1
==13176== at 0x9668630: __strcmp_sse2_unaligned (in /usr/lib64/libc-2.24.so)
==13176== by 0x414517: get_native_method (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x40B823: invoke_method (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x40C48F: vm (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x41A37C: jit (jit_runtime.cpp:602)
==13176== by 0x40B7D1: invoke_method (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x4113F5: call_finalize_method_on_free_object (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x411B52: free_object (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x413FF6: compaction (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x413958: heap_final (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x40719B: main (in /home/ab25cq/repo/clover2/clover2)
==13176== Address 0x99d4b10 is 0 bytes inside a block of size 21 free'd
==13176== at 0x4C2ED4A: free (vg_replace_malloc.c:530)
==13176== by 0x4146AD: native_method_final (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x407175: main (in /home/ab25cq/repo/clover2/clover2)
==13176== Block was alloc'd at
==13176== at 0x4C2DB9D: malloc (vg_replace_malloc.c:299)
==13176== by 0x9654CF9: strdup (in /usr/lib64/libc-2.24.so)
==13176== by 0x4075D5: xstrdup (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x414628: native_method_init (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x4070FD: main (in /home/ab25cq/repo/clover2/clover2)
==13176==
==13176== Invalid read of size 1
==13176== at 0x4C31C54: strcmp (vg_replace_strmem.c:842)
==13176== by 0x414517: get_native_method (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x40B823: invoke_method (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x40C48F: vm (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x41A37C: jit (jit_runtime.cpp:602)
==13176== by 0x40B7D1: invoke_method (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x4113F5: call_finalize_method_on_free_object (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x411B52: free_object (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x413FF6: compaction (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x413958: heap_final (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x40719B: main (in /home/ab25cq/repo/clover2/clover2)
==13176== Address 0x99d4b11 is 1 bytes inside a block of size 21 free'd
==13176== at 0x4C2ED4A: free (vg_replace_malloc.c:530)
==13176== by 0x4146AD: native_method_final (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x407175: main (in /home/ab25cq/repo/clover2/clover2)
==13176== Block was alloc'd at
==13176== at 0x4C2DB9D: malloc (vg_replace_malloc.c:299)
==13176== by 0x9654CF9: strdup (in /usr/lib64/libc-2.24.so)
==13176== by 0x4075D5: xstrdup (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x414628: native_method_init (in /home/ab25cq/repo/clover2/clover2)
==13176== by 0x4070FD: main (in /home/ab25cq/repo/clover2/clover2)
==13176==
eval_file
eval_file end
1
2
3
4
a1
a2
a3
a4
a5
5
6
eval_file final end
==13176==
==13176== HEAP SUMMARY:
==13176== in use at exit: 113,454 bytes in 726 blocks
==13176== total heap usage: 4,528 allocs, 3,802 frees, 2,245,572 bytes allocated
==13176==
==13176== LEAK SUMMARY:
==13176== definitely lost: 0 bytes in 0 blocks
==13176== indirectly lost: 0 bytes in 0 blocks
==13176== possibly lost: 0 bytes in 0 blocks
==13176== still reachable: 113,454 bytes in 726 blocks
==13176== suppressed: 0 bytes in 0 blocks
==13176== Rerun with --leak-check=full to see details of leaked memory
==13176==
==13176== For counts of detected and suppressed errors, rerun with: -v
==13176== ERROR SUMMARY: 21 errors from 2 contexts (suppressed: 0 from 0)
1 change: 1 addition & 0 deletions code/ext.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Clover.test("Clover2 extention test...", ExtTest.hello(123) == 246);
13 changes: 13 additions & 0 deletions code/ext.clc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

class ExtTest
{
def hello(param:int): native static int;

def initialize():static {
dlib:pointer = System.dlopen("libExtTest.so", System.RTLD_LAZY);

hello_method:pointer = System.dlsym(dlib, "ExtTest_hello");

System.put_fun_to_hash_for_native_method("ExtTest.hello(int)", "ExtTest_hello", hello_method);
}
}
15 changes: 15 additions & 0 deletions ext/hello.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "common.h"

BOOL ExtTest_hello(CLVALUE** stack_ptr, CLVALUE* lvar, sVMInfo* info)
{
CLVALUE* num = lvar;

int num_value = num->mIntValue;

printf("HELLO CLOVER2 EXTENSION %d\n", num_value);

(*stack_ptr)->mIntValue = num_value * 2;
(*stack_ptr)++;

return TRUE;
}
105 changes: 104 additions & 1 deletion src/class_system.c
Original file line number Diff line number Diff line change
Expand Up @@ -1090,7 +1090,17 @@ BOOL System_initialize_file_system(CLVALUE** stack_ptr, CLVALUE* lvar, sVMInfo*
system->mClassFields[LAST_INITIALIZE_FIELD_NUM_ON_STRING_SYSTEM+61].mValue.mIntValue = CLOCK_THREAD_CPUTIME_ID;
#endif

#define LAST_INITIALIZE_FIELD_NUM_ON_FILE_SYSTEM (LAST_INITIALIZE_FIELD_NUM_ON_STRING_SYSTEM+62)
system->mClassFields[LAST_INITIALIZE_FIELD_NUM_ON_STRING_SYSTEM+62].mValue.mIntValue = RTLD_LAZY;
system->mClassFields[LAST_INITIALIZE_FIELD_NUM_ON_STRING_SYSTEM+63].mValue.mIntValue = RTLD_NOW;
system->mClassFields[LAST_INITIALIZE_FIELD_NUM_ON_STRING_SYSTEM+64].mValue.mIntValue = RTLD_GLOBAL;
system->mClassFields[LAST_INITIALIZE_FIELD_NUM_ON_STRING_SYSTEM+65].mValue.mIntValue = RTLD_LOCAL;
system->mClassFields[LAST_INITIALIZE_FIELD_NUM_ON_STRING_SYSTEM+66].mValue.mIntValue = RTLD_NODELETE;
system->mClassFields[LAST_INITIALIZE_FIELD_NUM_ON_STRING_SYSTEM+67].mValue.mIntValue = RTLD_NOLOAD;
system->mClassFields[LAST_INITIALIZE_FIELD_NUM_ON_STRING_SYSTEM+68].mValue.mIntValue = RTLD_DEEPBIND;
system->mClassFields[LAST_INITIALIZE_FIELD_NUM_ON_STRING_SYSTEM+69].mValue.mPointerValue = RTLD_DEFAULT;
system->mClassFields[LAST_INITIALIZE_FIELD_NUM_ON_STRING_SYSTEM+70].mValue.mPointerValue = RTLD_NEXT;

#define LAST_INITIALIZE_FIELD_NUM_ON_FILE_SYSTEM (LAST_INITIALIZE_FIELD_NUM_ON_STRING_SYSTEM+71)

return TRUE;
}
Expand Down Expand Up @@ -2853,3 +2863,96 @@ BOOL System_unsetenv(CLVALUE** stack_ptr, CLVALUE* lvar, sVMInfo* info)

return TRUE;
}

BOOL System_dlopen(CLVALUE** stack_ptr, CLVALUE* lvar, sVMInfo* info)
{
CLVALUE* path = lvar;
CLVALUE* flags = lvar + 1;

/// Clover to c value ///
char* path_value = ALLOC string_object_to_char_array(path->mObjectValue);
int flags_value = flags->mIntValue;

/// go ///
void* result = dlopen(path_value, flags_value);

if(result == NULL) {
MFREE(path_value);
entry_exception_object_with_class_name(stack_ptr, info->current_stack, info->current_var_num, info, "Exception", "dlopen(3) is faield. The error is %s", dlerror());
return FALSE;
}

(*stack_ptr)->mPointerValue = result;
(*stack_ptr)++;

MFREE(path_value);

return TRUE;
}

BOOL System_dlclose(CLVALUE** stack_ptr, CLVALUE* lvar, sVMInfo* info)
{
CLVALUE* handle = lvar;

/// Clover to c value ///
void* handle_value = handle->mPointerValue;

/// go ///
int result = dlclose(handle_value);

if(result != 0) {
entry_exception_object_with_class_name(stack_ptr, info->current_stack, info->current_var_num, info, "Exception", "dlclose(3) is faield. The error is %s", dlerror());
return FALSE;
}

(*stack_ptr)->mIntValue = result;
(*stack_ptr)++;

return TRUE;
}

BOOL System_dlsym(CLVALUE** stack_ptr, CLVALUE* lvar, sVMInfo* info)
{
CLVALUE* handle = lvar;
CLVALUE* symbol = lvar + 1;

/// Clover to c value ///
void* handle_value = handle->mPointerValue;
char* symbol_value = ALLOC string_object_to_char_array(symbol->mObjectValue);

/// go ///
void* result = dlsym(handle_value, symbol_value);

if(result == NULL) {
MFREE(symbol_value);
entry_exception_object_with_class_name(stack_ptr, info->current_stack, info->current_var_num, info, "Exception", "dlsym(3) is faield. The error is %s", dlerror());
return FALSE;
}

(*stack_ptr)->mPointerValue = result;
(*stack_ptr)++;

MFREE(symbol_value);

return TRUE;
}

BOOL System_put_fun_to_hash_for_native_method(CLVALUE** stack_ptr, CLVALUE* lvar, sVMInfo* info)
{
CLVALUE* path = lvar;
CLVALUE* fun_name = lvar + 1;
CLVALUE* native_method = lvar + 2;

/// Clover to c value ///
char* path_value = ALLOC string_object_to_char_array(path->mObjectValue);
char* fun_name_value = ALLOC string_object_to_char_array(fun_name->mObjectValue);
fNativeMethod native_method_value = (fNativeMethod)native_method->mPointerValue;

/// go ///
put_fun_to_hash_for_native_method(path_value, fun_name_value, native_method_value);

MFREE(path_value);
MFREE(fun_name_value);

return TRUE;
}
18 changes: 8 additions & 10 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,9 @@ struct sCLMethodStruct {

sCLType* mResultType;

union {
sByteCode mByteCodes;
struct {
fNativeMethod mNativeMethod;
char* mNativeFunName;
};
} uCode;
sByteCode mByteCodes;
fNativeMethod mNativeMethod;
char* mNativeFunName;

int mVarNum;

Expand Down Expand Up @@ -341,9 +337,6 @@ typedef struct sClassTableStruct sClassTable;

extern sClassTable* gHeadClassTable;

typedef fNativeMethod (*fGetNativeMethod)(char* path, char** native_method_name);
extern fGetNativeMethod gGetNativeMethod;

/// node_type.c ///
struct sNodeBlockTypeStruct;

Expand Down Expand Up @@ -1669,6 +1662,7 @@ void native_method_init();
void native_method_final();

fNativeMethod get_native_method(char* path, char** fun_name);
void put_fun_to_hash_for_native_method(char* path, char* fun_name, fNativeMethod fun);

/// exception.c ///
void entry_exception_object_with_class_name(CLVALUE** stack_ptr, CLVALUE* stack, int var_num, sVMInfo* info, char* class_name, char* msg, ...);
Expand Down Expand Up @@ -1947,6 +1941,10 @@ BOOL System_system(CLVALUE** stack_ptr, CLVALUE* lvar, sVMInfo* info);
BOOL System_getenv(CLVALUE** stack_ptr, CLVALUE* lvar, sVMInfo* info);
BOOL System_setenv(CLVALUE** stack_ptr, CLVALUE* lvar, sVMInfo* info);
BOOL System_unsetenv(CLVALUE** stack_ptr, CLVALUE* lvar, sVMInfo* info);
BOOL System_dlopen(CLVALUE** stack_ptr, CLVALUE* lvar, sVMInfo* info);
BOOL System_dlclose(CLVALUE** stack_ptr, CLVALUE* lvar, sVMInfo* info);
BOOL System_dlsym(CLVALUE** stack_ptr, CLVALUE* lvar, sVMInfo* info);
BOOL System_put_fun_to_hash_for_native_method(CLVALUE** stack_ptr, CLVALUE* lvar, sVMInfo* info);

/// alignment.c ///
void alignment(unsigned int* size);
Expand Down
4 changes: 2 additions & 2 deletions src/interpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1610,10 +1610,10 @@ static void clover2_init()
static void clover2_final()
{
class_final_on_runtime();
native_method_final();
stack_final();
heap_final();
stack_final();
class_final();
native_method_final();
#ifdef ENABLE_JIT
jit_final_on_runtime();
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/jit_compile_method.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ static BOOL compile_jit_methods(sCLClass* klass)
char method_path2[METHOD_NAME_MAX + 128];
create_method_path_for_jit(klass, method, method_path2, METHOD_NAME_MAX + 128);

sByteCode* code = &method->uCode.mByteCodes;
sByteCode* code = &method->mByteCodes;
sConst* constant = &klass->mConst;

if(!compile_to_native_code(code, constant, klass, method, method_path2)) {
Expand Down
Loading

0 comments on commit 3d43ce8

Please sign in to comment.