summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2025-10-17 16:59:24 +0200
committerDylan Baker <dylan@pnwbakers.com>2025-12-08 10:08:10 -0800
commit3ddde0b6c97d42ee67e1beef6952bee4bde69668 (patch)
tree0e9f271ea04277d678e7e75ef45dfd09f32a19ca
parentc8ab1d29d62518c630e589941524e13643a4267a (diff)
downloadmeson-3ddde0b6c97d42ee67e1beef6952bee4bde69668.tar.gz
interpreterbase: make ArithmeticNode and MesonOperator both use operator names
This avoids creating a dictionary every time an arithmetic operator is evaluated. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--mesonbuild/ast/interpreter.py12
-rw-r--r--mesonbuild/ast/printer.py4
-rw-r--r--mesonbuild/cargo/builder.py2
-rw-r--r--mesonbuild/interpreterbase/interpreterbase.py26
-rw-r--r--mesonbuild/interpreterbase/operator.py5
-rw-r--r--mesonbuild/machinefile.py4
-rw-r--r--mesonbuild/mparser.py12
-rw-r--r--mesonbuild/optinterpreter.py2
-rw-r--r--mesonbuild/rewriter.py2
9 files changed, 29 insertions, 40 deletions
diff --git a/mesonbuild/ast/interpreter.py b/mesonbuild/ast/interpreter.py
index 133d78d5d..d3afb4de3 100644
--- a/mesonbuild/ast/interpreter.py
+++ b/mesonbuild/ast/interpreter.py
@@ -577,7 +577,7 @@ class AstInterpreter(InterpreterBase):
return [left] + right
if isinstance(left, UnknownValue) or isinstance(right, UnknownValue):
return UnknownValue()
- if node.operation == 'add':
+ if node.operation == '+':
if isinstance(left, dict) and isinstance(right, dict):
ret = left.copy()
for k, v in right.items():
@@ -588,16 +588,16 @@ class AstInterpreter(InterpreterBase):
right = [right]
return left + right
return left + right
- elif node.operation == 'sub':
+ elif node.operation == '-':
return left - right
- elif node.operation == 'mul':
+ elif node.operation == '*':
return left * right
- elif node.operation == 'div':
+ elif node.operation == '/':
if isinstance(left, int) and isinstance(right, int):
return left // right
elif isinstance(left, str) and isinstance(right, str):
return os.path.join(left, right).replace('\\', '/')
- elif node.operation == 'mod':
+ elif node.operation == '%':
if isinstance(left, int) and isinstance(right, int):
return left % right
elif isinstance(node, (UnknownValue, IntrospectionBuildTarget, IntrospectionFile, IntrospectionDependency, str, bool, int)):
@@ -671,7 +671,7 @@ class AstInterpreter(InterpreterBase):
if isinstance(lhs, UnknownValue):
newval = UnknownValue()
else:
- newval = mparser.ArithmeticNode(operation='add', left=lhs, operator=_symbol('+'), right=node.value)
+ newval = mparser.ArithmeticNode(operation='+', left=lhs, operator=_symbol('+'), right=node.value)
self.cur_assignments[node.var_name.value].append((self.nesting.copy(), newval))
self.all_assignment_nodes[node.var_name.value].append(node)
diff --git a/mesonbuild/ast/printer.py b/mesonbuild/ast/printer.py
index af865a48d..024b62b9e 100644
--- a/mesonbuild/ast/printer.py
+++ b/mesonbuild/ast/printer.py
@@ -25,9 +25,9 @@ def precedence_level(node: mparser.BaseNode) -> int:
elif isinstance(node, mparser.ComparisonNode):
return 4
elif isinstance(node, mparser.ArithmeticNode):
- if node.operation in {'add', 'sub'}:
+ if node.operation in {'+', '-'}:
return 5
- elif node.operation in {'mod', 'mul', 'div'}:
+ elif node.operation in {'%', '*', '/'}:
return 6
elif isinstance(node, (mparser.NotNode, mparser.UMinusNode)):
return 7
diff --git a/mesonbuild/cargo/builder.py b/mesonbuild/cargo/builder.py
index 9bee52b3c..16abe2697 100644
--- a/mesonbuild/cargo/builder.py
+++ b/mesonbuild/cargo/builder.py
@@ -202,7 +202,7 @@ class Builder:
:param rhs: The right of the addition
:return: The ArithmeticNode
"""
- return mparser.ArithmeticNode('add', lhs, self._symbol('+'), rhs)
+ return mparser.ArithmeticNode('+', lhs, self._symbol('+'), rhs)
def plusassign(self, value: mparser.BaseNode, varname: str) -> mparser.PlusAssignmentNode:
"""Create a "+=" node
diff --git a/mesonbuild/interpreterbase/interpreterbase.py b/mesonbuild/interpreterbase/interpreterbase.py
index 828bb6446..a601e5c6d 100644
--- a/mesonbuild/interpreterbase/interpreterbase.py
+++ b/mesonbuild/interpreterbase/interpreterbase.py
@@ -28,6 +28,7 @@ from .exceptions import (
)
from .. import mlog
+from . import operator
from .decorators import FeatureNew
from .disabler import Disabler, is_disabled
from .helpers import default_resolve_key, flatten, resolve_second_level_holders, stringifyUserArguments
@@ -344,24 +345,14 @@ class InterpreterBase:
if isinstance(val2, Disabler):
return val2
- # New code based on InterpreterObjects
- operator = {
- 'in': MesonOperator.IN,
- 'not in': MesonOperator.NOT_IN,
- '==': MesonOperator.EQUALS,
- '!=': MesonOperator.NOT_EQUALS,
- '>': MesonOperator.GREATER,
- '<': MesonOperator.LESS,
- '>=': MesonOperator.GREATER_EQUALS,
- '<=': MesonOperator.LESS_EQUALS,
- }[node.ctype]
+ op = operator.MAPPING[node.ctype]
# Check if the arguments should be reversed for simplicity (this essentially converts `in` to `contains`)
- if operator in (MesonOperator.IN, MesonOperator.NOT_IN):
+ if op in (MesonOperator.IN, MesonOperator.NOT_IN):
val1, val2 = val2, val1
val1.current_node = node
- return self._holderify(val1.operator_call(operator, _unholder(val2)))
+ return self._holderify(val1.operator_call(op, _unholder(val2)))
def evaluate_andstatement(self, cur: mparser.AndNode) -> InterpreterObject:
l = self.evaluate_statement(cur.left)
@@ -414,15 +405,8 @@ class InterpreterBase:
if l is None or r is None:
raise InvalidCodeOnVoid(cur.operation)
- mapping: T.Dict[str, MesonOperator] = {
- 'add': MesonOperator.PLUS,
- 'sub': MesonOperator.MINUS,
- 'mul': MesonOperator.TIMES,
- 'div': MesonOperator.DIV,
- 'mod': MesonOperator.MOD,
- }
l.current_node = cur
- res = l.operator_call(mapping[cur.operation], _unholder(r))
+ res = l.operator_call(operator.MAPPING[cur.operation], _unholder(r))
return self._holderify(res)
def evaluate_ternary(self, node: mparser.TernaryNode) -> T.Optional[InterpreterObject]:
diff --git a/mesonbuild/interpreterbase/operator.py b/mesonbuild/interpreterbase/operator.py
index 3419c4bec..d17cd3796 100644
--- a/mesonbuild/interpreterbase/operator.py
+++ b/mesonbuild/interpreterbase/operator.py
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: Apache-2.0
from enum import Enum
+import typing as T
class MesonOperator(Enum):
# Arithmetic
@@ -30,3 +31,7 @@ class MesonOperator(Enum):
IN = 'in'
NOT_IN = 'not in'
INDEX = '[]'
+
+# Accessing this directly is about 9x faster than calling MesonOperator(s),
+# and about 3 times faster than a staticmethod
+MAPPING: T.Mapping[str, MesonOperator] = {x.value: x for x in MesonOperator}
diff --git a/mesonbuild/machinefile.py b/mesonbuild/machinefile.py
index a20e25778..19a086574 100644
--- a/mesonbuild/machinefile.py
+++ b/mesonbuild/machinefile.py
@@ -83,12 +83,12 @@ class MachineFileParser():
elif isinstance(node, mparser.ArithmeticNode):
l = self._evaluate_statement(node.left)
r = self._evaluate_statement(node.right)
- if node.operation == 'add':
+ if node.operation == '+':
if isinstance(l, str) and isinstance(r, str):
return l + r
if isinstance(l, list) and isinstance(r, list):
return l + r
- elif node.operation == 'div':
+ elif node.operation == '/':
if isinstance(l, str) and isinstance(r, str):
return os.path.join(l, r)
raise MesonException('Unsupported node type')
diff --git a/mesonbuild/mparser.py b/mesonbuild/mparser.py
index eee6ffc04..b5792d251 100644
--- a/mesonbuild/mparser.py
+++ b/mesonbuild/mparser.py
@@ -674,7 +674,7 @@ class ParenthesizedNode(BaseNode):
if T.TYPE_CHECKING:
COMPARISONS = Literal['==', '!=', '<', '<=', '>=', '>', 'in', 'not in']
- ARITH_OPERATORS = Literal['add', 'sub', 'mul', 'div', 'mod']
+ ARITH_OPERATORS = Literal['+', '-', '*', '/', '%']
ALL_STRINGS = frozenset({'string', 'fstring', 'multiline_string', 'multiline_fstring'})
@@ -690,14 +690,14 @@ COMPARISON_MAP: T.Mapping[str, COMPARISONS] = {
}
ADDSUB_MAP: T.Mapping[str, ARITH_OPERATORS] = {
- 'plus': 'add',
- 'dash': 'sub',
+ 'plus': '+',
+ 'dash': '-',
}
MULDIV_MAP: T.Mapping[str, ARITH_OPERATORS] = {
- 'percent': 'mod',
- 'star': 'mul',
- 'fslash': 'div',
+ 'percent': '%',
+ 'star': '*',
+ 'fslash': '/',
}
# Recursive descent parser for Meson's definition language.
diff --git a/mesonbuild/optinterpreter.py b/mesonbuild/optinterpreter.py
index 892d4d5e3..1127cc936 100644
--- a/mesonbuild/optinterpreter.py
+++ b/mesonbuild/optinterpreter.py
@@ -138,7 +138,7 @@ class OptionInterpreter:
elif isinstance(arg, mparser.ArithmeticNode):
l = self.reduce_single(arg.left)
r = self.reduce_single(arg.right)
- if not (arg.operation == 'add' and isinstance(l, str) and isinstance(r, str)):
+ if not (arg.operation == '+' and isinstance(l, str) and isinstance(r, str)):
raise OptionException('Only string concatenation with the "+" operator is allowed')
FeatureNew.single_use('string concatenation in meson_options.txt', '0.55.0', self.subproject)
return l + r
diff --git a/mesonbuild/rewriter.py b/mesonbuild/rewriter.py
index 51846d075..ac23bd4de 100644
--- a/mesonbuild/rewriter.py
+++ b/mesonbuild/rewriter.py
@@ -756,7 +756,7 @@ class Rewriter:
new_kwarg_flag = True
old_extra_files = target.node.args.get_kwarg_or_default('extra_files', None)
target.node.args.kwargs = {k: v for k, v in target.node.args.kwargs.items() if not (isinstance(k, IdNode) and k.value == 'extra_files')}
- new_extra_files_node = ArithmeticNode('add', old_extra_files, _symbol('+'), chosen)
+ new_extra_files_node = ArithmeticNode('+', old_extra_files, _symbol('+'), chosen)
tgt_function.args.kwargs[extra_files_idnode] = new_extra_files_node