@@ -89,7 +89,8 @@ struct RewrittenOp {
89
89
bool needs_inline_cache;
90
90
};
91
91
92
- static RewrittenOp rewriteOperation (const Function& function, BytecodeOp op) {
92
+ static RewrittenOp rewriteOperation (const Function& function, BytecodeOp op,
93
+ bool is_builtin_module) {
93
94
auto cached_binop = [](Interpreter::BinaryOp bin_op) {
94
95
return RewrittenOp{BINARY_OP_ANAMORPHIC, static_cast <int32_t >(bin_op),
95
96
true };
@@ -177,6 +178,20 @@ static RewrittenOp rewriteOperation(const Function& function, BytecodeOp op) {
177
178
return cached_inplace (Interpreter::BinaryOp::XOR);
178
179
case LOAD_ATTR:
179
180
return RewrittenOp{LOAD_ATTR_ANAMORPHIC, op.arg , true };
181
+ case LOAD_GLOBAL: {
182
+ if (is_builtin_module) {
183
+ RawTuple names = Tuple::cast (Code::cast (function.code ()).names ());
184
+ RawStr name = Str::cast (names.at (op.arg ));
185
+ if (name.equalsCStr (" _Unbound" )) {
186
+ DCHECK (Unbound::object () ==
187
+ objectFromOparg (opargFromObject (Unbound::object ())),
188
+ " Expected to be able to fit _Unbound in a byte" );
189
+ return RewrittenOp{LOAD_IMMEDIATE, opargFromObject (Unbound::object ()),
190
+ false };
191
+ }
192
+ }
193
+ break ;
194
+ }
180
195
case LOAD_FAST: {
181
196
CHECK (op.arg < Code::cast (function.code ()).nlocals (),
182
197
" unexpected local number" );
@@ -291,7 +306,8 @@ void rewriteBytecode(Thread* thread, const Function& function) {
291
306
word num_caches = num_global_caches;
292
307
for (word i = 0 ; i < num_opcodes;) {
293
308
BytecodeOp op = nextBytecodeOp (bytecode, &i);
294
- RewrittenOp rewritten = rewriteOperation (function, op);
309
+ RewrittenOp rewritten = rewriteOperation (function, op,
310
+ /* is_builtin_module=*/ false );
295
311
if (rewritten.needs_inline_cache ) {
296
312
num_caches++;
297
313
}
@@ -308,10 +324,13 @@ void rewriteBytecode(Thread* thread, const Function& function) {
308
324
return ;
309
325
}
310
326
word cache = num_global_caches;
327
+ RawObject module = function.moduleObject ();
328
+ bool is_builtin_module =
329
+ module.isModule () && Module::cast (module).isBuiltin ();
311
330
for (word i = 0 ; i < num_opcodes;) {
312
331
BytecodeOp op = nextBytecodeOp (bytecode, &i);
313
332
word previous_index = i - 1 ;
314
- RewrittenOp rewritten = rewriteOperation (function, op);
333
+ RewrittenOp rewritten = rewriteOperation (function, op, is_builtin_module );
315
334
if (rewritten.bc == UNUSED_BYTECODE_0) continue ;
316
335
if (rewritten.needs_inline_cache ) {
317
336
rewrittenBytecodeOpAtPut (bytecode, previous_index, rewritten.bc );
0 commit comments