[gjs/april-maintenance: 9/11] function: Use JS::CallArgs throughout invocation call chain
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/april-maintenance: 9/11] function: Use JS::CallArgs throughout invocation call chain
- Date: Fri, 1 May 2020 04:48:07 +0000 (UTC)
commit 4c4dfd416cae36d85d69d58ae358595589219fa3
Author: Philip Chimento <philip chimento gmail com>
Date: Thu Apr 30 21:15:22 2020 -0700
function: Use JS::CallArgs throughout invocation call chain
If you have a JSObject for the 'this' object, a JS::Value array for the
arguments, and a mutable JS::Value for the return value, then that's
basically a JS::CallArgs.
The only difference is that when calling a constructor, you may not be
able to get the 'this' object from args.computeThis(). For
gjs_invoke_constructor_from_c(), we need to provide the 'this' object
that was provided to the constructor.
gi/function.cpp | 70 ++++++++++++++++++++++--------------------------------
gi/function.h | 3 ++-
gi/fundamental.cpp | 2 +-
gi/fundamental.h | 3 +--
gi/union.cpp | 14 ++++-------
5 files changed, 38 insertions(+), 54 deletions(-)
---
diff --git a/gi/function.cpp b/gi/function.cpp
index e65d09ff..45b05ca4 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -784,21 +784,17 @@ complete_async_calls(void)
}
}
-/*
- * This function can be called in 2 different ways. You can either use
- * it to create javascript objects by providing a @js_rval argument or
- * you can decide to keep the return values in #GArgument format by
- * providing a @r_value argument.
- */
+// This function can be called in two different ways. You can either use it to
+// create JavaScript objects by calling it without @r_value, or you can decide
+// to keep the return values in #GArgument format by providing a @r_value
+// argument.
GJS_JSAPI_RETURN_CONVENTION
-static bool gjs_invoke_c_function(
- JSContext* context, Function* function,
- JS::HandleObject obj, /* "this" object */
- const JS::HandleValueArray& args,
- mozilla::Maybe<JS::MutableHandleValue> js_rval,
- GIArgument* r_value = nullptr) {
- g_assert(!r_value != js_rval.isNothing() &&
- "Pass one of js_rval or r_value, not both or neither");
+static bool gjs_invoke_c_function(JSContext* context, Function* function,
+ const JS::CallArgs& args,
+ JS::HandleObject this_obj = nullptr,
+ GIArgument* r_value = nullptr) {
+ g_assert((args.isConstructing() || !this_obj) &&
+ "If not a constructor, then pass the 'this' object via CallArgs");
/* These first four are arrays which hold argument pointers.
* @in_arg_cvalues: C values which are passed on input (in or inout)
@@ -856,19 +852,14 @@ static bool gjs_invoke_c_function(
*
* @args.length() is the number of arguments that were actually passed.
*/
+ GjsAutoChar name = format_function_name(function, is_method);
if (args.length() > function->expected_js_argc) {
- GjsAutoChar name = format_function_name(function, is_method);
- if (!JS::WarnUTF8(context,
- "Too many arguments to %s: expected %d, "
- "got %" G_GSIZE_FORMAT,
- name.get(), function->expected_js_argc,
- args.length()))
+ if (!JS::WarnUTF8(
+ context, "Too many arguments to %s: expected %d, got %u",
+ name.get(), function->expected_js_argc, args.length()))
return false;
- } else if (args.length() < function->expected_js_argc) {
- GjsAutoChar name = format_function_name(function, is_method);
- gjs_throw(context, "Too few arguments to %s: "
- "expected %d, got %" G_GSIZE_FORMAT,
- name.get(), function->expected_js_argc, args.length());
+ } else if (!args.requireAtLeast(context, name,
+ function->expected_js_argc)) {
return false;
}
@@ -884,6 +875,10 @@ static bool gjs_invoke_c_function(
c_arg_pos = 0; /* index into in_arg_cvalues, etc */
js_arg_pos = 0; /* index into argv */
+ JS::RootedObject obj(context, this_obj);
+ if (!args.isConstructing() && !args.computeThis(context, &obj))
+ return false;
+
if (is_method) {
if (!gjs_fill_method_instance(context, obj, function,
&in_arg_cvalues[0], is_object_method))
@@ -990,7 +985,8 @@ static bool gjs_invoke_c_function(
callable_info = (GICallableInfo*) g_type_info_get_interface(&ainfo);
trampoline = gjs_callback_trampoline_new(
context, func, callable_info, scope,
- is_object_method ? obj : nullptr, false);
+ is_object_method ? JS::HandleObject(obj) : nullptr,
+ false);
closure = trampoline->closure;
g_base_info_unref(callable_info);
}
@@ -1144,7 +1140,7 @@ static bool gjs_invoke_c_function(
}
if (!r_value)
- js_rval->setUndefined();
+ args.rval().setUndefined();
/* Only process return values if the function didn't throw */
if (function->js_out_argc > 0 && !did_throw_gerror) {
@@ -1412,14 +1408,14 @@ release:
// own, otherwise return a JavaScript array with [return value,
// out arg 1, out arg 2, ...]
if (function->js_out_argc == 1) {
- js_rval->set(return_values[0]);
+ args.rval().set(return_values[0]);
} else {
JSObject *array;
array = JS_NewArrayObject(context, return_values);
if (array == NULL) {
failed = true;
} else {
- js_rval->setObject(*array);
+ args.rval().setObject(*array);
}
}
}
@@ -1440,12 +1436,10 @@ function_call(JSContext *context,
unsigned js_argc,
JS::Value *vp)
{
- GJS_GET_THIS(context, js_argc, vp, js_argv, object);
+ JS::CallArgs js_argv = JS::CallArgsFromVp(js_argc, vp);
JS::RootedObject callee(context, &js_argv.callee());
- bool success;
Function *priv;
- JS::RootedValue retval(context);
priv = priv_from_js(context, callee);
gjs_debug_marshal(GJS_DEBUG_GFUNCTION,
@@ -1455,12 +1449,7 @@ function_call(JSContext *context,
if (priv == NULL)
return true; /* we are the prototype, or have the wrong class */
- success = gjs_invoke_c_function(context, priv, object, js_argv,
- mozilla::Some(&retval));
- if (success)
- js_argv.rval().set(retval);
-
- return success;
+ return gjs_invoke_c_function(context, priv, js_argv);
}
GJS_NATIVE_CONSTRUCTOR_DEFINE_ABSTRACT(function)
@@ -1858,7 +1847,7 @@ gjs_define_function(JSContext *context,
bool gjs_invoke_constructor_from_c(JSContext* context, GIFunctionInfo* info,
JS::HandleObject obj,
- const JS::HandleValueArray& args,
+ const JS::CallArgs& args,
GIArgument* rvalue) {
Function function;
@@ -1866,8 +1855,7 @@ bool gjs_invoke_constructor_from_c(JSContext* context, GIFunctionInfo* info,
if (!init_cached_function_data(context, &function, 0, info))
return false;
- bool result = gjs_invoke_c_function(context, &function, obj, args,
- mozilla::Nothing(), rvalue);
+ bool result = gjs_invoke_c_function(context, &function, args, obj, rvalue);
uninit_cached_function_data(&function);
return result;
}
diff --git a/gi/function.h b/gi/function.h
index eef77afd..f8e251fc 100644
--- a/gi/function.h
+++ b/gi/function.h
@@ -30,6 +30,7 @@
#include <girepository.h>
#include <glib-object.h>
+#include <js/CallArgs.h>
#include <js/TypeDecls.h>
#include "gjs/macros.h"
@@ -76,7 +77,7 @@ JSObject *gjs_define_function(JSContext *context,
GJS_JSAPI_RETURN_CONVENTION
bool gjs_invoke_constructor_from_c(JSContext* cx, GIFunctionInfo* info,
JS::HandleObject this_obj,
- const JS::HandleValueArray& args,
+ const JS::CallArgs& args,
GIArgument* rvalue);
#endif // GI_FUNCTION_H_
diff --git a/gi/fundamental.cpp b/gi/fundamental.cpp
index bde80edd..2d3ef787 100644
--- a/gi/fundamental.cpp
+++ b/gi/fundamental.cpp
@@ -187,7 +187,7 @@ bool FundamentalPrototype::resolve_impl(JSContext* cx, JS::HandleObject obj,
*/
bool FundamentalInstance::invoke_constructor(JSContext* context,
JS::HandleObject obj,
- const JS::HandleValueArray& args,
+ const JS::CallArgs& args,
GIArgument* rvalue) {
GIFunctionInfo* constructor_info = get_prototype()->constructor_info();
if (!constructor_info) {
diff --git a/gi/fundamental.h b/gi/fundamental.h
index a1a9f363..465b93a8 100644
--- a/gi/fundamental.h
+++ b/gi/fundamental.h
@@ -158,8 +158,7 @@ class FundamentalInstance
GJS_JSAPI_RETURN_CONVENTION
bool invoke_constructor(JSContext* cx, JS::HandleObject obj,
- const JS::HandleValueArray& args,
- GIArgument* rvalue);
+ const JS::CallArgs& args, GIArgument* rvalue);
void ref(void) { get_prototype()->call_ref_function(m_ptr); }
void unref(void) { get_prototype()->call_unref_function(m_ptr); }
diff --git a/gi/union.cpp b/gi/union.cpp
index 34720f38..9661562f 100644
--- a/gi/union.cpp
+++ b/gi/union.cpp
@@ -95,11 +95,8 @@ bool UnionPrototype::resolve_impl(JSContext* context, JS::HandleObject obj,
}
GJS_JSAPI_RETURN_CONVENTION
-static void*
-union_new(JSContext *context,
- JS::HandleObject obj, /* "this" for constructor */
- GIUnionInfo *info)
-{
+static void* union_new(JSContext* context, JS::HandleObject this_obj,
+ const JS::CallArgs& args, GIUnionInfo* info) {
int n_methods;
int i;
@@ -116,9 +113,8 @@ union_new(JSContext *context,
if ((flags & GI_FUNCTION_IS_CONSTRUCTOR) != 0 &&
g_callable_info_get_n_args((GICallableInfo*) func_info) == 0) {
GIArgument rval;
- if (!gjs_invoke_constructor_from_c(context, func_info, obj,
- JS::HandleValueArray::empty(),
- &rval))
+ if (!gjs_invoke_constructor_from_c(context, func_info, this_obj,
+ args, &rval))
return nullptr;
if (!rval.v_pointer) {
@@ -148,7 +144,7 @@ bool UnionInstance::constructor_impl(JSContext* context,
name()))
return false;
- m_ptr = union_new(context, object, info());
+ m_ptr = union_new(context, object, args, info());
return !!m_ptr;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]