Chromium Code Reviews| 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 = arguments[0]->IsString() | |
| 81 ? AsForeignString(String::cast(arguments[0])) | |
| 82 : NULL; | |
| 83 void* result = dlopen(library, RTLD_LOCAL | RTLD_LAZY); | |
| 84 if (result == NULL) { | |
| 85 fprintf(stderr, "Failed libary lookup(%s): %s\n", library, dlerror()); | |
| 86 } | |
| 87 free(library); | |
| 88 return result != NULL | |
| 89 ? process->ToInteger(reinterpret_cast<intptr_t>(result)) | |
| 90 : Failure::index_out_of_bounds(); | |
| 91 } | |
| 92 | |
| 93 NATIVE(ForeignLibraryGetFunction) { | |
| 94 word address = AsForeignWord(arguments[0]); | |
| 95 void* handle = reinterpret_cast<void*>(address); | |
| 96 char* name = AsForeignString(String::cast(arguments[1])); | |
| 97 if (handle == NULL) handle = dlopen(NULL, RTLD_LOCAL | RTLD_LAZY); | |
| 98 void* result = dlsym(handle, name); | |
| 99 free(name); | |
| 100 return result != NULL | |
| 101 ? process->ToInteger(reinterpret_cast<intptr_t>(result)) | |
| 102 : Failure::index_out_of_bounds(); | |
| 103 } | |
| 104 | |
| 105 NATIVE(ForeignLibraryBundlePath) { | |
| 106 char* library = AsForeignString(String::cast(arguments[0])); | |
| 107 char executable[MAXPATHLEN + 1]; | |
| 108 GetPathOfExecutable(executable, sizeof(executable)); | |
| 109 char* directory = ForeignUtils::DirectoryName(executable); | |
| 110 // dirname on linux may mess with the content of the buffer, so we use a fresh | |
| 111 // buffer for the result. If anybody cares this can be optimized by manually | |
| 112 // writing the strings other than dirname to the executable buffer. | |
| 113 char result[MAXPATHLEN + 1]; | |
| 114 int wrote = snprintf(result, MAXPATHLEN + 1, "%s%s%s%s", directory, | |
| 115 ForeignUtils::kLibBundlePrefix, library, | |
| 116 ForeignUtils::kLibBundlePostfix); | |
| 117 if (wrote > MAXPATHLEN) { | |
| 118 return Failure::index_out_of_bounds(); | |
| 119 } | |
| 120 free(library); | |
| 121 return process->NewStringFromAscii(List<const char>(result, strlen(result))); | |
| 122 } | |
| 123 | |
| 124 NATIVE(ForeignLibraryClose) { | |
| 125 word address = AsForeignWord(arguments[0]); | |
| 126 void* handle = reinterpret_cast<void*>(address); | |
| 127 if (dlclose(handle) != 0) { | |
| 128 fprintf(stderr, "Failed to close handle: %s\n", dlerror()); | |
| 129 return Failure::index_out_of_bounds(); | |
| 130 } | |
| 131 return NULL; | |
| 132 } | |
| 133 | |
| 77 NATIVE(ForeignLookup) { | 134 NATIVE(ForeignLookup) { |
| 78 char* library = arguments[1]->IsString() | 135 char* library = arguments[1]->IsString() |
| 79 ? AsForeignString(String::cast(arguments[1])) | 136 ? AsForeignString(String::cast(arguments[1])) |
| 80 : NULL; | 137 : NULL; |
| 81 | 138 |
| 82 char* name = AsForeignString(String::cast(arguments[0])); | 139 char* name = AsForeignString(String::cast(arguments[0])); |
| 83 void* result = PerformForeignLookup(library, name); | 140 void* result = PerformForeignLookup(library, name); |
| 84 | 141 |
| 85 if (result == NULL) { | 142 if (result == NULL) { |
| 86 result = ForeignFunctionInterface::LookupInDefaultLibraries(name); | 143 result = ForeignFunctionInterface::LookupInDefaultLibraries(name); |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 395 type* address = reinterpret_cast<type*>(AsForeignWord(arguments[0])); \ | 452 type* address = reinterpret_cast<type*>(AsForeignWord(arguments[0])); \ |
| 396 return process->ToInteger(*address); \ | 453 return process->ToInteger(*address); \ |
| 397 } \ | 454 } \ |
| 398 \ | 455 \ |
| 399 NATIVE(ForeignSet##suffix) { \ | 456 NATIVE(ForeignSet##suffix) { \ |
| 400 Object* value = arguments[1]; \ | 457 Object* value = arguments[1]; \ |
| 401 if (!value->IsSmi() && !value->IsLargeInteger()) { \ | 458 if (!value->IsSmi() && !value->IsLargeInteger()) { \ |
| 402 return Failure::wrong_argument_type(); \ | 459 return Failure::wrong_argument_type(); \ |
| 403 } \ | 460 } \ |
| 404 type* address = reinterpret_cast<type*>(AsForeignWord(arguments[0])); \ | 461 type* address = reinterpret_cast<type*>(AsForeignWord(arguments[0])); \ |
| 405 *address = AsForeignWord(value); \ | 462 if (value->IsSmi()) { \ |
|
ricow1
2015/07/02 16:01:57
This already landed in another cl, I redid this he
| |
| 463 *address = Smi::cast(value)->value(); \ | |
| 464 } else { \ | |
| 465 *address = LargeInteger::cast(value)->value(); \ | |
| 466 } \ | |
| 406 return value; \ | 467 return value; \ |
| 407 } | 468 } |
| 408 | 469 |
| 409 DEFINE_FOREIGN_ACCESSORS_INTEGER(Int8, int8) | 470 DEFINE_FOREIGN_ACCESSORS_INTEGER(Int8, int8) |
| 410 DEFINE_FOREIGN_ACCESSORS_INTEGER(Int16, int16) | 471 DEFINE_FOREIGN_ACCESSORS_INTEGER(Int16, int16) |
| 411 DEFINE_FOREIGN_ACCESSORS_INTEGER(Int32, int32) | 472 DEFINE_FOREIGN_ACCESSORS_INTEGER(Int32, int32) |
| 412 DEFINE_FOREIGN_ACCESSORS_INTEGER(Int64, int64) | 473 DEFINE_FOREIGN_ACCESSORS_INTEGER(Int64, int64) |
| 413 | 474 |
| 414 DEFINE_FOREIGN_ACCESSORS_INTEGER(Uint8, uint8) | 475 DEFINE_FOREIGN_ACCESSORS_INTEGER(Uint8, uint8) |
| 415 DEFINE_FOREIGN_ACCESSORS_INTEGER(Uint16, uint16) | 476 DEFINE_FOREIGN_ACCESSORS_INTEGER(Uint16, uint16) |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 430 *address = Double::cast(value)->value(); \ | 491 *address = Double::cast(value)->value(); \ |
| 431 return value; \ | 492 return value; \ |
| 432 } | 493 } |
| 433 | 494 |
| 434 DEFINE_FOREIGN_ACCESSORS_DOUBLE(Float32, float) | 495 DEFINE_FOREIGN_ACCESSORS_DOUBLE(Float32, float) |
| 435 DEFINE_FOREIGN_ACCESSORS_DOUBLE(Float64, double) | 496 DEFINE_FOREIGN_ACCESSORS_DOUBLE(Float64, double) |
| 436 | 497 |
| 437 #undef DEFINE_FOREIGN_ACCESSORS | 498 #undef DEFINE_FOREIGN_ACCESSORS |
| 438 | 499 |
| 439 } // namespace fletch | 500 } // namespace fletch |
| OLD | NEW |