Chromium Code Reviews| Index: src/vm/ffi.cc |
| diff --git a/src/vm/ffi.cc b/src/vm/ffi.cc |
| index a101ae2b5b89aa9611e8c1d045f5704e3ba46f3a..7ee6823330898ef69cb2870198ebf3f6fdfcf513 100644 |
| --- a/src/vm/ffi.cc |
| +++ b/src/vm/ffi.cc |
| @@ -6,8 +6,10 @@ |
| #include <dlfcn.h> |
| #include <errno.h> |
| +#include <sys/param.h> |
| #include "src/shared/asan_helper.h" |
| +#include "src/shared/platform.h" |
| #include "src/vm/natives.h" |
| #include "src/vm/object.h" |
| #include "src/vm/port.h" |
| @@ -74,6 +76,61 @@ void* ForeignFunctionInterface::LookupInDefaultLibraries(const char* symbol) { |
| return NULL; |
| } |
| +NATIVE(ForeignLibraryLookup) { |
| + char* library = arguments[0]->IsString() |
| + ? AsForeignString(String::cast(arguments[0])) |
| + : NULL; |
| + void* result = dlopen(library, RTLD_LOCAL | RTLD_LAZY); |
| + if (result == NULL) { |
| + fprintf(stderr, "Failed libary lookup(%s): %s\n", library, dlerror()); |
| + } |
| + free(library); |
| + return result != NULL |
| + ? process->ToInteger(reinterpret_cast<intptr_t>(result)) |
| + : Failure::index_out_of_bounds(); |
| +} |
| + |
| +NATIVE(ForeignLibraryGetFunction) { |
| + word address = AsForeignWord(arguments[0]); |
| + void* handle = reinterpret_cast<void*>(address); |
| + char* name = AsForeignString(String::cast(arguments[1])); |
| + if (handle == NULL) handle = dlopen(NULL, RTLD_LOCAL | RTLD_LAZY); |
| + void* result = dlsym(handle, name); |
| + free(name); |
| + return result != NULL |
| + ? process->ToInteger(reinterpret_cast<intptr_t>(result)) |
| + : Failure::index_out_of_bounds(); |
| +} |
| + |
| +NATIVE(ForeignLibraryBundlePath) { |
| + char* library = AsForeignString(String::cast(arguments[0])); |
| + char executable[MAXPATHLEN + 1]; |
| + GetPathOfExecutable(executable, sizeof(executable)); |
| + char* directory = ForeignUtils::DirectoryName(executable); |
| + // dirname on linux may mess with the content of the buffer, so we use a fresh |
| + // buffer for the result. If anybody cares this can be optimized by manually |
| + // writing the strings other than dirname to the executable buffer. |
| + char result[MAXPATHLEN + 1]; |
| + int wrote = snprintf(result, MAXPATHLEN + 1, "%s%s%s%s", directory, |
| + ForeignUtils::kLibBundlePrefix, library, |
| + ForeignUtils::kLibBundlePostfix); |
| + if (wrote > MAXPATHLEN) { |
| + return Failure::index_out_of_bounds(); |
| + } |
| + free(library); |
| + return process->NewStringFromAscii(List<const char>(result, strlen(result))); |
| +} |
| + |
| +NATIVE(ForeignLibraryClose) { |
| + word address = AsForeignWord(arguments[0]); |
| + void* handle = reinterpret_cast<void*>(address); |
| + if (dlclose(handle) != 0) { |
| + fprintf(stderr, "Failed to close handle: %s\n", dlerror()); |
| + return Failure::index_out_of_bounds(); |
| + } |
| + return NULL; |
| +} |
| + |
| NATIVE(ForeignLookup) { |
| char* library = arguments[1]->IsString() |
| ? AsForeignString(String::cast(arguments[1])) |
| @@ -402,7 +459,11 @@ NATIVE(ForeignSet##suffix) { \ |
| return Failure::wrong_argument_type(); \ |
| } \ |
| type* address = reinterpret_cast<type*>(AsForeignWord(arguments[0])); \ |
| - *address = AsForeignWord(value); \ |
| + if (value->IsSmi()) { \ |
|
ricow1
2015/07/02 16:01:57
This already landed in another cl, I redid this he
|
| + *address = Smi::cast(value)->value(); \ |
| + } else { \ |
| + *address = LargeInteger::cast(value)->value(); \ |
| + } \ |
| return value; \ |
| } |