| 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 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 | 246 |
| 247 if (classInfo->subclass_differentiator.offset != SIZE_MAX) | 247 if (classInfo->subclass_differentiator.offset != SIZE_MAX) |
| 248 throw std::runtime_error("More than one subclass differentiator defined fo
r class " + classInfo->name); | 248 throw std::runtime_error("More than one subclass differentiator defined fo
r class " + classInfo->name); |
| 249 | 249 |
| 250 DifferentiatorInfo differentiatorInfo; | 250 DifferentiatorInfo differentiatorInfo; |
| 251 differentiatorInfo.offset = offset; | 251 differentiatorInfo.offset = offset; |
| 252 differentiatorInfo.mapping = mapping; | 252 differentiatorInfo.mapping = mapping; |
| 253 classInfo->subclass_differentiator = differentiatorInfo; | 253 classInfo->subclass_differentiator = differentiatorInfo; |
| 254 } | 254 } |
| 255 | 255 |
| 256 const std::string generateCall(const FunctionInfo& call, | 256 std::string generateCall(const FunctionInfo& call, |
| 257 std::vector<std::string>& params) | 257 std::vector<std::string>& params) |
| 258 { | 258 { |
| 259 if (call.returnType == TypeCategory::DEPENDENT_STRING || | 259 if (call.returnType == TypeCategory::DEPENDENT_STRING || |
| 260 call.returnType == TypeCategory::OWNED_STRING) | 260 call.returnType == TypeCategory::OWNED_STRING) |
| 261 { | 261 { |
| 262 params.insert(params.begin(), "string"); | 262 params.insert(params.begin(), "string"); |
| 263 } | 263 } |
| 264 | 264 |
| 265 std::string call_str(call.name); | 265 std::string call_str(call.name); |
| 266 call_str += "("; | 266 call_str += "("; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 result += " }\n"; | 317 result += " }\n"; |
| 318 result += " else\n"; | 318 result += " else\n"; |
| 319 result += " result = null;\n"; | 319 result += " result = null;\n"; |
| 320 return result; | 320 return result; |
| 321 } | 321 } |
| 322 default: | 322 default: |
| 323 throw std::runtime_error("Unexpected return type for " + std::string(cal
l.name)); | 323 throw std::runtime_error("Unexpected return type for " + std::string(cal
l.name)); |
| 324 } | 324 } |
| 325 } | 325 } |
| 326 | 326 |
| 327 const std::string wrapCall(const FunctionInfo& call) | 327 std::string wrapCall(const FunctionInfo& call, bool isFunction) |
| 328 { | 328 { |
| 329 bool hasStringArgs = false; | 329 bool hasStringArgs = false; |
| 330 std::vector<std::string> params; | 330 std::vector<std::string> params; |
| 331 std::string prefix = "function("; | 331 std::string prefix; |
| 332 |
| 333 if (isFunction) |
| 334 prefix += "function"; |
| 335 prefix += "("; |
| 332 for (int i = 0; i < call.args.size(); i++) | 336 for (int i = 0; i < call.args.size(); i++) |
| 333 { | 337 { |
| 334 std::string argName("arg" + std::to_string(i)); | 338 std::string argName("arg" + std::to_string(i)); |
| 335 if (i > 0) | 339 if (i > 0) |
| 336 prefix += ", "; | 340 prefix += ", "; |
| 337 prefix += argName; | 341 prefix += argName; |
| 338 | 342 |
| 339 if (call.args[i] == TypeCategory::STRING_REF) | 343 if (call.args[i] == TypeCategory::STRING_REF) |
| 340 { | 344 { |
| 341 hasStringArgs = true; | 345 hasStringArgs = true; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 364 prefix += " var sp = Runtime.stackSave();\n"; | 368 prefix += " var sp = Runtime.stackSave();\n"; |
| 365 suffix = " Runtime.stackRestore(sp);\n" + suffix; | 369 suffix = " Runtime.stackRestore(sp);\n" + suffix; |
| 366 } | 370 } |
| 367 | 371 |
| 368 if (call.instance_function) | 372 if (call.instance_function) |
| 369 params.insert(params.begin(), "this._pointer"); | 373 params.insert(params.begin(), "this._pointer"); |
| 370 | 374 |
| 371 return prefix + generateCall(call, params) + suffix; | 375 return prefix + generateCall(call, params) + suffix; |
| 372 } | 376 } |
| 373 | 377 |
| 374 std::string generatePropertyDescriptor(const PropertyInfo& property) | |
| 375 { | |
| 376 if (!property.jsValue.empty()) | |
| 377 return "value: " + property.jsValue; | |
| 378 | |
| 379 std::string result("get: " + wrapCall(property.getter)); | |
| 380 if (!property.setter.empty()) | |
| 381 result += ", set: " + wrapCall(property.setter); | |
| 382 return result; | |
| 383 } | |
| 384 | |
| 385 void printHelpers() | 378 void printHelpers() |
| 386 { | 379 { |
| 387 printf("var sizeofString = %i;\n", sizeof(String)); | 380 printf("var sizeofString = %i;\n", sizeof(String)); |
| 388 | 381 |
| 389 puts(R"( | 382 puts(R"( |
| 390 function copyString(str, buffer) | 383 function copyString(str, buffer) |
| 391 { | 384 { |
| 392 var length = str.length; | 385 var length = str.length; |
| 393 for (var i = 0, pointer = (buffer >> 1); i < length; i++, pointer++) | 386 for (var i = 0, pointer = (buffer >> 1); i < length; i++, pointer++) |
| 394 HEAP16[pointer] = str.charCodeAt(i); | 387 HEAP16[pointer] = str.charCodeAt(i); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 410 return result; | 403 return result; |
| 411 } | 404 } |
| 412 | 405 |
| 413 function readString(str) | 406 function readString(str) |
| 414 { | 407 { |
| 415 var length = Module._GetStringLength(str); | 408 var length = Module._GetStringLength(str); |
| 416 var pointer = Module._GetStringData(str) >> 1; | 409 var pointer = Module._GetStringData(str) >> 1; |
| 417 return String.fromCharCode.apply(String, HEAP16.slice(pointer, pointer +
length)); | 410 return String.fromCharCode.apply(String, HEAP16.slice(pointer, pointer +
length)); |
| 418 } | 411 } |
| 419 | 412 |
| 420 function createClass(superclass, ref_counted_offset) | 413 function createClass(superclass, ref_counted_offset, props) |
| 421 { | 414 { |
| 422 var result = function(pointer) | 415 var result = function(pointer) |
| 423 { | 416 { |
| 424 this._pointer = pointer; | 417 this._pointer = pointer; |
| 425 }; | 418 }; |
| 426 if (superclass) | 419 var proto = (superclass ? superclass.prototype : null); |
| 427 result.prototype = Object.create(superclass.prototype); | 420 result.prototype = Object.create(proto, Object.getOwnPropertyDescriptors
(props)); |
| 428 result.prototype.delete = function() | 421 result.prototype.delete = function() |
| 429 { | 422 { |
| 430 Module._ReleaseRef(this._pointer + ref_counted_offset); | 423 Module._ReleaseRef(this._pointer + ref_counted_offset); |
| 431 }; | 424 }; |
| 432 return result; | 425 return result; |
| 433 } | 426 } |
| 434 )"); | 427 )"); |
| 435 } | 428 } |
| 436 | 429 |
| 437 void printClass(const ClassInfo& cls) | 430 void printClass(const ClassInfo& cls) |
| 438 { | 431 { |
| 432 // Begin class definition |
| 433 |
| 439 ClassInfo* baseClass = find_class(cls.baseClass); | 434 ClassInfo* baseClass = find_class(cls.baseClass); |
| 440 printf("exports.%s = createClass(%s, %i);\n", cls.name.c_str(), | 435 printf("exports.%s = createClass(%s, %i, {\n", cls.name.c_str(), |
| 441 (baseClass ? ("exports." + baseClass->name).c_str() : "null"), | 436 (baseClass ? ("exports." + baseClass->name).c_str() : "null"), |
| 442 cls.ref_counted_offset); | 437 cls.ref_counted_offset); |
| 443 | 438 |
| 439 // Print prototype members |
| 440 |
| 441 for (const auto& property : cls.properties) |
| 442 { |
| 443 if (property.jsValue.empty()) |
| 444 { |
| 445 printf("get %s%s,\n", property.name.c_str(), |
| 446 wrapCall(property.getter, false).c_str()); |
| 447 if (!property.setter.empty()) |
| 448 { |
| 449 printf("set %s%s,\n", property.name.c_str(), |
| 450 wrapCall(property.setter, false).c_str()); |
| 451 } |
| 452 } |
| 453 else |
| 454 printf("%s: %s,\n", property.name.c_str(), property.jsValue.c_str()); |
| 455 } |
| 456 |
| 457 for (const auto& method : cls.methods) |
| 458 if (method.call.instance_function) |
| 459 printf("%s: %s,\n", method.name.c_str(), wrapCall(method.call).c_str()); |
| 460 |
| 461 // End class definition |
| 462 |
| 463 printf("});\n"); |
| 464 |
| 465 // Print static members |
| 466 |
| 444 DifferentiatorInfo differentiator = cls.subclass_differentiator; | 467 DifferentiatorInfo differentiator = cls.subclass_differentiator; |
| 445 if (differentiator.offset != SIZE_MAX) | 468 if (differentiator.offset != SIZE_MAX) |
| 446 { | 469 { |
| 447 printf("var %s_mapping = \n", cls.name.c_str()); | 470 printf("var %s_mapping = \n", cls.name.c_str()); |
| 448 puts("{"); | 471 puts("{"); |
| 449 for (const auto& item : differentiator.mapping) | 472 for (const auto& item : differentiator.mapping) |
| 450 printf(" %i: '%s',\n", item.first, item.second.c_str()); | 473 printf(" %i: '%s',\n", item.first, item.second.c_str()); |
| 451 puts("};"); | 474 puts("};"); |
| 452 | 475 |
| 453 printf("exports.%s.fromPointer = function(ptr)\n", cls.name.c_str()); | 476 printf("exports.%s.fromPointer = function(ptr)\n", cls.name.c_str()); |
| 454 puts("{"); | 477 puts("{"); |
| 455 printf(" var type = HEAP32[ptr + %i >> 2];\n", differentiator.offset); | 478 printf(" var type = HEAP32[ptr + %i >> 2];\n", differentiator.offset); |
| 456 printf(" if (type in %s_mapping)\n", cls.name.c_str()); | 479 printf(" if (type in %s_mapping)\n", cls.name.c_str()); |
| 457 printf(" return new (exports[%s_mapping[type]])(ptr);\n", cls.name.c_st
r()); | 480 printf(" return new (exports[%s_mapping[type]])(ptr);\n", cls.name.c_st
r()); |
| 458 printf(" throw new Error('Unexpected %s type: ' + type);\n", cls.name.c_s
tr()); | 481 printf(" throw new Error('Unexpected %s type: ' + type);\n", cls.name.c_s
tr()); |
| 459 puts("};"); | 482 puts("};"); |
| 460 } | 483 } |
| 461 else | 484 else |
| 462 { | 485 { |
| 463 printf("exports.%s.fromPointer = function(ptr)\n", cls.name.c_str()); | 486 printf("exports.%s.fromPointer = function(ptr)\n", cls.name.c_str()); |
| 464 puts("{"); | 487 puts("{"); |
| 465 printf(" return new exports.%s(ptr);\n", cls.name.c_str()); | 488 printf(" return new exports.%s(ptr);\n", cls.name.c_str()); |
| 466 puts("};"); | 489 puts("};"); |
| 467 } | 490 } |
| 468 | 491 |
| 469 for (const auto& item : cls.properties) | 492 for (const auto& method : cls.methods) |
| 470 { | 493 { |
| 471 printf("Object.defineProperty(exports.%s.prototype, '%s', {%s});\n", | 494 if (!method.call.instance_function) |
| 472 cls.name.c_str(), item.name.c_str(), | 495 { |
| 473 generatePropertyDescriptor(item).c_str()); | 496 printf("exports.%s.%s = %s;\n", cls.name.c_str(), method.name.c_str(), |
| 474 } | 497 wrapCall(method.call).c_str()); |
| 475 | 498 } |
| 476 for (const auto& item : cls.methods) | |
| 477 { | |
| 478 std::string obj("exports." + cls.name); | |
| 479 if (item.call.instance_function) | |
| 480 obj += ".prototype"; | |
| 481 printf("%s.%s = %s;\n", obj.c_str(), item.name.c_str(), | |
| 482 wrapCall(item.call).c_str()); | |
| 483 } | 499 } |
| 484 } | 500 } |
| 485 } | 501 } |
| 486 | 502 |
| 487 void printBindings() | 503 void printBindings() |
| 488 { | 504 { |
| 489 bindings_internal::printHelpers(); | 505 bindings_internal::printHelpers(); |
| 490 | 506 |
| 491 for (const auto& item : classes) | 507 for (const auto& item : classes) |
| 492 bindings_internal::printClass(item); | 508 bindings_internal::printClass(item); |
| 493 } | 509 } |
| OLD | NEW |