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; |