| 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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 121 | 121 | 
| 122   ClassInfo* find_class(TYPEID classID) | 122   ClassInfo* find_class(TYPEID classID) | 
| 123   { | 123   { | 
| 124     for (auto& classInfo : classes) | 124     for (auto& classInfo : classes) | 
| 125       if (classInfo.id == classID) | 125       if (classInfo.id == classID) | 
| 126         return &classInfo; | 126         return &classInfo; | 
| 127     return nullptr; | 127     return nullptr; | 
| 128   } | 128   } | 
| 129 | 129 | 
| 130   void register_class(const char* name, TYPEID classID, TYPEID baseClassID, | 130   void register_class(const char* name, TYPEID classID, TYPEID baseClassID, | 
| 131                       ptrdiff_t ref_counted_offset) | 131                       ptrdiff_t ref_counted_offset, | 
|  | 132                       const FunctionInfo& instanceGetter) | 
| 132   { | 133   { | 
| 133     if (find_class(classID)) | 134     if (find_class(classID)) | 
| 134       throw std::runtime_error(std::string("Duplicate definition for class ") + 
     name); | 135       throw std::runtime_error(std::string("Duplicate definition for class ") + 
     name); | 
| 135 | 136 | 
| 136     if (baseClassID != TypeInfo<NoBaseClass>() && !find_class(baseClassID)) | 137     if (baseClassID != TypeInfo<NoBaseClass>() && !find_class(baseClassID)) | 
| 137       throw std::runtime_error(std::string("Unknown base class defined for class
      ") + name); | 138       throw std::runtime_error(std::string("Unknown base class defined for class
      ") + name); | 
| 138 | 139 | 
| 139     ClassInfo classInfo; | 140     ClassInfo classInfo; | 
| 140     classInfo.id = classID; | 141     classInfo.id = classID; | 
| 141     classInfo.baseClass = baseClassID; | 142     classInfo.baseClass = baseClassID; | 
| 142     classInfo.name = name; | 143     classInfo.name = name; | 
| 143     classInfo.subclass_differentiator.offset = SIZE_MAX; | 144     classInfo.subclass_differentiator.offset = SIZE_MAX; | 
| 144     classInfo.ref_counted_offset = ref_counted_offset; | 145     classInfo.ref_counted_offset = ref_counted_offset; | 
|  | 146     classInfo.instanceGetter = instanceGetter; | 
| 145     classes.push_back(classInfo); | 147     classes.push_back(classInfo); | 
| 146   } | 148   } | 
| 147 | 149 | 
| 148   void register_property(TYPEID classID, const char* name, | 150   void register_property(TYPEID classID, const char* name, | 
| 149       const FunctionInfo& getter, const FunctionInfo& setter, | 151       const FunctionInfo& getter, const FunctionInfo& setter, | 
| 150       const char* jsValue) | 152       const char* jsValue) | 
| 151   { | 153   { | 
| 152     ClassInfo* classInfo = find_class(classID); | 154     ClassInfo* classInfo = find_class(classID); | 
| 153     if (!classInfo) | 155     if (!classInfo) | 
| 154       throw std::runtime_error(std::string("Property defined on unknown class: "
     ) + name); | 156       throw std::runtime_error(std::string("Property defined on unknown class: "
     ) + name); | 
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 238         result += "  Module._DestroyString(string);\n"; | 240         result += "  Module._DestroyString(string);\n"; | 
| 239         return result; | 241         return result; | 
| 240       } | 242       } | 
| 241       case TypeCategory::STRING_REF: | 243       case TypeCategory::STRING_REF: | 
| 242         return "  var result = readString(" + call_str + ");\n"; | 244         return "  var result = readString(" + call_str + ");\n"; | 
| 243       case TypeCategory::CLASS_PTR: | 245       case TypeCategory::CLASS_PTR: | 
| 244       { | 246       { | 
| 245         std::string result; | 247         std::string result; | 
| 246         result += "  var result = " + call_str + ";\n"; | 248         result += "  var result = " + call_str + ";\n"; | 
| 247         result += "  if (result)\n"; | 249         result += "  if (result)\n"; | 
| 248         result += "  {\n"; |  | 
| 249 | 250 | 
| 250         const ClassInfo* cls = find_class(call.pointerType); | 251         const ClassInfo* cls = find_class(call.pointerType); | 
| 251         if (!cls) | 252         if (!cls) | 
| 252           throw std::runtime_error("Function " + call.name + " returns pointer t
     o unknown class"); | 253           throw std::runtime_error("Function " + call.name + " returns pointer t
     o unknown class"); | 
| 253 | 254 | 
| 254         auto offset = cls->subclass_differentiator.offset; | 255         auto offset = cls->subclass_differentiator.offset; | 
| 255         if (offset == SIZE_MAX) | 256         if (offset == SIZE_MAX) | 
| 256           result += "    result = exports." + cls->name + "(result);\n"; | 257           result += "    result = exports." + cls->name + "(result);\n"; | 
| 257         else | 258         else | 
| 258           result += "    result = exports." + cls->name + ".fromPointer(result);
     \n"; | 259           result += "    result = exports." + cls->name + ".fromPointer(result);
     \n"; | 
| 259 | 260 | 
| 260         result += "  }\n"; |  | 
| 261         result += "  else\n"; | 261         result += "  else\n"; | 
| 262         result += "    result = null;\n"; | 262         result += "    result = null;\n"; | 
| 263         return result; | 263         return result; | 
| 264       } | 264       } | 
| 265       default: | 265       default: | 
| 266         throw std::runtime_error("Unexpected return type for " + call.name); | 266         throw std::runtime_error("Unexpected return type for " + call.name); | 
| 267     } | 267     } | 
| 268   } | 268   } | 
| 269 | 269 | 
| 270   std::string wrapCall(const FunctionInfo& call, bool isFunction) | 270   std::string wrapCall(const FunctionInfo& call, bool isFunction, | 
|  | 271       const FunctionInfo& instanceGetter) | 
| 271   { | 272   { | 
| 272     bool hasStringArgs = false; | 273     bool hasStringArgs = false; | 
| 273     std::vector<std::string> params; | 274     std::vector<std::string> params; | 
| 274     std::string prefix; | 275     std::string prefix; | 
| 275 | 276 | 
| 276     if (isFunction) | 277     if (isFunction) | 
| 277       prefix += "function"; | 278       prefix += "function"; | 
| 278     prefix += "("; | 279     prefix += "("; | 
| 279     for (int i = 0; i < call.args.size(); i++) | 280     for (int i = 0; i < call.args.size(); i++) | 
| 280     { | 281     { | 
| 281       std::string argName("arg" + std::to_string(i)); | 282       std::string argName("arg" + std::to_string(i)); | 
| 282       if (i > 0) | 283       if (i > 0) | 
| 283         prefix += ", "; | 284         prefix += ", "; | 
| 284       prefix += argName; | 285       prefix += argName; | 
| 285 | 286 | 
| 286       if (call.args[i] == TypeCategory::STRING_REF) | 287       if (call.args[i] == TypeCategory::STRING_REF) | 
| 287       { | 288       { | 
| 288         hasStringArgs = true; | 289         hasStringArgs = true; | 
| 289         params.push_back(std::string("createString(") + argName + ")"); | 290         params.push_back(std::string("createString(") + argName + ")"); | 
| 290       } | 291       } | 
| 291       else if (call.args[i] == TypeCategory::CLASS_PTR) | 292       else if (call.args[i] == TypeCategory::CLASS_PTR) | 
| 292         params.push_back(argName + "._pointer"); | 293         params.push_back(argName + " ? " + argName + "._pointer : 0"); | 
| 293       else if (call.args[i] == TypeCategory::INT64) | 294       else if (call.args[i] == TypeCategory::INT64) | 
| 294       { | 295       { | 
| 295         // 64-bit integers are passed as two integer parameters | 296         // 64-bit integers are passed as two integer parameters | 
| 296         params.push_back(argName + " >>> 0"); | 297         params.push_back(argName + " >>> 0"); | 
| 297         params.push_back(argName + " / 0x100000000 >>> 0"); | 298         params.push_back(argName + " / 0x100000000 >>> 0"); | 
| 298       } | 299       } | 
| 299       else | 300       else | 
| 300         params.push_back(argName); | 301         params.push_back(argName); | 
| 301     } | 302     } | 
| 302     prefix += ")\n{\n"; | 303     prefix += ")\n{\n"; | 
| 303 | 304 | 
| 304     std::string suffix = "}"; | 305     std::string suffix = "}"; | 
| 305     if (call.returnType != TypeCategory::VOID) | 306     if (call.returnType != TypeCategory::VOID) | 
| 306       suffix = "  return result;\n" + suffix; | 307       suffix = "  return result;\n" + suffix; | 
| 307 | 308 | 
| 308     if (call.returnType == TypeCategory::DEPENDENT_STRING || | 309     if (call.returnType == TypeCategory::DEPENDENT_STRING || | 
| 309         call.returnType == TypeCategory::OWNED_STRING || hasStringArgs) | 310         call.returnType == TypeCategory::OWNED_STRING || hasStringArgs) | 
| 310     { | 311     { | 
| 311       prefix += "  var sp = Runtime.stackSave();\n"; | 312       prefix += "  var sp = Runtime.stackSave();\n"; | 
| 312       suffix = "  Runtime.stackRestore(sp);\n" + suffix; | 313       suffix = "  Runtime.stackRestore(sp);\n" + suffix; | 
| 313     } | 314     } | 
| 314 | 315 | 
| 315     if (call.instance_function) | 316     if (call.instance_function) | 
| 316       params.insert(params.begin(), "this._pointer"); | 317     { | 
|  | 318       if (instanceGetter.empty()) | 
|  | 319         params.insert(params.begin(), "this._pointer"); | 
|  | 320       else | 
|  | 321         params.insert(params.begin(), instanceGetter.name + "()"); | 
|  | 322     } | 
| 317 | 323 | 
| 318     return prefix + generateCall(call, params) + suffix; | 324     return prefix + generateCall(call, params) + suffix; | 
| 319   } | 325   } | 
| 320 | 326 | 
| 321   void printHelpers() | 327   void printHelpers() | 
| 322   { | 328   { | 
| 323     printf("var sizeofString = %i;\n", sizeof(String)); | 329     printf("var sizeofString = %i;\n", sizeof(String)); | 
| 324 | 330 | 
| 325     puts(R"( | 331     puts(R"( | 
| 326       function copyString(str, buffer) | 332       function copyString(str, buffer) | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 373           Module._ReleaseRef(this._pointer + ref_counted_offset); | 379           Module._ReleaseRef(this._pointer + ref_counted_offset); | 
| 374         }; | 380         }; | 
| 375         return result; | 381         return result; | 
| 376       } | 382       } | 
| 377     )"); | 383     )"); | 
| 378   } | 384   } | 
| 379 | 385 | 
| 380   void printClass(const ClassInfo& cls) | 386   void printClass(const ClassInfo& cls) | 
| 381   { | 387   { | 
| 382     // Begin class definition | 388     // Begin class definition | 
| 383 | 389     bool singleton = !cls.instanceGetter.empty(); | 
| 384     ClassInfo* baseClass = find_class(cls.baseClass); | 390     if (singleton) | 
| 385     printf("exports.%s = createClass(%s, %i, {\n", cls.name.c_str(), | 391       printf("exports.%s = {\n", cls.name.c_str()); | 
| 386         (baseClass ? ("exports." + baseClass->name).c_str() : "null"), | 392     else | 
| 387         cls.ref_counted_offset); | 393     { | 
|  | 394       ClassInfo* baseClass = find_class(cls.baseClass); | 
|  | 395       printf("exports.%s = createClass(%s, %i, {\n", cls.name.c_str(), | 
|  | 396           (baseClass ? ("exports." + baseClass->name).c_str() : "null"), | 
|  | 397           cls.ref_counted_offset); | 
|  | 398     } | 
| 388 | 399 | 
| 389     // Print prototype members | 400     // Print prototype members | 
| 390 |  | 
| 391     for (const auto& property : cls.properties) | 401     for (const auto& property : cls.properties) | 
| 392     { | 402     { | 
| 393       if (property.jsValue.empty()) | 403       if (property.jsValue.empty()) | 
| 394       { | 404       { | 
| 395         printf("get %s%s,\n", property.name.c_str(), | 405         printf("get %s%s,\n", property.name.c_str(), | 
| 396                wrapCall(property.getter, false).c_str()); | 406                wrapCall(property.getter, false, cls.instanceGetter).c_str()); | 
| 397         if (!property.setter.empty()) | 407         if (!property.setter.empty()) | 
| 398         { | 408         { | 
| 399           printf("set %s%s,\n", property.name.c_str(), | 409           printf("set %s%s,\n", property.name.c_str(), | 
| 400                  wrapCall(property.setter, false).c_str()); | 410                  wrapCall(property.setter, false, cls.instanceGetter).c_str()); | 
| 401         } | 411         } | 
| 402       } | 412       } | 
| 403       else | 413       else | 
| 404         printf("%s: %s,\n", property.name.c_str(), property.jsValue.c_str()); | 414         printf("%s: %s,\n", property.name.c_str(), property.jsValue.c_str()); | 
| 405     } | 415     } | 
| 406 | 416 | 
| 407     for (const auto& method : cls.methods) | 417     for (const auto& method : cls.methods) | 
|  | 418     { | 
| 408       if (method.call.instance_function) | 419       if (method.call.instance_function) | 
| 409         printf("%s: %s,\n", method.name.c_str(), wrapCall(method.call).c_str()); | 420       { | 
|  | 421         printf("%s: %s,\n", | 
|  | 422             method.name.c_str(), | 
|  | 423             wrapCall(method.call, true, cls.instanceGetter).c_str()); | 
|  | 424       } | 
|  | 425     } | 
| 410 | 426 | 
| 411     // End class definition | 427     // End class definition | 
| 412 | 428     if (singleton) | 
| 413     printf("});\n"); | 429       printf("};\n"); | 
|  | 430     else | 
|  | 431       printf("});\n"); | 
| 414 | 432 | 
| 415     // Print static members | 433     // Print static members | 
| 416 |  | 
| 417     DifferentiatorInfo differentiator = cls.subclass_differentiator; | 434     DifferentiatorInfo differentiator = cls.subclass_differentiator; | 
| 418     if (differentiator.offset != SIZE_MAX) | 435     if (differentiator.offset != SIZE_MAX) | 
| 419     { | 436     { | 
| 420       printf("exports.%s.fromPointer = function(ptr)\n", cls.name.c_str()); | 437       printf("exports.%s.fromPointer = function(ptr)\n", cls.name.c_str()); | 
| 421       puts("{"); | 438       puts("{"); | 
| 422       printf("  var type = HEAP32[ptr + %i >> 2];\n", differentiator.offset); | 439       printf("  var type = HEAP32[ptr + %i >> 2];\n", differentiator.offset); | 
| 423       printf("  if (type in %s_mapping)\n", cls.name.c_str()); | 440       printf("  if (type in %s_mapping)\n", cls.name.c_str()); | 
| 424       printf("    return new %s_mapping[type](ptr);\n", cls.name.c_str()); | 441       printf("    return new %s_mapping[type](ptr);\n", cls.name.c_str()); | 
| 425       printf("  throw new Error('Unexpected %s type: ' + type);\n", cls.name.c_s
     tr()); | 442       printf("  throw new Error('Unexpected %s type: ' + type);\n", cls.name.c_s
     tr()); | 
| 426       puts("};"); | 443       puts("};"); | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 459 | 476 | 
| 460 void printBindings() | 477 void printBindings() | 
| 461 { | 478 { | 
| 462   bindings_internal::printHelpers(); | 479   bindings_internal::printHelpers(); | 
| 463 | 480 | 
| 464   for (const auto& cls : classes) | 481   for (const auto& cls : classes) | 
| 465     bindings_internal::printClass(cls); | 482     bindings_internal::printClass(cls); | 
| 466   for (const auto& cls : classes) | 483   for (const auto& cls : classes) | 
| 467     bindings_internal::printClassMapping(cls); | 484     bindings_internal::printClassMapping(cls); | 
| 468 } | 485 } | 
| OLD | NEW | 
|---|