The Wayback Machine - https://web.archive.org/web/20250523193413/https://github.com/RustPython/RustPython/pull/2006
Skip to content

Use loadname local replace loadname free #2006

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 11, 2020

Conversation

Lynskylate
Copy link
Contributor

Fix #2005 .

Use load local replace load free.

@@ -680,11 +682,11 @@ impl SymbolTableBuilder {
self.scan_expressions(vals, context)?;
}
Subscript { a, b } => {
self.scan_expression(a, context)?;
self.scan_expression(a, &ExpressionContext::Load)?;
Copy link
Contributor Author

@Lynskylate Lynskylate Jul 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The result that symtable analyze assign ast may be error.
e.g:

def f():
    sys.modules["test"] = test

Identity get a assign context, and symtable think the variable scope is local.

image

@@ -276,6 +276,8 @@ impl<'a> SymbolTableAnalyzer<'a> {
fn analyze_unknown_symbol(&self, symbol: &mut Symbol) {
if symbol.is_assigned || symbol.is_parameter {
symbol.scope = SymbolScope::Local;
} else if symbol.is_referenced {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure about the correctness of this treatment.

@Lynskylate Lynskylate changed the title Try to use loadname local replace loadname free [WIP]Try to use loadname local replace loadname free Jul 17, 2020
@coolreader18
Copy link
Member

Looks like global scope names in nested closures aren't getting resolved correctly?

@Lynskylate
Copy link
Contributor Author

Lynskylate commented Aug 8, 2020

Looks like global scope names in nested closures aren't getting resolved correctly?

Yes, the error is same as before.
Symtable thik object's context is assign when symtable analyze `registry[objcect] = func', and then think object is a local variable

@Lynskylate
Copy link
Contributor Author

Looks like global scope names in nested closures aren't getting resolved correctly?

import symtable
content = open("Lib/functools.py").read()
table = symtable.symtable(content, "?", "exec")
// True in python
// False in RustPython
table.lookup("singledispatch").get_namespace().lookup("object").is_global()
"""

@Lynskylate
Copy link
Contributor Author

RustPython‘s LoadLocal is not same as cpython's LoadFast.

def f():
  ch = chr (100)
  if ch == 'd':
    chr = ch
  return chr

"""
Bytecode:
  2           0 LOAD_FAST                0 (chr)
              2 LOAD_CONST               1 (100)
              4 CALL_FUNCTION            1
              6 STORE_FAST               1 (ch)

  3           8 LOAD_FAST                1 (ch)
             10 LOAD_CONST               2 ('d')
             12 COMPARE_OP               2 (==)
             14 POP_JUMP_IF_FALSE       20

  4          16 LOAD_FAST                1 (ch)
             18 STORE_FAST               0 (chr)

  5     >>   20 LOAD_FAST                0 (chr)
             22 RETURN_VALUE
"""

Cpython analyze chr's scope is Local, and use LoadFast to load chr, but we can't load chr if we use LoadName local.
@coolreader18 Do you have any suggestions for handling this situation?

@Lynskylate
Copy link
Contributor Author

@coolreader18 Current _codecss.py implemention is illegal in cpython.
In PyUnicode_DecodeUnicodeEscape function, chr referenced before assignment, and it will throw unbound error in cpython

@Lynskylate Lynskylate changed the title [WIP]Try to use loadname local replace loadname free Use loadname local replace loadname free Aug 9, 2020
@coolreader18
Copy link
Member

Hmm, that is tricky. Maybe we could do something in symtable to check if it's used global scope and then reassigned, to do a less optimized LoadName for it after? Or maybe we could just copy CPython's LoadFast, if feasible?

@Lynskylate
Copy link
Contributor Author

Lynskylate commented Aug 9, 2020

@coolreader18 I think that modifying the symtable will destroy the compatibility with cpython.
Current _codecs.PyUnicode_DecodeUnicodeEscape will throw unbound error in cpython, a simple example is as follows.
image
Maybe we need to update the implementation of _codecs.py

@coolreader18
Copy link
Member

Oh, I think we sent our comments at the same time, I didn't see yours before I sent mine. Yeah, I think the "reference before assignment" error + editing _codecs.py is the best course of action; the original version was from a PyPy branch compatible w/ python2 and there's been issues that pop up with it whenever a new module is added that calls into a part of _codecs that we haven't fixed yet.

Copy link
Member

@coolreader18 coolreader18 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job!!

@coolreader18 coolreader18 merged commit 3a6442f into RustPython:master Aug 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Should use (LoadName Local) instruction replace (LoadName Free)
2 participants