diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2025-10-17 16:59:24 +0200 |
|---|---|---|
| committer | Dylan Baker <dylan@pnwbakers.com> | 2025-12-08 10:08:10 -0800 |
| commit | 3ddde0b6c97d42ee67e1beef6952bee4bde69668 (patch) | |
| tree | 0e9f271ea04277d678e7e75ef45dfd09f32a19ca | |
| parent | c8ab1d29d62518c630e589941524e13643a4267a (diff) | |
| download | meson-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.py | 12 | ||||
| -rw-r--r-- | mesonbuild/ast/printer.py | 4 | ||||
| -rw-r--r-- | mesonbuild/cargo/builder.py | 2 | ||||
| -rw-r--r-- | mesonbuild/interpreterbase/interpreterbase.py | 26 | ||||
| -rw-r--r-- | mesonbuild/interpreterbase/operator.py | 5 | ||||
| -rw-r--r-- | mesonbuild/machinefile.py | 4 | ||||
| -rw-r--r-- | mesonbuild/mparser.py | 12 | ||||
| -rw-r--r-- | mesonbuild/optinterpreter.py | 2 | ||||
| -rw-r--r-- | mesonbuild/rewriter.py | 2 |
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 |
