| Index: compiled/bindings/generator.cpp |
| =================================================================== |
| --- a/compiled/bindings/generator.cpp |
| +++ b/compiled/bindings/generator.cpp |
| @@ -12,19 +12,18 @@ |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
| */ |
| #include <cstdio> |
| -#include <emscripten.h> |
| - |
| #include "generator.h" |
| +#include "library.h" |
| namespace |
| { |
| std::vector<bindings_internal::ClassInfo> classes; |
| std::vector<bindings_internal::NamespaceInfo> namespaces; |
| void printProperties(const bindings_internal::PropertyList& properties) |
| { |
| @@ -53,27 +52,24 @@ namespace |
| printf("%s: %s,\n", method.name.c_str(), wrapCall(method.call).c_str()); |
| } |
| } |
| namespace bindings_internal |
| { |
| FunctionInfo::FunctionInfo() |
| { |
| - name[0] = '\0'; |
| } |
| FunctionInfo::FunctionInfo(TypeCategory returnType, TYPEID pointerType, |
| std::initializer_list<TypeCategory> argTypes, bool instance_function, |
| void* function) |
| : returnType(returnType), pointerType(pointerType), |
| instance_function(instance_function) |
| { |
| - name[0] = '\0'; |
| - |
| // The function parameter is a pointer to the function pointer. |
| // Emscripten's "function pointers" are actually integers indicating the |
| // position in the call table. 0 represents nullptr. |
| if (!*reinterpret_cast<int*>(function)) |
| return; |
| std::string signature; |
| @@ -136,85 +132,24 @@ namespace bindings_internal |
| signature += 'd'; |
| break; |
| default: |
| throw std::runtime_error("Unexpected function argument type"); |
| } |
| args.push_back(type); |
| } |
| - get_function_name(function, signature.c_str()); |
| + int nameLength = GetFunctionName(nullptr, function, signature.c_str()); |
| + name.resize(nameLength); |
| + GetFunctionName(name.data(), function, signature.c_str()); |
|
sergei
2017/05/08 09:16:29
if std::string::data() returns only a const pointe
Wladimir Palant
2017/05/08 10:17:18
Oh, so the C++ standard in its most recent iterati
|
| } |
| bool FunctionInfo::empty() const |
| { |
| - return name[0] == '\0'; |
| - } |
| - |
| - void FunctionInfo::get_function_name(void* ptr, const char* signature) |
| - { |
| - // This is a hack, C++ won't let us get the mangled function name. |
| - // JavaScript is more dynamic so we pass the pointer to our function |
| - // there. With that and the function signature we can call the function - |
| - // with a full stack so that we will cause it to abort. Sometimes the |
| - // function we are calling will also be missing from the build. The result |
| - // is the same: abort() is called which in turn calls stackTrace(). By |
| - // replacing stackTrace() we get access to the call stack and search it |
| - // for the name of our function. |
| - |
| - EM_ASM_ARGS({ |
| - var signature = AsciiToString($2); |
| - var args = []; |
| - for (var i = 1; i < signature.length; i++) |
| - args.push(0); |
| - |
| - var oldPrint = Module.print; |
| - var oldPrintErr = Module.printErr; |
| - var oldStackTrace = stackTrace; |
| - var sp = Runtime.stackSave(); |
| - Module.print = function(){}; |
| - Module.printErr = function(){}; |
| - stackTrace = function() |
| - { |
| - var stack = []; |
| - for (var f = arguments.callee.caller; f; f = f.caller) |
| - { |
| - if (f.name) |
| - { |
| - if (f.name.indexOf("dynCall") == 0) |
| - break; |
| - else |
| - stack.push(f.name); |
| - } |
| - } |
| - |
| - result = stack[stack.length - 1]; |
| - if (result && result.indexOf("__wrapper") >= 0) |
| - result = stack[stack.length - 2]; |
| - throw result; |
| - }; |
| - |
| - Runtime.stackRestore(STACK_MAX); |
| - |
| - try |
| - { |
| - Runtime.dynCall(signature, HEAP32[$1 >> 2], args); |
| - } |
| - catch(e) |
| - { |
| - Module.stringToAscii(e, $0); |
| - } |
| - finally |
| - { |
| - Runtime.stackRestore(sp); |
| - Module.print = oldPrint; |
| - Module.printErr = oldPrintErr; |
| - stackTrace = oldStackTrace; |
| - } |
| - }, name, ptr, signature); |
| + return name.size() == 0; |
| } |
| ClassInfo* find_class(TYPEID classID) |
| { |
| for (auto& classInfo : classes) |
| if (classInfo.id == classID) |
| return &classInfo; |
| return nullptr; |
| @@ -332,17 +267,17 @@ namespace bindings_internal |
| std::vector<std::string>& params) |
| { |
| if (call.returnType == TypeCategory::DEPENDENT_STRING || |
| call.returnType == TypeCategory::OWNED_STRING) |
| { |
| params.insert(params.begin(), "string"); |
| } |
| - std::string call_str(call.name); |
| + std::string call_str(call.name.data()); |
| call_str += "("; |
| for (int i = 0; i < params.size(); i++) |
| { |
| if (i > 0) |
| call_str += ", "; |
| call_str += params[i]; |
| } |
| call_str += ")"; |
| @@ -376,31 +311,31 @@ namespace bindings_internal |
| { |
| std::string result; |
| result += " var result = " + call_str + ";\n"; |
| result += " if (result)\n"; |
| result += " {\n"; |
| const ClassInfo* cls = find_class(call.pointerType); |
| if (!cls) |
| - throw std::runtime_error("Function " + std::string(call.name) + " returns pointer to unknown class"); |
| + throw std::runtime_error("Function " + std::string(call.name.data()) + " returns pointer to unknown class"); |
| auto offset = cls->subclass_differentiator.offset; |
| if (offset == SIZE_MAX) |
| result += " result = exports." + cls->name + "(result);\n"; |
| else |
| result += " result = exports." + cls->name + ".fromPointer(result);\n"; |
| result += " }\n"; |
| result += " else\n"; |
| result += " result = null;\n"; |
| return result; |
| } |
| default: |
| - throw std::runtime_error("Unexpected return type for " + std::string(call.name)); |
| + throw std::runtime_error("Unexpected return type for " + std::string(call.name.data())); |
| } |
| } |
| std::string wrapCall(const FunctionInfo& call, bool isFunction) |
| { |
| bool hasStringArgs = false; |
| std::vector<std::string> params; |
| std::string prefix; |