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: Rebased, updated copyright year Created Aug. 22, 2017, 11:03 a.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-present eyeo GmbH 3 * Copyright (C) 2006-present 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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld