this repo has no description
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com)
2#include "modules.h"
3
4#include "builtins.h"
5#include "capi.h"
6#include "frozen-modules.h"
7#include "globals.h"
8#include "marshal.h"
9#include "module-builtins.h"
10#include "object-builtins.h"
11#include "runtime.h"
12#include "symbols.h"
13#include "type-builtins.h"
14
15namespace py {
16
17static word builtinModuleIndex(const Str& name) {
18 for (word i = 0; i < kNumFrozenModules; i++) {
19 if (name.equalsCStr(kFrozenModules[i].name)) {
20 return i;
21 }
22 }
23 return -1;
24}
25
26static RawObject createBuiltinModule(Thread* thread, const Str& name) {
27 HandleScope scope(thread);
28 Runtime* runtime = thread->runtime();
29 word builtin_index = builtinModuleIndex(name);
30 if (builtin_index >= 0) {
31 const FrozenModule* frozen_module = &kFrozenModules[builtin_index];
32 Module module(&scope, runtime->newModule(name));
33 Object modules(&scope, runtime->modules());
34 Object result(&scope, objectSetItem(thread, modules, name, module));
35 if (result.isErrorException()) return *result;
36 ModuleInitFunc init = frozen_module->init;
37 if (init == nullptr) {
38 init = executeFrozenModule;
39 }
40 View<byte> bytecode(frozen_module->marshalled_code,
41 frozen_module->marshalled_code_length);
42 init(thread, module, bytecode);
43 return *module;
44 }
45
46 Object module(&scope, moduleInitBuiltinExtension(thread, name));
47 if (module.isErrorException()) return *module;
48 Object modules(&scope, runtime->modules());
49 Object result(&scope, objectSetItem(thread, modules, name, module));
50 if (result.isErrorException()) return *result;
51 return *module;
52}
53
54RawObject ensureBuiltinModule(Thread* thread, const Str& name) {
55 DCHECK(Runtime::isInternedStr(thread, name), "expected interned str");
56 Runtime* runtime = thread->runtime();
57 HandleScope scope(thread);
58 Object result(&scope, runtime->findModule(name));
59 if (!result.isErrorNotFound()) return *result;
60 return createBuiltinModule(thread, name);
61}
62
63RawObject ensureBuiltinModuleById(Thread* thread, SymbolId id) {
64 Runtime* runtime = thread->runtime();
65 HandleScope scope(thread);
66 Object result(&scope, runtime->findModuleById(id));
67 if (!result.isErrorNotFound()) return *result;
68 Str name(&scope, runtime->symbols()->at(id));
69 return createBuiltinModule(thread, name);
70}
71
72void executeFrozenModule(Thread* thread, const Module& module,
73 View<byte> bytecode) {
74 HandleScope scope(thread);
75 Marshal::Reader reader(&scope, thread, bytecode);
76 reader.setBuiltinFunctions(kBuiltinFunctions, kNumBuiltinFunctions,
77 kIntrinsicFunctions, kNumIntrinsicFunctions);
78 Str filename(&scope, module.name());
79 // We don't write pyc headers for frozen modules because it would make
80 // bootstrapping tricky. Don't read the pyc header.
81 Code code(&scope, reader.readObject());
82 Object result(&scope, executeModule(thread, code, module));
83 CHECK(!result.isErrorException(), "Failed to execute %s module",
84 filename.toCStr());
85}
86
87RawObject executeModule(Thread* thread, const Code& code,
88 const Module& module) {
89 HandleScope scope(thread);
90 DCHECK(code.argcount() == 0, "invalid argcount %ld", code.argcount());
91 Object none(&scope, NoneType::object());
92 return thread->exec(code, module, none);
93}
94
95RawObject executeModuleFromCode(Thread* thread, const Code& code,
96 const Object& name) {
97 HandleScope scope(thread);
98 Runtime* runtime = thread->runtime();
99 Module module(&scope, runtime->newModule(name));
100 Object modules(&scope, runtime->modules());
101 Object result(&scope, objectSetItem(thread, modules, name, module));
102 if (result.isErrorException()) return *result;
103 result = executeModule(thread, code, module);
104 if (result.isError()) return *result;
105 return *module;
106}
107
108bool isFrozenModule(const Str& name) { return builtinModuleIndex(name) >= 0; }
109
110bool isFrozenPackage(const Str& name) {
111 word index = builtinModuleIndex(name);
112 if (index < 0) {
113 return false;
114 }
115 const FrozenModule* frozen_module = &kFrozenModules[index];
116 return frozen_module->is_package;
117}
118
119const FrozenModule* frozenModuleByName(const Str& name) {
120 word index = builtinModuleIndex(name);
121 if (index < 0) {
122 return nullptr;
123 }
124 return &kFrozenModules[index];
125}
126
127} // namespace py