@@ -3674,31 +3674,6 @@ Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallattrRe
36743674
36753675 int npassed_args = argspec.totalPassed ();
36763676
3677- if (rewrite_args && !rewrite_args->args_guarded ) {
3678- // TODO duplication with runtime_call
3679- // TODO should know which args don't need to be guarded, ex if we're guaranteed that they
3680- // already fit, either since the type inferencer could determine that,
3681- // or because they only need to fit into an UNKNOWN slot.
3682-
3683- if (npassed_args >= 1 )
3684- rewrite_args->arg1 ->addAttrGuard (offsetof (Box, cls), (intptr_t )arg1->cls );
3685- if (npassed_args >= 2 )
3686- rewrite_args->arg2 ->addAttrGuard (offsetof (Box, cls), (intptr_t )arg2->cls );
3687- if (npassed_args >= 3 )
3688- rewrite_args->arg3 ->addAttrGuard (offsetof (Box, cls), (intptr_t )arg3->cls );
3689-
3690- if (npassed_args > 3 ) {
3691- for (int i = 3 ; i < npassed_args; i++) {
3692- // TODO if there are a lot of args (>16), might be better to increment a pointer
3693- // rather index them directly?
3694- RewriterVar* v = rewrite_args->args ->getAttr ((i - 3 ) * sizeof (Box*), Location::any ());
3695- v->addAttrGuard (offsetof (Box, cls), (intptr_t )args[i - 3 ]->cls );
3696- }
3697- }
3698-
3699- rewrite_args->args_guarded = true ;
3700- }
3701-
37023677 // right now I don't think this is ever called with INST_ONLY?
37033678 assert (scope != INST_ONLY);
37043679
@@ -5083,6 +5058,36 @@ const char* PyEval_GetFuncDesc(PyObject* func) noexcept {
50835058 }
50845059}
50855060
5061+ static void addArgGuards (CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1, Box* arg2, Box* arg3,
5062+ Box** args) {
5063+ // TODO should know which args don't need to be guarded, ex if we're guaranteed that they
5064+ // already fit, either since the type inferencer could determine that,
5065+ // or because they only need to fit into an UNKNOWN slot.
5066+
5067+ int kwargs_index = -1 ;
5068+ if (argspec.has_kwargs )
5069+ kwargs_index = argspec.kwargsIndex ();
5070+
5071+ for (int i = 0 ; i < argspec.totalPassed (); i++) {
5072+ Box* v = getArg (i, arg1, arg2, arg3, args);
5073+
5074+ if (i == kwargs_index) {
5075+ if (v == NULL ) {
5076+ // I don't think this case should ever get hit currently -- the only places
5077+ // we offer rewriting are places that don't have the ability to pass a NULL
5078+ // kwargs.
5079+ getArg (i, rewrite_args)->addGuard (0 );
5080+ } else {
5081+ getArg (i, rewrite_args)->addAttrGuard (offsetof (Box, cls), (intptr_t )v->cls );
5082+ }
5083+ } else {
5084+ assert (v);
5085+ getArg (i, rewrite_args)->addAttrGuard (offsetof (Box, cls), (intptr_t )v->cls );
5086+ }
5087+ }
5088+ rewrite_args->args_guarded = true ;
5089+ }
5090+
50865091
50875092template <ExceptionStyle S, Rewritable rewritable>
50885093Box* runtimeCallInternal (Box* obj, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1, Box* arg2, Box* arg3,
@@ -5173,65 +5178,46 @@ Box* runtimeCallInternal(Box* obj, CallRewriteArgs* rewrite_args, ArgPassSpec ar
51735178 return rtn;
51745179 }
51755180
5176- if (rewrite_args) {
5177- if (!rewrite_args->args_guarded ) {
5178- // TODO should know which args don't need to be guarded, ex if we're guaranteed that they
5179- // already fit, either since the type inferencer could determine that,
5180- // or because they only need to fit into an UNKNOWN slot.
5181-
5182- int kwargs_index = -1 ;
5183- if (argspec.has_kwargs )
5184- kwargs_index = argspec.kwargsIndex ();
5185-
5186- for (int i = 0 ; i < npassed_args; i++) {
5187- Box* v = getArg (i, arg1, arg2, arg3, args);
5188-
5189- if (i == kwargs_index) {
5190- if (v == NULL ) {
5191- // I don't think this case should ever get hit currently -- the only places
5192- // we offer rewriting are places that don't have the ability to pass a NULL
5193- // kwargs.
5194- getArg (i, rewrite_args)->addGuard (0 );
5195- } else {
5196- getArg (i, rewrite_args)->addAttrGuard (offsetof (Box, cls), (intptr_t )v->cls );
5197- }
5198- } else {
5199- assert (v);
5200- getArg (i, rewrite_args)->addAttrGuard (offsetof (Box, cls), (intptr_t )v->cls );
5201- }
5202- }
5203- rewrite_args->args_guarded = true ;
5204- }
5205- }
52065181
52075182 if (obj->cls == function_cls || obj->cls == builtin_function_or_method_cls) {
52085183 BoxedFunctionBase* f = static_cast <BoxedFunctionBase*>(obj);
5209-
5210- if (rewrite_args && !rewrite_args->func_guarded ) {
5211- rewrite_args->obj ->addGuard ((intptr_t )f);
5212- rewrite_args->func_guarded = true ;
5213- rewrite_args->rewriter ->addDependenceOn (f->dependent_ics );
5214- }
5184+ auto md = f->md ;
52155185
52165186 // Some functions are sufficiently important that we want them to be able to patchpoint themselves;
52175187 // they can do this by setting the "internal_callable" field:
5218- auto callable = f->md ->internal_callable .get <S>();
5219-
5188+ auto callable = md->internal_callable .get <S>();
52205189 if (S == CAPI)
5221- assert ((bool (f-> md ->internal_callable .get (CXX)) == bool (callable))
5190+ assert ((bool (md->internal_callable .get (CXX)) == bool (callable))
52225191 && " too many opportunities for mistakes unless both CXX and CAPI versions are implemented" );
52235192 else
5224- assert ((bool (f-> md ->internal_callable .get (CAPI)) == bool (callable))
5193+ assert ((bool (md->internal_callable .get (CAPI)) == bool (callable))
52255194 && " too many opportunities for mistake unless both CXX and CAPI versions are implementeds" );
52265195
52275196 if (callable == NULL ) {
52285197 callable = callFunc<S>;
52295198 }
52305199
5200+ if (rewrite_args && !rewrite_args->args_guarded ) {
5201+ bool does_not_need_guards = callable == &callFunc<S> && md->always_use_version ;
5202+ if (!does_not_need_guards)
5203+ addArgGuards (rewrite_args, argspec, arg1, arg2, arg3, args);
5204+ }
5205+
5206+ if (rewrite_args && !rewrite_args->func_guarded ) {
5207+ rewrite_args->obj ->addGuard ((intptr_t )f);
5208+ rewrite_args->func_guarded = true ;
5209+ // callFunc will add the invalidator
5210+ if (callable != &callFunc<S>)
5211+ rewrite_args->rewriter ->addDependenceOn (f->dependent_ics );
5212+ }
5213+
52315214 KEEP_ALIVE (f);
52325215 Box* res = callable (f, rewrite_args, argspec, arg1, arg2, arg3, args, keyword_names);
52335216 return res;
52345217 } else if (obj->cls == instancemethod_cls) {
5218+ if (rewrite_args && !rewrite_args->args_guarded )
5219+ addArgGuards (rewrite_args, argspec, arg1, arg2, arg3, args);
5220+
52355221 BoxedInstanceMethod* im = static_cast <BoxedInstanceMethod*>(obj);
52365222
52375223 RewriterVar* r_im_func = NULL ;
0 commit comments