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 |