this repo has no description
at trunk 120 lines 4.8 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "type-utils.h" 3 4#include "api-handle.h" 5#include "globals.h" 6#include "handles.h" 7#include "runtime.h" 8#include "symbols.h" 9#include "thread.h" 10 11namespace py { 12 13static const SymbolId kParamsSelfValue[] = {ID(self), ID(value)}; 14static const SymbolId kParamsSelf[] = {ID(self)}; 15 16RawObject newExtCode(Thread* thread, const Object& name, 17 View<SymbolId> parameters, word flags, 18 BuiltinFunction function, void* slot_value) { 19 HandleScope scope(thread); 20 Runtime* runtime = thread->runtime(); 21 Object code_code(&scope, 22 SmallInt::fromAlignedCPtr(bit_cast<void*>(function))); 23 Tuple empty_tuple(&scope, runtime->emptyTuple()); 24 Object varnames_obj(&scope, *empty_tuple); 25 26 word num_parameters = parameters.length(); 27 if (num_parameters > 0) { 28 MutableTuple varnames(&scope, runtime->newMutableTuple(num_parameters)); 29 for (word i = 0; i < num_parameters; i++) { 30 varnames.atPut(i, runtime->symbols()->at(parameters.get(i))); 31 } 32 varnames_obj = varnames.becomeImmutable(); 33 } 34 35 word argcount = num_parameters - ((flags & Code::Flags::kVarargs) != 0) - 36 ((flags & Code::Flags::kVarkeyargs) != 0); 37 flags |= Code::Flags::kOptimized | Code::Flags::kNewlocals; 38 39 Object filename(&scope, Str::empty()); 40 Object lnotab(&scope, Bytes::empty()); 41 Object ptr(&scope, runtime->newIntFromCPtr(slot_value)); 42 Tuple consts(&scope, runtime->newTupleWith1(ptr)); 43 return runtime->newCode(argcount, /*posonlyargcount=*/num_parameters, 44 /*kwonlyargcount=*/0, 45 /*nlocals=*/num_parameters, 46 /*stacksize=*/0, flags, code_code, consts, 47 /*names=*/empty_tuple, varnames_obj, 48 /*freevars=*/empty_tuple, /*cellvars=*/empty_tuple, 49 filename, name, /*firstlineno=*/0, lnotab); 50} 51 52static ALIGN_16 RawObject getterWrapper(Thread* thread, Arguments args) { 53 PyGetSetDef* getset = reinterpret_cast<PyGetSetDef*>(getNativeFunc(thread)); 54 getter func = getset->get; 55 void* closure = getset->closure; 56 PyObject* self = ApiHandle::newReference(thread->runtime(), args.get(0)); 57 PyObject* result = (*func)(self, closure); 58 ApiHandle::decref(ApiHandle::fromPyObject(self)); 59 return ApiHandle::checkFunctionResult(thread, result); 60} 61 62static RawObject getSetGetter(Thread* thread, const Object& name, 63 PyGetSetDef* def) { 64 if (def->get == nullptr) return NoneType::object(); 65 HandleScope scope(thread); 66 Runtime* runtime = thread->runtime(); 67 Code code(&scope, newExtCode(thread, name, kParamsSelf, 68 /*flags=*/0, getterWrapper, 69 reinterpret_cast<void*>(def))); 70 Object globals(&scope, NoneType::object()); 71 Function function(&scope, 72 runtime->newFunctionWithCode(thread, name, code, globals)); 73 if (def->doc != nullptr) { 74 Object doc(&scope, runtime->newStrFromCStr(def->doc)); 75 function.setDoc(*doc); 76 } 77 return *function; 78} 79 80static ALIGN_16 RawObject setterWrapper(Thread* thread, Arguments args) { 81 PyGetSetDef* getset = reinterpret_cast<PyGetSetDef*>(getNativeFunc(thread)); 82 setter func = getset->set; 83 void* closure = getset->closure; 84 Runtime* runtime = thread->runtime(); 85 PyObject* self = ApiHandle::newReference(runtime, args.get(0)); 86 PyObject* value = ApiHandle::newReference(runtime, args.get(1)); 87 int result = func(self, value, closure); 88 ApiHandle::decref(ApiHandle::fromPyObject(self)); 89 ApiHandle::decref(ApiHandle::fromPyObject(value)); 90 if (result < 0) return Error::exception(); 91 return NoneType::object(); 92} 93 94static RawObject getSetSetter(Thread* thread, const Object& name, 95 PyGetSetDef* def) { 96 if (def->set == nullptr) return NoneType::object(); 97 HandleScope scope(thread); 98 Runtime* runtime = thread->runtime(); 99 Code code(&scope, newExtCode(thread, name, kParamsSelfValue, 100 /*flags=*/0, setterWrapper, 101 reinterpret_cast<void*>(def))); 102 Object globals(&scope, NoneType::object()); 103 Function function(&scope, 104 runtime->newFunctionWithCode(thread, name, code, globals)); 105 if (def->doc != nullptr) { 106 Object doc(&scope, runtime->newStrFromCStr(def->doc)); 107 function.setDoc(*doc); 108 } 109 return *function; 110} 111 112RawObject newGetSet(Thread* thread, const Object& name, PyGetSetDef* def) { 113 HandleScope scope(thread); 114 Object getter(&scope, getSetGetter(thread, name, def)); 115 Object setter(&scope, getSetSetter(thread, name, def)); 116 Object none(&scope, NoneType::object()); 117 return thread->runtime()->newProperty(getter, setter, none); 118} 119 120} // namespace py