[gjs: 2/16] function: Don't use alloca for CallState values




commit ac0b11a8a4efeccff47706f334717e0923db3122
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Mon Oct 26 17:44:11 2020 +0100

    function: Don't use alloca for CallState values
    
    Usage of alloca() is at least discouraged, especially in a project
    that it is supposed to work in multiple architectures and OSes, as its
    implementation is very hw/compiler dependent.
    
    Not only, when a function has many arguments we may end up in filling up
    the stack space, leading to unexpected behavior.
    
    It also prevents us from usage of C++ constructors and destructors in
    GjsFunctionCallState.
    
    As per this, remove g_newa() and rely on default C++ allocators, while
    use some utilities to compute the proper offsets.

 gi/function.cpp | 11 +----------
 gi/function.h   | 26 ++++++++++++++++++++++----
 2 files changed, 23 insertions(+), 14 deletions(-)
---
diff --git a/gi/function.cpp b/gi/function.cpp
index 063dd652..39f41f62 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -776,16 +776,7 @@ static bool gjs_invoke_c_function(JSContext* context, Function* function,
     //
     // Use gi_arg_pos to index inside the GIArgument array. Use ffi_arg_pos to
     // index inside ffi_arg_pointers.
-    GjsFunctionCallState state(context);
-    if (is_method) {
-        state.in_cvalues = g_newa(GIArgument, gi_argc + 2) + 2;
-        state.out_cvalues = g_newa(GIArgument, gi_argc + 2) + 2;
-        state.inout_original_cvalues = g_newa(GIArgument, gi_argc + 2) + 2;
-    } else {
-        state.in_cvalues = g_newa(GIArgument, gi_argc + 1) + 1;
-        state.out_cvalues = g_newa(GIArgument, gi_argc + 1) + 1;
-        state.inout_original_cvalues = g_newa(GIArgument, gi_argc + 1) + 1;
-    }
+    GjsFunctionCallState state(context, function->info, gi_argc);
 
     void** ffi_arg_pointers = g_newa(void*, ffi_argc);
 
diff --git a/gi/function.h b/gi/function.h
index feec3cab..4d1e767f 100644
--- a/gi/function.h
+++ b/gi/function.h
@@ -89,10 +89,28 @@ struct GjsFunctionCallState {
     GIArgument* inout_original_cvalues;
     std::unordered_set<GIArgument*> ignore_release;
     JS::RootedObject instance_object;
-    bool call_completed;
-
-    explicit GjsFunctionCallState(JSContext* cx)
-        : instance_object(cx), call_completed(false) {}
+    int gi_argc;
+    bool call_completed : 1;
+    bool is_method : 1;
+
+    GjsFunctionCallState(JSContext* cx, GICallableInfo* callable, int args)
+        : instance_object(cx),
+          gi_argc(args),
+          call_completed(false),
+          is_method(g_callable_info_is_method(callable)) {
+        int size = gi_argc + first_arg_offset();
+        in_cvalues = new GIArgument[size] + first_arg_offset();
+        out_cvalues = new GIArgument[size] + first_arg_offset();
+        inout_original_cvalues = new GIArgument[size] + first_arg_offset();
+    }
+
+    ~GjsFunctionCallState() {
+        delete[](in_cvalues - first_arg_offset());
+        delete[](out_cvalues - first_arg_offset());
+        delete[](inout_original_cvalues - first_arg_offset());
+    }
+
+    constexpr int first_arg_offset() const { return is_method ? 2 : 1; }
 };
 
 GJS_JSAPI_RETURN_CONVENTION


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]