From b97ac039a304fbbb99aa8720aeb41750b2a3227e Mon Sep 17 00:00:00 2001 From: Jorrit Rouwe Date: Sat, 19 Oct 2024 23:32:19 +0200 Subject: [PATCH] Allowing all binary C++ operators in WebIDL Also erroring on previously allowed, but non-existing operators like 'x='. --- .../porting/connecting_cpp_and_javascript/WebIDL-Binder.rst | 2 +- test/webidl/post.js | 2 ++ test/webidl/test.h | 5 ++++- test/webidl/test.idl | 5 ++++- test/webidl/test_ALL.out | 2 ++ test/webidl/test_DEFAULT.out | 2 ++ test/webidl/test_FAST.out | 2 ++ tools/webidl_binder.py | 5 ++++- 8 files changed, 21 insertions(+), 4 deletions(-) diff --git a/site/source/docs/porting/connecting_cpp_and_javascript/WebIDL-Binder.rst b/site/source/docs/porting/connecting_cpp_and_javascript/WebIDL-Binder.rst index 744ed75cfbbe..71bb5d36b007 100644 --- a/site/source/docs/porting/connecting_cpp_and_javascript/WebIDL-Binder.rst +++ b/site/source/docs/porting/connecting_cpp_and_javascript/WebIDL-Binder.rst @@ -318,7 +318,7 @@ You can bind to C++ operators using ``[Operator=]``: .. note:: - The operator name can be anything (``add`` is just an example). - - Support is currently limited to operators that contain ``=``: ``+=``, ``*=``, ``-=`` etc., and to the array indexing operator ``[]``. + - Support is currently limited to the following binary operators: ``+``, ``-``, ``*``, ``/``, ``%``, ``^``, ``&``, ``|``, ``=``, ``<``, ``>``, ``+=``, ``-=``, ``*=``, ``/=``, ``%=``, ``^=``, ``&=``, ``|=``, ``<<``, ``>>``, ``>>=``, ``<<=``, ``==``, ``!=``, ``<=``, ``>=``, ``<=>``, ``&&``, ``||``, and to the array indexing operator ``[]``. enums diff --git a/test/webidl/post.js b/test/webidl/post.js index ddcb07c52599..30b4a536d4b0 100644 --- a/test/webidl/post.js +++ b/test/webidl/post.js @@ -144,6 +144,8 @@ console.log(new TheModule.Inner().get()); console.log('getAsArray: ' + new TheModule.Inner().getAsArray(12)); new TheModule.Inner().mul(2); new TheModule.Inner().incInPlace(new TheModule.Inner()); +console.log('add: ' + new TheModule.Inner(1).add(new TheModule.Inner(2)).get_value()); +console.log('mul2: ' + new TheModule.Inner(10).mul2(5)); console.log(TheModule.enum_value1); console.log(TheModule.enum_value2); diff --git a/test/webidl/test.h b/test/webidl/test.h index b3ec73f5f00a..b40486135e62 100644 --- a/test/webidl/test.h +++ b/test/webidl/test.h @@ -95,14 +95,17 @@ struct VoidPointerUser { namespace Space { struct Inner { int value; - Inner() : value(1) {} + Inner(int x = 1) : value(x) {} int get() { return 198; } + int get_value() { return value; } Inner& operator*=(float x) { return *this; } int operator[](int x) { return x*2; } void operator+=(const Inner& other) { value += other.value; printf("Inner::+= => %d\n", value); } + Inner operator+(const Inner& other) { return Inner(value + other.value); } + int operator*(int x) { return value * x; } }; // We test compilation of abstract base classes in a namespace here. diff --git a/test/webidl/test.idl b/test/webidl/test.idl index ae9ee6d15bdf..4dd7bcecbcaa 100644 --- a/test/webidl/test.idl +++ b/test/webidl/test.idl @@ -85,11 +85,14 @@ interface VoidPointerUser { [Prefix="Space::"] interface Inner { - void Inner(); + void Inner(optional long value); long get(); + long get_value(); [Operator="*=", Ref] Inner mul(float x); [Operator="[]"] long getAsArray(long x); [Operator="+="] void incInPlace([Const, Ref] Inner i); + [Operator="+", Value] Inner add([Const, Ref] Inner i); + [Operator="*"] long mul2(long x); }; [Prefix = "Space::"] diff --git a/test/webidl/test_ALL.out b/test/webidl/test_ALL.out index dd0006286151..94882507078f 100644 --- a/test/webidl/test_ALL.out +++ b/test/webidl/test_ALL.out @@ -71,6 +71,8 @@ object 198 getAsArray: 24 Inner::+= => 2 +add: 3 +mul2: 50 0 1 34,34 diff --git a/test/webidl/test_DEFAULT.out b/test/webidl/test_DEFAULT.out index 76b9c9f3b823..fba3558d40d2 100644 --- a/test/webidl/test_DEFAULT.out +++ b/test/webidl/test_DEFAULT.out @@ -71,6 +71,8 @@ object 198 getAsArray: 24 Inner::+= => 2 +add: 3 +mul2: 50 0 1 34,34 diff --git a/test/webidl/test_FAST.out b/test/webidl/test_FAST.out index 76b9c9f3b823..fba3558d40d2 100644 --- a/test/webidl/test_FAST.out +++ b/test/webidl/test_FAST.out @@ -71,6 +71,8 @@ object 198 getAsArray: 24 Inner::+= => 2 +add: 3 +mul2: 50 0 1 34,34 diff --git a/tools/webidl_binder.py b/tools/webidl_binder.py index 9cdb6a83f57d..2898709bb9dd 100644 --- a/tools/webidl_binder.py +++ b/tools/webidl_binder.py @@ -614,7 +614,10 @@ def make_call_args(i): # this function comes from an ancestor class; for operators, we must cast it cast_self = 'dynamic_cast<' + type_to_c(func_scope) + '>(' + cast_self + ')' maybe_deref = deref_if_nonpointer(raw[0]) - if '=' in operator: + operator = operator.strip() + if operator in ["+", "-", "*", "/", "%", "^", "&", "|", "=", + "<", ">", "+=", "-=", "*=", "/=", "%=", "^=", "&=", "|=", "<<", ">>", ">>=", + "<<=", "==", "!=", "<=", ">=", "<=>", "&&", "||"]: call = '(*%s %s %s%s)' % (cast_self, operator, maybe_deref, args[0]) elif operator == '[]': call = '((*%s)[%s%s])' % (cast_self, maybe_deref, args[0])