Skip to content

Commit b15a74d

Browse files
committed
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>
1 parent 025dcb1 commit b15a74d

File tree

9 files changed

+30
-40
lines changed

9 files changed

+30
-40
lines changed

mesonbuild/ast/interpreter.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ def node_to_runtime_value(self, node: T.Union[UnknownValue, BaseNode, TYPE_var])
571571
return [left] + right
572572
if isinstance(left, UnknownValue) or isinstance(right, UnknownValue):
573573
return UnknownValue()
574-
if node.operation == 'add':
574+
if node.operation == '+':
575575
if isinstance(left, dict) and isinstance(right, dict):
576576
ret = left.copy()
577577
for k, v in right.items():
@@ -582,16 +582,16 @@ def node_to_runtime_value(self, node: T.Union[UnknownValue, BaseNode, TYPE_var])
582582
right = [right]
583583
return left + right
584584
return left + right
585-
elif node.operation == 'sub':
585+
elif node.operation == '-':
586586
return left - right
587-
elif node.operation == 'mul':
587+
elif node.operation == '*':
588588
return left * right
589-
elif node.operation == 'div':
589+
elif node.operation == '/':
590590
if isinstance(left, int) and isinstance(right, int):
591591
return left // right
592592
elif isinstance(left, str) and isinstance(right, str):
593593
return os.path.join(left, right).replace('\\', '/')
594-
elif node.operation == 'mod':
594+
elif node.operation == '%':
595595
if isinstance(left, int) and isinstance(right, int):
596596
return left % right
597597
elif isinstance(node, (UnknownValue, IntrospectionBuildTarget, IntrospectionFile, IntrospectionDependency, str, bool, int)):
@@ -665,7 +665,7 @@ def evaluate_plusassign(self, node: PlusAssignmentNode) -> None:
665665
if isinstance(lhs, UnknownValue):
666666
newval = UnknownValue()
667667
else:
668-
newval = mparser.ArithmeticNode(operation='add', left=lhs, operator=_symbol('+'), right=node.value)
668+
newval = mparser.ArithmeticNode(operation='+', left=lhs, operator=_symbol('+'), right=node.value)
669669
self.cur_assignments[node.var_name.value].append((self.nesting.copy(), newval))
670670
self.all_assignment_nodes[node.var_name.value].append(node)
671671

mesonbuild/ast/printer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ def precedence_level(node: mparser.BaseNode) -> int:
2525
elif isinstance(node, mparser.ComparisonNode):
2626
return 4
2727
elif isinstance(node, mparser.ArithmeticNode):
28-
if node.operation in {'add', 'sub'}:
28+
if node.operation in {'+', '-'}:
2929
return 5
30-
elif node.operation in {'mod', 'mul', 'div'}:
30+
elif node.operation in {'%', '*', '/'}:
3131
return 6
3232
elif isinstance(node, (mparser.NotNode, mparser.UMinusNode)):
3333
return 7

mesonbuild/cargo/builder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ def plus(self, lhs: mparser.BaseNode, rhs: mparser.BaseNode) -> mparser.Arithmet
202202
:param rhs: The right of the addition
203203
:return: The ArithmeticNode
204204
"""
205-
return mparser.ArithmeticNode('add', lhs, self._symbol('+'), rhs)
205+
return mparser.ArithmeticNode('+', lhs, self._symbol('+'), rhs)
206206

207207
def plusassign(self, value: mparser.BaseNode, varname: str) -> mparser.PlusAssignmentNode:
208208
"""Create a "+=" node

mesonbuild/interpreterbase/interpreterbase.py

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
)
2929

3030
from .. import mlog
31+
from . import operator
3132
from .decorators import FeatureNew
3233
from .disabler import Disabler, is_disabled
3334
from .helpers import default_resolve_key, flatten, resolve_second_level_holders, stringifyUserArguments
@@ -344,24 +345,14 @@ def evaluate_comparison(self, node: mparser.ComparisonNode) -> InterpreterObject
344345
if isinstance(val2, Disabler):
345346
return val2
346347

347-
# New code based on InterpreterObjects
348-
operator = {
349-
'in': MesonOperator.IN,
350-
'not in': MesonOperator.NOT_IN,
351-
'==': MesonOperator.EQUALS,
352-
'!=': MesonOperator.NOT_EQUALS,
353-
'>': MesonOperator.GREATER,
354-
'<': MesonOperator.LESS,
355-
'>=': MesonOperator.GREATER_EQUALS,
356-
'<=': MesonOperator.LESS_EQUALS,
357-
}[node.ctype]
348+
op = operator.MAPPING[node.ctype]
358349

359350
# Check if the arguments should be reversed for simplicity (this essentially converts `in` to `contains`)
360-
if operator in (MesonOperator.IN, MesonOperator.NOT_IN):
351+
if op in (MesonOperator.IN, MesonOperator.NOT_IN):
361352
val1, val2 = val2, val1
362353

363354
val1.current_node = node
364-
return self._holderify(val1.operator_call(operator, _unholder(val2)))
355+
return self._holderify(val1.operator_call(op, _unholder(val2)))
365356

366357
def evaluate_andstatement(self, cur: mparser.AndNode) -> InterpreterObject:
367358
l = self.evaluate_statement(cur.left)
@@ -414,15 +405,8 @@ def evaluate_arithmeticstatement(self, cur: mparser.ArithmeticNode) -> Interpret
414405
if l is None or r is None:
415406
raise InvalidCodeOnVoid(cur.operation)
416407

417-
mapping: T.Dict[str, MesonOperator] = {
418-
'add': MesonOperator.PLUS,
419-
'sub': MesonOperator.MINUS,
420-
'mul': MesonOperator.TIMES,
421-
'div': MesonOperator.DIV,
422-
'mod': MesonOperator.MOD,
423-
}
424408
l.current_node = cur
425-
res = l.operator_call(mapping[cur.operation], _unholder(r))
409+
res = l.operator_call(operator.MAPPING[cur.operation], _unholder(r))
426410
return self._holderify(res)
427411

428412
def evaluate_ternary(self, node: mparser.TernaryNode) -> T.Optional[InterpreterObject]:

mesonbuild/interpreterbase/operator.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# SPDX-License-Identifier: Apache-2.0
22

33
from enum import Enum
4+
import typing as T
45

56
class MesonOperator(Enum):
67
# Arithmetic
@@ -30,3 +31,8 @@ class MesonOperator(Enum):
3031
IN = 'in'
3132
NOT_IN = 'not in'
3233
INDEX = '[]'
34+
35+
# Accessing this directly is about 9x faster than calling MesonOperator(s),
36+
# and about 3 times faster than a staticmethod
37+
MAPPING: T.Mapping[str, MesonOperator] = T.cast('T.Mapping[str, MesonOperator]',
38+
MesonOperator._value2member_map_)

mesonbuild/machinefile.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,12 @@ def _evaluate_statement(self, node: mparser.BaseNode) -> ElementaryOptionValues:
9797
elif isinstance(node, mparser.ArithmeticNode):
9898
l = self._evaluate_statement(node.left)
9999
r = self._evaluate_statement(node.right)
100-
if node.operation == 'add':
100+
if node.operation == '+':
101101
if isinstance(l, str) and isinstance(r, str):
102102
return l + r
103103
if isinstance(l, list) and isinstance(r, list):
104104
return l + r
105-
elif node.operation == 'div':
105+
elif node.operation == '/':
106106
if isinstance(l, str) and isinstance(r, str):
107107
return os.path.join(l, r)
108108
raise MesonException('Unsupported node type')

mesonbuild/mparser.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,7 @@ def __init__(self, lpar: SymbolNode, inner: BaseNode, rpar: SymbolNode):
674674

675675
if T.TYPE_CHECKING:
676676
COMPARISONS = Literal['==', '!=', '<', '<=', '>=', '>', 'in', 'not in']
677-
ARITH_OPERATORS = Literal['add', 'sub', 'mul', 'div', 'mod']
677+
ARITH_OPERATORS = Literal['+', '-', '*', '/', '%']
678678

679679
comparison_map: T.Mapping[str, COMPARISONS] = {
680680
'equal': '==',
@@ -688,14 +688,14 @@ def __init__(self, lpar: SymbolNode, inner: BaseNode, rpar: SymbolNode):
688688
}
689689

690690
addsub_map: T.Mapping[str, ARITH_OPERATORS] = {
691-
'plus': 'add',
692-
'dash': 'sub',
691+
'plus': '+',
692+
'dash': '-',
693693
}
694694

695695
muldiv_map: T.Mapping[str, ARITH_OPERATORS] = {
696-
'percent': 'mod',
697-
'star': 'mul',
698-
'fslash': 'div',
696+
'percent': '%',
697+
'star': '*',
698+
'fslash': '/',
699699
}
700700

701701
# Recursive descent parser for Meson's definition language.

mesonbuild/optinterpreter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ def reduce_single(self, arg: T.Union[str, mparser.BaseNode]) -> 'TYPE_var':
138138
elif isinstance(arg, mparser.ArithmeticNode):
139139
l = self.reduce_single(arg.left)
140140
r = self.reduce_single(arg.right)
141-
if not (arg.operation == 'add' and isinstance(l, str) and isinstance(r, str)):
141+
if not (arg.operation == '+' and isinstance(l, str) and isinstance(r, str)):
142142
raise OptionException('Only string concatenation with the "+" operator is allowed')
143143
FeatureNew.single_use('string concatenation in meson_options.txt', '0.55.0', self.subproject)
144144
return l + r

mesonbuild/rewriter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,7 @@ def path_contains_unknowns(candidate: BaseNode) -> bool:
744744
new_kwarg_flag = True
745745
old_extra_files = target.node.args.get_kwarg_or_default('extra_files', None)
746746
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')}
747-
new_extra_files_node = ArithmeticNode('add', old_extra_files, _symbol('+'), chosen)
747+
new_extra_files_node = ArithmeticNode('+', old_extra_files, _symbol('+'), chosen)
748748

749749
tgt_function.args.kwargs[extra_files_idnode] = new_extra_files_node
750750

0 commit comments

Comments
 (0)