Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 10 additions & 14 deletions runtime/runtime-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1403,16 +1403,15 @@ TEST_F(RuntimeTest, CollectAttributes) {
Code code0(&scope, newCodeWithBytesConstsNamesLocals(bytecode0, consts, names,
&locals));

Dict attributes(&scope, runtime_->newDict());
Set attributes(&scope, runtime_->newSet());
runtime_->collectAttributes(code0, attributes);

// We should have collected a single attribute: 'foo'
EXPECT_EQ(attributes.numItems(), 1);

// Check that we collected 'foo'
Object result(&scope, dictAtByStr(thread_, attributes, foo));
ASSERT_TRUE(result.isStr());
EXPECT_TRUE(Str::cast(*result).equals(*foo));
word hash = strHash(thread_, *foo);
EXPECT_TRUE(setIncludes(thread_, attributes, foo, hash));

// Bytecode for the snippet:
//
Expand All @@ -1430,14 +1429,12 @@ TEST_F(RuntimeTest, CollectAttributes) {
EXPECT_EQ(attributes.numItems(), 3);

// Check that we collected 'bar'
result = dictAtByStr(thread_, attributes, bar);
ASSERT_TRUE(result.isStr());
EXPECT_TRUE(Str::cast(*result).equals(*bar));
hash = strHash(thread_, *bar);
EXPECT_TRUE(setIncludes(thread_, attributes, bar, hash));

// Check that we collected 'baz'
result = dictAtByStr(thread_, attributes, baz);
ASSERT_TRUE(result.isStr());
EXPECT_TRUE(Str::cast(*result).equals(*baz));
hash = strHash(thread_, *baz);
EXPECT_TRUE(setIncludes(thread_, attributes, baz, hash));
}

TEST_F(RuntimeTest, CollectAttributesWithExtendedArg) {
Expand Down Expand Up @@ -1467,16 +1464,15 @@ TEST_F(RuntimeTest, CollectAttributesWithExtendedArg) {
Code code(&scope, newCodeWithBytesConstsNamesLocals(bytecode, consts, names,
&locals));

Dict attributes(&scope, runtime_->newDict());
Set attributes(&scope, runtime_->newSet());
runtime_->collectAttributes(code, attributes);

// We should have collected a single attribute: 'foo'
EXPECT_EQ(attributes.numItems(), 1);

// Check that we collected 'foo'
Object result(&scope, dictAtByStr(thread_, attributes, foo));
ASSERT_TRUE(result.isStr());
EXPECT_TRUE(Str::cast(*result).equals(*foo));
word hash = strHash(thread_, *foo);
EXPECT_TRUE(setIncludes(thread_, attributes, foo, hash));
}

TEST_F(RuntimeTest, GetTypeConstructor) {
Expand Down
14 changes: 8 additions & 6 deletions runtime/runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2872,18 +2872,19 @@ RawObject Runtime::newWeakRef(Thread* thread, const Object& referent) {
return *ref;
}

void Runtime::collectAttributes(const Code& code, const Dict& attributes) {
void Runtime::collectAttributes(const Code& code, const Set& attributes) {
Thread* thread = Thread::current();
HandleScope scope(thread);
Bytes bc(&scope, code.code());
Tuple names(&scope, code.names());
Str name(&scope, Str::empty());

word len = bc.length();
for (word i = 0; i < len - 3; i += 2) {
for (word i = 0; i < len - 3; i += kCompilerCodeUnitSize) {
// If the current instruction is EXTENDED_ARG we must skip it and the next
// instruction.
if (bc.byteAt(i) == Bytecode::EXTENDED_ARG) {
i += 2;
while (bc.byteAt(i) == Bytecode::EXTENDED_ARG) {
i += kCompilerCodeUnitSize;
continue;
}
// Check for LOAD_FAST 0 (self)
Expand All @@ -2895,8 +2896,9 @@ void Runtime::collectAttributes(const Code& code, const Dict& attributes) {
continue;
}
word name_index = bc.byteAt(i + 3);
Str name(&scope, names.at(name_index));
dictAtPutByStr(thread, attributes, name, name);
name = names.at(name_index);
word hash = strHash(thread, *name);
setAdd(thread, attributes, name, hash);
}
}

Expand Down
2 changes: 1 addition & 1 deletion runtime/runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ class Runtime {

// Performs a simple scan of the bytecode and collects all attributes that
// are set via `self.<attribute> =` into attributes.
void collectAttributes(const Code& code, const Dict& attributes);
void collectAttributes(const Code& code, const Set& attributes);

// Returns type's __init__ method, or None
RawObject classConstructor(const Type& type);
Expand Down
2 changes: 1 addition & 1 deletion runtime/type-builtins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ static word estimateNumAttributes(Thread* thread, const Type& type) {
// each class in the MRO. This is used to determine the number of slots
// allocated for in-object attributes when instances are created.
Tuple mro(&scope, type.mro());
Dict attr_names(&scope, runtime->newDict());
Set attr_names(&scope, runtime->newSet());
for (word i = 0; i < mro.length(); i++) {
Type mro_type(&scope, mro.at(i));
Object maybe_init(&scope, runtime->classConstructor(mro_type));
Expand Down