| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 
| 3  * Copyright (C) 2006-2017 eyeo GmbH | 3  * Copyright (C) 2006-2017 eyeo GmbH | 
| 4  * | 4  * | 
| 5  * Adblock Plus is free software: you can redistribute it and/or modify | 5  * Adblock Plus is free software: you can redistribute it and/or modify | 
| 6  * it under the terms of the GNU General Public License version 3 as | 6  * it under the terms of the GNU General Public License version 3 as | 
| 7  * published by the Free Software Foundation. | 7  * published by the Free Software Foundation. | 
| 8  * | 8  * | 
| 9  * Adblock Plus is distributed in the hope that it will be useful, | 9  * Adblock Plus is distributed in the hope that it will be useful, | 
| 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
| 35 | 35 | 
| 36 namespace bindings_internal | 36 namespace bindings_internal | 
| 37 { | 37 { | 
| 38   typedef void* TYPEID; | 38   typedef void* TYPEID; | 
| 39 | 39 | 
| 40   enum class TypeCategory | 40   enum class TypeCategory | 
| 41   { | 41   { | 
| 42     UNKNOWN, | 42     UNKNOWN, | 
| 43     VOID, | 43     VOID, | 
| 44     INT, | 44     INT, | 
|  | 45     FLOAT, | 
| 45     DEPENDENT_STRING, | 46     DEPENDENT_STRING, | 
| 46     OWNED_STRING, | 47     OWNED_STRING, | 
| 47     STRING_REF, | 48     STRING_REF, | 
| 48     CLASS_PTR | 49     CLASS_PTR | 
| 49   }; | 50   }; | 
| 50 | 51 | 
| 51   template<typename T> | 52   template<typename T> | 
| 52   struct TypeInfo | 53   struct TypeInfo | 
| 53   { | 54   { | 
| 54     /* | 55     /* | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 66     } | 67     } | 
| 67 | 68 | 
| 68     constexpr operator TypeCategory() const | 69     constexpr operator TypeCategory() const | 
| 69     { | 70     { | 
| 70       if (std::is_void<T>()) | 71       if (std::is_void<T>()) | 
| 71         return TypeCategory::VOID; | 72         return TypeCategory::VOID; | 
| 72 | 73 | 
| 73       if (std::is_integral<T>() || std::is_enum<T>()) | 74       if (std::is_integral<T>() || std::is_enum<T>()) | 
| 74         return TypeCategory::INT; | 75         return TypeCategory::INT; | 
| 75 | 76 | 
|  | 77       if (std::is_floating_point<T>()) | 
|  | 78         return TypeCategory::FLOAT; | 
|  | 79 | 
| 76       if (std::is_same<DependentString, T>() || std::is_same<const DependentStri
     ng, T>()) | 80       if (std::is_same<DependentString, T>() || std::is_same<const DependentStri
     ng, T>()) | 
| 77         return TypeCategory::DEPENDENT_STRING; | 81         return TypeCategory::DEPENDENT_STRING; | 
| 78 | 82 | 
| 79       if (std::is_same<OwnedString, T>() || std::is_same<const OwnedString, T>()
     ) | 83       if (std::is_same<OwnedString, T>() || std::is_same<const OwnedString, T>()
     ) | 
| 80         return TypeCategory::OWNED_STRING; | 84         return TypeCategory::OWNED_STRING; | 
| 81 | 85 | 
| 82       if (std::is_same<String&, T>() || std::is_same<const String&, T>() || | 86       if (std::is_same<String&, T>() || std::is_same<const String&, T>() || | 
| 83         std::is_same<DependentString&, T>()) | 87         std::is_same<DependentString&, T>()) | 
| 84       { | 88       { | 
| 85         return TypeCategory::STRING_REF; | 89         return TypeCategory::STRING_REF; | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 125           instance_function(instance_function) | 129           instance_function(instance_function) | 
| 126     { | 130     { | 
| 127       name[0] = '\0'; | 131       name[0] = '\0'; | 
| 128 | 132 | 
| 129       // The function parameter is a pointer to the function pointer. | 133       // The function parameter is a pointer to the function pointer. | 
| 130       // Emscripten's "function pointers" are actually integers indicating the | 134       // Emscripten's "function pointers" are actually integers indicating the | 
| 131       // position in the call table. 0 represents nullptr. | 135       // position in the call table. 0 represents nullptr. | 
| 132       if (!*reinterpret_cast<int*>(function)) | 136       if (!*reinterpret_cast<int*>(function)) | 
| 133         return; | 137         return; | 
| 134 | 138 | 
|  | 139       char signature[256]; | 
|  | 140       int pos = 0; | 
|  | 141       if (returnType == TypeCategory::DEPENDENT_STRING || | 
|  | 142           returnType == TypeCategory::OWNED_STRING) | 
|  | 143       { | 
|  | 144         // Objects aren't really returned but passed as parameter. Note that | 
|  | 145         // this pointer might come before it but we don't care because both | 
|  | 146         // are integers (pointers) as far as Emscripten is concerned. | 
|  | 147         signature[pos++] = 'v'; | 
|  | 148         signature[pos++] = 'i'; | 
|  | 149       } | 
|  | 150       else if (returnType == TypeCategory::VOID) | 
|  | 151         signature[pos++] = 'v'; | 
|  | 152       else if (returnType == TypeCategory::FLOAT) | 
|  | 153         signature[pos++] = 'd'; | 
|  | 154       else if (returnType == TypeCategory::INT || | 
|  | 155           returnType == TypeCategory::STRING_REF || | 
|  | 156           returnType == TypeCategory::CLASS_PTR) | 
|  | 157       { | 
|  | 158         signature[pos++] = 'i'; | 
|  | 159       } | 
|  | 160       else | 
|  | 161         throw std::runtime_error("Unexpected function return type"); | 
|  | 162 | 
|  | 163       if (instance_function) | 
|  | 164       { | 
|  | 165         // this pointer is an implicit parameter | 
|  | 166         signature[pos++] = 'i'; | 
|  | 167       } | 
|  | 168 | 
| 135       for (const auto& item : argTypes) | 169       for (const auto& item : argTypes) | 
| 136       { | 170       { | 
| 137         if (item != TypeCategory::INT && item != TypeCategory::STRING_REF && | 171         if (item == TypeCategory::INT || item == TypeCategory::STRING_REF || | 
| 138             item != TypeCategory::CLASS_PTR) | 172             item == TypeCategory::CLASS_PTR) | 
| 139         { | 173         { | 
|  | 174           signature[pos++] = 'i'; | 
|  | 175         } | 
|  | 176         else if (item == TypeCategory::FLOAT) | 
|  | 177           signature[pos++] = 'd'; | 
|  | 178         else | 
| 140           throw std::runtime_error("Unexpected function argument type"); | 179           throw std::runtime_error("Unexpected function argument type"); | 
| 141         } |  | 
| 142         args.push_back(item); | 180         args.push_back(item); | 
| 143       } | 181       } | 
| 144 | 182 | 
| 145       if (returnType != TypeCategory::VOID && returnType != TypeCategory::INT && | 183       signature[pos] = 0; | 
| 146           returnType != TypeCategory::DEPENDENT_STRING && |  | 
| 147           returnType != TypeCategory::OWNED_STRING && |  | 
| 148           returnType != TypeCategory::STRING_REF && |  | 
| 149           returnType != TypeCategory::CLASS_PTR) |  | 
| 150       { |  | 
| 151         throw std::runtime_error("Unexpected function return type"); |  | 
| 152       } |  | 
| 153 | 184 | 
| 154       effectiveArgs = args.size(); | 185       get_function_name(function, signature); | 
| 155       effectiveReturnType = returnType; |  | 
| 156       if (instance_function) |  | 
| 157         effectiveArgs++; |  | 
| 158 |  | 
| 159       if (returnType == TypeCategory::DEPENDENT_STRING || |  | 
| 160           returnType == TypeCategory::OWNED_STRING) |  | 
| 161       { |  | 
| 162         effectiveArgs++; |  | 
| 163         effectiveReturnType = TypeCategory::VOID; |  | 
| 164       } |  | 
| 165 |  | 
| 166       get_function_name(function, effectiveArgs, |  | 
| 167           effectiveReturnType == TypeCategory::VOID); |  | 
| 168     } | 186     } | 
| 169 | 187 | 
| 170     template<typename ReturnType, typename... Args> | 188     template<typename ReturnType, typename... Args> | 
| 171     FunctionInfo(ReturnType (*function)(Args...)) | 189     FunctionInfo(ReturnType (*function)(Args...)) | 
| 172         : FunctionInfo(TypeInfo<ReturnType>(), | 190         : FunctionInfo(TypeInfo<ReturnType>(), | 
| 173           TypeInfo<ReturnType>().pointer_type(), { TypeInfo<Args>()... }, false, | 191           TypeInfo<ReturnType>().pointer_type(), { TypeInfo<Args>()... }, false, | 
| 174           &function) | 192           &function) | 
| 175     { | 193     { | 
| 176     } | 194     } | 
| 177 | 195 | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 189           TypeInfo<ReturnType>().pointer_type(), { TypeInfo<Args>()... }, true, | 207           TypeInfo<ReturnType>().pointer_type(), { TypeInfo<Args>()... }, true, | 
| 190           &function) | 208           &function) | 
| 191     { | 209     { | 
| 192     } | 210     } | 
| 193 | 211 | 
| 194     bool empty() const | 212     bool empty() const | 
| 195     { | 213     { | 
| 196       return name[0] == '\0'; | 214       return name[0] == '\0'; | 
| 197     } | 215     } | 
| 198 | 216 | 
| 199     void get_function_name(void* ptr, int numArgs, bool voidResult) | 217     void get_function_name(void* ptr, char* signature) | 
| 200     { | 218     { | 
| 201       // This is a hack, C++ won't let us get the mangled function name. | 219       // This is a hack, C++ won't let us get the mangled function name. | 
| 202       // JavaScript is more dynamic so we pass the pointer to our function | 220       // JavaScript is more dynamic so we pass the pointer to our function | 
| 203       // there. With that and the function signature we can call the function - | 221       // there. With that and the function signature we can call the function - | 
| 204       // with a full stack so that we will cause it to abort. Sometimes the | 222       // with a full stack so that we will cause it to abort. Sometimes the | 
| 205       // function we are calling will also be missing from the build. The result | 223       // function we are calling will also be missing from the build. The result | 
| 206       // is the same: abort() is called which in turn calls stackTrace(). By | 224       // is the same: abort() is called which in turn calls stackTrace(). By | 
| 207       // replacing stackTrace() we get access to the call stack and search it | 225       // replacing stackTrace() we get access to the call stack and search it | 
| 208       // for the name of our function. | 226       // for the name of our function. | 
| 209 | 227 | 
| 210       EM_ASM_ARGS({ | 228       EM_ASM_ARGS({ | 
| 211         var signature = $3 ? "v" : "i"; | 229         var signature = AsciiToString($2); | 
| 212         var args = []; | 230         var args = []; | 
| 213         for (var i = 0; i < $2; i++) | 231         for (var i = 1; i < signature.length; i++) | 
| 214         { |  | 
| 215           signature += "i"; |  | 
| 216           args.push(0); | 232           args.push(0); | 
| 217         } |  | 
| 218 | 233 | 
| 219         var oldPrint = Module.print; | 234         var oldPrint = Module.print; | 
| 220         var oldPrintErr = Module.printErr; | 235         var oldPrintErr = Module.printErr; | 
| 221         var oldStackTrace = stackTrace; | 236         var oldStackTrace = stackTrace; | 
| 222         var sp = Runtime.stackSave(); | 237         var sp = Runtime.stackSave(); | 
| 223         Module.print = function(){}; | 238         Module.print = function(){}; | 
| 224         Module.printErr = function(){}; | 239         Module.printErr = function(){}; | 
| 225         stackTrace = function() | 240         stackTrace = function() | 
| 226         { | 241         { | 
| 227           var stack = []; | 242           var stack = []; | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
| 252         { | 267         { | 
| 253           Module.stringToAscii(e, $0); | 268           Module.stringToAscii(e, $0); | 
| 254         } | 269         } | 
| 255         finally | 270         finally | 
| 256         { | 271         { | 
| 257           Runtime.stackRestore(sp); | 272           Runtime.stackRestore(sp); | 
| 258           Module.print = oldPrint; | 273           Module.print = oldPrint; | 
| 259           Module.printErr = oldPrintErr; | 274           Module.printErr = oldPrintErr; | 
| 260           stackTrace = oldStackTrace; | 275           stackTrace = oldStackTrace; | 
| 261         } | 276         } | 
| 262       }, name, ptr, numArgs, voidResult); | 277       }, name, ptr, signature); | 
| 263     } | 278     } | 
| 264   }; | 279   }; | 
| 265 | 280 | 
| 266   class NoBaseClass | 281   class NoBaseClass | 
| 267   { | 282   { | 
| 268   }; | 283   }; | 
| 269 | 284 | 
| 270   struct PropertyInfo | 285   struct PropertyInfo | 
| 271   { | 286   { | 
| 272     std::string name; | 287     std::string name; | 
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 392     for (int i = 0; i < params.size(); i++) | 407     for (int i = 0; i < params.size(); i++) | 
| 393     { | 408     { | 
| 394       if (i > 0) | 409       if (i > 0) | 
| 395         call_str += ", "; | 410         call_str += ", "; | 
| 396       call_str += params[i]; | 411       call_str += params[i]; | 
| 397     } | 412     } | 
| 398     call_str += ")"; | 413     call_str += ")"; | 
| 399 | 414 | 
| 400     if (call.returnType == TypeCategory::VOID) | 415     if (call.returnType == TypeCategory::VOID) | 
| 401       return "  " + call_str + ";\n"; | 416       return "  " + call_str + ";\n"; | 
| 402     else if (call.returnType == TypeCategory::INT) | 417     else if (call.returnType == TypeCategory::INT || | 
|  | 418           call.returnType == TypeCategory::FLOAT) | 
|  | 419     { | 
| 403       return "  var result = " + call_str + ";\n"; | 420       return "  var result = " + call_str + ";\n"; | 
|  | 421     } | 
| 404     else if (call.returnType == TypeCategory::DEPENDENT_STRING || | 422     else if (call.returnType == TypeCategory::DEPENDENT_STRING || | 
| 405         call.returnType == TypeCategory::OWNED_STRING) | 423         call.returnType == TypeCategory::OWNED_STRING) | 
| 406     { | 424     { | 
| 407       std::string result; | 425       std::string result; | 
| 408       result += "  var string = createString();\n"; | 426       result += "  var string = createString();\n"; | 
| 409       result += "  " + call_str + ";\n"; | 427       result += "  " + call_str + ";\n"; | 
| 410       result += "  var result = readString(string);\n"; | 428       result += "  var result = readString(string);\n"; | 
| 411       if (call.returnType == TypeCategory::OWNED_STRING) | 429       if (call.returnType == TypeCategory::OWNED_STRING) | 
| 412         result += "  Module._DestroyString(string);\n"; | 430         result += "  Module._DestroyString(string);\n"; | 
| 413       return result; | 431       return result; | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 458       sprintf(buffer, "arg%i", i); | 476       sprintf(buffer, "arg%i", i); | 
| 459       if (i > 0) | 477       if (i > 0) | 
| 460         prefix += ", "; | 478         prefix += ", "; | 
| 461       prefix += buffer; | 479       prefix += buffer; | 
| 462 | 480 | 
| 463       if (call.args[i] == TypeCategory::STRING_REF) | 481       if (call.args[i] == TypeCategory::STRING_REF) | 
| 464       { | 482       { | 
| 465         hasStringArgs = true; | 483         hasStringArgs = true; | 
| 466         params.push_back(std::string("createString(") + buffer + ")"); | 484         params.push_back(std::string("createString(") + buffer + ")"); | 
| 467       } | 485       } | 
|  | 486       else if (call.args[i] == TypeCategory::CLASS_PTR) | 
|  | 487         params.push_back(std::string(buffer) + "._pointer"); | 
| 468       else | 488       else | 
| 469         params.push_back(buffer); | 489         params.push_back(buffer); | 
| 470     } | 490     } | 
| 471     prefix += ")\n{\n"; | 491     prefix += ")\n{\n"; | 
| 472 | 492 | 
| 473     std::string suffix = "}"; | 493     std::string suffix = "}"; | 
| 474     if (call.returnType != TypeCategory::VOID) | 494     if (call.returnType != TypeCategory::VOID) | 
| 475       suffix = "  return result;\n" + suffix; | 495       suffix = "  return result;\n" + suffix; | 
| 476 | 496 | 
| 477     if (call.returnType == TypeCategory::DEPENDENT_STRING || | 497     if (call.returnType == TypeCategory::DEPENDENT_STRING || | 
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 736 | 756 | 
| 737     std::vector<std::pair<int, std::string>> mapping; | 757     std::vector<std::pair<int, std::string>> mapping; | 
| 738     for (const auto& item : list) | 758     for (const auto& item : list) | 
| 739       mapping.emplace_back(item.first, item.second); | 759       mapping.emplace_back(item.first, item.second); | 
| 740 | 760 | 
| 741     bindings_internal::register_differentiator( | 761     bindings_internal::register_differentiator( | 
| 742         bindings_internal::TypeInfo<ClassType>(), offset, mapping); | 762         bindings_internal::TypeInfo<ClassType>(), offset, mapping); | 
| 743     return *this; | 763     return *this; | 
| 744   } | 764   } | 
| 745 }; | 765 }; | 
| OLD | NEW | 
|---|