Commit 87a1c7eb authored by Stefan Behnel's avatar Stefan Behnel

special-case the substring list processing in JoinedStrNode again to reduce...

special-case the substring list processing in JoinedStrNode again to reduce the number of temp vars used
parent 188bdbca
...@@ -2964,24 +2964,46 @@ class RawCNameExprNode(ExprNode): ...@@ -2964,24 +2964,46 @@ class RawCNameExprNode(ExprNode):
class JoinedStrNode(ExprNode): class JoinedStrNode(ExprNode):
# F-strings # F-strings
# #
# values ListNode([UnicodeNode|FormattedValueNode]) Substrings of the f-string # values [UnicodeNode|FormattedValueNode] Substrings of the f-string
# #
type = py_object_type type = unicode_type
is_temp = True is_temp = True
subexprs = ['values'] subexprs = ['values']
def analyse_types(self, env): def analyse_types(self, env):
self.values = self.values.analyse_expressions(env) self.values = [v.analyse_types(env).coerce_to_pyobject(env) for v in self.values]
return self return self
def generate_result_code(self, code): def generate_evaluation_code(self, code):
code.mark_pos(self.pos)
num_items = len(self.values)
list_var = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
code.putln('%s = PyList_New(%s); %s' % (
list_var,
num_items,
code.error_goto_if_null(list_var, self.pos)))
code.put_gotref(list_var)
for i, node in enumerate(self.values):
node.generate_evaluation_code(code)
node.make_owned_reference(code)
code.put_giveref(node.py_result())
code.putln('PyList_SET_ITEM(%s, %s, %s);' % (list_var, i, node.py_result()))
node.generate_post_assignment_code(code)
node.free_temps(code)
code.mark_pos(self.pos)
self.allocate_temp_result(code)
code.putln('%s = PyUnicode_Join(%s, %s); %s' % ( code.putln('%s = PyUnicode_Join(%s, %s); %s' % (
self.result(), self.result(),
Naming.empty_unicode, Naming.empty_unicode,
self.values.py_result(), list_var,
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.py_result(), self.pos)))
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
code.put_decref_clear(list_var, py_object_type)
code.funcstate.release_temp(list_var)
class FormattedValueNode(ExprNode): class FormattedValueNode(ExprNode):
......
...@@ -350,9 +350,9 @@ class PostParse(ScopeTrackingTransform): ...@@ -350,9 +350,9 @@ class PostParse(ScopeTrackingTransform):
def visit_JoinedStrNode(self, node): def visit_JoinedStrNode(self, node):
""" """
Clean up after the parser by wrapping the substrings in a ListNode and Clean up after the parser by discarding empty Unicode strings.
discarding empty Unicode strings. Empty or single-value join lists are not Empty or single-value join lists are not uncommon because f-string
uncommon because f-string format specs are always parsed into JoinedStrNodes. format specs are always parsed into JoinedStrNodes.
""" """
values = [] values = []
for value in node.values: for value in node.values:
...@@ -365,7 +365,7 @@ class PostParse(ScopeTrackingTransform): ...@@ -365,7 +365,7 @@ class PostParse(ScopeTrackingTransform):
elif len(values) == 1: elif len(values) == 1:
node = values[0] node = values[0]
else: else:
node.values = ExprNodes.ListNode(node.pos, args=values) node.values = values
self.visitchildren(node) self.visitchildren(node)
return node return node
......
...@@ -279,7 +279,7 @@ f'{a * x()}'""" ...@@ -279,7 +279,7 @@ f'{a * x()}'"""
self.assertEqual(cy_eval(build_fstr(i), x=x, width=width), (x+' ')*i) self.assertEqual(cy_eval(build_fstr(i), x=x, width=width), (x+' ')*i)
# Test concatenating 2 largs fstrings. # Test concatenating 2 largs fstrings.
self.assertEqual(cy_eval(build_fstr(255)*2, x=x, width=width), (x+' ')*(255*2)) # CPython uses 255*256 self.assertEqual(cy_eval(build_fstr(255)*3, x=x, width=width), (x+' ')*(255*3)) # CPython uses 255*256
s = build_fstr(253, '{x:{width}} ') s = build_fstr(253, '{x:{width}} ')
self.assertEqual(cy_eval(s, x=x, width=width), (x+' ')*254) self.assertEqual(cy_eval(s, x=x, width=width), (x+' ')*254)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment