Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: compiled/bindings/generator.cpp

Issue 29426559: Issue 5137 - [emscripten] Added basic filter storage implementation (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore
Patch Set: Created May 1, 2017, 2:36 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
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
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 #include <cstdio> 18 #include <cstdio>
19 19
20 #include <emscripten.h> 20 #include <emscripten.h>
21 21
22 #include "generator.h" 22 #include "generator.h"
23 23
24 namespace 24 namespace
25 { 25 {
26 std::vector<bindings_internal::ClassInfo> classes; 26 std::vector<bindings_internal::ClassInfo> classes;
27 std::vector<bindings_internal::NamespaceInfo> namespaces;
28
29 void printProperties(const bindings_internal::PropertyList& properties)
30 {
31 for (const auto& property : properties)
32 {
33 if (property.jsValue.empty())
34 {
35 printf("get %s%s,\n", property.name.c_str(),
36 wrapCall(property.getter, false).c_str());
37 if (!property.setter.empty())
38 {
39 printf("set %s%s,\n", property.name.c_str(),
40 wrapCall(property.setter, false).c_str());
41 }
42 }
43 else
44 printf("%s: %s,\n", property.name.c_str(), property.jsValue.c_str());
45 }
46 }
47
48 void printMethods(const bindings_internal::MethodList& methods,
49 bool instanceOnly = true)
50 {
51 for (const auto& method : methods)
52 if (!instanceOnly || method.call.instance_function)
53 printf("%s: %s,\n", method.name.c_str(), wrapCall(method.call).c_str());
54 }
27 } 55 }
28 56
29 namespace bindings_internal 57 namespace bindings_internal
30 { 58 {
31 FunctionInfo::FunctionInfo() 59 FunctionInfo::FunctionInfo()
32 { 60 {
33 name[0] = '\0'; 61 name[0] = '\0';
34 } 62 }
35 63
36 FunctionInfo::FunctionInfo(TypeCategory returnType, TYPEID pointerType, 64 FunctionInfo::FunctionInfo(TypeCategory returnType, TYPEID pointerType,
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 276
249 if (classInfo->subclass_differentiator.offset != SIZE_MAX) 277 if (classInfo->subclass_differentiator.offset != SIZE_MAX)
250 throw std::runtime_error("More than one subclass differentiator defined fo r class " + classInfo->name); 278 throw std::runtime_error("More than one subclass differentiator defined fo r class " + classInfo->name);
251 279
252 DifferentiatorInfo differentiatorInfo; 280 DifferentiatorInfo differentiatorInfo;
253 differentiatorInfo.offset = offset; 281 differentiatorInfo.offset = offset;
254 differentiatorInfo.mapping = mapping; 282 differentiatorInfo.mapping = mapping;
255 classInfo->subclass_differentiator = differentiatorInfo; 283 classInfo->subclass_differentiator = differentiatorInfo;
256 } 284 }
257 285
286 NamespaceInfo* find_namespace(const char* namespaceName)
287 {
288 for (auto& namespaceInfo : namespaces)
289 if (namespaceInfo.name == namespaceName)
290 return &namespaceInfo;
291 return nullptr;
292 }
293
294 void register_namespace(const char* name)
295 {
296 if (find_namespace(name))
297 throw std::runtime_error(std::string("Duplicate definition for namespace " ) + name);
298
299 NamespaceInfo namespaceInfo;
300 namespaceInfo.name = name;
301 namespaces.push_back(namespaceInfo);
302 }
303
304 void register_namespace_property(const char* namespaceName, const char* name,
305 const FunctionInfo& getter, const FunctionInfo& setter)
306 {
307 NamespaceInfo* namespaceInfo = find_namespace(namespaceName);
308 if (!namespaceInfo)
309 throw std::runtime_error(std::string("Property defined on unknown namespac e: ") + name);
310
311 PropertyInfo propertyInfo;
312 propertyInfo.name = name;
313 propertyInfo.getter = getter;
314 propertyInfo.setter = setter;
315 namespaceInfo->properties.push_back(propertyInfo);
316 }
317
318 void register_namespace_method(const char* namespaceName, const char* name,
319 const FunctionInfo& call)
320 {
321 NamespaceInfo* namespaceInfo = find_namespace(namespaceName);
322 if (!namespaceInfo)
323 throw std::runtime_error(std::string("Method defined on unknown namespace: ") + name);
324
325 MethodInfo methodInfo;
326 methodInfo.name = name;
327 methodInfo.call = call;
328 namespaceInfo->methods.push_back(methodInfo);
329 }
Wladimir Palant 2017/05/01 14:47:25 I'm not really happy with the complexity required
sergei 2017/05/08 10:54:39 I would like to include in that discussion the des
Wladimir Palant 2017/05/08 12:55:41 I considered making FilterStorage a singleton clas
sergei 2017/08/24 13:32:04 Singleton and global variables are actually equall
330
258 std::string generateCall(const FunctionInfo& call, 331 std::string generateCall(const FunctionInfo& call,
259 std::vector<std::string>& params) 332 std::vector<std::string>& params)
260 { 333 {
261 if (call.returnType == TypeCategory::DEPENDENT_STRING || 334 if (call.returnType == TypeCategory::DEPENDENT_STRING ||
262 call.returnType == TypeCategory::OWNED_STRING) 335 call.returnType == TypeCategory::OWNED_STRING)
263 { 336 {
264 params.insert(params.begin(), "string"); 337 params.insert(params.begin(), "string");
265 } 338 }
266 339
267 std::string call_str(call.name); 340 std::string call_str(call.name);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 if (i > 0) 414 if (i > 0)
342 prefix += ", "; 415 prefix += ", ";
343 prefix += argName; 416 prefix += argName;
344 417
345 if (call.args[i] == TypeCategory::STRING_REF) 418 if (call.args[i] == TypeCategory::STRING_REF)
346 { 419 {
347 hasStringArgs = true; 420 hasStringArgs = true;
348 params.push_back(std::string("createString(") + argName + ")"); 421 params.push_back(std::string("createString(") + argName + ")");
349 } 422 }
350 else if (call.args[i] == TypeCategory::CLASS_PTR) 423 else if (call.args[i] == TypeCategory::CLASS_PTR)
351 params.push_back(argName + "._pointer"); 424 params.push_back(argName + " ? " + argName + "._pointer : 0");
Wladimir Palant 2017/05/01 14:47:25 Turns out we weren't supporting null for parameter
sergei 2017/05/08 10:54:39 In addition I wonder whether we can use C++ refere
Wladimir Palant 2017/05/08 12:55:41 We could use references easily but these won't be
sergei 2017/08/24 13:32:04 Currently one has to manually test whether a point
Wladimir Palant 2017/08/31 11:32:34 I filed https://issues.adblockplus.org/ticket/5603
352 else if (call.args[i] == TypeCategory::INT64) 425 else if (call.args[i] == TypeCategory::INT64)
353 { 426 {
354 // 64-bit integers are passed as two integer parameters 427 // 64-bit integers are passed as two integer parameters
355 params.push_back(argName + " >>> 0"); 428 params.push_back(argName + " >>> 0");
356 params.push_back(argName + " / 0x100000000 >>> 0"); 429 params.push_back(argName + " / 0x100000000 >>> 0");
357 } 430 }
358 else 431 else
359 params.push_back(argName); 432 params.push_back(argName);
360 } 433 }
361 prefix += ")\n{\n"; 434 prefix += ")\n{\n";
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 Module._ReleaseRef(this._pointer + ref_counted_offset); 498 Module._ReleaseRef(this._pointer + ref_counted_offset);
426 }; 499 };
427 return result; 500 return result;
428 } 501 }
429 )"); 502 )");
430 } 503 }
431 504
432 void printClass(const ClassInfo& cls) 505 void printClass(const ClassInfo& cls)
433 { 506 {
434 // Begin class definition 507 // Begin class definition
435
436 ClassInfo* baseClass = find_class(cls.baseClass); 508 ClassInfo* baseClass = find_class(cls.baseClass);
437 printf("exports.%s = createClass(%s, %i, {\n", cls.name.c_str(), 509 printf("exports.%s = createClass(%s, %i, {\n", cls.name.c_str(),
438 (baseClass ? ("exports." + baseClass->name).c_str() : "null"), 510 (baseClass ? ("exports." + baseClass->name).c_str() : "null"),
439 cls.ref_counted_offset); 511 cls.ref_counted_offset);
440 512
441 // Print prototype members 513 // Print prototype members
442 514 printProperties(cls.properties);
443 for (const auto& property : cls.properties) 515 printMethods(cls.methods);
444 {
445 if (property.jsValue.empty())
446 {
447 printf("get %s%s,\n", property.name.c_str(),
448 wrapCall(property.getter, false).c_str());
449 if (!property.setter.empty())
450 {
451 printf("set %s%s,\n", property.name.c_str(),
452 wrapCall(property.setter, false).c_str());
453 }
454 }
455 else
456 printf("%s: %s,\n", property.name.c_str(), property.jsValue.c_str());
457 }
458
459 for (const auto& method : cls.methods)
460 if (method.call.instance_function)
461 printf("%s: %s,\n", method.name.c_str(), wrapCall(method.call).c_str());
462 516
463 // End class definition 517 // End class definition
464
465 printf("});\n"); 518 printf("});\n");
466 519
467 // Print static members 520 // Print static members
468
469 DifferentiatorInfo differentiator = cls.subclass_differentiator; 521 DifferentiatorInfo differentiator = cls.subclass_differentiator;
470 if (differentiator.offset != SIZE_MAX) 522 if (differentiator.offset != SIZE_MAX)
471 { 523 {
472 printf("var %s_mapping = \n", cls.name.c_str()); 524 printf("var %s_mapping = \n", cls.name.c_str());
473 puts("{"); 525 puts("{");
474 for (const auto& item : differentiator.mapping) 526 for (const auto& item : differentiator.mapping)
475 printf(" %i: '%s',\n", item.first, item.second.c_str()); 527 printf(" %i: '%s',\n", item.first, item.second.c_str());
476 puts("};"); 528 puts("};");
477 529
478 printf("exports.%s.fromPointer = function(ptr)\n", cls.name.c_str()); 530 printf("exports.%s.fromPointer = function(ptr)\n", cls.name.c_str());
(...skipping 14 matching lines...) Expand all
493 545
494 for (const auto& method : cls.methods) 546 for (const auto& method : cls.methods)
495 { 547 {
496 if (!method.call.instance_function) 548 if (!method.call.instance_function)
497 { 549 {
498 printf("exports.%s.%s = %s;\n", cls.name.c_str(), method.name.c_str(), 550 printf("exports.%s.%s = %s;\n", cls.name.c_str(), method.name.c_str(),
499 wrapCall(method.call).c_str()); 551 wrapCall(method.call).c_str());
500 } 552 }
501 } 553 }
502 } 554 }
555
556 void printNamespace(const NamespaceInfo& namespaceInfo)
557 {
558 printf("exports.%s = {\n", namespaceInfo.name.c_str());
559 printProperties(namespaceInfo.properties);
560 printMethods(namespaceInfo.methods, false);
561 puts("};");
562 }
503 } 563 }
504 564
505 void printBindings() 565 void printBindings()
506 { 566 {
507 bindings_internal::printHelpers(); 567 bindings_internal::printHelpers();
508 568
509 for (const auto& item : classes) 569 for (const auto& item : classes)
510 bindings_internal::printClass(item); 570 bindings_internal::printClass(item);
571 for (const auto& item : namespaces)
572 bindings_internal::printNamespace(item);
511 } 573 }
OLDNEW

Powered by Google App Engine
This is Rietveld