this repo has no description
at trunk 86 lines 2.9 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "frame.h" 3 4#include <cstring> 5 6#include "dict-builtins.h" 7#include "handles.h" 8#include "objects.h" 9#include "runtime.h" 10 11namespace py { 12 13const char* Frame::isInvalid() { 14 if (!at(kPreviousFrameOffset).isSmallInt()) { 15 return "bad previousFrame field"; 16 } 17 if (!isSentinel() && !(locals() + kFunctionOffsetFromLocals)->isFunction()) { 18 return "bad function"; 19 } 20 return nullptr; 21} 22 23RawObject frameLocals(Thread* thread, Frame* frame) { 24 HandleScope scope(thread); 25 Function function(&scope, frame->function()); 26 if (!function.hasOptimizedOrNewlocals()) { 27 Object implicit_globals(&scope, frame->implicitGlobals()); 28 if (implicit_globals.isNoneType()) { 29 Module module(&scope, function.moduleObject()); 30 return module.moduleProxy(); 31 } 32 return *implicit_globals; 33 } 34 35 Code code(&scope, function.code()); 36 Runtime* runtime = thread->runtime(); 37 Tuple empty_tuple(&scope, runtime->emptyTuple()); 38 Tuple var_names(&scope, 39 code.varnames().isTuple() ? code.varnames() : *empty_tuple); 40 Tuple freevar_names( 41 &scope, code.freevars().isTuple() ? code.freevars() : *empty_tuple); 42 Tuple cellvar_names( 43 &scope, code.cellvars().isTuple() ? code.cellvars() : *empty_tuple); 44 45 word var_names_length = var_names.length(); 46 word freevar_names_length = freevar_names.length(); 47 word cellvar_names_length = cellvar_names.length(); 48 49 DCHECK(function.totalLocals() == 50 var_names_length + freevar_names_length + cellvar_names_length, 51 "numbers of local variables do not match"); 52 53 Dict result(&scope, runtime->newDict()); 54 Str name(&scope, Str::empty()); 55 Object value(&scope, NoneType::object()); 56 for (word i = 0; i < var_names_length; ++i) { 57 name = var_names.at(i); 58 value = frame->local(i); 59 // TODO(T89882231) Remove check when we can verify locals have been 60 // initialized 61 if (value.isInternal()) continue; 62 dictAtPutByStr(thread, result, name, value); 63 } 64 for (word i = 0, j = var_names_length; i < freevar_names_length; ++i, ++j) { 65 name = freevar_names.at(i); 66 DCHECK(frame->local(j).isCell(), "freevar must be Cell"); 67 value = Cell::cast(frame->local(j)).value(); 68 // TODO(T89882231) Remove check when we can verify locals have been 69 // initialized 70 if (value.isInternal()) continue; 71 dictAtPutByStr(thread, result, name, value); 72 } 73 for (word i = 0, j = var_names_length + freevar_names_length; 74 i < cellvar_names_length; ++i, ++j) { 75 name = cellvar_names.at(i); 76 DCHECK(frame->local(j).isCell(), "cellvar must be Cell"); 77 value = Cell::cast(frame->local(j)).value(); 78 // TODO(T89882231) Remove check when we can verify locals have been 79 // initialized 80 if (value.isInternal()) continue; 81 dictAtPutByStr(thread, result, name, value); 82 } 83 return *result; 84} 85 86} // namespace py