@@ -221,7 +221,7 @@ def load_global(self, name) -> _AbstractVariable:
221221 return self .load_builtin (name )
222222
223223 def load_builtin (self , name ) -> _AbstractVariable :
224- builtin = self ._ctx .abstract_loader .load_builtin_by_name (name )
224+ builtin = self ._ctx .abstract_loader .load_builtin (name )
225225 return builtin .to_variable (name )
226226
227227 def load_deref (self , name ) -> _AbstractVariable :
@@ -392,8 +392,15 @@ def byte_RESUME(self, opcode):
392392 # Load and store operations
393393
394394 def byte_LOAD_CONST (self , opcode ):
395- constant = self ._ctx .consts [self ._code .consts [opcode .arg ]]
396- self ._stack .push (constant .to_variable ())
395+ const = self ._code .consts [opcode .arg ]
396+ if isinstance (const , tuple ):
397+ # Tuple literals with all primitive elements are stored as a single raw
398+ # constant; we need to wrap each element in a variable for consistency
399+ # with tuples created via BUILD_TUPLE
400+ val = self ._ctx .abstract_loader .build_tuple (const )
401+ else :
402+ val = self ._ctx .consts [const ]
403+ self ._stack .push (val .to_variable ())
397404
398405 def byte_RETURN_VALUE (self , opcode ):
399406 self ._returns .append (self ._stack .pop ())
@@ -524,6 +531,12 @@ def byte_LOAD_METHOD(self, opcode):
524531 self ._stack .push (self ._ctx .consts .singles ['NULL' ].to_variable ())
525532 self ._stack .push (self ._load_attr (instance_var , method_name ))
526533
534+ def byte_IMPORT_NAME (self , opcode ):
535+ full_name = opcode .argval
536+ unused_level_var , unused_fromlist = self ._stack .popn (2 )
537+ module = abstract .Module (self ._ctx , full_name )
538+ return self ._stack .push (module .to_variable ())
539+
527540 # ---------------------------------------------------------------
528541 # Function and method calls
529542
@@ -558,6 +571,40 @@ def byte_CALL_FUNCTION(self, opcode):
558571 callargs = abstract .Args (posargs = tuple (args ), frame = self )
559572 self ._call_function (func , callargs )
560573
574+ def _unpack_starargs (self , starargs ):
575+ # TODO(b/331853896): This follows vm_utils.ensure_unpacked_starargs, but
576+ # does not yet handle indefinite iterables.
577+ posargs = starargs .get_atomic_value ()
578+ if isinstance (posargs , abstract .FunctionArgTuple ):
579+ # This has already been converted
580+ pass
581+ elif isinstance (posargs , abstract .Tuple ):
582+ posargs = abstract .FunctionArgTuple (self ._ctx , posargs .constant )
583+ elif isinstance (posargs , tuple ):
584+ posargs = abstract .FunctionArgTuple (self ._ctx , posargs )
585+ else :
586+ assert False , f'unexpected posargs type: { posargs } : { type (posargs )} '
587+ return posargs
588+
589+ def _unpack_starstarargs (self , starstarargs ):
590+ kwargs = abstract .get_atomic_constant (starstarargs , dict )
591+ return {abstract .get_atomic_constant (k , str ): v
592+ for k , v in kwargs .items ()}
593+
594+ def byte_CALL_FUNCTION_EX (self , opcode ):
595+ if opcode .arg & _Flags .CALL_FUNCTION_EX_HAS_KWARGS :
596+ starstarargs = self ._stack .pop ()
597+ kwargs = self ._unpack_starstarargs (starstarargs )
598+ else :
599+ kwargs = _EMPTY_MAP
600+ starargs = self ._stack .pop ()
601+ posargs = self ._unpack_starargs (starargs ).constant
602+ func = self ._stack .pop ()
603+ if self ._code .python_version >= (3 , 11 ):
604+ self ._stack .pop_and_discard ()
605+ callargs = abstract .Args (posargs = posargs , kwargs = kwargs , frame = self )
606+ self ._call_function (func , callargs )
607+
561608 def byte_CALL_METHOD (self , opcode ):
562609 args = self ._stack .popn (opcode .arg )
563610 func = self ._stack .pop ()
@@ -615,6 +662,8 @@ def byte_BUILD_CONST_KEY_MAP(self, opcode):
615662 # to abstract objects because they are used internally to construct function
616663 # call args.
617664 keys = abstract .get_atomic_constant (keys , tuple )
665+ # Unpack the keys into raw strings.
666+ keys = [abstract .get_atomic_constant (k , str ) for k in keys ]
618667 assert len (keys ) == n_elts
619668 vals = self ._stack .popn (n_elts )
620669 ret = dict (zip (keys , vals ))
0 commit comments