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

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

Issue 29431555: Issue 5216 - [emscripten] Use a more reliable way of retrieving mangled function name (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore
Patch Set: Created May 6, 2017, 8:36 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-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>
21
22 #include "generator.h" 20 #include "generator.h"
21 #include "library.h"
23 22
24 namespace 23 namespace
25 { 24 {
26 std::vector<bindings_internal::ClassInfo> classes; 25 std::vector<bindings_internal::ClassInfo> classes;
27 std::vector<bindings_internal::NamespaceInfo> namespaces; 26 std::vector<bindings_internal::NamespaceInfo> namespaces;
28 27
29 void printProperties(const bindings_internal::PropertyList& properties) 28 void printProperties(const bindings_internal::PropertyList& properties)
30 { 29 {
31 for (const auto& property : properties) 30 for (const auto& property : properties)
32 { 31 {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 break; 133 break;
135 case TypeCategory::DOUBLE: 134 case TypeCategory::DOUBLE:
136 signature += 'd'; 135 signature += 'd';
137 break; 136 break;
138 default: 137 default:
139 throw std::runtime_error("Unexpected function argument type"); 138 throw std::runtime_error("Unexpected function argument type");
140 } 139 }
141 args.push_back(type); 140 args.push_back(type);
142 } 141 }
143 142
144 get_function_name(function, signature.c_str()); 143 GetFunctionName(name, function, signature.c_str());
145 } 144 }
146 145
147 bool FunctionInfo::empty() const 146 bool FunctionInfo::empty() const
148 { 147 {
149 return name[0] == '\0'; 148 return name[0] == '\0';
150 } 149 }
151 150
152 void FunctionInfo::get_function_name(void* ptr, const char* signature)
153 {
154 // This is a hack, C++ won't let us get the mangled function name.
155 // JavaScript is more dynamic so we pass the pointer to our function
156 // there. With that and the function signature we can call the function -
157 // with a full stack so that we will cause it to abort. Sometimes the
158 // function we are calling will also be missing from the build. The result
159 // is the same: abort() is called which in turn calls stackTrace(). By
160 // replacing stackTrace() we get access to the call stack and search it
161 // for the name of our function.
162
163 EM_ASM_ARGS({
164 var signature = AsciiToString($2);
165 var args = [];
166 for (var i = 1; i < signature.length; i++)
167 args.push(0);
168
169 var oldPrint = Module.print;
170 var oldPrintErr = Module.printErr;
171 var oldStackTrace = stackTrace;
172 var sp = Runtime.stackSave();
173 Module.print = function(){};
174 Module.printErr = function(){};
175 stackTrace = function()
176 {
177 var stack = [];
178 for (var f = arguments.callee.caller; f; f = f.caller)
179 {
180 if (f.name)
181 {
182 if (f.name.indexOf("dynCall") == 0)
183 break;
184 else
185 stack.push(f.name);
186 }
187 }
188
189 result = stack[stack.length - 1];
190 if (result && result.indexOf("__wrapper") >= 0)
191 result = stack[stack.length - 2];
192 throw result;
193 };
194
195 Runtime.stackRestore(STACK_MAX);
196
197 try
198 {
199 Runtime.dynCall(signature, HEAP32[$1 >> 2], args);
200 }
201 catch(e)
202 {
203 Module.stringToAscii(e, $0);
204 }
205 finally
206 {
207 Runtime.stackRestore(sp);
208 Module.print = oldPrint;
209 Module.printErr = oldPrintErr;
210 stackTrace = oldStackTrace;
211 }
212 }, name, ptr, signature);
213 }
214
215 ClassInfo* find_class(TYPEID classID) 151 ClassInfo* find_class(TYPEID classID)
216 { 152 {
217 for (auto& classInfo : classes) 153 for (auto& classInfo : classes)
218 if (classInfo.id == classID) 154 if (classInfo.id == classID)
219 return &classInfo; 155 return &classInfo;
220 return nullptr; 156 return nullptr;
221 } 157 }
222 158
223 void register_class(const char* name, TYPEID classID, TYPEID baseClassID, 159 void register_class(const char* name, TYPEID classID, TYPEID baseClassID,
224 ptrdiff_t ref_counted_offset) 160 ptrdiff_t ref_counted_offset)
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 500
565 void printBindings() 501 void printBindings()
566 { 502 {
567 bindings_internal::printHelpers(); 503 bindings_internal::printHelpers();
568 504
569 for (const auto& item : classes) 505 for (const auto& item : classes)
570 bindings_internal::printClass(item); 506 bindings_internal::printClass(item);
571 for (const auto& item : namespaces) 507 for (const auto& item : namespaces)
572 bindings_internal::printNamespace(item); 508 bindings_internal::printNamespace(item);
573 } 509 }
OLDNEW
« no previous file with comments | « compile ('k') | compiled/bindings/library.h » ('j') | compiled/bindings/library.js » ('J')

Powered by Google App Engine
This is Rietveld