| OLD | NEW |
| 1 // Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
| 4 | 4 |
| 5 #include "src/vm/ffi.h" | 5 #include "src/vm/ffi.h" |
| 6 | 6 |
| 7 #include <dlfcn.h> | 7 #include <dlfcn.h> |
| 8 #include <errno.h> | 8 #include <errno.h> |
| 9 #include <sys/param.h> |
| 9 | 10 |
| 10 #include "src/shared/asan_helper.h" | 11 #include "src/shared/asan_helper.h" |
| 12 #include "src/shared/platform.h" |
| 11 #include "src/vm/natives.h" | 13 #include "src/vm/natives.h" |
| 12 #include "src/vm/object.h" | 14 #include "src/vm/object.h" |
| 13 #include "src/vm/port.h" | 15 #include "src/vm/port.h" |
| 14 #include "src/vm/process.h" | 16 #include "src/vm/process.h" |
| 15 | 17 |
| 16 namespace fletch { | 18 namespace fletch { |
| 17 | 19 |
| 18 class DefaultLibraryEntry { | 20 class DefaultLibraryEntry { |
| 19 public: | 21 public: |
| 20 DefaultLibraryEntry(char* library, DefaultLibraryEntry* next) | 22 DefaultLibraryEntry(char* library, DefaultLibraryEntry* next) |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 ScopedLock lock(mutex_); | 69 ScopedLock lock(mutex_); |
| 68 for (DefaultLibraryEntry* current = libraries_; | 70 for (DefaultLibraryEntry* current = libraries_; |
| 69 current != NULL; | 71 current != NULL; |
| 70 current = current->next()) { | 72 current = current->next()) { |
| 71 void* result = PerformForeignLookup(current->library(), symbol); | 73 void* result = PerformForeignLookup(current->library(), symbol); |
| 72 if (result != NULL) return result; | 74 if (result != NULL) return result; |
| 73 } | 75 } |
| 74 return NULL; | 76 return NULL; |
| 75 } | 77 } |
| 76 | 78 |
| 79 NATIVE(ForeignLibraryLookup) { |
| 80 char* library = AsForeignString(String::cast(arguments[0])); |
| 81 void* result = dlopen(library, RTLD_LOCAL | RTLD_LAZY); |
| 82 if (result == NULL) { |
| 83 fprintf(stderr, "Failed libary lookup(%s): %s\n", library, dlerror()); |
| 84 } |
| 85 free(library); |
| 86 return result != NULL |
| 87 ? process->ToInteger(reinterpret_cast<intptr_t>(result)) |
| 88 : Failure::index_out_of_bounds(); |
| 89 } |
| 90 |
| 91 NATIVE(ForeignLibraryGetFunction) { |
| 92 word address = AsForeignWord(arguments[0]); |
| 93 void* handle = reinterpret_cast<void*>(address); |
| 94 char* name = AsForeignString(String::cast(arguments[1])); |
| 95 if (handle == NULL) handle = dlopen(NULL, RTLD_LOCAL | RTLD_LAZY); |
| 96 void* result = dlsym(handle, name); |
| 97 free(name); |
| 98 return result != NULL |
| 99 ? process->ToInteger(reinterpret_cast<intptr_t>(result)) |
| 100 : Failure::index_out_of_bounds(); |
| 101 } |
| 102 |
| 103 NATIVE(ForeignLibraryBundlePath) { |
| 104 char* library = AsForeignString(String::cast(arguments[0])); |
| 105 char executable[MAXPATHLEN + 1]; |
| 106 GetPathOfExecutable(executable, sizeof(executable)); |
| 107 char* directory = FFIUtils::DirName(executable); |
| 108 // dirname on linux may mess with the content of the buffer, so we use a fresh |
| 109 // buffer for the result. If anybody cares this can be optimized by manually |
| 110 // writing the strings other than dirname to the executable buffer. |
| 111 char result[MAXPATHLEN + 1]; |
| 112 int wrote = snprintf(result, MAXPATHLEN + 1, "%s%s%s%s", directory, |
| 113 FFIUtils::kLibBundlePrefix, library, |
| 114 FFIUtils::kLibBundlePostfix); |
| 115 if (wrote > MAXPATHLEN) { |
| 116 return Failure::index_out_of_bounds(); |
| 117 } |
| 118 free(library); |
| 119 return process->NewStringFromAscii(List<const char>(result, strlen(result))); |
| 120 } |
| 121 |
| 122 NATIVE(ForeignLibraryClose) { |
| 123 word address = AsForeignWord(arguments[0]); |
| 124 void* handle = reinterpret_cast<void*>(address); |
| 125 if (dlclose(handle) != 0) { |
| 126 fprintf(stderr, "Failed to close handle: %s\n", dlerror()); |
| 127 return Failure::index_out_of_bounds(); |
| 128 } |
| 129 return NULL; |
| 130 } |
| 131 |
| 77 NATIVE(ForeignLookup) { | 132 NATIVE(ForeignLookup) { |
| 78 char* library = arguments[1]->IsString() | 133 char* library = arguments[1]->IsString() |
| 79 ? AsForeignString(String::cast(arguments[1])) | 134 ? AsForeignString(String::cast(arguments[1])) |
| 80 : NULL; | 135 : NULL; |
| 81 | 136 |
| 82 char* name = AsForeignString(String::cast(arguments[0])); | 137 char* name = AsForeignString(String::cast(arguments[0])); |
| 83 void* result = PerformForeignLookup(library, name); | 138 void* result = PerformForeignLookup(library, name); |
| 84 | 139 |
| 85 if (result == NULL) { | 140 if (result == NULL) { |
| 86 result = ForeignFunctionInterface::LookupInDefaultLibraries(name); | 141 result = ForeignFunctionInterface::LookupInDefaultLibraries(name); |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 *address = Double::cast(value)->value(); \ | 485 *address = Double::cast(value)->value(); \ |
| 431 return value; \ | 486 return value; \ |
| 432 } | 487 } |
| 433 | 488 |
| 434 DEFINE_FOREIGN_ACCESSORS_DOUBLE(Float32, float) | 489 DEFINE_FOREIGN_ACCESSORS_DOUBLE(Float32, float) |
| 435 DEFINE_FOREIGN_ACCESSORS_DOUBLE(Float64, double) | 490 DEFINE_FOREIGN_ACCESSORS_DOUBLE(Float64, double) |
| 436 | 491 |
| 437 #undef DEFINE_FOREIGN_ACCESSORS | 492 #undef DEFINE_FOREIGN_ACCESSORS |
| 438 | 493 |
| 439 } // namespace fletch | 494 } // namespace fletch |
| OLD | NEW |