VaKeR CYBER ARMY
Logo of a company Server : Apache/2.4.41 (Ubuntu)
System : Linux absol.cf 5.4.0-198-generic #218-Ubuntu SMP Fri Sep 27 20:18:53 UTC 2024 x86_64
User : www-data ( 33)
PHP Version : 7.4.33
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Directory :  /usr/share/emscripten/src/experimental/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //usr/share/emscripten/src/experimental/functypeopt.diff
diff --git a/src/parseTools.js b/src/parseTools.js
index 9786460..fb4be9f 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -205,26 +205,57 @@ function isFunctionDef(token, out) {
 function isPossiblyFunctionType(type) {
   // A quick but unreliable way to see if something is a function type. Yes is just 'maybe', no is definite.
   var len = type.length;
-  return type[len-2] == ')' && type[len-1] == '*';
+  return type[len-2] == ')' && type[len-1] == '*' && type.indexOf('(') > 0;
 }
 
 function isFunctionType(type, out) {
   if (!isPossiblyFunctionType(type)) return false;
   type = type.replace(/"[^"]+"/g, '".."');
-  var parts;
   // hackish, but quick splitting of function def parts. this must be fast as it happens a lot
-  if (type[0] != '[') {
-    parts = type.split(' ');
-  } else {
-    var index = type.search(']');
-    index += type.substr(index).search(' ');
-    parts = [type.substr(0, index), type.substr(index+1)];
-  }
+  var parts = type.split(' ');
   if (pointingLevels(type) !== 1) return false;
   var text = removeAllPointing(parts.slice(1).join(' '));
   if (!text) return false;
-  if (out) out.returnType = parts[0];
-  return isType(parts[0]) && isFunctionDef({ text: text, item: tokenize(text.substr(1, text.length-2), true) }, out);
+  if (!isType(parts[0])) return false;
+  var level = 0;
+  var chunks = [];
+  var currStart = 0;
+  for (var i = 0; i < type.length; i++) {
+    var curr = type[i];
+    if (curr == '(') {
+      level++;
+      if (level == 1) {
+        chunks.push(type.substring(currStart, i));
+        currStart = i+1;
+      }
+    } else if (curr == ')') {
+      level--;
+      if (level == 0) {
+        curr = type.substring(currStart, i);
+        if (curr == '') curr = '$'; // make sure inside of () stays valid
+        chunks.push(curr);
+        currStart = i+1;
+      }
+    }
+  }
+//printErr('pre chunks ' + JSON.stringify(chunks));
+  chunks = chunks.map(function(chunk) { return chunk.replace(/ /g, '') })
+                 .filter(function(chunk) { return chunk.length > 0 })
+                 .map(function(chunk) { return chunk.replace(/\$/g, ' ') });
+//printErr('post chunks ' + JSON.stringify(chunks));
+  switch (chunks.length) {
+    case 2: { // e.g.  void (i32,i32)
+      if (out) out.returnType = chunks[0]; // TODO: add cache, with this as the value
+      return isFunctionDef({ text: '(' + chunks[1] + ')', item: tokenize(chunks[1], true) }, out);
+    }
+    case 4: { // e.g.  void (i32)* (i32, i32)  (i.e., returns void (i32)*!)
+      if (chunks[2] != '*') return false;
+      if (out) out.returnType = chunks[0] + ' ' + chunks[1];
+      return isFunctionDef({ text: '(' + chunks[1] + ')', item: tokenize(chunks[1], true) }) &&
+             isFunctionDef({ text: '(' + chunks[2] + ')', item: tokenize(chunks[2], true) }, out);
+    }
+  }
+  return false;
 }
 
 var isTypeCache = {}; // quite hot, optimize as much as possible
diff --git a/tests/runner.py b/tests/runner.py
index 842daca..312541f 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -2860,6 +2860,35 @@ Exiting setjmp function, level: 0, prev_jmp: -1
           '''
         self.do_run(src, 'fn2(-5) = 5, fn(10) = 3.16')
 
+    def test_funcptrfunc(self):
+      src = r'''
+        #include <stdio.h>
+
+/*
+define internal fastcc void ()* @sqlite3OsDlSym(%struct.sqlite3_vfs* %pVfs, i8* %pHdle, i8* %zSym) nounwind {
+  %1 = getelementptr inbounds %struct.sqlite3_vfs* %pVfs, i32 0, i32 12
+  %2 = load void ()* (%struct.sqlite3_vfs*, i8*, i8*)** %1, align 4
+  %3 = tail call void ()* (%struct.sqlite3_vfs*, i8*, i8*)* %2(%struct.sqlite3_vfs* %pVfs, i8* %pHdle, i8* %zSym) nounwind
+  ret void ()* %3
+}
+*/
+
+        typedef void (*funcptr)(int, int);
+        typedef funcptr (*funcptrfunc)(int);
+
+        funcptr __attribute__ ((noinline)) getIt(int x) {
+          return (funcptr)x;
+        }
+
+        int main(int argc, char **argv)
+        {
+          funcptrfunc fpf = argc < 100 ? getIt : NULL;
+          printf("*%p*\n", fpf(argc));
+          return 0;
+        }
+      '''
+      self.do_run(src, '*0x1*')
+
     def test_emptyclass(self):
         if self.emcc_args is None: return self.skip('requires emcc')
         src = '''

VaKeR 2022